1
0
Fork 0

DBG: use export/import data from modules instead of from memory

This commit is contained in:
Duncan Ogilvie 2018-02-12 03:08:13 +01:00
parent 476bc093bc
commit 73a5ffebd9
No known key found for this signature in database
GPG Key ID: FC89E0AAA0C1AAD8
3 changed files with 21 additions and 115 deletions

View File

@ -13,54 +13,25 @@
///api functions
bool apienumexports(duint base, const EXPORTENUMCALLBACK & cbEnum)
{
duint export_dir_rva, export_dir_size;
{
SHARED_ACQUIRE(LockModules);
auto modinfo = ModInfoFromAddr(base);
if(!modinfo)
return false;
export_dir_rva = GetPE32DataFromMappedFile(modinfo->fileMapVA, 0, UE_EXPORTTABLEADDRESS);
export_dir_size = GetPE32DataFromMappedFile(modinfo->fileMapVA, 0, UE_EXPORTTABLESIZE);
}
IMAGE_EXPORT_DIRECTORY export_dir;
memset(&export_dir, 0, sizeof(export_dir));
MemRead((export_dir_rva + base), &export_dir, sizeof(export_dir));
unsigned int NumberOfNames = export_dir.NumberOfNames;
if(!export_dir.NumberOfFunctions || !NumberOfNames) //no named exports
SHARED_ACQUIRE(LockModules);
auto modinfo = ModInfoFromAddr(base);
if(!modinfo)
return false;
char modname[MAX_MODULE_SIZE] = "";
ModNameFromAddr(base, modname, true);
duint original_name_va = export_dir.Name + base;
char original_name[deflen] = "";
memset(original_name, 0, sizeof(original_name));
MemRead(original_name_va, original_name, deflen);
char* AddrOfFunctions_va = (char*)(export_dir.AddressOfFunctions + base); //not a valid local pointer
char* AddrOfNames_va = (char*)(export_dir.AddressOfNames + base); //not a valid local pointer
char* AddrOfNameOrdinals_va = (char*)(export_dir.AddressOfNameOrdinals + base); //not a valid local pointer
for(DWORD i = 0; i < NumberOfNames; i++)
{
DWORD curAddrOfName = 0;
MemRead((duint)(AddrOfNames_va + sizeof(DWORD)*i), &curAddrOfName, sizeof(DWORD));
char* cur_name_va = (char*)(curAddrOfName + base);
char cur_name[deflen] = "";
memset(cur_name, 0, deflen);
MemRead((duint)cur_name_va, cur_name, deflen);
WORD curAddrOfNameOrdinals = 0;
MemRead((duint)(AddrOfNameOrdinals_va + sizeof(WORD)*i), &curAddrOfNameOrdinals, sizeof(WORD));
DWORD curFunctionRva = 0;
MemRead((duint)(AddrOfFunctions_va + sizeof(DWORD)*curAddrOfNameOrdinals), &curFunctionRva, sizeof(DWORD));
if(curFunctionRva >= export_dir_rva && curFunctionRva < export_dir_rva + export_dir_size)
char modname[MAX_MODULE_SIZE] = "";
sprintf_s(modname, "%s%s", modinfo->name, modinfo->extension);
for(auto & modExport : modinfo->exports)
{
if(modExport.forwarded)
{
char forwarded_api[deflen] = "";
MemRead((curFunctionRva + base), forwarded_api, deflen - 1);
duint remote_addr;
if(valfromstring(forwarded_api, &remote_addr))
cbEnum(base, modname, cur_name, remote_addr);
if(valfromstring(modExport.forwardName.c_str(), &remote_addr))
cbEnum(base, modname, modExport.name.c_str(), remote_addr);
}
else
{
cbEnum(base, modname, cur_name, curFunctionRva + base);
cbEnum(base, modname, modExport.name.c_str(), modExport.rva + base);
}
}
return true;
@ -68,82 +39,17 @@ bool apienumexports(duint base, const EXPORTENUMCALLBACK & cbEnum)
bool apienumimports(duint base, const IMPORTENUMCALLBACK & cbEnum)
{
ULONG_PTR importTableRva, importTableSize;
{
SHARED_ACQUIRE(LockModules);
auto modinfo = ModInfoFromAddr(base);
if(!modinfo)
return false;
importTableRva = GetPE32DataFromMappedFile(modinfo->fileMapVA, 0, UE_IMPORTTABLEADDRESS);
importTableSize = GetPE32DataFromMappedFile(modinfo->fileMapVA, 0, UE_IMPORTTABLESIZE);
}
// Variables
bool readSuccess;
Memory<char*> importName(MAX_IMPORT_SIZE + 1, "apienumimports:buffer");
char importModuleName[MAX_MODULE_SIZE + 1] = "";
PIMAGE_IMPORT_DESCRIPTOR importTableVa;
IMAGE_IMPORT_DESCRIPTOR importDescriptor;
PIMAGE_THUNK_DATA imageIATVa, imageINTVa;
IMAGE_THUNK_DATA imageOftThunkData, imageFtThunkData;
PIMAGE_IMPORT_BY_NAME pImageImportByNameVa;
// Return if no imports
if(!importTableSize)
SHARED_ACQUIRE(LockModules);
auto modinfo = ModInfoFromAddr(base);
if(!modinfo)
return false;
importTableVa = (PIMAGE_IMPORT_DESCRIPTOR)(base + importTableRva);
char modname[MAX_MODULE_SIZE] = "";
sprintf_s(modname, "%s%s", modinfo->name, modinfo->extension);
readSuccess = MemRead((duint)importTableVa, &importDescriptor, sizeof(importDescriptor));
// Loop through all dlls
while(readSuccess && importDescriptor.FirstThunk)
for(auto & modImport : modinfo->imports)
{
// Copy module name into importModuleName
MemRead((duint)(base + importDescriptor.Name), &importModuleName, MAX_MODULE_SIZE);
imageIATVa = (PIMAGE_THUNK_DATA)(base + importDescriptor.FirstThunk);
imageINTVa = (PIMAGE_THUNK_DATA)(base + importDescriptor.OriginalFirstThunk);
if(!MemRead((duint)imageIATVa, &imageFtThunkData, sizeof(imageFtThunkData)))
return false;
if(!MemRead((duint)imageINTVa, &imageOftThunkData, sizeof(imageOftThunkData)))
return false;
// Loop through all imported function in this dll
while(imageFtThunkData.u1.AddressOfData)
{
if((imageOftThunkData.u1.Ordinal & IMAGE_ORDINAL_FLAG) == IMAGE_ORDINAL_FLAG)
{
sprintf_s(importName(), MAX_IMPORT_SIZE, "Ordinal%u", imageOftThunkData.u1.Ordinal & ~IMAGE_ORDINAL_FLAG);
}
else
{
pImageImportByNameVa = (PIMAGE_IMPORT_BY_NAME)(base + imageOftThunkData.u1.AddressOfData);
// Read every IMPORT_BY_NAME.name
duint bytesRead = 0;
if(!MemRead((duint)pImageImportByNameVa + sizeof(WORD), importName(), MAX_IMPORT_SIZE, &bytesRead) && !bytesRead)
return false;
}
// Callback
cbEnum(base, (duint)imageIATVa, importName(), importModuleName);
// Move to next address in the INT
imageINTVa++;
if(!MemRead((duint)imageINTVa, &imageOftThunkData, sizeof(imageOftThunkData)))
return false;
// Move to next address in the IAT and read it into imageFtThunkData
imageIATVa++;
if(!MemRead((duint)imageIATVa, &imageFtThunkData, sizeof(imageFtThunkData)))
return false;
}
importTableVa++;
readSuccess = MemRead((duint)importTableVa, &importDescriptor, sizeof(importDescriptor));
cbEnum(base, modImport.iatRva + base, modImport.name.c_str(), modinfo->importModules.at(modImport.moduleIndex).c_str());
}
return true;
}

View File

@ -53,7 +53,7 @@ struct DepthModuleRangeCompare
//typedefs
typedef std::function<void (duint base, const char* mod, const char* name, duint addr)> EXPORTENUMCALLBACK;
typedef std::function<void (duint base, duint addr, char* name, char* moduleName)> IMPORTENUMCALLBACK;
typedef std::function<void (duint base, duint addr, const char* name, const char* moduleName)> IMPORTENUMCALLBACK;
bool apienumexports(duint base, const EXPORTENUMCALLBACK & cbEnum);
bool apienumimports(duint base, const IMPORTENUMCALLBACK & cbEnum);

View File

@ -26,7 +26,7 @@ static void SymEnumImports(duint Base, CBSYMBOLENUM EnumCallback, SYMBOLCBDATA &
SYMBOLINFO symbol;
memset(&symbol, 0, sizeof(SYMBOLINFO));
symbol.isImported = true;
apienumimports(Base, [&](duint base, duint addr, char* name, char* moduleName)
apienumimports(Base, [&](duint base, duint addr, const char* name, const char* moduleName)
{
cbData.decoratedSymbol[0] = '\0';
cbData.undecoratedSymbol[0] = '\0';