Skip to content

Instantly share code, notes, and snippets.

@mrexodia
Last active September 12, 2022 16:10
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save mrexodia/1f9c5aa6570f6c782194 to your computer and use it in GitHub Desktop.
Save mrexodia/1f9c5aa6570f6c782194 to your computer and use it in GitHub Desktop.
PE Import Table Parser
#include <windows.h>
#include <stdio.h>
int gtfo(const char* text = "")
{
printf("gtfo! (%s)\n", text);
return -1;
}
int main(int argc, char* argv[])
{
if (argc < 2)
return gtfo("argc");
//read the file
auto hFile = CreateFileA(argv[1], GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
if (hFile == INVALID_HANDLE_VALUE)
return gtfo("CreateFile");
//map the file
auto hMappedFile = CreateFileMappingA(hFile, nullptr, PAGE_READONLY | SEC_IMAGE, 0, 0, nullptr);
if (!hMappedFile)
return gtfo("CreateFileMappingA");
//map the sections appropriately
auto fileMap = MapViewOfFile(hMappedFile, FILE_MAP_READ, 0, 0, 0);
if (!fileMap)
return gtfo("MapViewOfFile");
auto pidh = PIMAGE_DOS_HEADER(fileMap);
if (pidh->e_magic != IMAGE_DOS_SIGNATURE)
return gtfo("IMAGE_DOS_SIGNATURE");
auto pnth = PIMAGE_NT_HEADERS(ULONG_PTR(fileMap) + pidh->e_lfanew);
if (pnth->Signature != IMAGE_NT_SIGNATURE)
return gtfo("IMAGE_NT_SIGNATURE");
if (pnth->FileHeader.Machine != IMAGE_FILE_MACHINE_I386)
return gtfo("IMAGE_FILE_MACHINE_I386");
if (pnth->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)
return gtfo("IMAGE_NT_OPTIONAL_HDR_MAGIC");
auto importDir = pnth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
puts("Import Directory");
printf(" RVA: %08X\n", importDir.VirtualAddress);
printf("Size: %08X\n\n", importDir.Size);
if (!importDir.VirtualAddress || !importDir.Size)
return gtfo("No Import directory!");
auto importDescriptor = PIMAGE_IMPORT_DESCRIPTOR(ULONG_PTR(fileMap) + importDir.VirtualAddress);
if (!IsBadReadPtr((char*)fileMap + importDir.VirtualAddress, 0x1000))
{
for (; importDescriptor->FirstThunk; importDescriptor++)
{
printf("OriginalFirstThunk: %08X\n", importDescriptor->OriginalFirstThunk);
printf(" TimeDateStamp: %08X\n", importDescriptor->TimeDateStamp);
printf(" ForwarderChain: %08X\n", importDescriptor->ForwarderChain);
if (!IsBadReadPtr((char*)fileMap + importDescriptor->Name, 0x1000))
printf(" Name: %08X \"%s\"\n", importDescriptor->Name, (char*)fileMap + importDescriptor->Name);
else
printf(" Name: %08X INVALID\n", importDescriptor->Name);
printf(" Name: %08X\n", importDescriptor->Name);
printf(" FirstThunk: %08X\n", importDescriptor->FirstThunk);
auto thunkData = PIMAGE_THUNK_DATA(ULONG_PTR(fileMap) + importDescriptor->FirstThunk);
for (; thunkData->u1.AddressOfData; thunkData++)
{
auto rva = ULONG_PTR(thunkData) - ULONG_PTR(fileMap);
auto data = thunkData->u1.AddressOfData;
if (data & IMAGE_ORDINAL_FLAG)
printf(" Ordinal: %08X\n", data & ~IMAGE_ORDINAL_FLAG);
else
{
auto importByName = PIMAGE_IMPORT_BY_NAME(ULONG_PTR(fileMap) + data);
if (!IsBadReadPtr(importByName, 0x1000))
printf(" Function: %08X \"%s\"\n", data, (char*)importByName->Name);
else
printf(" Function: %08X INVALID\n", data);
}
}
puts("");
}
}
else
puts("INVALID IMPORT DESCRIPTOR");
return 0;
}
@andriyankov
Copy link

I think the statement can be after 53 line and shift code between 55 and 83 lines to left

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment