diff --git a/.gitignore b/.gitignore index 567d830..c9ea959 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,28 @@ -#generic files/directories to ignore -Win32/ -x64/ -ipch/ -*.opensdf -*.sdf -*.aps -*.suo -Scylla.vcxproj.user - -#tinyxml ignore + exceptions -tinyxml/* -!tinyxml/README -!tinyxml/tinyxml.vcxproj* - -#WTL ignore + exceptions -WTL/* -!WTL/README \ No newline at end of file +#generic files/directories to ignore +Win32/ +x64/ +ipch/ +*.opensdf +*.sdf +*.aps +*.suo +Scylla.vcxproj.user +.vs/ + +#tinyxml ignore + exceptions +tinyxml/* +!tinyxml/README +!tinyxml/tinyxml.vcxproj* + +#WTL ignore + exceptions +WTL/* +!WTL/README + +#diStorm ignore + exceptions +diStorm/* +!diStorm/include/ +!diStorm/include/* +!diStorm/src/ +!diStorm/src/* +!diStorm/README +!diStorm/diStorm.vcxproj* \ No newline at end of file diff --git a/COMPILING b/COMPILING index c7782c6..a33d9df 100644 --- a/COMPILING +++ b/COMPILING @@ -1,7 +1,7 @@ -To compile Scylla you need to have VS2008 installed. -In addition to that you need source codes for the following libraries: -diStorm -tinyxml -WTL - +To compile Scylla you need to have VS2008 installed. +In addition to that you need source codes for the following libraries: +diStorm +tinyxml +WTL + See the corresponding README files for installation instructions. \ No newline at end of file diff --git a/Scylla/ApiReader.cpp b/Scylla/ApiReader.cpp index ed2b764..858dc27 100644 --- a/Scylla/ApiReader.cpp +++ b/Scylla/ApiReader.cpp @@ -1,1257 +1,1257 @@ #include "ApiReader.h" #include "Scylla.h" #include "Architecture.h" #include "SystemInformation.h" #include "StringConversion.h" #include "PeParser.h" stdext::hash_multimap ApiReader::apiList; //api look up table std::map * ApiReader::moduleThunkList; //store found apis DWORD_PTR ApiReader::minApiAddress = (DWORD_PTR)-1; DWORD_PTR ApiReader::maxApiAddress = 0; //#define DEBUG_COMMENTS void ApiReader::readApisFromModuleList() { if (Scylla::config[APIS_ALWAYS_FROM_DISK].isTrue()) { readExportTableAlwaysFromDisk = true; } else { readExportTableAlwaysFromDisk = false; } 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; } Scylla::windowLog.log(L"Module parsing: %s",moduleList[i].fullPath); if (!moduleList[i].isAlreadyParsed) { parseModule(&moduleList[i]); } } #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"Address Min " PRINTF_DWORD_PTR_FULL L" Max " PRINTF_DWORD_PTR_FULL L"\nimagebase " PRINTF_DWORD_PTR_FULL L" maxValidAddress " PRINTF_DWORD_PTR_FULL, minApiAddress, maxApiAddress, targetImageBase ,maxValidAddress); #endif } void ApiReader::parseModule(ModuleInfo *module) { module->parsing = true; if (isWinSxSModule(module)) { parseModuleWithMapping(module); } else if (isModuleLoadedInOwnProcess(module)) //this is always ok { parseModuleWithOwnProcess(module); } else { if (readExportTableAlwaysFromDisk) { parseModuleWithMapping(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, WORD ordinalParent, ModuleInfo *moduleParent) { size_t dllNameLength = 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, fordwardedString, dllNameLength); } searchFunctionName++; if (strchr(searchFunctionName,'#')) { searchFunctionName++; ordinal = (WORD)atoi(searchFunctionName); } //Since Windows 7 if (!_strnicmp(dllName, "API-", 4) || !_strnicmp(dllName, "EXT-", 4)) //API_SET_PREFIX_NAME, API_SET_EXTENSION { /* Info: http://www.nirsoft.net/articles/windows_7_kernel_architecture_changes.html */ FARPROC addy = 0; HMODULE hModTemp = GetModuleHandleA(dllName); if (hModTemp == 0) { hModTemp = LoadLibraryA(dllName); } if (ordinal) { addy = GetProcAddress(hModTemp, (char *)ordinal); } else { addy = GetProcAddress(hModTemp, searchFunctionName); } #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"API_SET_PREFIX_NAME %s %S Module Handle %p addy %p",moduleParent->fullPath, dllName, hModTemp, addy); #endif if (addy != 0) { addApi(functionNameParent,0, ordinalParent, (DWORD_PTR)addy, (DWORD_PTR)addy - (DWORD_PTR)hModTemp, true, moduleParent); } return; } strcat_s(dllName, ".dll"); StringConversion::ToUTF16(dllName, dllNameW, _countof(dllNameW)); 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 (ordinal) { //forwarding by ordinal findApiByModuleAndOrdinal(module, ordinal, &vaApi, &rvaApi); } else { findApiByModuleAndName(module, searchFunctionName, &vaApi, &rvaApi); } if (rvaApi == 0) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"handleForwardedApi :: Api not found, this is really BAD! %S",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(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, WORD ordinal, DWORD_PTR va, DWORD_PTR rva, bool isForwarded, ModuleInfo *moduleInfo) { ApiInfo *apiInfo = new ApiInfo(); if ((functionName != 0) && (strlen(functionName) < _countof(apiInfo->name))) { strcpy_s(apiInfo->name, 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 Scylla::debugLog.log(L"getHeaderFromProcess :: Error reading header"); #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 Scylla::debugLog.log(L"Something is wrong with the PE Header here Export table size %d", readSize); #endif readSize = sizeof(IMAGE_EXPORT_DIRECTORY) + 100; } if (readSize) { bufferExportTable = new BYTE[readSize]; if (!bufferExportTable) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"Something is wrong with the PE Header here Export table size %d", readSize); #endif return 0; } if(!readMemoryFromProcess(module->modBaseAddr + pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress, readSize, bufferExportTable)) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"getExportTableFromProcess :: Error reading export table from process"); #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; PeParser peParser(module->modBaseAddr, false); if (!peParser.isValidPeFile()) return; pNtHeader = peParser.getCurrentNtHeader(); if (peParser.hasExportDirectory()) { 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; } } } 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; 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 Scylla::debugLog.log(L"parseExportTable :: module %s NumberOfNames %X", module->fullPath, pExportDir->NumberOfNames); #endif for (i = 0; i < pExportDir->NumberOfNames; i++) { functionName = (char*)(addressOfNamesArray[i] + deltaAddress); ordinal = (WORD)(addressOfNameOrdinalsArray[i] + pExportDir->Base); RVA = addressOfFunctionsArray[addressOfNameOrdinalsArray[i]]; VA = addressOfFunctionsArray[addressOfNameOrdinalsArray[i]] + module->modBaseAddr; #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"parseExportTable :: api %S ordinal %d imagebase " PRINTF_DWORD_PTR_FULL L" RVA " PRINTF_DWORD_PTR_FULL L" VA " PRINTF_DWORD_PTR_FULL, functionName, ordinal, module->modBaseAddr, RVA, VA); #endif if (!isApiBlacklisted(functionName)) { if (!isApiForwarded(RVA,pNtHeader)) { 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 = (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, 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, WORD ordinal, DWORD_PTR * vaApi, DWORD_PTR * rvaApi) { if (isModuleLoadedInOwnProcess(module)) { HMODULE hModule = GetModuleHandle(module->getFilename()); if (hModule) { if (vaApi) { if (ordinal) { *vaApi = (DWORD_PTR)GetProcAddress(hModule, (LPCSTR)ordinal); } else { *vaApi = (DWORD_PTR)GetProcAddress(hModule, searchFunctionName); } *rvaApi = (*vaApi) - (DWORD_PTR)hModule; *vaApi = (*rvaApi) + module->modBaseAddr; } else { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"findApiByModule :: vaApi == NULL, should never happen %S", searchFunctionName); #endif } } else { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"findApiByModule :: hModule == NULL, should never happen %s", 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 Scylla::debugLog.log(L"parseModuleWithOwnProcess :: hModule is NULL"); #endif } } bool ApiReader::isPeAndExportTableValid(PIMAGE_NT_HEADERS pNtHeader) { if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) { Scylla::windowLog.log(L"-> 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)) { Scylla::windowLog.log(L"-> No export table."); return false; } else { return true; } } 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, 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(); //imports by kernelbase don't exist if (!_wcsicmp(moduleFileName, L"kernelbase.dll")) { module->priority = -1; } else if (!_wcsicmp(moduleFileName, L"ntdll.dll")) { module->priority = 0; } else if (!_wcsicmp(moduleFileName, L"shlwapi.dll")) { module->priority = 0; } else if (!_wcsicmp(moduleFileName, L"ShimEng.dll")) { module->priority = 0; } else if (!_wcsicmp(moduleFileName, L"kernel32.dll")) { module->priority = 2; } else if (!_wcsnicmp(moduleFileName, L"API-", 4) || !_wcsnicmp(moduleFileName, L"EXT-", 4)) //API_SET_PREFIX_NAME, API_SET_EXTENSION { module->priority = 0; } 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::iterator it1, it2; size_t c = 0; size_t countDuplicates = apiList.count(virtualAddress); int countHighPriority = 0; ApiInfo *apiFound = 0; if (countDuplicates == 0) { 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. //any high priority with a name apiFound = getScoredApi(it1,countDuplicates,true,false,false,true,false,false,false,false); if (apiFound) return apiFound; *isSuspect = true; //high priority with a name and ansi/unicode name apiFound = getScoredApi(it1,countDuplicates,true,true,false,true,false,false,false,false); if (apiFound) return apiFound; //priority 2 with no underline in name apiFound = getScoredApi(it1,countDuplicates,true,false,true,false,false,false,true,false); if (apiFound) return apiFound; //priority 1 with a name apiFound = getScoredApi(it1,countDuplicates,true,false,false,false,false,true,false,false); if (apiFound) return apiFound; //With a name apiFound = getScoredApi(it1,countDuplicates,true,false,false,false,false,false,false,false); if (apiFound) return apiFound; //any with priority, name, ansi/unicode apiFound = getScoredApi(it1,countDuplicates,true,true,false,true,false,false,false,true); if (apiFound) return apiFound; //any with priority apiFound = getScoredApi(it1,countDuplicates,false,false,false,true,false,false,false,true); if (apiFound) return apiFound; //has prio 0 and name apiFound = getScoredApi(it1,countDuplicates,false,false,false,false,true,false,false,true); if (apiFound) return apiFound; } //is never reached Scylla::windowLog.log(L"getApiByVirtualAddress :: There is a api resolving bug, VA: " PRINTF_DWORD_PTR_FULL, virtualAddress); for (size_t c = 0; c < countDuplicates; c++, it1++) { apiFound = (ApiInfo *)((*it1).second); Scylla::windowLog.log(L"-> Possible API: %S ord: %d ", apiFound->name, apiFound->ordinal); } return (ApiInfo *) 1; } ApiInfo * ApiReader::getScoredApi(stdext::hash_multimap::iterator it1,size_t countDuplicates, bool hasName, bool hasUnicodeAnsiName, bool hasNoUnderlineInName, bool hasPrioDll,bool hasPrio0Dll,bool hasPrio1Dll, bool hasPrio2Dll, bool firstWin ) { ApiInfo * foundApi = 0; ApiInfo * foundMatchingApi = 0; int countFoundApis = 0; int scoreNeeded = 0; int scoreValue = 0; size_t apiNameLength = 0; if (hasUnicodeAnsiName || hasNoUnderlineInName) { hasName = true; } if (hasName) scoreNeeded++; if (hasUnicodeAnsiName) scoreNeeded++; if (hasNoUnderlineInName) scoreNeeded++; if (hasPrioDll) scoreNeeded++; if (hasPrio0Dll) scoreNeeded++; if (hasPrio1Dll) scoreNeeded++; if (hasPrio2Dll) scoreNeeded++; for (size_t c = 0; c < countDuplicates; c++, it1++) { foundApi = (ApiInfo *)((*it1).second); scoreValue = 0; if (hasName) { if (foundApi->name[0] != 0x00) { scoreValue++; if (hasUnicodeAnsiName) { apiNameLength = strlen(foundApi->name); if ((foundApi->name[apiNameLength - 1] == 'W') || (foundApi->name[apiNameLength - 1] == 'A')) { scoreValue++; } } if (hasNoUnderlineInName) { if (!strrchr(foundApi->name, '_')) { scoreValue++; } } } } if (hasPrioDll) { if (foundApi->module->priority >= 1) { scoreValue++; } } if (hasPrio0Dll) { if (foundApi->module->priority == 0) { scoreValue++; } } if (hasPrio1Dll) { if (foundApi->module->priority == 1) { scoreValue++; } } if (hasPrio2Dll) { if (foundApi->module->priority == 2) { scoreValue++; } } if (scoreValue == scoreNeeded) { foundMatchingApi = foundApi; countFoundApis++; if (firstWin) { return foundMatchingApi; } } } if (countFoundApis == 1) { return foundMatchingApi; } else { return (ApiInfo *)0; } } void ApiReader::setMinMaxApiAddress(DWORD_PTR virtualAddress) { if (virtualAddress == 0 || virtualAddress == (DWORD_PTR)-1) return; if (virtualAddress < minApiAddress) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"virtualAddress %p < minApiAddress %p", virtualAddress, minApiAddress); #endif minApiAddress = virtualAddress - 1; } if (virtualAddress > maxApiAddress) { maxApiAddress = virtualAddress + 1; } } void ApiReader::readAndParseIAT(DWORD_PTR addressIAT, DWORD sizeIAT, std::map &moduleListNew) { moduleThunkList = &moduleListNew; BYTE *dataIat = new BYTE[sizeIAT]; if (readMemoryFromProcess(addressIAT,sizeIAT,dataIat)) { parseIAT(addressIAT,dataIat,sizeIAT); } else { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"ApiReader::readAndParseIAT :: error reading iat " PRINTF_DWORD_PTR_FULL, 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); for (SIZE_T i = 0; i < sizeIAT; i++) { //Scylla::windowLog.log(L"%08X %08X %d von %d", addressIAT + (DWORD_PTR)&pIATAddress[i] - (DWORD_PTR)iatBuffer, pIATAddress[i],i,sizeIAT); - if (!isInvalidMemoryForIat(pIATAddress[i])) + if (!isInvalidMemoryForIat(pIATAddress[i])) //to prevent amdaemon self reference address being corrupted append && pIATAddress[i] != 0x0000000140A0E650 { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"min %p max %p address %p", minApiAddress, maxApiAddress, pIATAddress[i]); #endif if ( (pIATAddress[i] > minApiAddress) && (pIATAddress[i] < maxApiAddress) ) { apiFound = getApiByVirtualAddress(pIATAddress[i], &isSuspect); #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"apiFound %p address %p", apiFound, pIATAddress[i]); #endif if (apiFound == 0) { Scylla::windowLog.log(L"getApiByVirtualAddress :: No Api found " PRINTF_DWORD_PTR_FULL, pIATAddress[i]); } if (apiFound == (ApiInfo *)1) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"apiFound == (ApiInfo *)1 -> " PRINTF_DWORD_PTR_FULL, pIATAddress[i]); #endif } else if (apiFound) { countApiFound++; #ifdef DEBUG_COMMENTS Scylla::debugLog.log(PRINTF_DWORD_PTR_FULL L" %s %d %s", 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]); } } } Scylla::windowLog.log(L"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, moduleName); (*moduleThunkList).insert(std::pair(firstThunk,module)); return true; } void ApiReader::addUnknownModuleToModuleList(DWORD_PTR firstThunk) { ImportModuleThunk module; module.firstThunk = firstThunk; wcscpy_s(module.moduleName, L"?"); (*moduleThunkList).insert(std::pair(firstThunk,module)); } bool ApiReader::addFunctionToModuleList(ApiInfo * apiFound, DWORD_PTR va, DWORD_PTR rva, WORD ordinal, bool valid, bool suspect) { ImportThunk import; ImportModuleThunk * module = 0; std::map::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 Scylla::debugLog.log(L"Error iterator1 != (*moduleThunkList).end()"); #endif break; } } } else { iterator1 = (*moduleThunkList).begin(); module = &(iterator1->second); } if (!module) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"ImportsHandling::addFunction module not found rva " PRINTF_DWORD_PTR_FULL, 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, apiFound->module->getFilename()); strcpy_s(import.name, apiFound->name); module->thunkList.insert(std::pair(import.rva, import)); return true; } void ApiReader::clearAll() { minApiAddress = (DWORD_PTR)-1; maxApiAddress = 0; for ( stdext::hash_map::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::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 Scylla::debugLog.log(L"Error iterator1 != (*moduleThunkList).end()\r\n"); #endif break; } } } else { //new unknown module addUnknownModuleToModuleList(rva); module = &((*moduleThunkList).find(rva)->second); } if (!module) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"ImportsHandling::addFunction module not found rva " PRINTF_DWORD_PTR_FULL,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, L"?"); strcpy_s(import.name, "?"); module->thunkList.insert(std::pair(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, L"\\WinSxS\\")) { return true; } else if (wcsstr(module->fullPath, L"\\winsxs\\")) { return true; } else { return false; } } bool ApiReader::isInvalidMemoryForIat( DWORD_PTR address ) { if (address == 0) return true; if (address == -1) return true; MEMORY_BASIC_INFORMATION memBasic = {0}; if (VirtualQueryEx(ProcessAccessHelp::hProcess, (LPCVOID)address, &memBasic, sizeof(MEMORY_BASIC_INFORMATION))) { if((memBasic.State == MEM_COMMIT) && ProcessAccessHelp::isPageAccessable(memBasic.Protect)) { return false; } else { return true; } } else { return true; } } diff --git a/Scylla/FunctionExport.cpp b/Scylla/FunctionExport.cpp index d28571e..7c27962 100644 --- a/Scylla/FunctionExport.cpp +++ b/Scylla/FunctionExport.cpp @@ -1,297 +1,354 @@ #include #include "PeParser.h" #include "ProcessAccessHelp.h" #include "Scylla.h" #include "Architecture.h" #include "FunctionExport.h" #include "ProcessLister.h" #include "ApiReader.h" #include "IATSearch.h" #include "ImportRebuilder.h" +#define EXPORT comment(linker, "/EXPORT:" __FUNCTION__ "=" __FUNCDNAME__) extern HINSTANCE hDllModule; const WCHAR * WINAPI ScyllaVersionInformationW() { return APPNAME L" " ARCHITECTURE L" " APPVERSION; } const char * WINAPI ScyllaVersionInformationA() { return APPNAME_S " " ARCHITECTURE_S " " APPVERSION_S; } DWORD WINAPI ScyllaVersionInformationDword() { return APPVERSIONDWORD; } BOOL DumpProcessW(const WCHAR * fileToDump, DWORD_PTR imagebase, DWORD_PTR entrypoint, const WCHAR * fileResult) { PeParser * peFile = 0; if (fileToDump) { peFile = new PeParser(fileToDump, true); } else { peFile = new PeParser(imagebase, true); } bool result = peFile->dumpProcess(imagebase, entrypoint, fileResult); delete peFile; return result; } BOOL WINAPI ScyllaRebuildFileW(const WCHAR * fileToRebuild, BOOL removeDosStub, BOOL updatePeHeaderChecksum, BOOL createBackup) { if (createBackup) { if (!ProcessAccessHelp::createBackupFile(fileToRebuild)) { return FALSE; } } PeParser peFile(fileToRebuild, true); if (peFile.readPeSectionsFromFile()) { peFile.setDefaultFileAlignment(); if (removeDosStub) { peFile.removeDosStub(); } peFile.alignAllSectionHeaders(); peFile.fixPeHeader(); if (peFile.savePeFileToDisk(fileToRebuild)) { if (updatePeHeaderChecksum) { PeParser::updatePeHeaderChecksum(fileToRebuild, (DWORD)ProcessAccessHelp::getFileSize(fileToRebuild)); } return TRUE; } } return FALSE; } BOOL WINAPI ScyllaRebuildFileA(const char * fileToRebuild, BOOL removeDosStub, BOOL updatePeHeaderChecksum, BOOL createBackup) { WCHAR fileToRebuildW[MAX_PATH]; if (MultiByteToWideChar(CP_ACP, 0, fileToRebuild, -1, fileToRebuildW, _countof(fileToRebuildW)) == 0) { return FALSE; } return ScyllaRebuildFileW(fileToRebuildW, removeDosStub, updatePeHeaderChecksum, createBackup); } BOOL WINAPI ScyllaDumpCurrentProcessW(const WCHAR * fileToDump, DWORD_PTR imagebase, DWORD_PTR entrypoint, const WCHAR * fileResult) { ProcessAccessHelp::setCurrentProcessAsTarget(); return DumpProcessW(fileToDump, imagebase, entrypoint, fileResult); } BOOL WINAPI ScyllaDumpProcessW(DWORD_PTR pid, const WCHAR * fileToDump, DWORD_PTR imagebase, DWORD_PTR entrypoint, const WCHAR * fileResult) { if (ProcessAccessHelp::openProcessHandle((DWORD)pid)) { return DumpProcessW(fileToDump, imagebase, entrypoint, fileResult); } else { return FALSE; } } BOOL WINAPI ScyllaDumpCurrentProcessA(const char * fileToDump, DWORD_PTR imagebase, DWORD_PTR entrypoint, const char * fileResult) { WCHAR fileToDumpW[MAX_PATH]; WCHAR fileResultW[MAX_PATH]; if (fileResult == 0) { return FALSE; } if (MultiByteToWideChar(CP_ACP, 0, fileResult, -1, fileResultW, _countof(fileResultW)) == 0) { return FALSE; } if (fileToDump != 0) { if (MultiByteToWideChar(CP_ACP, 0, fileToDump, -1, fileToDumpW, _countof(fileToDumpW)) == 0) { return FALSE; } return ScyllaDumpCurrentProcessW(fileToDumpW, imagebase, entrypoint, fileResultW); } else { return ScyllaDumpCurrentProcessW(0, imagebase, entrypoint, fileResultW); } } BOOL WINAPI ScyllaDumpProcessA(DWORD_PTR pid, const char * fileToDump, DWORD_PTR imagebase, DWORD_PTR entrypoint, const char * fileResult) { WCHAR fileToDumpW[MAX_PATH]; WCHAR fileResultW[MAX_PATH]; if (fileResult == 0) { return FALSE; } if (MultiByteToWideChar(CP_ACP, 0, fileResult, -1, fileResultW, _countof(fileResultW)) == 0) { return FALSE; } if (fileToDump != 0) { if (MultiByteToWideChar(CP_ACP, 0, fileToDump, -1, fileToDumpW, _countof(fileToDumpW)) == 0) { return FALSE; } return ScyllaDumpProcessW(pid, fileToDumpW, imagebase, entrypoint, fileResultW); } else { return ScyllaDumpProcessW(pid, 0, imagebase, entrypoint, fileResultW); } } INT WINAPI ScyllaStartGui(DWORD dwProcessId, HINSTANCE mod, DWORD_PTR entrypoint) { GUI_DLL_PARAMETER guiParam; guiParam.dwProcessId = dwProcessId; guiParam.mod = mod; guiParam.entrypoint = entrypoint; return InitializeGui(hDllModule, (LPARAM)&guiParam); } int WINAPI ScyllaIatSearch(DWORD dwProcessId, DWORD_PTR * iatStart, DWORD * iatSize, DWORD_PTR searchStart, BOOL advancedSearch) { ApiReader apiReader; ProcessLister processLister; Process *processPtr = 0; IATSearch iatSearch; std::vector& processList = processLister.getProcessListSnapshotNative(); for(std::vector::iterator it = processList.begin(); it != processList.end(); ++it) { if(it->PID == dwProcessId) { processPtr = &(*it); break; } } if(!processPtr) return SCY_ERROR_PIDNOTFOUND; ProcessAccessHelp::closeProcessHandle(); apiReader.clearAll(); if (!ProcessAccessHelp::openProcessHandle(processPtr->PID)) { return SCY_ERROR_PROCOPEN; } ProcessAccessHelp::getProcessModules(ProcessAccessHelp::hProcess, ProcessAccessHelp::moduleList); ProcessAccessHelp::selectedModule = 0; ProcessAccessHelp::targetImageBase = processPtr->imageBase; ProcessAccessHelp::targetSizeOfImage = processPtr->imageSize; apiReader.readApisFromModuleList(); int retVal = SCY_ERROR_IATNOTFOUND; if (advancedSearch) { if (iatSearch.searchImportAddressTableInProcess(searchStart, iatStart, iatSize, true)) { retVal = SCY_ERROR_SUCCESS; } } else { if (iatSearch.searchImportAddressTableInProcess(searchStart, iatStart, iatSize, false)) { retVal = SCY_ERROR_SUCCESS; } } processList.clear(); ProcessAccessHelp::closeProcessHandle(); apiReader.clearAll(); return retVal; } +int WINAPI ScyllaIatFixCurrentAutoW(DWORD_PTR iatAddr, DWORD iatSize, const WCHAR * dumpFile, const WCHAR * iatFixFile) +{ + #pragma EXPORT + ApiReader apiReader; + ProcessLister processLister; + std::map moduleList; + + Scylla::debugLog.log(L"in ScyllaIatFixCurrentAutoW"); + + ProcessAccessHelp::closeProcessHandle(); + apiReader.clearAll(); + + ProcessAccessHelp::setCurrentProcessAsTarget(); + + Scylla::debugLog.log(L"set current process as target"); + + ProcessAccessHelp::getProcessModules(ProcessAccessHelp::hProcess, ProcessAccessHelp::moduleList); + + Scylla::debugLog.log(L"got process modules"); + + ProcessAccessHelp::selectedModule = 0; + Scylla::debugLog.log(L"set selected module"); + ProcessAccessHelp::targetImageBase = 0x0000000140000000; + ProcessAccessHelp::getSizeOfImageCurrentProcess(); + + apiReader.readApisFromModuleList(); + + Scylla::debugLog.log(L"read api from module list"); + + apiReader.readAndParseIAT(iatAddr, iatSize, moduleList); + + Scylla::debugLog.log(L"iat"); + + //add IAT section to dump + ImportRebuilder importRebuild(dumpFile); + importRebuild.enableOFTSupport(); + + Scylla::debugLog.log(L"rebuild"); + + int retVal = SCY_ERROR_IATWRITE; + + if (importRebuild.rebuildImportTable(iatFixFile, moduleList)) + { + retVal = SCY_ERROR_SUCCESS; + } + + Scylla::debugLog.log(L"finishing"); + + moduleList.clear(); + ProcessAccessHelp::closeProcessHandle(); + apiReader.clearAll(); + + Scylla::debugLog.log(L"done"); + + return retVal; +} int WINAPI ScyllaIatFixAutoW(DWORD_PTR iatAddr, DWORD iatSize, DWORD dwProcessId, const WCHAR * dumpFile, const WCHAR * iatFixFile) { ApiReader apiReader; ProcessLister processLister; Process *processPtr = 0; std::map moduleList; std::vector& processList = processLister.getProcessListSnapshotNative(); for(std::vector::iterator it = processList.begin(); it != processList.end(); ++it) { if(it->PID == dwProcessId) { processPtr = &(*it); break; } } if(!processPtr) return SCY_ERROR_PIDNOTFOUND; ProcessAccessHelp::closeProcessHandle(); apiReader.clearAll(); if (!ProcessAccessHelp::openProcessHandle(processPtr->PID)) { return SCY_ERROR_PROCOPEN; } ProcessAccessHelp::getProcessModules(ProcessAccessHelp::hProcess, ProcessAccessHelp::moduleList); ProcessAccessHelp::selectedModule = 0; ProcessAccessHelp::targetImageBase = processPtr->imageBase; ProcessAccessHelp::targetSizeOfImage = processPtr->imageSize; apiReader.readApisFromModuleList(); apiReader.readAndParseIAT(iatAddr, iatSize, moduleList); //add IAT section to dump ImportRebuilder importRebuild(dumpFile); importRebuild.enableOFTSupport(); int retVal = SCY_ERROR_IATWRITE; if (importRebuild.rebuildImportTable(iatFixFile, moduleList)) { retVal = SCY_ERROR_SUCCESS; } processList.clear(); moduleList.clear(); ProcessAccessHelp::closeProcessHandle(); apiReader.clearAll(); return retVal; } diff --git a/Scylla/FunctionExport.h b/Scylla/FunctionExport.h index 78c3dea..e7664a6 100644 --- a/Scylla/FunctionExport.h +++ b/Scylla/FunctionExport.h @@ -1,54 +1,55 @@ #pragma once #include const int SCY_ERROR_SUCCESS = 0; const int SCY_ERROR_PROCOPEN = -1; const int SCY_ERROR_IATWRITE = -2; const int SCY_ERROR_IATSEARCH = -3; const int SCY_ERROR_IATNOTFOUND = -4; const int SCY_ERROR_PIDNOTFOUND = -5; typedef struct _GUI_DLL_PARAMETER { DWORD dwProcessId; HINSTANCE mod; DWORD_PTR entrypoint; } GUI_DLL_PARAMETER, *PGUI_DLL_PARAMETER; int InitializeGui(HINSTANCE hInstance, LPARAM param); //function to export in DLL BOOL DumpProcessW(const WCHAR * fileToDump, DWORD_PTR imagebase, DWORD_PTR entrypoint, const WCHAR * fileResult); BOOL WINAPI ScyllaDumpCurrentProcessW(const WCHAR * fileToDump, DWORD_PTR imagebase, DWORD_PTR entrypoint, const WCHAR * fileResult); BOOL WINAPI ScyllaDumpCurrentProcessA(const char * fileToDump, DWORD_PTR imagebase, DWORD_PTR entrypoint, const char * fileResult); BOOL WINAPI ScyllaDumpProcessW(DWORD_PTR pid, const WCHAR * fileToDump, DWORD_PTR imagebase, DWORD_PTR entrypoint, const WCHAR * fileResult); BOOL WINAPI ScyllaDumpProcessA(DWORD_PTR pid, const char * fileToDump, DWORD_PTR imagebase, DWORD_PTR entrypoint, const char * fileResult); BOOL WINAPI ScyllaRebuildFileW(const WCHAR * fileToRebuild, BOOL removeDosStub, BOOL updatePeHeaderChecksum, BOOL createBackup); BOOL WINAPI ScyllaRebuildFileA(const char * fileToRebuild, BOOL removeDosStub, BOOL updatePeHeaderChecksum, BOOL createBackup); const WCHAR * WINAPI ScyllaVersionInformationW(); const char * WINAPI ScyllaVersionInformationA(); DWORD WINAPI ScyllaVersionInformationDword(); int WINAPI ScyllaStartGui(DWORD dwProcessId, HINSTANCE mod); int WINAPI ScyllaIatSearch(DWORD dwProcessId, DWORD_PTR * iatStart, DWORD * iatSize, DWORD_PTR searchStart, BOOL advancedSearch); int WINAPI ScyllaIatFixAutoW(DWORD_PTR iatAddr, DWORD iatSize, DWORD dwProcessId, const WCHAR * dumpFile, const WCHAR * iatFixFile); +int WINAPI ScyllaIatFixCurrentAutoW(DWORD_PTR iatAddr, DWORD iatSize, const WCHAR * dumpFile, const WCHAR * iatFixFile); /* C/C++ Prototyps typedef const WCHAR * (WINAPI * def_ScyllaVersionInformationW)(); typedef const char * (WINAPI * def_ScyllaVersionInformationA)(); typedef DWORD (WINAPI * def_ScyllaVersionInformationDword)(); typedef int (WINAPI * def_ScyllaIatSearch)(DWORD dwProcessId, DWORD_PTR * iatStart, DWORD * iatSize, DWORD_PTR searchStart, BOOL advancedSearch); typedef int (WINAPI * def_ScyllaStartGui)(DWORD dwProcessId, HINSTANCE mod); */ diff --git a/Scylla/Scylla.vcxproj b/Scylla/Scylla.vcxproj index f8f32da..da55c8e 100644 --- a/Scylla/Scylla.vcxproj +++ b/Scylla/Scylla.vcxproj @@ -1,266 +1,269 @@  Debug Win32 Debug x64 Release Win32 Release x64 {710434C9-FC4B-4F1D-B318-E10ADC78499F} Win32Proj Scylla + 10.0.14393.0 Application true Unicode v90 - Application + DynamicLibrary true Unicode + v140 - Application + DynamicLibrary false true Unicode - v90 + v140 - Application + DynamicLibrary false true Unicode + v140 true $(SolutionDir)$(Platform)\$(Configuration)\ $(Platform)\$(Configuration)\ $(SolutionDir)WTL\Include;$(IncludePath) true $(SolutionDir)WTL\Include;$(IncludePath) false $(SolutionDir)$(Platform)\$(Configuration)\ $(Platform)\$(Configuration)\ $(SolutionDir)WTL\Include;$(IncludePath) false $(SolutionDir)WTL\Include;$(IncludePath) Level3 Disabled WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) $(SolutionDir)tinyxml;$(SolutionDir)diStorm\include;%(AdditionalIncludeDirectories) Windows true $(SolutionDir)$(Platform)\$(Configuration)\diStorm.lib;$(SolutionDir)$(Platform)\$(Configuration)\tinyxml.lib;%(AdditionalDependencies) type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' true $(TargetDir)$(TargetName).map Level3 Disabled - WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS=1;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) $(SolutionDir)tinyxml;$(SolutionDir)diStorm\include;%(AdditionalIncludeDirectories) Windows true $(SolutionDir)$(Platform)\$(Configuration)\diStorm.lib;$(SolutionDir)$(Platform)\$(Configuration)\tinyxml.lib;%(AdditionalDependencies) type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' Level3 MaxSpeed true true - WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS=1;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) MultiThreaded $(SolutionDir)tinyxml;$(SolutionDir)diStorm\include;%(AdditionalIncludeDirectories) true Speed Windows false true true $(SolutionDir)$(Platform)\$(Configuration)\diStorm.lib;$(SolutionDir)$(Platform)\$(Configuration)\tinyxml.lib;%(AdditionalDependencies) type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' true Level3 MaxSpeed true true - WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS=1;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) MultiThreaded $(SolutionDir)tinyxml;$(SolutionDir)diStorm\include;%(AdditionalIncludeDirectories) true Windows false true true $(SolutionDir)$(Platform)\$(Configuration)\diStorm.lib;$(SolutionDir)$(Platform)\$(Configuration)\tinyxml.lib;%(AdditionalDependencies) type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' true \ No newline at end of file diff --git a/Scylla/Scylla.vcxproj.filters b/Scylla/Scylla.vcxproj.filters index 2f5dfeb..f62599a 100644 --- a/Scylla/Scylla.vcxproj.filters +++ b/Scylla/Scylla.vcxproj.filters @@ -1,253 +1,253 @@ - - - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {e037d0d5-35ad-4034-83db-746a56a4fee7} - - - {94d7cf3b-0d27-4bd6-b08f-e5894e02ef30} - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {6f76186f-b79c-41e2-8939-05d9de028aad} - - - {bbdfcdb4-3526-43c4-8984-da0f635cc93b} - - - - - Source Files - - - Source Files\GUI - - - Source Files\GUI - - - Source Files - - - Source Files\GUI - - - Source Files\GUI - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files\GUI - - - Source Files - - - Source Files - - - Source Files\GUI - - - Source Files\GUI - - - Source Files\GUI - - - Source Files - - - Source Files\GUI - - - Source Files - - - Source Files - - - Source Files\GUI - - - Source Files\Helper - - - Source Files - - - Source Files\GUI - - - Source Files - - - Source Files - - - Source Files - - - Source Files\GUI - - - Source Files - - - - - Header Files - - - Header Files\GUI - - - Header Files\GUI - - - Header Files - - - Header Files\GUI - - - Header Files\GUI - - - Header Files - - - Header Files - - - Header Files - - - Header Files\GUI - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files\GUI - - - Header Files - - - Header Files - - - Header Files\GUI - - - Header Files\GUI - - - Header Files\GUI - - - Header Files\GUI - - - Header Files - - - Header Files\GUI - - - Header Files - - - Header Files - - - Header Files\GUI - - - Header Files - - - Header Files\Helper - - - Header Files - - - Header Files\GUI - - - Header Files - - - Header Files - - - Header Files\GUI - - - Header Files - - - Header Files - - - - - Resource Files - - - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - + + + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {e037d0d5-35ad-4034-83db-746a56a4fee7} + + + {94d7cf3b-0d27-4bd6-b08f-e5894e02ef30} + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {6f76186f-b79c-41e2-8939-05d9de028aad} + + + {bbdfcdb4-3526-43c4-8984-da0f635cc93b} + + + + + Source Files + + + Source Files\GUI + + + Source Files\GUI + + + Source Files + + + Source Files\GUI + + + Source Files\GUI + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files\GUI + + + Source Files + + + Source Files + + + Source Files\GUI + + + Source Files\GUI + + + Source Files\GUI + + + Source Files + + + Source Files\GUI + + + Source Files + + + Source Files + + + Source Files\GUI + + + Source Files\Helper + + + Source Files + + + Source Files\GUI + + + Source Files + + + Source Files + + + Source Files + + + Source Files\GUI + + + Source Files + + + + + Header Files + + + Header Files\GUI + + + Header Files\GUI + + + Header Files + + + Header Files\GUI + + + Header Files\GUI + + + Header Files + + + Header Files + + + Header Files + + + Header Files\GUI + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files\GUI + + + Header Files + + + Header Files + + + Header Files\GUI + + + Header Files\GUI + + + Header Files\GUI + + + Header Files\GUI + + + Header Files + + + Header Files\GUI + + + Header Files + + + Header Files + + + Header Files\GUI + + + Header Files + + + Header Files\Helper + + + Header Files + + + Header Files\GUI + + + Header Files + + + Header Files + + + Header Files\GUI + + + Header Files + + + Header Files + + + + + Resource Files + + + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + \ No newline at end of file diff --git a/WTL/README b/WTL/README index d3dedcd..64dc239 100644 --- a/WTL/README +++ b/WTL/README @@ -1,2 +1,2 @@ -Download WTL from here: https://sourceforge.net/projects/wtl/ +Download WTL from here: https://sourceforge.net/projects/wtl/ Extract the contents of the ZIP in this directory. \ No newline at end of file diff --git a/diStorm/diStorm.vcxproj b/diStorm/diStorm.vcxproj index b268de3..93966b6 100644 --- a/diStorm/diStorm.vcxproj +++ b/diStorm/diStorm.vcxproj @@ -1,177 +1,181 @@  Debug Win32 Debug x64 Release Win32 Release x64 {A4B94DE4-BE0E-4E7D-95E7-7B84E6F117A1} diStorm Win32Proj + 10.0.10240.0 StaticLibrary Unicode true + v140 StaticLibrary Unicode StaticLibrary Unicode true + v140 StaticLibrary Unicode + v140 <_ProjectFileVersion>10.0.30319.1 $(SolutionDir)$(Platform)\$(Configuration)\ $(Platform)\$(Configuration)\ $(SolutionDir)$(Platform)\$(Configuration)\ $(Platform)\$(Configuration)\ $(SolutionDir)$(Platform)\$(Configuration)\ $(Platform)\$(Configuration)\ $(SolutionDir)$(Platform)\$(Configuration)\ $(Platform)\$(Configuration)\ AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset Disabled WIN32;SUPPORT_64BIT_OFFSET;_DEBUG;_LIB;DISTORM_STATIC;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebug Level3 EditAndContinue include X64 Disabled WIN32;SUPPORT_64BIT_OFFSET;_DEBUG;_LIB;DISTORM_STATIC;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebug Level3 ProgramDatabase include MaxSpeed true false WIN32;SUPPORT_64BIT_OFFSET;NDEBUG;_LIB;DISTORM_STATIC;%(PreprocessorDefinitions) true MultiThreaded true Level3 ProgramDatabase include X64 MaxSpeed true false WIN32;SUPPORT_64BIT_OFFSET;NDEBUG;_LIB;DISTORM_STATIC;%(PreprocessorDefinitions) true MultiThreaded true Level3 ProgramDatabase include \ No newline at end of file diff --git a/diStorm/diStorm.vcxproj.filters b/diStorm/diStorm.vcxproj.filters index 477bfd9..02de516 100644 --- a/diStorm/diStorm.vcxproj.filters +++ b/diStorm/diStorm.vcxproj.filters @@ -1,84 +1,81 @@  {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files - - Source Files - Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files \ No newline at end of file diff --git a/tinyxml/README b/tinyxml/README index 89e8fd9..8e5d788 100644 --- a/tinyxml/README +++ b/tinyxml/README @@ -1,8 +1,8 @@ -Download tinyxml from here: https://sourceforge.net/projects/tinyxml/ -Copy the following files in this directory: -tinystr.cpp -tinyxml.cpp -tinyxmlerror.cpp -tinyxmlparser.cpp -tinystr.h +Download tinyxml from here: https://sourceforge.net/projects/tinyxml/ +Copy the following files in this directory: +tinystr.cpp +tinyxml.cpp +tinyxmlerror.cpp +tinyxmlparser.cpp +tinystr.h tinyxml.h \ No newline at end of file diff --git a/tinyxml/tinyxml.vcxproj b/tinyxml/tinyxml.vcxproj index 2e3f1ee..5642d20 100644 --- a/tinyxml/tinyxml.vcxproj +++ b/tinyxml/tinyxml.vcxproj @@ -1,166 +1,167 @@  Debug Win32 Debug x64 Release Win32 Release x64 {187A751B-B47D-4A95-9F24-55D3D7ABB570} Win32Proj tinyxml + 10.0.14393.0 StaticLibrary true Unicode v90 StaticLibrary true Unicode - v90 + v140 StaticLibrary false true Unicode - v90 + v140 StaticLibrary false true Unicode - v90 + v140 $(SolutionDir)$(Platform)\$(Configuration)\ $(Platform)\$(Configuration)\ $(SolutionDir)$(Platform)\$(Configuration)\ $(Platform)\$(Configuration)\ $(SolutionDir)$(Platform)\$(Configuration)\ $(SolutionDir)$(Platform)\$(Configuration)\ $(Platform)\$(Configuration)\ $(Platform)\$(Configuration)\ Level3 Disabled WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) MultiThreadedDebug Windows true Level3 Disabled WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) MultiThreadedDebug Windows true Level3 MaxSpeed true true WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) MultiThreaded Windows true true true Level3 MaxSpeed true true WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) MultiThreaded Windows true true true \ No newline at end of file