2 years ago
#46762
Patrick
Can't get IAT Thunk data (functions) from certain processes (PE32)
I have made a tool to parse the IAT out of PEs (IAT hooking also desirable). It works great for almost everything I've tried. There's one process however that I am completely failing to parse; I can iterate through the import descriptors and get the libraries (all with the correct data) but then my code for parsing the functions seems to just produce nonsense or crash. Here is my code:
// hMod is just the process module pointer thingy
LPBYTE pImageBase = (LPBYTE)hMod;
PIMAGE_DOS_HEADER pImgDosHeaders = (PIMAGE_DOS_HEADER)hMod;
PIMAGE_NT_HEADERS pImgNTHeaders = (PIMAGE_NT_HEADERS)((LPBYTE)pImgDosHeaders + pImgDosHeaders->e_lfanew);
PIMAGE_IMPORT_DESCRIPTOR pImgImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((LPBYTE)pImgDosHeaders + pImgNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
if (pImgDosHeaders->e_magic != IMAGE_DOS_SIGNATURE)
// This doesn't happen
LogError("Signature in the PE header wrong!");
for (; pImgImportDesc->Name != 0; pImgImportDesc++) {
libraryName = (LPCSTR)(pImageBase + pImgImportDesc->Name);
// This is all good...
LogDebug("Lib name: %s, RVA: %p", libraryName, pImgImportDesc->Name);
// This is NOT good. pImgImportDesc->OriginalFirstThunk is zero.
if (!pImgImportDesc->OriginalFirstThunk || !pImgImportDesc->FirstThunk) {
LogWarn("Thunk data missing for %s (%d, %d)", libraryName, pImgImportDesc->OriginalFirstThunk, pImgImportDesc->FirstThunk);
}
pOrigThunk = (PIMAGE_THUNK_DATA)(pImageBase + pImgImportDesc->OriginalFirstThunk);
pThunk = (PIMAGE_THUNK_DATA)(pImageBase + pImgImportDesc->FirstThunk);
for (; pOrigThunk->u1.AddressOfData != 0; pOrigThunk++, pThunk++) {
if (pOrigThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) {
LogDebug("Non-string entry at RVA: %p", pOrigThunk->u1.AddressOfData);
}
else {
// here we just get nonsense data. also the wrong number of functions. so we're parsing it all wrong
functionName = (PIMAGE_IMPORT_BY_NAME)(pImageBase + pOrigThunk->u1.AddressOfData);
LogDebug("Function name: %s, RVA: %p", functionName->Name, pOrigThunk->u1.AddressOfData);
// Then we can do something with &pThunk->u1.Function if we so desire
}
}
}
The good folks at NTCore have a 32bit CFF explorer which works well on the process I am trying to read, however that's only from reading the file not the process. I have googled a lot and tried using other people's code but their code is always very similar to the above and also fails (sometimes crashing instead).
Important detail: this code is running injected inside the process, I am not reading a file.
EDIT: It seems I can sort of parse the file itself but this doesn't work in memory, so the real issue is that the IAT is getting obfuscated or something. Here is the redacted output: https://textsaver.flap.tv/lists/4jsn
(Generated using this code)
Anyone got any suggestions for workarounds or am I at a dead end?
c
winapi
portable-executable
0 Answers
Your Answer