1
0
Fork 0

DBG: dont copy MODINFO and MODIMPORT/MODEXPORT structures

This commit is contained in:
Duncan Ogilvie 2018-03-20 23:33:12 +01:00
parent 4e88b399fe
commit 013cd1e5f7
No known key found for this signature in database
GPG Key ID: FC89E0AAA0C1AAD8
2 changed files with 57 additions and 60 deletions

View File

@ -10,8 +10,9 @@
#include <shlwapi.h>
#include "console.h"
#include "debugger.h"
#include <memory>
std::map<Range, MODINFO, RangeCompare> modinfo;
std::map<Range, std::unique_ptr<MODINFO>, RangeCompare> modinfo;
std::unordered_map<duint, std::string> hashNameMap;
static void ReadExportDirectory(MODINFO & Info, ULONG_PTR FileMapVA)
@ -53,7 +54,8 @@ static void ReadExportDirectory(MODINFO & Info, ULONG_PTR FileMapVA)
for(DWORD i = 0; i < exportDir->NumberOfFunctions; i++)
{
MODEXPORT entry;
Info.exports.emplace_back();
auto & entry = Info.exports.back();
entry.ordinal = i + exportDir->Base;
entry.rva = addressOfFunctions[i];
if(entry.forwarded = entry.rva >= exportDirRva && entry.rva < exportDirRva + exportDirSize)
@ -62,7 +64,6 @@ static void ReadExportDirectory(MODINFO & Info, ULONG_PTR FileMapVA)
if(forwardNameOffset) // TODO: what does the Windows loader do if this fails?
entry.forwardName = String((const char*)(forwardNameOffset + FileMapVA));
}
Info.exports.push_back(entry);
}
for(DWORD i = 0; i < exportDir->NumberOfNames; i++)
@ -121,8 +122,7 @@ static void ReadImportDirectory(MODINFO & Info, ULONG_PTR FileMapVA)
if(!moduleNameOffset) // TODO: what does the Windows loader do if this fails?
continue;
auto moduleName = String((const char*)(moduleNameOffset + FileMapVA));
Info.importModules.push_back(moduleName);
Info.importModules.emplace_back((const char*)(moduleNameOffset + FileMapVA));
auto firstThunkOffset = rva2offset(importDescriptor->FirstThunk);
if(!firstThunkOffset) // TODO: what does the Windows loader do if this fails?
@ -131,7 +131,8 @@ static void ReadImportDirectory(MODINFO & Info, ULONG_PTR FileMapVA)
auto thunkData = PIMAGE_THUNK_DATA(firstThunkOffset + FileMapVA);
for(auto iatRva = importDescriptor->FirstThunk; thunkData->u1.AddressOfData; thunkData++, iatRva += sizeof(duint))
{
MODIMPORT entry;
Info.imports.emplace_back();
auto & entry = Info.imports.back();
entry.iatRva = iatRva;
entry.moduleIndex = moduleIndex;
if((thunkData->u1.Ordinal & IMAGE_ORDINAL_FLAG) == IMAGE_ORDINAL_FLAG)
@ -148,7 +149,6 @@ static void ReadImportDirectory(MODINFO & Info, ULONG_PTR FileMapVA)
entry.name = String((const char*)importByName->Name);
entry.ordinal = -1;
}
Info.imports.push_back(entry);
}
}
@ -476,6 +476,7 @@ void GetModuleInfo(MODINFO & Info, ULONG_PTR FileMapVA)
ReadExportDirectory(Info, FileMapVA);
ReadImportDirectory(Info, FileMapVA);
dprintf("[%s%s] read %d imports and %d exports\n", Info.name, Info.extension, Info.imports.size(), Info.exports.size());
ReadTlsCallbacks(Info, FileMapVA);
ReadBaseRelocationTable(Info, FileMapVA);
ReadDebugDirectory(Info, FileMapVA);
@ -487,8 +488,10 @@ bool ModLoad(duint Base, duint Size, const char* FullPath)
if(!Base || !Size || !FullPath)
return false;
auto infoPtr = std::make_unique<MODINFO>();
auto & info = *infoPtr;
// Copy the module path in the struct
MODINFO info;
strcpy_s(info.path, FullPath);
// Break the module path into a directory and file name
@ -589,7 +592,7 @@ bool ModLoad(duint Base, duint Size, const char* FullPath)
// Add module to list
EXCLUSIVE_ACQUIRE(LockModules);
modinfo.insert(std::make_pair(Range(Base, Base + Size - 1), info));
modinfo.insert(std::make_pair(Range(Base, Base + Size - 1), std::move(infoPtr)));
EXCLUSIVE_RELEASE();
// Put labels for virtual module exports
@ -618,14 +621,6 @@ bool ModUnload(duint Base)
if(found == modinfo.end())
return false;
// Unload the mapped file from memory
auto & info = found->second;
if(info.fileMapVA)
StaticFileUnloadW(StringUtils::Utf8ToUtf16(info.path).c_str(), false, info.fileHandle, info.loadedSize, info.fileMap, info.fileMapVA);
// Unload symbols from the module
info.unloadSymbols();
// Remove it from the list
modinfo.erase(found);
EXCLUSIVE_RELEASE();
@ -640,26 +635,6 @@ void ModClear()
{
// Clean up all the modules
EXCLUSIVE_ACQUIRE(LockModules);
for(const auto & mod : modinfo)
{
// Unload the mapped file from memory
const auto & info = mod.second;
if(info.fileMapVA)
StaticFileUnloadW(StringUtils::Utf8ToUtf16(info.path).c_str(), false, info.fileHandle, info.loadedSize, info.fileMap, info.fileMapVA);
if(info.symbols != nullptr &&
info.symbols != &EmptySymbolSource)
{
if(info.symbols->isLoading())
{
info.symbols->cancelLoading();
}
delete info.symbols;
}
}
modinfo.clear();
}
@ -684,7 +659,7 @@ MODINFO* ModInfoFromAddr(duint Address)
if(found == modinfo.end())
return nullptr;
return &found->second;
return found->second.get();
}
bool ModNameFromAddr(duint Address, char* Name, bool Extension)
@ -787,16 +762,16 @@ duint ModBaseFromName(const char* Module)
{
const auto & currentModule = i.second;
char currentModuleName[MAX_MODULE_SIZE];
strcpy_s(currentModuleName, currentModule.name);
strcat_s(currentModuleName, currentModule.extension);
strcpy_s(currentModuleName, currentModule->name);
strcat_s(currentModuleName, currentModule->extension);
// Compare with extension (perfect match)
if(!_stricmp(currentModuleName, Module))
return currentModule.base;
return currentModule->base;
// Compare without extension, possible candidate (thanks to chessgod101 for finding this)
if(!candidate && !_stricmp(currentModule.name, Module))
candidate = currentModule.base;
if(!candidate && !_stricmp(currentModule->name, Module))
candidate = currentModule->base;
}
return candidate;
@ -867,20 +842,11 @@ int ModPathFromName(const char* Module, char* Path, int Size)
return ModPathFromAddr(ModBaseFromName(Module), Path, Size);
}
void ModGetList(std::vector<MODINFO> & list)
{
SHARED_ACQUIRE(LockModules);
list.clear();
list.reserve(modinfo.size());
for(const auto & mod : modinfo)
list.push_back(mod.second);
}
void ModEnum(const std::function<void(const MODINFO &)> & cbEnum)
{
SHARED_ACQUIRE(LockModules);
for(const auto & mod : modinfo)
cbEnum(mod.second);
cbEnum(*mod.second);
}
int ModGetParty(duint Address)
@ -1042,12 +1008,32 @@ void MODINFO::unloadSymbols()
{
if(symbols != nullptr && symbols != &EmptySymbolSource)
{
if(symbols->isLoading())
{
symbols->cancelLoading();
}
delete symbols;
symbols = &EmptySymbolSource;
}
}
void MODINFO::unmapFile()
{
// Unload the mapped file from memory
if(fileMapVA)
StaticFileUnloadW(StringUtils::Utf8ToUtf16(path).c_str(), false, fileHandle, loadedSize, fileMap, fileMapVA);
}
void MODIMPORT::convertToGuiSymbol(duint base, SYMBOLINFO* info) const
{
info->addr = base + iatRva;
info->type = sym_import;
info->decoratedSymbol = (char*)name.c_str();
info->undecoratedSymbol = "";
info->freeDecorated = info->freeUndecorated = false;
}
void MODEXPORT::convertToGuiSymbol(duint base, SYMBOLINFO* info) const
{
info->addr = base + rva;
info->type = sym_export;
info->decoratedSymbol = (char*)name.c_str();
info->undecoratedSymbol = "";
info->freeDecorated = info->freeUndecorated = false;
}

View File

@ -37,21 +37,25 @@ struct PdbValidationData
}
};
struct MODEXPORT
struct MODEXPORT : SymbolInfoGui
{
DWORD ordinal = 0;
DWORD rva = 0;
bool forwarded = false;
String forwardName;
String name;
virtual void convertToGuiSymbol(duint base, SYMBOLINFO* info) const override;
};
struct MODIMPORT
struct MODIMPORT : SymbolInfoGui
{
size_t moduleIndex; //index in MODINFO.importModules
DWORD iatRva;
duint ordinal; //equal to -1 if imported by name
String name;
virtual void convertToGuiSymbol(duint base, SYMBOLINFO* info) const override;
};
struct MODINFO
@ -98,8 +102,15 @@ struct MODINFO
memset(path, 0, sizeof(path));
}
~MODINFO()
{
unmapFile();
unloadSymbols();
}
bool loadSymbols();
void unloadSymbols();
void unmapFile();
};
bool ModLoad(duint Base, duint Size, const char* FullPath);