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); }
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; } }
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,
public static AADClient Inject(uint processId, InjectionClrVersion clrVersion) { return(Inject(processId, clrVersion, Guid.NewGuid().ToString())); }
/// <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)); }
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); }
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); }
/// <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)); }