Created
May 12, 2021 14:02
-
-
Save Slaynash/a07da4a7e755f8f17882e9686d25bf82 to your computer and use it in GitHub Desktop.
PE (x64) Imports listing example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[StructLayout(LayoutKind.Explicit)] | |
internal struct ImageDataDirectory | |
{ | |
[FieldOffset(0)] | |
public uint virtualAddress; | |
[FieldOffset(4)] | |
public uint size; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public struct ImageFileHeader | |
{ | |
public ushort machine; | |
public ushort numberOfSections; | |
public uint timeDateStamp; | |
public uint pointerToSymbolTable; | |
public uint numberOfSymbols; | |
public ushort sizeOfOptionalHeader; | |
public ushort characteristrics; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[StructLayout(LayoutKind.Explicit)] | |
internal struct ImageImportDescriptor | |
{ | |
[FieldOffset(0)] | |
public uint OriginalFirstThunk; | |
[FieldOffset(4)] | |
public uint TimeDateStamp; | |
[FieldOffset(8)] | |
public uint ForwarderChain; | |
[FieldOffset(12)] | |
public uint Name; | |
[FieldOffset(16)] | |
public uint FirstThunk; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[StructLayout(LayoutKind.Explicit)] | |
internal struct ImageNtHeaders | |
{ | |
[FieldOffset(0)] | |
public uint signature; | |
[FieldOffset(4)] | |
public ImageFileHeader fileHeader; | |
[FieldOffset(24)] | |
public OptionalFileHeader64 optionalHeader64; | |
//[FieldOffset(24)] | |
//public OptionalFileHeader32 optionalHeader32; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[StructLayout(LayoutKind.Explicit)] | |
internal struct ImageSectionHeader | |
{ | |
//[FieldOffset(0)] | |
//[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] | |
//public char[8] name; | |
[FieldOffset(8)] | |
public int virtualSize; | |
[FieldOffset(12)] | |
public int virtualAddress; | |
[FieldOffset(16)] | |
public int sizeOfRawData; | |
[FieldOffset(20)] | |
public int pointerToRawData; | |
[FieldOffset(24)] | |
public int pointerToRelocations; | |
[FieldOffset(28)] | |
public int pointerToLinenumbers; | |
[FieldOffset(32)] | |
public ushort numberOfRelocations; | |
[FieldOffset(34)] | |
public ushort numberOfLinenumbers; | |
[FieldOffset(36)] | |
public /* DataSectionFlags */ uint characteristics; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[StructLayout(LayoutKind.Explicit)] | |
internal struct ImageThunkData32 | |
{ | |
[FieldOffset(0)] | |
public uint forwarderString; | |
[FieldOffset(0)] | |
public uint function; | |
[FieldOffset(0)] | |
public uint ordinal; | |
[FieldOffset(0)] | |
public uint addressOfData; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[StructLayout(LayoutKind.Explicit)] | |
internal struct ImageThunkData64 | |
{ | |
[FieldOffset(0)] | |
public ulong forwarderString; | |
[FieldOffset(0)] | |
public ulong function; | |
[FieldOffset(0)] | |
public ulong ordinal; | |
[FieldOffset(0)] | |
public ulong addressOfData; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[StructLayout(LayoutKind.Explicit)] | |
internal struct OptionalFileHeader64 | |
{ | |
[FieldOffset(120)] | |
public ImageDataDirectory importTable; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
internal static class PEParser | |
{ | |
internal static unsafe ImageNtHeaders* AnalyseModuleWin(IntPtr moduleBaseAddress) | |
{ | |
if (*(byte*)(moduleBaseAddress + 0x0) != 0x4D || *(byte*)(moduleBaseAddress + 0x1) != 0x5A) | |
throw new ArgumentException("The passed module isn't a valid PE file"); | |
int OFFSET_TO_PE_HEADER_OFFSET = 0x3c; | |
uint offsetToPESig = *(uint*)(moduleBaseAddress + OFFSET_TO_PE_HEADER_OFFSET); | |
IntPtr pPESig = IntPtr.Add(moduleBaseAddress, (int)offsetToPESig); | |
if (*(byte*)(pPESig + 0x0) != 0x50 || *(byte*)(pPESig + 0x1) != 0x45 || *(byte*)(pPESig + 0x2) != 0x0 || *(byte*)(pPESig + 0x3) != 0x0) | |
throw new ArgumentException("The passed module isn't a valid PE file"); | |
return (ImageNtHeaders*)pPESig; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private unsafe void TestThingy() | |
{ | |
byte[] data = File.ReadAllBytes(@"C:\UnityInstalls\2018.4.20f1\Editor\Data\PlaybackEngines\windowsstandalonesupport\Variations\win64_nondevelopment_mono\UnityPlayer.dll"); | |
fixed (byte* dataPtr = data) | |
{ | |
ImageNtHeaders* imageNtHeaders = PEParser.AnalyseModuleWin((IntPtr)dataPtr); | |
ImageSectionHeader* pSech = ImageFirstSection(imageNtHeaders); | |
ImageDataDirectory* imageDirectoryEntryImport = &imageNtHeaders->optionalHeader64.importTable; | |
ImageImportDescriptor* pImportDescriptor = (ImageImportDescriptor*)(dataPtr + Rva2Offset(imageDirectoryEntryImport->virtualAddress, pSech, imageNtHeaders)); | |
for (uint i = 0; i < imageDirectoryEntryImport->size / sizeof(ImageImportDescriptor); ++i) | |
{ | |
ImageImportDescriptor* pImportDescriptorI = pImportDescriptor + i; | |
if (pImportDescriptorI->Name != 0) | |
{ | |
string imagename = CppUtils.CharArrayPtrToString((IntPtr)((ulong)dataPtr + Rva2Offset(pImportDescriptorI->Name, pSech, imageNtHeaders))); | |
ulong baseFunctionOffset = (ulong)dataPtr + Rva2Offset(pImportDescriptorI->FirstThunk, pSech, imageNtHeaders); | |
ImageThunkData64* thunkData = (ImageThunkData64*)((ulong)dataPtr + Rva2Offset(pImportDescriptorI->OriginalFirstThunk, pSech, imageNtHeaders)); | |
uint j = 0; | |
ulong functionoffset = 0; | |
while (*(IntPtr*)(functionoffset = baseFunctionOffset + (uint)(j * IntPtr.Size)) != IntPtr.Zero) | |
{ | |
// TODO handle ordinals | |
string importname = CppUtils.CharArrayPtrToString((IntPtr)((ulong)dataPtr + Rva2Offset((uint)thunkData->addressOfData, pSech, imageNtHeaders) + 0x2)); | |
UnityEngine.Debug.Log(imagename + "::" + importname + " at [UnityPlayer.dll+" + string.Format("{0:X}", functionoffset - (ulong)dataPtr) + "]"); | |
thunkData++; | |
j++; | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment