internal static void *GetFunctionAddressInternal(void *processHandle, void *moduleHandle, string functionName) { IMAGE_EXPORT_DIRECTORY ied; uint[] nameOffsets; string name; ushort ordinal; uint addressOffset; if (!SafeGetExportTableInfo((IntPtr)processHandle, (IntPtr)moduleHandle, out ied, out nameOffsets)) { return(null); } for (uint i = 0; i < ied.NumberOfNames; i++) { if (!NativeProcess.ReadStringInternal(processHandle, (byte *)moduleHandle + nameOffsets[i], out name, false, Encoding.ASCII) || name != functionName) { continue; } if (!NativeProcess.ReadUInt16Internal(processHandle, (byte *)moduleHandle + ied.AddressOfNameOrdinals + i * 2, out ordinal)) { continue; } if (!NativeProcess.ReadUInt32Internal(processHandle, (byte *)moduleHandle + ied.AddressOfFunctions + ordinal * 4, out addressOffset)) { continue; } return((byte *)moduleHandle + addressOffset); } return(null); }
internal static IntPtr GetFunctionAddressInternal(IntPtr processHandle, IntPtr moduleHandle, string functionName) { IMAGE_EXPORT_DIRECTORY ied; uint[] nameOffsets; string name; ushort ordinal; uint addressOffset; if (!GetExportTableInfo(processHandle, moduleHandle, out ied, out nameOffsets)) { return(IntPtr.Zero); } for (uint i = 0; i < ied.NumberOfNames; i++) { if (!NativeProcess.ReadStringInternal(processHandle, (IntPtr)((byte *)moduleHandle + nameOffsets[i]), out name, false, Encoding.ASCII)) { continue; } if (name == functionName) { if (!NativeProcess.ReadUInt16Internal(processHandle, (IntPtr)((byte *)moduleHandle + ied.AddressOfNameOrdinals + i * 2), out ordinal)) { continue; } if (!NativeProcess.ReadUInt32Internal(processHandle, (IntPtr)((byte *)moduleHandle + ied.AddressOfFunctions + ordinal * 4), out addressOffset)) { continue; } return((IntPtr)((byte *)moduleHandle + addressOffset)); } } return(IntPtr.Zero); }
internal static ExportFunctionInfo[] GetFunctionInfosInternal(IntPtr processHandle, IntPtr moduleHandle) { IMAGE_EXPORT_DIRECTORY ied; uint[] nameOffsets; string functionName; ushort ordinal; uint addressOffset; List <ExportFunctionInfo> exportFunctionInfoList; if (!GetExportTableInfo(processHandle, moduleHandle, out ied, out nameOffsets)) { return(null); } exportFunctionInfoList = new List <ExportFunctionInfo>(nameOffsets.Length); for (uint i = 0; i < ied.NumberOfNames; i++) { if (!NativeProcess.ReadStringInternal(processHandle, (IntPtr)((byte *)moduleHandle + nameOffsets[i]), out functionName, false, Encoding.ASCII)) { continue; } if (!NativeProcess.ReadUInt16Internal(processHandle, (IntPtr)((byte *)moduleHandle + ied.AddressOfNameOrdinals + i * 2), out ordinal)) { continue; } if (!NativeProcess.ReadUInt32Internal(processHandle, (IntPtr)((byte *)moduleHandle + ied.AddressOfFunctions + ordinal * 4), out addressOffset)) { continue; } exportFunctionInfoList.Add(new ExportFunctionInfo((IntPtr)((byte *)moduleHandle + addressOffset), functionName, ordinal)); } return(exportFunctionInfoList.ToArray()); }
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 bool SafeGetExportFunctionInfo(IntPtr processHandle, IntPtr moduleHandle, IMAGE_EXPORT_DIRECTORY ied, uint[] nameOffsets, uint i, out ExportFunctionInfo functionInfo) { functionInfo = ExportFunctionInfo.Empty; if (!NativeProcess.ReadStringInternal((void *)processHandle, (byte *)moduleHandle + nameOffsets[i], out string functionName, false, Encoding.ASCII)) { return(false); } if (!NativeProcess.ReadUInt16Internal((void *)processHandle, (byte *)moduleHandle + ied.AddressOfNameOrdinals + (i * 2), out ushort ordinal)) { return(false); } if (!NativeProcess.ReadUInt32Internal((void *)processHandle, (byte *)moduleHandle + ied.AddressOfFunctions + (ordinal * 4), out uint addressOffset)) { return(false); } functionInfo = new ExportFunctionInfo((byte *)moduleHandle + addressOffset, functionName, ordinal); return(true); }