Page MenuHomedesp's stash

No OneTemporary

diff --git a/Scylla/ApiReader.cpp b/Scylla/ApiReader.cpp
index aeff6fe..f07ed76 100644
--- a/Scylla/ApiReader.cpp
+++ b/Scylla/ApiReader.cpp
@@ -1,1116 +1,1117 @@
#include "ApiReader.h"
#include "Logger.h"
#include "definitions.h"
#include "SystemInformation.h"
stdext::hash_multimap<DWORD_PTR, ApiInfo *> ApiReader::apiList; //api look up table
std::map<DWORD_PTR, ImportModuleThunk> * ApiReader::moduleThunkList; //store found apis
DWORD_PTR ApiReader::minApiAddress = 0xFFFFFFFF;
DWORD_PTR ApiReader::maxApiAddress = 0;
//#define DEBUG_COMMENTS
void ApiReader::readApisFromModuleList()
{
for (unsigned int i = 0; i < moduleList.size();i++)
{
setModulePriority(&moduleList[i]);
if (moduleList[i].modBaseAddr + moduleList[i].modBaseSize > maxValidAddress)
{
maxValidAddress = moduleList[i].modBaseAddr + moduleList[i].modBaseSize;
}
Logger::printfDialog(TEXT("Module parsing: %s"),moduleList[i].fullPath);
if (!moduleList[i].isAlreadyParsed)
{
parseModule(&moduleList[i]);
}
}
#ifdef DEBUG_COMMENTS
Logger::debugLog(TEXT("Address Min ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT(" Max ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT("\nimagebase ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT(" maxValidAddress ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT("\r\n"),minApiAddress,maxApiAddress,targetImageBase,maxValidAddress);
#endif
}
void ApiReader::parseModule(ModuleInfo *module)
{
module->parsing = true;
if (isWinSxSModule(module))
{
parseModuleWithMapping(module);
}
else if (isModuleLoadedInOwnProcess(module))
{
parseModuleWithOwnProcess(module);
}
else
{
parseModuleWithProcess(module);
}
module->isAlreadyParsed = true;
}
void ApiReader::parseModuleWithMapping(ModuleInfo *moduleInfo)
{
LPVOID fileMapping = 0;
PIMAGE_NT_HEADERS pNtHeader = 0;
PIMAGE_DOS_HEADER pDosHeader = 0;
fileMapping = createFileMappingViewRead(moduleInfo->fullPath);
if (fileMapping == 0)
return;
pDosHeader = (PIMAGE_DOS_HEADER)fileMapping;
pNtHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)fileMapping + (DWORD_PTR)(pDosHeader->e_lfanew));
if (isPeAndExportTableValid(pNtHeader))
{
parseExportTable(moduleInfo, pNtHeader, (PIMAGE_EXPORT_DIRECTORY)((DWORD_PTR)fileMapping + pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress), (DWORD_PTR)fileMapping);
}
UnmapViewOfFile(fileMapping);
}
inline bool ApiReader::isApiForwarded(DWORD_PTR rva, PIMAGE_NT_HEADERS pNtHeader)
{
if ((rva > pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress) && (rva < (pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size)))
{
return true;
}
else
{
return false;
}
}
-void ApiReader::handleForwardedApi(DWORD_PTR vaStringPointer,char * functionNameParent, DWORD_PTR rvaParent, DWORD_PTR ordinalParent, ModuleInfo *moduleParent)
+void ApiReader::handleForwardedApi(DWORD_PTR vaStringPointer,char * functionNameParent, DWORD_PTR rvaParent, WORD ordinalParent, ModuleInfo *moduleParent)
{
size_t dllNameLength = 0;
- DWORD_PTR ordinal = 0;
+ WORD ordinal = 0;
ModuleInfo *module = 0;
DWORD_PTR vaApi = 0;
DWORD_PTR rvaApi = 0;
char dllName[100] = {0};
WCHAR dllNameW[100] = {0};
char *fordwardedString = (char *)vaStringPointer;
char *searchFunctionName = strchr(fordwardedString, '.');
if (!searchFunctionName)
return;
dllNameLength = searchFunctionName - fordwardedString;
if (dllNameLength >= 99)
{
return;
}
else
{
strncpy_s(dllName,sizeof(dllName),fordwardedString,dllNameLength);
}
searchFunctionName++;
//Windows 7
if (!strncmp(dllName,"api-ms-win-", 11))
{
/*
Info: http://www.nirsoft.net/articles/windows_7_kernel_architecture_changes.html
*/
FARPROC addy = GetProcAddress(GetModuleHandleA(dllName), searchFunctionName);
if (addy != 0)
{
addApi(functionNameParent,0, ordinalParent, (DWORD_PTR)addy, (DWORD_PTR)addy - (DWORD_PTR)GetModuleHandleA(dllName), true, moduleParent);
}
return;
}
strcat_s(dllName,sizeof(dllName),".dll");
size_t convertedChars = 0;
mbstowcs_s(&convertedChars, dllNameW, strlen(dllName) + 1, dllName, _TRUNCATE);
if (!_wcsicmp(dllNameW, moduleParent->getFilename()))
{
module = moduleParent;
}
else
{
module = findModuleByName(dllNameW);
}
if (module != 0) // module == 0 -> can be ignored
{
/*if ((module->isAlreadyParsed == false) && (module != moduleParent))
{
//do API extract
if (module->parsing == true)
{
//some stupid circle dependency
printf("stupid circle dependency %s\n",module->getFilename());
}
else
{
parseModule(module);
}
}*/
if (strchr(searchFunctionName,'#'))
{
//forwarding by ordinal
searchFunctionName++;
- ordinal = atoi(searchFunctionName);
+ ordinal = (WORD)atoi(searchFunctionName);
findApiByModuleAndOrdinal(module, ordinal, &vaApi, &rvaApi);
}
else
{
findApiByModuleAndName(module, searchFunctionName, &vaApi, &rvaApi);
}
if (rvaApi == 0)
{
#ifdef DEBUG_COMMENTS
Logger::debugLog(L"handleForwardedApi :: Api not found, this is really BAD! %S\r\n",fordwardedString);
#endif
}
else
{
addApi(functionNameParent,0, ordinalParent, vaApi, rvaApi, true, moduleParent);
}
}
}
ModuleInfo * ApiReader::findModuleByName(WCHAR *name)
{
for (unsigned int i = 0; i < moduleList.size(); i++) {
if (!_wcsicmp(moduleList[i].getFilename(), name))
{
return &moduleList[i];
}
}
return 0;
}
-void ApiReader::addApiWithoutName(DWORD_PTR ordinal, DWORD_PTR va, DWORD_PTR rva,bool isForwarded, ModuleInfo *moduleInfo)
+void ApiReader::addApiWithoutName(WORD ordinal, DWORD_PTR va, DWORD_PTR rva,bool isForwarded, ModuleInfo *moduleInfo)
{
addApi(0, 0, ordinal, va, rva, isForwarded, moduleInfo);
}
-void ApiReader::addApi(char *functionName, WORD hint, DWORD_PTR ordinal, DWORD_PTR va, DWORD_PTR rva, bool isForwarded, ModuleInfo *moduleInfo)
+void ApiReader::addApi(char *functionName, WORD hint, WORD ordinal, DWORD_PTR va, DWORD_PTR rva, bool isForwarded, ModuleInfo *moduleInfo)
{
ApiInfo *apiInfo = new ApiInfo();
if ((functionName != 0) && (strlen(functionName) < MAX_PATH))
{
strcpy_s(apiInfo->name, MAX_PATH, functionName);
}
else
{
apiInfo->name[0] = 0x00;
}
apiInfo->ordinal = ordinal;
apiInfo->isForwarded = isForwarded;
apiInfo->module = moduleInfo;
apiInfo->rva = rva;
apiInfo->va = va;
apiInfo->hint = hint;
setMinMaxApiAddress(va);
moduleInfo->apiList.push_back(apiInfo);
apiList.insert(API_Pair(va, apiInfo));
}
BYTE * ApiReader::getHeaderFromProcess(ModuleInfo * module)
{
BYTE *bufferHeader = 0;
DWORD readSize = 0;
if (module->modBaseSize < PE_HEADER_BYTES_COUNT)
{
readSize = module->modBaseSize;
}
else
{
readSize = PE_HEADER_BYTES_COUNT;
}
bufferHeader = new BYTE[readSize];
if(!readMemoryFromProcess(module->modBaseAddr, readSize, bufferHeader))
{
#ifdef DEBUG_COMMENTS
Logger::debugLog(L"getHeaderFromProcess :: Error reading header\r\n");
#endif
delete[] bufferHeader;
return 0;
}
else
{
return bufferHeader;
}
}
BYTE * ApiReader::getExportTableFromProcess(ModuleInfo * module, PIMAGE_NT_HEADERS pNtHeader)
{
DWORD readSize = 0;
BYTE *bufferExportTable = 0;
readSize = pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
if (readSize < (sizeof(IMAGE_EXPORT_DIRECTORY) + 8))
{
//Something is wrong with the PE Header
#ifdef DEBUG_COMMENTS
Logger::debugLog(L"Something is wrong with the PE Header here Export table size %d\r\n",readSize);
#endif
readSize = sizeof(IMAGE_EXPORT_DIRECTORY) + 100;
}
if (readSize)
{
bufferExportTable = new BYTE[readSize];
if(!readMemoryFromProcess(module->modBaseAddr + pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress, readSize, bufferExportTable))
{
#ifdef DEBUG_COMMENTS
Logger::debugLog(L"getExportTableFromProcess :: Error reading export table from process\r\n");
#endif
delete[] bufferExportTable;
return 0;
}
else
{
return bufferExportTable;
}
}
else
{
return 0;
}
}
void ApiReader::parseModuleWithProcess(ModuleInfo * module)
{
PIMAGE_NT_HEADERS pNtHeader = 0;
PIMAGE_DOS_HEADER pDosHeader = 0;
BYTE *bufferHeader = 0;
BYTE *bufferExportTable = 0;
bufferHeader = getHeaderFromProcess(module);
if (bufferHeader == 0)
return;
pDosHeader = (PIMAGE_DOS_HEADER)bufferHeader;
pNtHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)bufferHeader + (DWORD_PTR)(pDosHeader->e_lfanew));
if (isPeAndExportTableValid(pNtHeader))
{
bufferExportTable = getExportTableFromProcess(module, pNtHeader);
if(bufferExportTable)
{
parseExportTable(module,pNtHeader,(PIMAGE_EXPORT_DIRECTORY)bufferExportTable, (DWORD_PTR)bufferExportTable - pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
delete[] bufferExportTable;
}
}
delete[] bufferHeader;
}
void ApiReader::parseExportTable(ModuleInfo *module, PIMAGE_NT_HEADERS pNtHeader, PIMAGE_EXPORT_DIRECTORY pExportDir, DWORD_PTR deltaAddress)
{
DWORD *addressOfFunctionsArray = 0,*addressOfNamesArray = 0;
WORD *addressOfNameOrdinalsArray = 0;
char *functionName = 0;
- DWORD_PTR RVA = 0, VA = 0, ordinal = 0;
- DWORD i = 0, j = 0;
+ DWORD_PTR RVA = 0, VA = 0;
+ WORD ordinal = 0;
+ WORD i = 0, j = 0;
bool withoutName;
addressOfFunctionsArray = (DWORD *)((DWORD_PTR)pExportDir->AddressOfFunctions + deltaAddress);
addressOfNamesArray = (DWORD *)((DWORD_PTR)pExportDir->AddressOfNames + deltaAddress);
addressOfNameOrdinalsArray = (WORD *)((DWORD_PTR)pExportDir->AddressOfNameOrdinals + deltaAddress);
#ifdef DEBUG_COMMENTS
Logger::debugLog(L"parseExportTable :: module %s NumberOfNames %X\r\n",module->fullPath,pExportDir->NumberOfNames);
#endif
for (i = 0; i < pExportDir->NumberOfNames; i++)
{
functionName = (char*)(addressOfNamesArray[i] + deltaAddress);
- ordinal = (addressOfNameOrdinalsArray[i] + pExportDir->Base);
+ ordinal = (WORD)(addressOfNameOrdinalsArray[i] + pExportDir->Base);
RVA = addressOfFunctionsArray[addressOfNameOrdinalsArray[i]];
VA = addressOfFunctionsArray[addressOfNameOrdinalsArray[i]] + module->modBaseAddr;
#ifdef DEBUG_COMMENTS
Logger::debugLog(TEXT("parseExportTable :: api %S ")TEXT(" ordinal %d imagebase ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT(" RVA ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT(" VA ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT("\r\n"),functionName,ordinal,module->modBaseAddr,RVA,VA);
#endif
if (!isApiBlacklisted(functionName))
{
if (!isApiForwarded(RVA,pNtHeader))
{
- addApi(functionName, (WORD)i, ordinal,VA,RVA,false,module);
+ addApi(functionName, i, ordinal,VA,RVA,false,module);
}
else
{
//printf("Forwarded: %s\n",functionName);
handleForwardedApi(RVA + deltaAddress,functionName,RVA,ordinal,module);
}
}
}
/*Exports without name*/
if (pExportDir->NumberOfNames != pExportDir->NumberOfFunctions)
{
for (i = 0; i < pExportDir->NumberOfFunctions; i++)
{
withoutName = true;
for (j = 0; j < pExportDir->NumberOfNames; j++)
{
if(addressOfNameOrdinalsArray[j] == i)
{
withoutName = false;
break;
}
}
if (withoutName && addressOfFunctionsArray[i] != 0)
{
- ordinal = (i+pExportDir->Base);
+ ordinal = (WORD)(i+pExportDir->Base);
RVA = addressOfFunctionsArray[i];
VA = (addressOfFunctionsArray[i] + module->modBaseAddr);
if (!isApiForwarded(RVA,pNtHeader))
{
addApiWithoutName(ordinal,VA,RVA,false,module);
}
else
{
handleForwardedApi(RVA + deltaAddress,0,RVA,ordinal,module);
}
}
}
}
}
-void ApiReader::findApiByModuleAndOrdinal(ModuleInfo * module, DWORD_PTR ordinal, DWORD_PTR * vaApi, DWORD_PTR * rvaApi)
+void ApiReader::findApiByModuleAndOrdinal(ModuleInfo * module, WORD ordinal, DWORD_PTR * vaApi, DWORD_PTR * rvaApi)
{
findApiByModule(module,0,ordinal,vaApi,rvaApi);
}
void ApiReader::findApiByModuleAndName(ModuleInfo * module, char * searchFunctionName, DWORD_PTR * vaApi, DWORD_PTR * rvaApi)
{
findApiByModule(module,searchFunctionName,0,vaApi,rvaApi);
}
-void ApiReader::findApiByModule(ModuleInfo * module, char * searchFunctionName, DWORD_PTR ordinal, DWORD_PTR * vaApi, DWORD_PTR * rvaApi)
+void ApiReader::findApiByModule(ModuleInfo * module, char * searchFunctionName, WORD ordinal, DWORD_PTR * vaApi, DWORD_PTR * rvaApi)
{
if (isModuleLoadedInOwnProcess(module))
{
HMODULE hModule = GetModuleHandle(module->getFilename());
if (hModule)
{
if (ordinal)
{
*vaApi = (DWORD_PTR)GetProcAddress(hModule, (LPCSTR)ordinal);
}
else
{
*vaApi = (DWORD_PTR)GetProcAddress(hModule, searchFunctionName);
}
if (vaApi)
{
*rvaApi = (*vaApi) - (DWORD_PTR)hModule;
*vaApi = (*rvaApi) + module->modBaseAddr;
}
else
{
#ifdef DEBUG_COMMENTS
Logger::debugLog(TEXT("findApiByModule :: vaApi == NULL, should never happen %S\r\n"),searchFunctionName);
#endif
}
}
else
{
#ifdef DEBUG_COMMENTS
Logger::debugLog(TEXT("findApiByModule :: hModule == NULL, should never happen %s\r\n"),module->getFilename());
#endif
}
}
else
{
//search api in extern process
findApiInProcess(module,searchFunctionName,ordinal,vaApi,rvaApi);
}
}
bool ApiReader::isModuleLoadedInOwnProcess(ModuleInfo * module)
{
for (unsigned int i = 0; i < ownModuleList.size(); i++)
{
if (!_wcsicmp(module->fullPath, ownModuleList[i].fullPath))
{
//printf("isModuleLoadedInOwnProcess :: %s %s\n",module->fullPath,ownModuleList[i].fullPath);
return true;
}
}
return false;
}
void ApiReader::parseModuleWithOwnProcess( ModuleInfo * module )
{
PIMAGE_NT_HEADERS pNtHeader = 0;
PIMAGE_DOS_HEADER pDosHeader = 0;
HMODULE hModule = GetModuleHandle(module->getFilename());
if (hModule)
{
pDosHeader = (PIMAGE_DOS_HEADER)hModule;
pNtHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)hModule + (DWORD_PTR)(pDosHeader->e_lfanew));
if (isPeAndExportTableValid(pNtHeader))
{
parseExportTable(module, pNtHeader, (PIMAGE_EXPORT_DIRECTORY)((DWORD_PTR)hModule + pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress), (DWORD_PTR)hModule);
}
}
else
{
#ifdef DEBUG_COMMENTS
Logger::debugLog(TEXT("parseModuleWithOwnProcess :: hModule is NULL\r\n"));
#endif
}
}
bool ApiReader::isPeAndExportTableValid(PIMAGE_NT_HEADERS pNtHeader)
{
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE)
{
Logger::printfDialog(TEXT("-> IMAGE_NT_SIGNATURE doesn't match."));
return false;
}
else if ((pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress == 0) || (pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size == 0))
{
Logger::printfDialog(TEXT("-> No export table."));
return false;
}
else
{
return true;
}
}
-void ApiReader::findApiInProcess(ModuleInfo * module, char * searchFunctionName, DWORD_PTR ordinal, DWORD_PTR * vaApi, DWORD_PTR * rvaApi)
+void ApiReader::findApiInProcess(ModuleInfo * module, char * searchFunctionName, WORD ordinal, DWORD_PTR * vaApi, DWORD_PTR * rvaApi)
{
PIMAGE_NT_HEADERS pNtHeader = 0;
PIMAGE_DOS_HEADER pDosHeader = 0;
BYTE *bufferHeader = 0;
BYTE *bufferExportTable = 0;
bufferHeader = getHeaderFromProcess(module);
if (bufferHeader == 0)
return;
pDosHeader = (PIMAGE_DOS_HEADER)bufferHeader;
pNtHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)bufferHeader + (DWORD_PTR)(pDosHeader->e_lfanew));
if (isPeAndExportTableValid(pNtHeader))
{
bufferExportTable = getExportTableFromProcess(module, pNtHeader);
if(bufferExportTable)
{
findApiInExportTable(module,(PIMAGE_EXPORT_DIRECTORY)bufferExportTable, (DWORD_PTR)bufferExportTable - pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress,searchFunctionName,ordinal,vaApi,rvaApi);
delete[] bufferExportTable;
}
}
delete[] bufferHeader;
}
-bool ApiReader::findApiInExportTable(ModuleInfo *module, PIMAGE_EXPORT_DIRECTORY pExportDir, DWORD_PTR deltaAddress, char * searchFunctionName, DWORD_PTR ordinal, DWORD_PTR * vaApi, DWORD_PTR * rvaApi)
+bool ApiReader::findApiInExportTable(ModuleInfo *module, PIMAGE_EXPORT_DIRECTORY pExportDir, DWORD_PTR deltaAddress, char * searchFunctionName, WORD ordinal, DWORD_PTR * vaApi, DWORD_PTR * rvaApi)
{
DWORD *addressOfFunctionsArray = 0,*addressOfNamesArray = 0;
WORD *addressOfNameOrdinalsArray = 0;
char *functionName = 0;
DWORD i = 0, j = 0;
addressOfFunctionsArray = (DWORD *)((DWORD_PTR)pExportDir->AddressOfFunctions + deltaAddress);
addressOfNamesArray = (DWORD *)((DWORD_PTR)pExportDir->AddressOfNames + deltaAddress);
addressOfNameOrdinalsArray = (WORD *)((DWORD_PTR)pExportDir->AddressOfNameOrdinals + deltaAddress);
if (searchFunctionName)
{
for (i = 0; i < pExportDir->NumberOfNames; i++)
{
functionName = (char*)(addressOfNamesArray[i] + deltaAddress);
if (!strcmp(functionName,searchFunctionName))
{
*rvaApi = addressOfFunctionsArray[addressOfNameOrdinalsArray[i]];
*vaApi = addressOfFunctionsArray[addressOfNameOrdinalsArray[i]] + module->modBaseAddr;
return true;
}
}
}
else
{
for (i = 0; i < pExportDir->NumberOfFunctions; i++)
{
if (ordinal == (i+pExportDir->Base))
{
*rvaApi = addressOfFunctionsArray[i];
*vaApi = (addressOfFunctionsArray[i] + module->modBaseAddr);
return true;
}
}
}
return false;
}
void ApiReader::setModulePriority(ModuleInfo * module)
{
const WCHAR *moduleFileName = module->getFilename();
if (!_wcsicmp(moduleFileName, TEXT("kernelbase.dll")))
{
module->priority = 0;
}
else if (!_wcsicmp(moduleFileName, TEXT("ntdll.dll")))
{
module->priority = 0;
}
else if (!_wcsicmp(moduleFileName, TEXT("shlwapi.dll")))
{
module->priority = 0;
}
else if (!_wcsicmp(moduleFileName, TEXT("ShimEng.dll")))
{
module->priority = 0;
}
else if (!_wcsicmp(moduleFileName, TEXT("kernel32.dll")))
{
module->priority = 2;
}
else
{
module->priority = 1;
}
}
bool ApiReader::isApiAddressValid(DWORD_PTR virtualAddress)
{
return apiList.count(virtualAddress) > 0;
}
ApiInfo * ApiReader::getApiByVirtualAddress(DWORD_PTR virtualAddress, bool * isSuspect)
{
stdext::hash_multimap<DWORD_PTR, ApiInfo *>::iterator it1, it2;
size_t c = 0;
size_t countDuplicates = apiList.count(virtualAddress);
int countHighPriority = 0;
ApiInfo *apiFound = 0;
if (countDuplicates == 0)
{
Logger::printfDialog(TEXT("getApiByVirtualAddress :: No Api found ")TEXT(PRINTF_DWORD_PTR_FULL),virtualAddress);
return 0;
}
else if (countDuplicates == 1)
{
//API is 100% correct
*isSuspect = false;
it1 = apiList.find(virtualAddress); // Find first match.
return (ApiInfo *)((*it1).second);
}
else
{
it1 = apiList.find(virtualAddress); // Find first match.
it2 = it1;
for (c = 0; c < countDuplicates; c++, it1++)
{
apiFound = (ApiInfo *)((*it1).second);
if (apiFound->module->priority >= 1) //1 == high priority
{
countHighPriority++;
}
}
it1 = it2;
/*
This is flawed:
It chooses api(prio:1, name:no) over api(prio:0, name:yes)
(e.g. SHLWAPI.PathCombineW vs SHELL32.#25)
Maybe there should be a check higher up in the code, to see if this API is surrounded
by APIs of a DLL and pick the duplicate from that DLL
*/
if (countHighPriority == 0)
{
#ifdef DEBUG_COMMENTS
Logger::debugLog(TEXT("getApiByVirtualAddress :: countHighPriority == 0 ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT("\r\n"),virtualAddress);
#endif
*isSuspect = true;
return (ApiInfo *)((*it1).second);
}
else if (countHighPriority == 1) // what about kernel32, it has priority 2
{
//API is 100% correct if countHighPriority == 1 and name export
*isSuspect = false;
for (c = 0; c < countDuplicates; c++, it1++)
{
apiFound = (ApiInfo *)((*it1).second);
if (apiFound->module->priority >= 1 && apiFound->name[0] != 0x00) //1 == high priority
{
return apiFound;
}
}
}
//else // fall through for case api1(priority:1, name:false) <> api2(priority:0, name:true)
{
//API not 100% correct
#ifdef DEBUG_COMMENTS
Logger::debugLog(TEXT("getApiByVirtualAddress :: countHighPriority == %d ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT("\r\n"),countHighPriority,virtualAddress);
#endif
*isSuspect = true;
/*for (c = 0; c < countDuplicates; c++, it1++)
{
apiFound = (ApiInfo *)((*it1).second);
Logger::printfDialog("%s - %s %X %X\n",apiFound->name,apiFound->module->getFilename(),apiFound->rva, apiFound->ordinal);
}
it1 = it2;*/
for (c = 0; c < countDuplicates; c++, it1++)
{
apiFound = (ApiInfo *)((*it1).second);
//prefer APIs with a name
if (apiFound->module->priority >= 1 && apiFound->name[0] != 0x00) //1 == high priority
{
//prefer ANSI/UNICODE APIs
if (strrchr(apiFound->name,TEXT('W')) || strrchr(apiFound->name,TEXT('A')))
{
return apiFound;
}
}
}
it1 = it2;
for (c = 0; c < countDuplicates; c++, it1++)
{
apiFound = (ApiInfo *)((*it1).second);
//prefer APIs with a name
if (apiFound->module->priority == 2 && !strrchr(apiFound->name,TEXT('_'))) //1 == high priority
{
return apiFound;
}
}
it1 = it2;
for (c = 0; c < countDuplicates; c++, it1++)
{
apiFound = (ApiInfo *)((*it1).second);
if (apiFound->module->priority == 1 && apiFound->name[0] != 0x00) //1 == high priority
{
return apiFound;
}
}
it1 = it2;
for (c = 0; c < countDuplicates; c++, it1++)
{
apiFound = (ApiInfo *)((*it1).second);
if (apiFound->module->priority == 1) //1 == high priority
{
return apiFound;
}
}
}
}
//is never reached
Logger::printfDialog(TEXT("getApiByVirtualAddress :: There is a big bug"));
return (ApiInfo *) 1;
}
void ApiReader::setMinMaxApiAddress(DWORD_PTR virtualAddress)
{
if (virtualAddress < minApiAddress)
{
minApiAddress = virtualAddress - 1;
}
if (virtualAddress > maxApiAddress)
{
maxApiAddress = virtualAddress + 1;
}
}
void ApiReader::readAndParseIAT(DWORD_PTR addressIAT, DWORD sizeIAT, std::map<DWORD_PTR, ImportModuleThunk> &moduleListNew)
{
moduleThunkList = &moduleListNew;
BYTE *dataIat = new BYTE[sizeIAT];
if (readMemoryFromProcess(addressIAT,sizeIAT,dataIat))
{
parseIAT(addressIAT,dataIat,sizeIAT);
}
else
{
#ifdef DEBUG_COMMENTS
Logger::debugLog(TEXT("ApiReader::readAndParseIAT :: error reading iat ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT("\r\n"),addressIAT);
#endif
}
delete[] dataIat;
}
void ApiReader::parseIAT(DWORD_PTR addressIAT, BYTE * iatBuffer, SIZE_T size)
{
ApiInfo *apiFound = 0;
ModuleInfo *module = 0;
bool isSuspect = false;
int countApiFound = 0, countApiNotFound = 0;
DWORD_PTR * pIATAddress = (DWORD_PTR *)iatBuffer;
SIZE_T sizeIAT = size / sizeof(DWORD_PTR);
bool foundModuleBreak = false;
for (SIZE_T i = 0; i < sizeIAT; i++)
{
//Logger::printfDialog("%08X %08X %d von %d",addressIAT + (DWORD_PTR)&pIATAddress[i] - (DWORD_PTR)iatBuffer,pIATAddress[i],i,sizeIAT);
if (pIATAddress[i] == 0 || pIATAddress[i] == -1)
{
/*if (pIATAddress[i+1] != 0)
{
printf("parseIAT :: Module break\n");
}*/
/*else
{
printf("parseIAT :: IAT finished\n");
break;
}*/
foundModuleBreak = true;
}
else if ( (pIATAddress[i] > minApiAddress) && (pIATAddress[i] < maxApiAddress) )
{
apiFound = getApiByVirtualAddress(pIATAddress[i], &isSuspect);
if (apiFound == (ApiInfo *)1)
{
#ifdef DEBUG_COMMENTS
Logger::debugLog(TEXT("apiFound == (ApiInfo *)1 -> ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT("\r\n"),pIATAddress[i]);
#endif
}
else if (apiFound)
{
countApiFound++;
#ifdef DEBUG_COMMENTS
Logger::debugLog(TEXT("")TEXT(PRINTF_DWORD_PTR_FULL)TEXT(" %s %d %s\r\n"),apiFound->va, apiFound->module->getFilename(), apiFound->ordinal,apiFound->name);
#endif
if (module != apiFound->module)
{
module = apiFound->module;
addFoundApiToModuleList(addressIAT + (DWORD_PTR)&pIATAddress[i] - (DWORD_PTR)iatBuffer, apiFound, true, isSuspect);
}
else
{
addFoundApiToModuleList(addressIAT + (DWORD_PTR)&pIATAddress[i] - (DWORD_PTR)iatBuffer, apiFound, false, isSuspect);
}
}
else
{
countApiNotFound++;
addNotFoundApiToModuleList(addressIAT + (DWORD_PTR)&pIATAddress[i] - (DWORD_PTR)iatBuffer, pIATAddress[i]);
//printf("parseIAT :: API not found %08X\n", pIATAddress[i]);
}
}
else
{
//printf("parseIAT :: API not found %08X\n", pIATAddress[i]);
countApiNotFound++;
addNotFoundApiToModuleList(addressIAT + (DWORD_PTR)&pIATAddress[i] - (DWORD_PTR)iatBuffer, pIATAddress[i]);
}
}
Logger::printfDialog(TEXT("IAT parsing finished, found %d valid APIs, missed %d APIs"),countApiFound,countApiNotFound);
}
void ApiReader::addFoundApiToModuleList(DWORD_PTR iatAddressVA, ApiInfo * apiFound, bool isNewModule, bool isSuspect)
{
if (isNewModule)
{
addModuleToModuleList(apiFound->module->getFilename(), iatAddressVA - targetImageBase);
}
addFunctionToModuleList(apiFound, iatAddressVA, iatAddressVA - targetImageBase, apiFound->ordinal, true, isSuspect);
}
bool ApiReader::addModuleToModuleList(const WCHAR * moduleName, DWORD_PTR firstThunk)
{
ImportModuleThunk module;
module.firstThunk = firstThunk;
wcscpy_s(module.moduleName, MAX_PATH, moduleName);
(*moduleThunkList).insert(std::pair<DWORD_PTR,ImportModuleThunk>(firstThunk,module));
return true;
}
void ApiReader::addUnknownModuleToModuleList(DWORD_PTR firstThunk)
{
ImportModuleThunk module;
module.firstThunk = firstThunk;
wcscpy_s(module.moduleName, MAX_PATH, TEXT("?"));
(*moduleThunkList).insert(std::pair<DWORD_PTR,ImportModuleThunk>(firstThunk,module));
}
-bool ApiReader::addFunctionToModuleList(ApiInfo * apiFound, DWORD_PTR va, DWORD_PTR rva, DWORD_PTR ordinal, bool valid, bool suspect)
+bool ApiReader::addFunctionToModuleList(ApiInfo * apiFound, DWORD_PTR va, DWORD_PTR rva, WORD ordinal, bool valid, bool suspect)
{
ImportThunk import;
ImportModuleThunk * module = 0;
std::map<DWORD_PTR, ImportModuleThunk>::iterator iterator1;
if ((*moduleThunkList).size() > 1)
{
iterator1 = (*moduleThunkList).begin();
while (iterator1 != (*moduleThunkList).end())
{
if (rva >= iterator1->second.firstThunk)
{
iterator1++;
if (iterator1 == (*moduleThunkList).end())
{
iterator1--;
module = &(iterator1->second);
break;
}
else if (rva < iterator1->second.firstThunk)
{
iterator1--;
module = &(iterator1->second);
break;
}
}
else
{
#ifdef DEBUG_COMMENTS
Logger::debugLog(TEXT("Error iterator1 != (*moduleThunkList).end()\r\n"));
#endif
break;
}
}
}
else
{
iterator1 = (*moduleThunkList).begin();
module = &(iterator1->second);
}
if (!module)
{
#ifdef DEBUG_COMMENTS
Logger::debugLog(TEXT("ImportsHandling::addFunction module not found rva ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT("\r\n"),rva);
#endif
return false;
}
import.suspect = suspect;
import.valid = valid;
import.va = va;
import.rva = rva;
import.apiAddressVA = apiFound->va;
import.ordinal = ordinal;
import.hint = (WORD)apiFound->hint;
wcscpy_s(import.moduleName, MAX_PATH, apiFound->module->getFilename());
strcpy_s(import.name, MAX_PATH, apiFound->name);
module->thunkList.insert(std::pair<DWORD_PTR,ImportThunk>(import.rva, import));
return true;
}
void ApiReader::clearAll()
{
minApiAddress = -1;
maxApiAddress = 0;
for ( stdext::hash_multimap<DWORD_PTR, ApiInfo *>::iterator it = apiList.begin(); it != apiList.end(); ++it )
{
delete it->second;
}
apiList.clear();
if (moduleThunkList != 0)
{
(*moduleThunkList).clear();
}
}
bool ApiReader::addNotFoundApiToModuleList(DWORD_PTR iatAddressVA, DWORD_PTR apiAddress)
{
ImportThunk import;
ImportModuleThunk * module = 0;
std::map<DWORD_PTR, ImportModuleThunk>::iterator iterator1;
DWORD_PTR rva = iatAddressVA - targetImageBase;
if ((*moduleThunkList).size() > 0)
{
iterator1 = (*moduleThunkList).begin();
while (iterator1 != (*moduleThunkList).end())
{
if (rva >= iterator1->second.firstThunk)
{
iterator1++;
if (iterator1 == (*moduleThunkList).end())
{
iterator1--;
//new unknown module
if (iterator1->second.moduleName[0] == L'?')
{
module = &(iterator1->second);
}
else
{
addUnknownModuleToModuleList(rva);
module = &((*moduleThunkList).find(rva)->second);
}
break;
}
else if (rva < iterator1->second.firstThunk)
{
iterator1--;
module = &(iterator1->second);
break;
}
}
else
{
#ifdef DEBUG_COMMENTS
Logger::debugLog(TEXT("Error iterator1 != (*moduleThunkList).end()\r\n"));
#endif
break;
}
}
}
else
{
//new unknown module
addUnknownModuleToModuleList(rva);
module = &((*moduleThunkList).find(rva)->second);
}
if (!module)
{
#ifdef DEBUG_COMMENTS
Logger::debugLog(TEXT("ImportsHandling::addFunction module not found rva ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT("\r\n"),rva);
#endif
return false;
}
import.suspect = true;
import.valid = false;
import.va = iatAddressVA;
import.rva = rva;
import.apiAddressVA = apiAddress;
import.ordinal = 0;
wcscpy_s(import.moduleName, MAX_PATH, TEXT("?"));
strcpy_s(import.name, MAX_PATH, "?");
module->thunkList.insert(std::pair<DWORD_PTR,ImportThunk>(import.rva, import));
return true;
}
bool ApiReader::isApiBlacklisted( const char * functionName )
{
if (SystemInformation::currenOS < WIN_VISTA_32)
{
if (!strcmp(functionName, "RestoreLastError"))
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
/*#ifdef _WIN64
else if (SystemInformation::currenOS == WIN_XP_64 && !strcmp(functionName, "DecodePointer"))
{
return true;
}
#endif*/
}
bool ApiReader::isWinSxSModule( ModuleInfo * module )
{
if (wcsstr(module->fullPath, TEXT("\\WinSxS\\")))
{
return true;
}
else if (wcsstr(module->fullPath, TEXT("\\winsxs\\")))
{
return true;
}
else
{
return false;
}
}
diff --git a/Scylla/ApiReader.h b/Scylla/ApiReader.h
index de09da2..36f86a2 100644
--- a/Scylla/ApiReader.h
+++ b/Scylla/ApiReader.h
@@ -1,70 +1,70 @@
#pragma once
#include "ProcessAccessHelp.h"
#include "Thunks.h"
typedef std::pair<DWORD_PTR, ApiInfo *> API_Pair;
class ApiReader : public ProcessAccessHelp {
public:
static stdext::hash_multimap<DWORD_PTR, ApiInfo *> apiList; //api look up table
static std::map<DWORD_PTR, ImportModuleThunk> * moduleThunkList; //store found apis
static DWORD_PTR minApiAddress;
static DWORD_PTR maxApiAddress;
/*
* Read all APIs from target process
*/
void readApisFromModuleList();
bool isApiAddressValid(DWORD_PTR virtualAddress);
ApiInfo * getApiByVirtualAddress(DWORD_PTR virtualAddress, bool * isSuspect);
void readAndParseIAT(DWORD_PTR addressIAT, DWORD sizeIAT,std::map<DWORD_PTR, ImportModuleThunk> &moduleListNew );
void clearAll();
private:
void parseIAT(DWORD_PTR addressIAT, BYTE * iatBuffer, SIZE_T size);
- void addApi(char *functionName, WORD hint, DWORD_PTR ordinal, DWORD_PTR va, DWORD_PTR rva, bool isForwarded, ModuleInfo *moduleInfo);
- void addApiWithoutName(DWORD_PTR ordinal, DWORD_PTR va, DWORD_PTR rva,bool isForwarded, ModuleInfo *moduleInfo);
+ void addApi(char *functionName, WORD hint, WORD ordinal, DWORD_PTR va, DWORD_PTR rva, bool isForwarded, ModuleInfo *moduleInfo);
+ void addApiWithoutName(WORD ordinal, DWORD_PTR va, DWORD_PTR rva,bool isForwarded, ModuleInfo *moduleInfo);
inline bool isApiForwarded(DWORD_PTR rva, PIMAGE_NT_HEADERS pNtHeader);
- void handleForwardedApi(DWORD_PTR vaStringPointer,char *functionNameParent,DWORD_PTR rvaParent, DWORD_PTR ordinalParent, ModuleInfo *moduleParent);
+ void handleForwardedApi(DWORD_PTR vaStringPointer,char *functionNameParent,DWORD_PTR rvaParent, WORD ordinalParent, ModuleInfo *moduleParent);
void parseModule(ModuleInfo *module);
void parseModuleWithProcess(ModuleInfo * module);
void parseExportTable(ModuleInfo *module, PIMAGE_NT_HEADERS pNtHeader, PIMAGE_EXPORT_DIRECTORY pExportDir, DWORD_PTR deltaAddress);
ModuleInfo * findModuleByName(WCHAR *name);
- void findApiByModuleAndOrdinal(ModuleInfo * module, DWORD_PTR ordinal, DWORD_PTR * vaApi, DWORD_PTR * rvaApi);
+ void findApiByModuleAndOrdinal(ModuleInfo * module, WORD ordinal, DWORD_PTR * vaApi, DWORD_PTR * rvaApi);
void findApiByModuleAndName(ModuleInfo * module, char * searchFunctionName, DWORD_PTR * vaApi, DWORD_PTR * rvaApi);
- void findApiByModule(ModuleInfo * module, char * searchFunctionName, DWORD_PTR ordinal, DWORD_PTR * vaApi, DWORD_PTR * rvaApi);
+ void findApiByModule(ModuleInfo * module, char * searchFunctionName, WORD ordinal, DWORD_PTR * vaApi, DWORD_PTR * rvaApi);
bool isModuleLoadedInOwnProcess( ModuleInfo * module );
void parseModuleWithOwnProcess( ModuleInfo * module );
bool isPeAndExportTableValid(PIMAGE_NT_HEADERS pNtHeader);
- void findApiInProcess( ModuleInfo * module, char * searchFunctionName, DWORD_PTR ordinal, DWORD_PTR * vaApi, DWORD_PTR * rvaApi );
- bool findApiInExportTable(ModuleInfo *module, PIMAGE_EXPORT_DIRECTORY pExportDir, DWORD_PTR deltaAddress, char * searchFunctionName, DWORD_PTR ordinal, DWORD_PTR * vaApi, DWORD_PTR * rvaApi);
+ void findApiInProcess( ModuleInfo * module, char * searchFunctionName, WORD ordinal, DWORD_PTR * vaApi, DWORD_PTR * rvaApi );
+ bool findApiInExportTable(ModuleInfo *module, PIMAGE_EXPORT_DIRECTORY pExportDir, DWORD_PTR deltaAddress, char * searchFunctionName, WORD ordinal, DWORD_PTR * vaApi, DWORD_PTR * rvaApi);
BYTE * getHeaderFromProcess(ModuleInfo * module);
BYTE * getExportTableFromProcess(ModuleInfo * module, PIMAGE_NT_HEADERS pNtHeader);
void setModulePriority(ModuleInfo * module);
void setMinMaxApiAddress(DWORD_PTR virtualAddress);
void parseModuleWithMapping(ModuleInfo *moduleInfo); //not used
void addFoundApiToModuleList(DWORD_PTR iatAddress, ApiInfo * apiFound, bool isNewModule, bool isSuspect);
bool addModuleToModuleList(const WCHAR * moduleName, DWORD_PTR firstThunk);
- bool addFunctionToModuleList(ApiInfo * apiFound, DWORD_PTR va, DWORD_PTR rva, DWORD_PTR ordinal, bool valid, bool suspect);
+ bool addFunctionToModuleList(ApiInfo * apiFound, DWORD_PTR va, DWORD_PTR rva, WORD ordinal, bool valid, bool suspect);
bool addNotFoundApiToModuleList(DWORD_PTR iatAddressVA, DWORD_PTR apiAddress);
void addUnknownModuleToModuleList(DWORD_PTR firstThunk);
bool isApiBlacklisted( const char * functionName );
bool isWinSxSModule( ModuleInfo * module );
};
\ No newline at end of file
diff --git a/Scylla/ImportsHandling.cpp b/Scylla/ImportsHandling.cpp
index d9b4744..ea8ca46 100644
--- a/Scylla/ImportsHandling.cpp
+++ b/Scylla/ImportsHandling.cpp
@@ -1,788 +1,771 @@
#include "ImportsHandling.h"
#include "Thunks.h"
#include "definitions.h"
#include <atlmisc.h>
#include <atlcrack.h>
#include "multitree.h" // CMultiSelectTreeViewCtrl
#include "resource.h"
//#define DEBUG_COMMENTS
-ImportsHandling::ImportsHandling(CMultiSelectTreeViewCtrl& TreeImports) : TreeImports(TreeImports)
-{
- hIconCheck.LoadIcon(IDI_ICON_CHECK);
- hIconWarning.LoadIcon(IDI_ICON_WARNING);
- hIconError.LoadIcon(IDI_ICON_ERROR);
-
- TreeIcons.Create(16, 16, ILC_COLOR32, 3, 1);
- TreeIcons.AddIcon(hIconCheck);
- TreeIcons.AddIcon(hIconWarning);
- TreeIcons.AddIcon(hIconError);
-}
-
-ImportsHandling::~ImportsHandling()
-{
- TreeIcons.Destroy();
+void ImportThunk::invalidate()
+{
+ ordinal = 0;
+ hint = 0;
+ valid = false;
+ suspect = false;
+ moduleName[0] = 0;
+ name[0] = 0;
}
bool ImportModuleThunk::isValid() const
{
std::map<DWORD_PTR, ImportThunk>::const_iterator iterator = thunkList.begin();
while (iterator != thunkList.end())
{
if (iterator->second.valid == false)
{
return false;
}
iterator++;
}
return true;
}
DWORD_PTR ImportModuleThunk::getFirstThunk() const
{
if (thunkList.size() > 0)
{
const std::map<DWORD_PTR, ImportThunk>::const_iterator iterator = thunkList.begin();
return iterator->first;
}
else
{
return 0;
}
}
-/*bool ImportsHandling::addModule(WCHAR * moduleName, DWORD_PTR firstThunk)
+ImportsHandling::ImportsHandling(CMultiSelectTreeViewCtrl& TreeImports) : TreeImports(TreeImports)
{
- ImportModuleThunk module;
+ hIconCheck.LoadIcon(IDI_ICON_CHECK, 16, 16);
+ hIconWarning.LoadIcon(IDI_ICON_WARNING, 16, 16);
+ hIconError.LoadIcon(IDI_ICON_ERROR, 16, 16);
- module.firstThunk = firstThunk;
- wcscpy_s(module.moduleName, MAX_PATH, moduleName);
+ TreeIcons.Create(16, 16, ILC_COLOR32, 3, 1);
+ TreeIcons.AddIcon(hIconCheck);
+ TreeIcons.AddIcon(hIconWarning);
+ TreeIcons.AddIcon(hIconError);
+}
- moduleList.insert(std::pair<DWORD_PTR,ImportModuleThunk>(firstThunk,module));
+ImportsHandling::~ImportsHandling()
+{
+ TreeIcons.Destroy();
+}
- return true;
-}*/
+bool ImportsHandling::isModule(CTreeItem item)
+{
+ return (0 != getModuleThunk(item));
+}
+
+bool ImportsHandling::isImport(CTreeItem item)
+{
+ return (0 != getImportThunk(item));
+}
+
+ImportModuleThunk * ImportsHandling::getModuleThunk(CTreeItem item)
+{
+ std::hash_map<HTREEITEM, TreeItemData>::const_iterator it;
+ it = itemData.find(item);
+ if(it != itemData.end())
+ {
+ const TreeItemData * data = &it->second;
+ if(data->isModule)
+ {
+ return data->module;
+ }
+ }
+ return NULL;
+}
+
+ImportThunk * ImportsHandling::getImportThunk(CTreeItem item)
+{
+ std::hash_map<HTREEITEM, TreeItemData>::const_iterator it;
+ TreeItemData * data = getItemData(item);
+ if(data && !data->isModule)
+ {
+ return data->import;
+ }
+ return NULL;
+}
+
+void ImportsHandling::setItemData(CTreeItem item, const TreeItemData& data)
+{
+ itemData[item] = data;
+}
+
+ImportsHandling::TreeItemData * ImportsHandling::getItemData(CTreeItem item)
+{
+ std::hash_map<HTREEITEM, TreeItemData>::iterator it;
+ it = itemData.find(item);
+ if(it != itemData.end())
+ {
+ return &it->second;
+ }
+ return NULL;
+}
+
+void ImportsHandling::updateCounts()
+{
+ std::map<DWORD_PTR, ImportModuleThunk>::iterator it_module;
+ std::map<DWORD_PTR, ImportThunk>::iterator it_import;
+
+ m_thunkCount = m_invalidThunkCount = m_suspectThunkCount = 0;
+
+ it_module = moduleList.begin();
+ while (it_module != moduleList.end())
+ {
+ ImportModuleThunk &moduleThunk = it_module->second;
+
+ it_import = moduleThunk.thunkList.begin();
+ while (it_import != moduleThunk.thunkList.end())
+ {
+ ImportThunk &importThunk = it_import->second;
+
+ m_thunkCount++;
+ if(!importThunk.valid)
+ m_invalidThunkCount++;
+ else if(importThunk.suspect)
+ m_suspectThunkCount++;
+
+ it_import++;
+ }
+
+ it_module++;
+ }
+}
-/*bool ImportsHandling::addFunction(WCHAR * moduleName, char * name, DWORD_PTR va, DWORD_PTR rva, DWORD_PTR ordinal, bool valid, bool suspect)
+/*bool ImportsHandling::addImport(const WCHAR * moduleName, const CHAR * name, DWORD_PTR va, DWORD_PTR rva, WORD ordinal, bool valid, bool suspect)
{
ImportThunk import;
ImportModuleThunk * module = 0;
std::map<DWORD_PTR, ImportModuleThunk>::iterator iterator1;
if (moduleList.size() > 1)
{
iterator1 = moduleList.begin();
while (iterator1 != moduleList.end())
{
if (rva >= iterator1->second.firstThunk)
{
iterator1++;
if (iterator1 == moduleList.end())
{
iterator1--;
module = &(iterator1->second);
break;
}
else if (rva < iterator1->second.firstThunk)
{
iterator1--;
module = &(iterator1->second);
break;
}
}
}
}
else
{
iterator1 = moduleList.begin();
module = &(iterator1->second);
}
if (!module)
{
Logger::debugLog(TEXT("ImportsHandling::addFunction module not found rva ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT(""),rva);
return false;
}
//TODO
import.suspect = true;
import.valid = false;
import.va = va;
import.rva = rva;
import.ordinal = ordinal;
wcscpy_s(import.moduleName, MAX_PATH, moduleName);
strcpy_s(import.name, MAX_PATH, name);
module->thunkList.insert(std::pair<DWORD_PTR,ImportThunk>(import.rva, import));
return true;
-}*/
+}
+*/
+
+/*
+bool ImportsHandling::addModule(const WCHAR * moduleName, DWORD_PTR firstThunk)
+{
+ ImportModuleThunk module;
+
+ module.firstThunk = firstThunk;
+ wcscpy_s(module.moduleName, MAX_PATH, moduleName);
+
+ moduleList.insert(std::pair<DWORD_PTR,ImportModuleThunk>(firstThunk,module));
+
+ return true;
+}
+*/
void ImportsHandling::displayAllImports()
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator it_module;
- std::map<DWORD_PTR, ImportThunk>::iterator it_thunk;
- ImportModuleThunk * moduleThunk;
- ImportThunk * importThunk;
- CTreeItem module;
- CTreeItem apiFunction;
+ std::map<DWORD_PTR, ImportThunk>::iterator it_import;
TreeImports.DeleteAllItems();
+ itemData.clear();
TreeImports.SetImageList(TreeIcons);
- it_module = moduleList.begin();
+ it_module = moduleList.begin();
+ while (it_module != moduleList.end())
+ {
+ ImportModuleThunk &moduleThunk = it_module->second;
- while (it_module != moduleList.end())
- {
- moduleThunk = &(it_module->second);
+ moduleThunk.hTreeItem = addDllToTreeView(TreeImports, &moduleThunk);
- module = addDllToTreeView(TreeImports,moduleThunk);
-
- moduleThunk->hTreeItem = module;
+ it_import = moduleThunk.thunkList.begin();
+ while (it_import != moduleThunk.thunkList.end())
+ {
+ ImportThunk &importThunk = it_import->second;
- it_thunk = moduleThunk->thunkList.begin();
+ importThunk.hTreeItem = addApiToTreeView(TreeImports, moduleThunk.hTreeItem, &importThunk);
- while (it_thunk != moduleThunk->thunkList.end())
- {
- importThunk = &(it_thunk->second);
- apiFunction = addApiToTreeView(TreeImports,module,importThunk);
- importThunk->hTreeItem = apiFunction;
- it_thunk++;
- }
+ it_import++;
+ }
+
+ it_module++;
+ }
+
+ updateCounts();
+}
- it_module++;
- }
+void ImportsHandling::clearAllImports()
+{
+ TreeImports.DeleteAllItems();
+ itemData.clear();
+ moduleList.clear();
+ updateCounts();
}
-CTreeItem ImportsHandling::addDllToTreeView(CMultiSelectTreeViewCtrl& idTreeView, const ImportModuleThunk * importThunk)
+CTreeItem ImportsHandling::addDllToTreeView(CMultiSelectTreeViewCtrl& idTreeView, ImportModuleThunk * moduleThunk)
{
CTreeItem item = idTreeView.InsertItem(L"", NULL, TVI_ROOT);
- updateModuleInTreeView(importThunk, item);
+
+ item.SetData(itemData.size());
+
+ TreeItemData data;
+ data.isModule = true;
+ data.module = moduleThunk;
+
+ setItemData(item, data);
+
+ updateModuleInTreeView(moduleThunk, item);
return item;
}
-CTreeItem ImportsHandling::addApiToTreeView(CMultiSelectTreeViewCtrl& idTreeView, CTreeItem parentDll, const ImportThunk * importThunk)
+CTreeItem ImportsHandling::addApiToTreeView(CMultiSelectTreeViewCtrl& idTreeView, CTreeItem parentDll, ImportThunk * importThunk)
{
CTreeItem item = idTreeView.InsertItem(L"", parentDll, TVI_LAST);
+
+ item.SetData(itemData.size());
+
+ TreeItemData data;
+ data.isModule = false;
+ data.import = importThunk;
+
+ setItemData(item, data);
+
updateImportInTreeView(importThunk, item);
return item;
}
-void ImportsHandling::showImports(bool invalid, bool suspect)
+void ImportsHandling::selectImports(bool invalid, bool suspect)
{
- std::map<DWORD_PTR, ImportModuleThunk>::iterator iterator1;
- std::map<DWORD_PTR, ImportThunk>::iterator iterator2;
- ImportModuleThunk * moduleThunk;
- ImportThunk * importThunk;
+ std::map<DWORD_PTR, ImportModuleThunk>::iterator it_module;
+ std::map<DWORD_PTR, ImportThunk>::iterator it_import;
- TreeImports.SetFocus(); // should be GotoDlgCtrl...
TreeImports.SelectAllItems(FALSE); //remove selection
- iterator1 = moduleList.begin();
-
- while (iterator1 != moduleList.end())
+ it_module = moduleList.begin();
+ while (it_module != moduleList.end())
{
- moduleThunk = &(iterator1->second);
+ ImportModuleThunk &moduleThunk = it_module->second;
- iterator2 = moduleThunk->thunkList.begin();
-
- while (iterator2 != moduleThunk->thunkList.end())
+ it_import = moduleThunk.thunkList.begin();
+ while (it_import != moduleThunk.thunkList.end())
{
- importThunk = &(iterator2->second);
+ ImportThunk &importThunk = it_import->second;
- if (invalid && !importThunk->valid)
- {
- selectItem(importThunk->hTreeItem);
- setFocus(TreeImports, importThunk->hTreeItem);
- }
- else if (suspect && importThunk->suspect)
- {
- selectItem(importThunk->hTreeItem);
- setFocus(TreeImports, importThunk->hTreeItem);
- }
- else
+ if ((invalid && !importThunk.valid) || (suspect && importThunk.suspect))
{
- unselectItem(importThunk->hTreeItem);
+ TreeImports.SelectItem(importThunk.hTreeItem, TRUE);
+ importThunk.hTreeItem.EnsureVisible();
}
- iterator2++;
+ it_import++;
}
- iterator1++;
+ it_module++;
}
}
-bool ImportsHandling::isItemSelected(CTreeItem hItem)
-{
- const UINT state = TVIS_SELECTED;
- return ((hItem.GetState(state) & state) == state);
-}
-
-void ImportsHandling::unselectItem(CTreeItem htItem)
-{
- selectItem(htItem, false);
-}
-
-bool ImportsHandling::selectItem(CTreeItem hItem, bool select)
-{
- const UINT state = TVIS_SELECTED;
- return FALSE != hItem.SetState((select ? state : 0), state);
-}
-
-void ImportsHandling::setFocus(CMultiSelectTreeViewCtrl& hwndTV, CTreeItem htItem)
+bool ImportsHandling::invalidateImport(CTreeItem item)
{
- // the current focus
- CTreeItem htFocus = hwndTV.GetFirstSelectedItem();
-
- if ( htItem )
+ ImportThunk * import = getImportThunk(item);
+ if(import)
{
- // set the focus
- if ( htItem != htFocus )
+ CTreeItem parent = item.GetParent();
+ if(!parent.IsNull())
{
- // remember the selection state of the item
- bool wasSelected = isItemSelected(htItem);
-
- if ( htFocus && isItemSelected(htFocus) )
+ const ImportModuleThunk * module = getModuleThunk(parent);
+ if(module)
{
- // prevent the tree from unselecting the old focus which it
- // would do by default (TreeView_SelectItem unselects the
- // focused item)
- hwndTV.SelectAllItems(FALSE);
- selectItem(htFocus);
- }
+ import->invalidate();
- hwndTV.SelectItem(htItem, FALSE);
+ updateImportInTreeView(import, import->hTreeItem);
+ updateModuleInTreeView(module, module->hTreeItem);
- if ( !wasSelected )
- {
- // need to clear the selection which TreeView_SelectItem() gave
- // us
- unselectItem(htItem);
- }
- //else: was selected, still selected - ok
- }
- //else: nothing to do, focus already there
- }
- else
- {
- if ( htFocus )
- {
- bool wasFocusSelected = isItemSelected(htFocus);
-
- // just clear the focus
- hwndTV.SelectItem(NULL, FALSE);
-
- if ( wasFocusSelected )
- {
- // restore the selection state
- selectItem(htFocus);
+ updateCounts();
+ return true;
}
}
- //else: nothing to do, no focus already
}
+ return false;
}
-bool ImportsHandling::invalidateFunction(CTreeItem selectedTreeNode)
+bool ImportsHandling::setImport(CTreeItem item, const WCHAR * moduleName, const CHAR * apiName, WORD ordinal, WORD hint, bool valid, bool suspect)
{
- std::map<DWORD_PTR, ImportModuleThunk>::iterator iterator1;
- std::map<DWORD_PTR, ImportThunk>::iterator iterator2;
- ImportModuleThunk * moduleThunk;
- ImportThunk * importThunk;
-
-
- iterator1 = moduleList.begin();
-
- while (iterator1 != moduleList.end())
+ ImportThunk * import = getImportThunk(item);
+ if(import)
{
- moduleThunk = &(iterator1->second);
-
- iterator2 = moduleThunk->thunkList.begin();
-
- while (iterator2 != moduleThunk->thunkList.end())
+ CTreeItem parent = item.GetParent();
+ if(!parent.IsNull())
{
- importThunk = &(iterator2->second);
-
- if (importThunk->hTreeItem == selectedTreeNode)
+ const ImportModuleThunk * module = getModuleThunk(parent);
+ if(module)
{
- importThunk->ordinal = 0;
- importThunk->hint = 0;
- importThunk->valid = false;
- importThunk->suspect = false;
- importThunk->moduleName[0] = 0;
- importThunk->name[0] = 0;
-
- updateImportInTreeView(importThunk, importThunk->hTreeItem);
- updateModuleInTreeView(moduleThunk, moduleThunk->hTreeItem);
+ wcscpy_s(import->moduleName, MAX_PATH, moduleName);
+ strcpy_s(import->name, MAX_PATH, apiName);
+ import->ordinal = ordinal;
+ //import->apiAddressVA = api->va; //??
+ import->hint = hint;
+ import->valid = valid;
+ import->suspect = suspect;
+
+ updateImportInTreeView(import, item);
+ updateModuleInTreeView(module, module->hTreeItem);
+
+ updateCounts();
return true;
}
-
- iterator2++;
}
-
- iterator1++;
}
-
return false;
}
void ImportsHandling::updateImportInTreeView(const ImportThunk * importThunk, CTreeItem item)
{
if (importThunk->valid)
{
WCHAR tempString[300];
if (importThunk->name[0] != 0x00)
{
swprintf_s(tempString, _countof(tempString),TEXT("ord: %04X name: %S"),importThunk->ordinal,importThunk->name);
}
else
{
swprintf_s(tempString, _countof(tempString),TEXT("ord: %04X"),importThunk->ordinal);
}
swprintf_s(stringBuffer, _countof(stringBuffer),TEXT(" rva: ")TEXT(PRINTF_DWORD_PTR_HALF)TEXT(" mod: %s %s"),importThunk->rva,importThunk->moduleName,tempString);
}
else
{
swprintf_s(stringBuffer, _countof(stringBuffer),TEXT(" rva: ")TEXT(PRINTF_DWORD_PTR_HALF)TEXT(" ptr: ")TEXT(PRINTF_DWORD_PTR_FULL),importThunk->rva,importThunk->apiAddressVA);
}
item.SetText(stringBuffer);
Icon icon = getAppropiateIcon(importThunk);
item.SetImage(icon, icon);
}
void ImportsHandling::updateModuleInTreeView(const ImportModuleThunk * importThunk, CTreeItem item)
{
swprintf_s(stringBuffer, _countof(stringBuffer),TEXT("%s (%d) FThunk: ")TEXT(PRINTF_DWORD_PTR_HALF),importThunk->moduleName,importThunk->thunkList.size(), importThunk->firstThunk);
item.SetText(stringBuffer);
Icon icon = getAppropiateIcon(importThunk->isValid());
item.SetImage(icon, icon);
}
ImportsHandling::Icon ImportsHandling::getAppropiateIcon(const ImportThunk * importThunk)
{
if(importThunk->valid)
{
if(importThunk->suspect)
{
return iconWarning;
}
else
{
return iconCheck;
}
}
else
{
return iconError;
}
}
ImportsHandling::Icon ImportsHandling::getAppropiateIcon(bool valid)
{
if(valid)
{
return iconCheck;
}
else
{
return iconError;
}
}
-bool ImportsHandling::cutThunk(CTreeItem selectedTreeNode)
+bool ImportsHandling::cutImport(CTreeItem item)
{
- std::map<DWORD_PTR, ImportModuleThunk>::iterator iterator1;
- std::map<DWORD_PTR, ImportThunk>::iterator iterator2;
- ImportModuleThunk * moduleThunk;
- ImportThunk * importThunk;
-
- iterator1 = moduleList.begin();
-
- while (iterator1 != moduleList.end())
+ ImportThunk * import = getImportThunk(item);
+ if(import)
{
- moduleThunk = &(iterator1->second);
-
- iterator2 = moduleThunk->thunkList.begin();
-
- while (iterator2 != moduleThunk->thunkList.end())
+ CTreeItem parent = item.GetParent();
+ if(!parent.IsNull())
{
- importThunk = &(iterator2->second);
-
- if (importThunk->hTreeItem == selectedTreeNode)
+ ImportModuleThunk * module = getModuleThunk(parent);
+ if(module)
{
- importThunk->hTreeItem.Delete();
- moduleThunk->thunkList.erase(iterator2);
+ itemData.erase(item);
+ import->hTreeItem.Delete();
+ module->thunkList.erase(import->rva);
+ import = 0;
- if (moduleThunk->thunkList.empty())
+ if (module->thunkList.empty())
{
- moduleThunk->hTreeItem.Delete();
- moduleList.erase(iterator1);
+ itemData.erase(parent);
+ module->hTreeItem.Delete();
+ moduleList.erase(module->firstThunk);
+ module = 0;
}
else
{
- updateModuleInTreeView(moduleThunk, moduleThunk->hTreeItem);
+ updateModuleInTreeView(module, module->hTreeItem);
}
+
+ updateCounts();
return true;
}
-
- iterator2++;
}
-
- iterator1++;
}
-
return false;
}
-bool ImportsHandling::deleteTreeNode(CTreeItem selectedTreeNode)
+bool ImportsHandling::cutModule(CTreeItem item)
{
- std::map<DWORD_PTR, ImportModuleThunk>::iterator iterator1;
- std::map<DWORD_PTR, ImportThunk>::iterator iterator2;
- ImportModuleThunk * moduleThunk;
- ImportThunk * importThunk;
-
- iterator1 = moduleList.begin();
-
- while (iterator1 != moduleList.end())
+ ImportModuleThunk * module = getModuleThunk(item);
+ if(module)
{
- moduleThunk = &(iterator1->second);
-
- if (moduleThunk->hTreeItem == selectedTreeNode)
+ CTreeItem child = item.GetChild();
+ while(!child.IsNull())
{
- moduleThunk->hTreeItem.Delete();
-
- moduleThunk->thunkList.clear();
- moduleList.erase(iterator1);
- return true;
+ itemData.erase(child);
+ child = child.GetNextSibling();
}
- else
- {
- iterator2 = moduleThunk->thunkList.begin();
-
- while (iterator2 != moduleThunk->thunkList.end())
- {
- importThunk = &(iterator2->second);
-
- if (importThunk->hTreeItem == selectedTreeNode)
- {
- moduleThunk->hTreeItem.Delete();
- moduleThunk->thunkList.clear();
- moduleList.erase(iterator1);
- return true;
- }
-
- iterator2++;
- }
- }
-
- iterator1++;
+ itemData.erase(item);
+ module->hTreeItem.Delete();
+ moduleList.erase(module->firstThunk);
+ module = 0;
+ updateCounts();
+ return true;
}
-
return false;
}
-DWORD_PTR ImportsHandling::getApiAddressByNode(CTreeItem selectedTreeNode)
+DWORD_PTR ImportsHandling::getApiAddressByNode(CTreeItem item)
{
- std::map<DWORD_PTR, ImportModuleThunk>::iterator iterator1;
- std::map<DWORD_PTR, ImportThunk>::iterator iterator2;
- ImportModuleThunk * moduleThunk;
- ImportThunk * importThunk;
-
- iterator1 = moduleList.begin();
-
- while (iterator1 != moduleList.end())
+ const ImportThunk * import = getImportThunk(item);
+ if(import)
{
- moduleThunk = &(iterator1->second);
-
- iterator2 = moduleThunk->thunkList.begin();
-
- while (iterator2 != moduleThunk->thunkList.end())
- {
- importThunk = &(iterator2->second);
-
- if (importThunk->hTreeItem == selectedTreeNode)
- {
- return importThunk->apiAddressVA;
- }
-
- iterator2++;
- }
-
- iterator1++;
+ return import->apiAddressVA;
}
return 0;
}
-
void ImportsHandling::scanAndFixModuleList()
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator iterator1;
std::map<DWORD_PTR, ImportThunk>::iterator iterator2;
ImportModuleThunk * moduleThunk;
ImportThunk * importThunk;
iterator1 = moduleList.begin();
while (iterator1 != moduleList.end())
{
moduleThunk = &(iterator1->second);
iterator2 = moduleThunk->thunkList.begin();
while (iterator2 != moduleThunk->thunkList.end())
{
importThunk = &(iterator2->second);
if (importThunk->moduleName[0] == 0 || importThunk->moduleName[0] == L'?')
{
addNotFoundApiToModuleList(importThunk);
}
else
{
if (isNewModule(importThunk->moduleName))
{
addModuleToModuleList(importThunk->moduleName, importThunk->rva);
}
addFunctionToModuleList(importThunk);
}
iterator2++;
}
moduleThunk->thunkList.clear();
iterator1++;
}
moduleList = moduleListNew;
moduleListNew.clear();
}
bool ImportsHandling::findNewModules(std::map<DWORD_PTR, ImportThunk> & thunkList)
{
throw std::exception("The method or operation is not implemented.");
}
bool ImportsHandling::addModuleToModuleList(const WCHAR * moduleName, DWORD_PTR firstThunk)
{
ImportModuleThunk module;
module.firstThunk = firstThunk;
wcscpy_s(module.moduleName, MAX_PATH, moduleName);
moduleListNew.insert(std::pair<DWORD_PTR,ImportModuleThunk>(firstThunk,module));
return true;
}
bool ImportsHandling::isNewModule(const WCHAR * moduleName)
{
- std::map<DWORD_PTR, ImportModuleThunk>::iterator iterator1;
-
- iterator1 = moduleListNew.begin();
+ std::map<DWORD_PTR, ImportModuleThunk>::iterator it_module;
- while (iterator1 != moduleListNew.end())
+ it_module = moduleListNew.begin();
+ while (it_module != moduleListNew.end())
{
- if (!_wcsicmp(iterator1->second.moduleName, moduleName))
+ if (!_wcsicmp(it_module->second.moduleName, moduleName))
{
return false;
}
- iterator1++;
+ it_module++;
}
return true;
}
void ImportsHandling::addUnknownModuleToModuleList(DWORD_PTR firstThunk)
{
ImportModuleThunk module;
module.firstThunk = firstThunk;
wcscpy_s(module.moduleName, MAX_PATH, L"?");
moduleListNew.insert(std::pair<DWORD_PTR,ImportModuleThunk>(firstThunk,module));
}
bool ImportsHandling::addNotFoundApiToModuleList(const ImportThunk * apiNotFound)
{
ImportThunk import;
ImportModuleThunk * module = 0;
- std::map<DWORD_PTR, ImportModuleThunk>::iterator iterator1;
+ std::map<DWORD_PTR, ImportModuleThunk>::iterator it_module;
DWORD_PTR rva = apiNotFound->rva;
if (moduleListNew.size() > 0)
{
- iterator1 = moduleListNew.begin();
- while (iterator1 != moduleListNew.end())
+ it_module = moduleListNew.begin();
+ while (it_module != moduleListNew.end())
{
- if (rva >= iterator1->second.firstThunk)
+ if (rva >= it_module->second.firstThunk)
{
- iterator1++;
- if (iterator1 == moduleListNew.end())
+ it_module++;
+ if (it_module == moduleListNew.end())
{
- iterator1--;
+ it_module--;
//new unknown module
- if (iterator1->second.moduleName[0] == L'?')
+ if (it_module->second.moduleName[0] == L'?')
{
- module = &(iterator1->second);
+ module = &(it_module->second);
}
else
{
addUnknownModuleToModuleList(apiNotFound->rva);
module = &(moduleListNew.find(rva)->second);
}
break;
}
- else if (rva < iterator1->second.firstThunk)
+ else if (rva < it_module->second.firstThunk)
{
- iterator1--;
- module = &(iterator1->second);
+ it_module--;
+ module = &(it_module->second);
break;
}
}
else
{
#ifdef DEBUG_COMMENTS
Logger::debugLog("Error iterator1 != (*moduleThunkList).end()\r\n");
#endif
break;
}
}
}
else
{
//new unknown module
addUnknownModuleToModuleList(apiNotFound->rva);
module = &(moduleListNew.find(rva)->second);
}
if (!module)
{
#ifdef DEBUG_COMMENTS
Logger::debugLog(TEXT("ImportsHandling::addFunction module not found rva ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT("\r\n"),rva);
#endif
return false;
}
import.suspect = true;
import.valid = false;
import.va = apiNotFound->va;
import.rva = apiNotFound->rva;
import.apiAddressVA = apiNotFound->apiAddressVA;
import.ordinal = 0;
wcscpy_s(import.moduleName, MAX_PATH, L"?");
strcpy_s(import.name, MAX_PATH, "?");
module->thunkList.insert(std::pair<DWORD_PTR,ImportThunk>(import.rva, import));
return true;
}
bool ImportsHandling::addFunctionToModuleList(const ImportThunk * apiFound)
{
ImportThunk import;
ImportModuleThunk * module = 0;
- std::map<DWORD_PTR, ImportModuleThunk>::iterator iterator1;
+ std::map<DWORD_PTR, ImportModuleThunk>::iterator it_module;
if (moduleListNew.size() > 1)
{
- iterator1 = moduleListNew.begin();
- while (iterator1 != moduleListNew.end())
+ it_module = moduleListNew.begin();
+ while (it_module != moduleListNew.end())
{
- if (apiFound->rva >= iterator1->second.firstThunk)
+ if (apiFound->rva >= it_module->second.firstThunk)
{
- iterator1++;
- if (iterator1 == moduleListNew.end())
+ it_module++;
+ if (it_module == moduleListNew.end())
{
- iterator1--;
- module = &(iterator1->second);
+ it_module--;
+ module = &(it_module->second);
break;
}
- else if (apiFound->rva < iterator1->second.firstThunk)
+ else if (apiFound->rva < it_module->second.firstThunk)
{
- iterator1--;
- module = &(iterator1->second);
+ it_module--;
+ module = &(it_module->second);
break;
}
}
else
{
#ifdef DEBUG_COMMENTS
Logger::debugLog(TEXT("Error iterator1 != moduleListNew.end()\r\n"));
#endif
break;
}
}
}
else
{
- iterator1 = moduleListNew.begin();
- module = &(iterator1->second);
+ it_module = moduleListNew.begin();
+ module = &(it_module->second);
}
if (!module)
{
#ifdef DEBUG_COMMENTS
Logger::debugLog(TEXT("ImportsHandling::addFunction module not found rva ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT("\r\n"),apiFound->rva);
#endif
return false;
}
import.suspect = apiFound->suspect;
import.valid = apiFound->valid;
import.va = apiFound->va;
import.rva = apiFound->rva;
import.apiAddressVA = apiFound->apiAddressVA;
import.ordinal = apiFound->ordinal;
import.hint = apiFound->hint;
wcscpy_s(import.moduleName, MAX_PATH, apiFound->moduleName);
strcpy_s(import.name, MAX_PATH, apiFound->name);
module->thunkList.insert(std::pair<DWORD_PTR,ImportThunk>(import.rva, import));
return true;
}
void ImportsHandling::expandAllTreeNodes()
{
changeExpandStateOfTreeNodes(TVE_EXPAND);
}
void ImportsHandling::collapseAllTreeNodes()
{
changeExpandStateOfTreeNodes(TVE_COLLAPSE);
}
void ImportsHandling::changeExpandStateOfTreeNodes(UINT flag)
{
- std::map<DWORD_PTR, ImportModuleThunk>::iterator iterator1;
- ImportModuleThunk * moduleThunk;
-
- iterator1 = moduleList.begin();
+ std::map<DWORD_PTR, ImportModuleThunk>::iterator it_module;
- while (iterator1 != moduleList.end())
+ it_module = moduleList.begin();
+ while (it_module != moduleList.end())
{
- moduleThunk = &(iterator1->second);
+ ImportModuleThunk &moduleThunk = it_module->second;
- moduleThunk->hTreeItem.Expand(flag);
+ moduleThunk.hTreeItem.Expand(flag);
- iterator1++;
+ it_module++;
}
}
diff --git a/Scylla/ImportsHandling.h b/Scylla/ImportsHandling.h
index 8950ddc..7de87aa 100644
--- a/Scylla/ImportsHandling.h
+++ b/Scylla/ImportsHandling.h
@@ -1,77 +1,111 @@
#pragma once
#include <map>
+#include <hash_map>
// WTL
#include <atlbase.h>
#include <atlapp.h>
#include <atlctrls.h> // CTreeItem
class CMultiSelectTreeViewCtrl;
class ImportThunk;
class ImportModuleThunk;
class ImportsHandling
{
public:
std::map<DWORD_PTR, ImportModuleThunk> moduleList;
std::map<DWORD_PTR, ImportModuleThunk> moduleListNew;
- //bool addFunction(WCHAR * moduleName, char * name, DWORD_PTR va, DWORD_PTR rva, DWORD_PTR ordinal, bool valid, bool suspect);
- //bool addModule(WCHAR * moduleName, DWORD_PTR firstThunk);
-
ImportsHandling(CMultiSelectTreeViewCtrl& TreeImports);
~ImportsHandling();
+ unsigned int thunkCount() const { return m_thunkCount; }
+ unsigned int invalidThunkCount() const { return m_invalidThunkCount; }
+ unsigned int suspectThunkCount() const { return m_suspectThunkCount; }
+
+ bool isModule(CTreeItem item);
+ bool isImport(CTreeItem item);
+
+ ImportModuleThunk * getModuleThunk(CTreeItem item);
+ ImportThunk * getImportThunk(CTreeItem item);
+
void displayAllImports();
- void showImports(bool invalid, bool suspect);
- bool invalidateFunction(CTreeItem selectedTreeNode);
- bool cutThunk(CTreeItem selectedTreeNode);
- bool deleteTreeNode(CTreeItem selectedTreeNode);
+ void clearAllImports();
+ void selectImports(bool invalid, bool suspect);
+
+ bool invalidateImport(CTreeItem item);
+ bool setImport(CTreeItem item, const WCHAR * moduleName, const CHAR * apiName, WORD ordinal = 0, WORD hint = 0, bool valid = true, bool suspect = false);
+ bool cutImport(CTreeItem item);
+ bool cutModule(CTreeItem item);
+ //bool addImport(const WCHAR * moduleName, const CHAR * name, DWORD_PTR va, DWORD_PTR rva, WORD ordinal = 0, bool valid = true, bool suspect = false);
+ //bool addModule(const WCHAR * moduleName, DWORD_PTR firstThunk);
- void updateImportInTreeView(const ImportThunk * importThunk, CTreeItem item);
- void updateModuleInTreeView(const ImportModuleThunk * importThunk, CTreeItem item);
DWORD_PTR getApiAddressByNode(CTreeItem selectedTreeNode);
void scanAndFixModuleList();
void expandAllTreeNodes();
void collapseAllTreeNodes();
private:
DWORD numberOfFunctions;
+ unsigned int m_thunkCount;
+ unsigned int m_invalidThunkCount;
+ unsigned int m_suspectThunkCount;
+
+ struct TreeItemData
+ {
+ bool isModule;
+ union
+ {
+ ImportModuleThunk * module;
+ ImportThunk * import;
+ };
+ };
+
+ std::hash_map<HTREEITEM, TreeItemData> itemData;
+
+ void setItemData(CTreeItem item, const TreeItemData& data);
+ TreeItemData * getItemData(CTreeItem item);
+
WCHAR stringBuffer[600];
CMultiSelectTreeViewCtrl& TreeImports;
CImageList TreeIcons;
CIcon hIconCheck;
CIcon hIconWarning;
CIcon hIconError;
// They have to be added to the image list in that order!
enum Icon {
iconCheck = 0,
iconWarning,
iconError
};
- CTreeItem addDllToTreeView(CMultiSelectTreeViewCtrl& idTreeView, const ImportModuleThunk * importThunk);
- CTreeItem addApiToTreeView(CMultiSelectTreeViewCtrl& idTreeView, CTreeItem parentDll, const ImportThunk * importThunk);
+ void updateCounts();
+
+ CTreeItem addDllToTreeView(CMultiSelectTreeViewCtrl& idTreeView, ImportModuleThunk * moduleThunk);
+ CTreeItem addApiToTreeView(CMultiSelectTreeViewCtrl& idTreeView, CTreeItem parentDll, ImportThunk * importThunk);
+
+ void updateImportInTreeView(const ImportThunk * importThunk, CTreeItem item);
+ void updateModuleInTreeView(const ImportModuleThunk * importThunk, CTreeItem item);
- bool isItemSelected(CTreeItem hItem);
- void unselectItem(CTreeItem htItem);
- bool selectItem(CTreeItem hItem, bool select = true);
- void setFocus(CMultiSelectTreeViewCtrl& hwndTV, CTreeItem htItem);
+ //bool isItemSelected(CTreeItem hItem);
+ //void unselectItem(CTreeItem htItem);
+ //bool selectItem(CTreeItem hItem, bool select = true);
bool findNewModules(std::map<DWORD_PTR, ImportThunk> & thunkList);
Icon getAppropiateIcon(const ImportThunk * importThunk);
Icon getAppropiateIcon(bool valid);
bool addModuleToModuleList(const WCHAR * moduleName, DWORD_PTR firstThunk);
void addUnknownModuleToModuleList(DWORD_PTR firstThunk);
bool addNotFoundApiToModuleList(const ImportThunk * apiNotFound);
bool addFunctionToModuleList(const ImportThunk * apiFound);
bool isNewModule(const WCHAR * moduleName);
void changeExpandStateOfTreeNodes(UINT flag);
};

File Metadata

Mime Type
text/x-diff
Expires
Tue, Jan 7, 12:46 AM (2 h, 42 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
c3/a2/6d66797db925675986a2f9309caa

Event Timeline