Beispiel #1
0
    public static AADClient Inject(uint processId, InjectionClrVersion clrVersion, string pipeName)
    {
        if (processId == 0)
        {
            throw new ArgumentNullException(nameof(processId));
        }
        if (string.IsNullOrEmpty(pipeName))
        {
            throw new ArgumentException($"'{nameof(pipeName)}' cannot be null or empty.", nameof(pipeName));
        }

        bool b = Injector.InjectManaged(processId, GetAADCorePath(), "ExtremeDumper.AntiAntiDump.Injection", "Main", pipeName, clrVersion);

        if (!b)
        {
            throw new InvalidOperationException("Can't inject ExtremeDumper.AntiAntiDump.dll to target process.");
        }
        Logger.Info($"ExtremeDumper.AntiAntiDump.dll has been injected into process {processId} and clr version is {clrVersion}");

        var client = AADClient.Create(pipeName);

        if (client is null)
        {
            throw new InvalidOperationException($"Can't create {nameof(AADClient)}.");
        }
        Logger.Info($"Create {nameof(AADClient)} of process {processId} successfully and clr version is {clrVersion}");

        return(client);
    }
Beispiel #2
0
        private static void IsAssembly(string path, out bool isAssembly, out InjectionClrVersion clrVersion)
        {
            BinaryReader binaryReader;

            try {
                using (binaryReader = new BinaryReader(new FileStream(path, FileMode.Open, FileAccess.Read)))
                    switch (GetVersionString(binaryReader))
                    {
                    case CLR_V2:
                        clrVersion = InjectionClrVersion.V2;
                        break;

                    case CLR_V4:
                        clrVersion = InjectionClrVersion.V4;
                        break;

                    default:
                        clrVersion = default;
                        break;
                    }
                isAssembly = true;
            }
            catch {
                clrVersion = default;
                isAssembly = false;
            }
        }
Beispiel #3
0
 private static void IsAssembly(string path, out bool isAssembly, out InjectionClrVersion clrVersion)
 {
     try {
         using (BinaryReader reader = new BinaryReader(new FileStream(path, FileMode.Open, FileAccess.Read)))
             clrVersion = GetVersionString(reader) switch
             {
                 CLR_V2 => InjectionClrVersion.V2,
                 CLR_V4 => InjectionClrVersion.V4,
                 _ => default,
Beispiel #4
0
 public static AADClient Inject(uint processId, InjectionClrVersion clrVersion)
 {
     return(Inject(processId, clrVersion, Guid.NewGuid().ToString()));
 }
Beispiel #5
0
        /// <summary>
        /// 注入托管DLL,并获取被调用方法的返回值(警告:被调用方法返回后才能获取到返回值,<see cref="InjectManaged(string, string, string, string, out int)"/>方法将一直等待到被调用方法返回。如果仅注入程序集而不需要获取返回值,请使用重载版本<see cref="InjectManaged(string, string, string, string)"/>)
        /// </summary>
        /// <param name="assemblyPath">要注入程序集的路径</param>
        /// <param name="typeName">类型名(命名空间+类型名,比如NamespaceA.ClassB)</param>
        /// <param name="methodName">方法名(比如MethodC),该方法必须具有此类签名static int MethodName(string),比如private static int InjectingMain(string argument)</param>
        /// <param name="argument">参数,可传入 <see langword="null"/></param>
        /// <param name="clrVersion">使用的CLR版本</param>
        /// <param name="returnValue">被调用方法返回的整数值</param>
        /// <returns></returns>
        public bool InjectManaged(string assemblyPath, string typeName, string methodName, string argument, InjectionClrVersion clrVersion, out int returnValue)
        {
            if (string.IsNullOrEmpty(assemblyPath))
            {
                throw new ArgumentNullException(nameof(assemblyPath));
            }
            if (!File.Exists(assemblyPath))
            {
                throw new FileNotFoundException();
            }
            if (string.IsNullOrEmpty(typeName))
            {
                throw new ArgumentNullException(nameof(typeName));
            }
            if (string.IsNullOrEmpty(methodName))
            {
                throw new ArgumentNullException(nameof(methodName));
            }

            QuickDemand(ProcessAccess.CreateThread | ProcessAccess.MemoryOperation | ProcessAccess.MemoryRead | ProcessAccess.MemoryWrite | ProcessAccess.QueryInformation | ProcessAccess.Synchronize);
            return(Injector.InjectManagedInternal(_handle, assemblyPath, typeName, methodName, argument, clrVersion, out returnValue, true));
        }
Beispiel #6
0
        private static void *WriteMachineCode(void *processHandle, InjectionClrVersion clrVersion, string assemblyPath, string typeName, string methodName, string argument)
        {
            bool   is64Bit;
            string clrVersionString;

            byte[] machineCode;
            void * pEnvironment;
            void * pCorBindToRuntimeEx;
            void * pCLRCreateInstance;

            if (!NativeProcess.Is64BitProcessInternal(processHandle, out is64Bit))
            {
                return(null);
            }
            clrVersionString = clrVersion switch
            {
                InjectionClrVersion.V2 => CLR_V2,
                InjectionClrVersion.V4 => CLR_V4,
                _ => throw new ArgumentOutOfRangeException(nameof(clrVersion)),
            };
            machineCode  = GetMachineCodeTemplate(clrVersionString, assemblyPath, typeName, methodName, argument);
            pEnvironment = NativeProcess.AllocMemoryInternal(processHandle, 0x1000 + (argument is null ? 0 : (uint)argument.Length * 2 + 2), MemoryProtection.ExecuteReadWrite);
            if (pEnvironment == null)
            {
                return(null);
            }
            try
            {
                fixed(byte *p = machineCode)
                switch (clrVersion)
                {
                case InjectionClrVersion.V2:
                    pCorBindToRuntimeEx = NativeModule.GetFunctionAddressInternal(processHandle, "mscoree.dll", "CorBindToRuntimeEx");
                    if (pCorBindToRuntimeEx == null)
                    {
                        return(null);
                    }
                    if (is64Bit)
                    {
                        WriteMachineCode64v2(p, (ulong)pEnvironment, (ulong)pCorBindToRuntimeEx);
                    }
                    else
                    {
                        WriteMachineCode32v2(p, (uint)pEnvironment, (uint)pCorBindToRuntimeEx);
                    }
                    break;

                case InjectionClrVersion.V4:
                    pCLRCreateInstance = NativeModule.GetFunctionAddressInternal(processHandle, "mscoree.dll", "CLRCreateInstance");
                    if (pCLRCreateInstance == null)
                    {
                        return(null);
                    }
                    if (is64Bit)
                    {
                        WriteMachineCode64v4(p, (ulong)pEnvironment, (ulong)pCLRCreateInstance);
                    }
                    else
                    {
                        WriteMachineCode32v4(p, (uint)pEnvironment, (uint)pCLRCreateInstance);
                    }
                    break;
                }
                if (!NativeProcess.WriteBytesInternal(processHandle, pEnvironment, machineCode))
                {
                    return(null);
                }
            }
            catch {
                NativeProcess.FreeMemoryInternal(processHandle, pEnvironment);
                return(null);
            }
            return(pEnvironment);
        }
Beispiel #7
0
        internal static bool InjectManagedInternal(void *processHandle, string assemblyPath, string typeName, string methodName, string argument, InjectionClrVersion clrVersion, out int returnValue, bool wait)
        {
            bool isAssembly;
            InjectionClrVersion clrVersionTemp;
            void *pEnvironment;
            void *threadHandle;
            uint  exitCode;

            returnValue  = 0;
            assemblyPath = Path.GetFullPath(assemblyPath);
            // 获取绝对路径
            IsAssembly(assemblyPath, out isAssembly, out clrVersionTemp);
            if (clrVersion == InjectionClrVersion.Auto)
            {
                clrVersion = clrVersionTemp;
            }
            if (!isAssembly)
            {
                throw new NotSupportedException("Not a valid .NET assembly.");
            }
            if (!InjectUnmanagedInternal(processHandle, Path.Combine(Environment.GetEnvironmentVariable("SystemRoot"), @"System32\mscoree.dll")))
            {
                return(false);
            }
            // 加载对应进程位数的mscoree.dll
            pEnvironment = WriteMachineCode(processHandle, clrVersion, assemblyPath, typeName, methodName, argument);
            // 获取远程进程中启动CLR的函数指针
            if (pEnvironment == null)
            {
                return(false);
            }
            threadHandle = CreateRemoteThread(processHandle, null, 0, pEnvironment, ((byte *)pEnvironment + ReturnValueOffset), 0, null);
            if (threadHandle == null)
            {
                return(false);
            }
            if (wait)
            {
                WaitForSingleObject(threadHandle, INFINITE);
                // 等待线程结束
                if (!GetExitCodeThread(threadHandle, out exitCode))
                {
                    return(false);
                }
                if (!NativeProcess.ReadInt32Internal(processHandle, ((byte *)pEnvironment + ReturnValueOffset), out returnValue))
                {
                    return(false);
                }
                // 获取程序集中被调用方法的返回值
                if (!NativeProcess.FreeMemoryInternal(processHandle, pEnvironment))
                {
                    return(false);
                }
                return(exitCode == 0);
            }
            return(true);
        }
Beispiel #8
0
 /// <summary>
 /// 注入托管DLL,并获取被调用方法的返回值(警告:被调用方法返回后才能获取到返回值,<see cref="InjectManaged(string, string, string, string, out int)"/>方法将一直等待到被调用方法返回。如果仅注入程序集而不需要获取返回值,请使用重载版本<see cref="InjectManaged(string, string, string, string)"/>)
 /// </summary>
 /// <param name="processId"></param>
 /// <param name="assemblyPath">要注入程序集的路径</param>
 /// <param name="typeName">类型名(命名空间+类型名,比如NamespaceA.ClassB)</param>
 /// <param name="methodName">方法名(比如MethodC),该方法必须具有此类签名static int MethodName(string),比如private static int InjectingMain(string argument)</param>
 /// <param name="argument">参数,可传入 <see langword="null"/></param>
 /// <param name="clrVersion">使用的CLR版本</param>
 /// <param name="returnValue">被调用方法返回的整数值</param>
 /// <returns></returns>
 public static bool InjectManagedAndWait(uint processId, string assemblyPath, string typeName, string methodName, string argument, InjectionClrVersion clrVersion, out int returnValue)
 {
     returnValue       = 0;
     using var process = NativeSharp.NativeProcess.Open(processId);
     if (process.IsInvalid)
     {
         return(false);
     }
     return(process.InjectManaged(assemblyPath, typeName, methodName, argument, (NativeSharp.InjectionClrVersion)clrVersion, out returnValue));
 }