private static bool SafeGetExportTableInfo(IntPtr processHandle, IntPtr moduleHandle, out IMAGE_EXPORT_DIRECTORY ied, out uint[] nameOffsets) { ied = default; nameOffsets = Array2.Empty <uint>(); if (!NativeProcess.ReadUInt32Internal((void *)processHandle, (byte *)moduleHandle + 0x3C, out uint ntHeaderOffset)) { return(false); } if (!NativeProcess.Is64BitProcessInternal((void *)processHandle, out bool is64Bit)) { return(false); } uint iedRVA; if (is64Bit) { if (!NativeProcess.ReadUInt32Internal((void *)processHandle, (byte *)moduleHandle + ntHeaderOffset + 0x88, out iedRVA)) { return(false); } } else { if (!NativeProcess.ReadUInt32Internal((void *)processHandle, (byte *)moduleHandle + ntHeaderOffset + 0x78, out iedRVA)) { return(false); } } fixed(void *p = &ied) { if (!NativeProcess.ReadInternal((void *)processHandle, (byte *)moduleHandle + iedRVA, p, IMAGE_EXPORT_DIRECTORY.UnmanagedSize)) { return(false); } } if (ied.NumberOfNames == 0) { return(true); } nameOffsets = new uint[ied.NumberOfNames]; fixed(void *p = nameOffsets) { if (!NativeProcess.ReadInternal((void *)processHandle, (byte *)moduleHandle + ied.AddressOfNames, p, ied.NumberOfNames * 4)) { return(false); } } return(true); }
private static bool GetExportTableInfo(IntPtr processHandle, IntPtr moduleHandle, out IMAGE_EXPORT_DIRECTORY ied, out uint[] nameOffsets) { uint ntHeaderOffset; bool is64Bit; uint iedRVA; ied = default(IMAGE_EXPORT_DIRECTORY); nameOffsets = null; if (!NativeProcess.ReadUInt32Internal(processHandle, (IntPtr)((byte *)moduleHandle + 0x3C), out ntHeaderOffset)) { return(false); } if (!NativeProcess.Is64BitProcessInternal(processHandle, out is64Bit)) { return(false); } if (is64Bit) { if (!NativeProcess.ReadUInt32Internal(processHandle, (IntPtr)((byte *)moduleHandle + ntHeaderOffset + 0x88), out iedRVA)) { return(false); } } else { if (!NativeProcess.ReadUInt32Internal(processHandle, (IntPtr)((byte *)moduleHandle + ntHeaderOffset + 0x78), out iedRVA)) { return(false); } } fixed(void *p = &ied) if (!ReadProcessMemory(processHandle, (IntPtr)((byte *)moduleHandle + iedRVA), p, IMAGE_EXPORT_DIRECTORY.UnmanagedSize, null)) { return(false); } if (ied.NumberOfNames == 0) { return(true); } nameOffsets = new uint[ied.NumberOfNames]; fixed(void *p = nameOffsets) if (!ReadProcessMemory(processHandle, (IntPtr)((byte *)moduleHandle + ied.AddressOfNames), p, ied.NumberOfNames * 4, null)) { return(false); } return(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); }
private static IntPtr WriteMachineCode(IntPtr processHandle, string clrVersion, string assemblyPath, string typeName, string methodName, string argument) { bool is64Bit; byte[] machineCode; IntPtr pEnvironment; IntPtr pCorBindToRuntimeEx; IntPtr pCLRCreateInstance; if (!NativeProcess.Is64BitProcessInternal(processHandle, out is64Bit)) { return(IntPtr.Zero); } machineCode = GetMachineCodeTemplate(clrVersion, assemblyPath, typeName, methodName, argument); pEnvironment = NativeProcess.AllocMemoryInternal(processHandle, 0x1000 + (argument == null ? 0 : (uint)argument.Length * 2 + 2), MemoryProtection.ExecuteReadWrite); if (pEnvironment == IntPtr.Zero) { return(IntPtr.Zero); } try { fixed(byte *p = machineCode) { switch (clrVersion) { case "v2.0.50727": pCorBindToRuntimeEx = NativeModule.GetFunctionAddressInternal(processHandle, "mscoree.dll", "CorBindToRuntimeEx"); if (pCorBindToRuntimeEx == IntPtr.Zero) { return(IntPtr.Zero); } if (is64Bit) { SetMachineCode64v2(p, (ulong)pEnvironment, (ulong)pCorBindToRuntimeEx); } else { SetMachineCode32v2(p, (uint)pEnvironment, (uint)pCorBindToRuntimeEx); } break; case "v4.0.30319": pCLRCreateInstance = NativeModule.GetFunctionAddressInternal(processHandle, "mscoree.dll", "CLRCreateInstance"); if (pCLRCreateInstance == IntPtr.Zero) { return(IntPtr.Zero); } if (is64Bit) { SetMachineCode64v4(p, (ulong)pEnvironment, (ulong)pCLRCreateInstance); } else { SetMachineCode32v4(p, (uint)pEnvironment, (uint)pCLRCreateInstance); } break; default: return(IntPtr.Zero); } } if (!NativeProcess.WriteBytesInternal(processHandle, pEnvironment, machineCode)) { return(IntPtr.Zero); } } catch { NativeProcess.FreeMemoryInternal(processHandle, pEnvironment); return(IntPtr.Zero); } return(pEnvironment); }