diff --git a/Scylla/FunctionExport.cpp b/Scylla/FunctionExport.cpp index bf246ac..102e491 100644 --- a/Scylla/FunctionExport.cpp +++ b/Scylla/FunctionExport.cpp @@ -1,374 +1,412 @@ #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__) +//#define DEBUG_COMMENTS +#include 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) +int WINAPI ScyllaIatFixCurrentAutoW(DWORD_PTR iatAddr, DWORD iatSize, const WCHAR * dumpFile, const WCHAR * iatFixFile, const WCHAR * moduleName) { #pragma EXPORT ApiReader apiReader; - Process *processPtr = 0; std::map moduleList; #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"in ScyllaIatFixCurrentAutoW"); #endif ProcessAccessHelp::closeProcessHandle(); apiReader.clearAll(); ProcessAccessHelp::setCurrentProcessAsTarget(); #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"set current process as target"); #endif ProcessAccessHelp::getProcessModules(ProcessAccessHelp::hProcess, ProcessAccessHelp::moduleList); #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"got process modules"); #endif - ProcessLister::getProcessImageInformation(ProcessAccessHelp::hProcess, processPtr); +#ifdef DEBUG_COMMENTS + Scylla::debugLog.log(L"got process image information"); +#endif + + ModuleInfo* moduleInfo = 0; - ProcessAccessHelp::selectedModule = 0; + if (moduleName) { +#ifdef DEBUG_COMMENTS + Scylla::debugLog.log(L"get module"); +#endif + for (ModuleInfo info : ProcessAccessHelp::moduleList) { +#ifdef DEBUG_COMMENTS + Scylla::debugLog.log(info.getFilename()); +#endif + if (wcscmp(info.getFilename(), moduleName) == 0) { + moduleInfo = &info; + break; + } + } + } + + ProcessAccessHelp::selectedModule = moduleInfo; #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"set selected module"); #endif - ProcessAccessHelp::targetImageBase = processPtr->imageBase; - ProcessAccessHelp::targetSizeOfImage = processPtr->imageSize; + + if (moduleInfo) { + ProcessAccessHelp::targetImageBase = moduleInfo->modBaseAddr; + ProcessAccessHelp::targetSizeOfImage = moduleInfo->modBaseSize; + iatAddr = ((DWORD)ProcessAccessHelp::targetImageBase) + iatAddr; // if module use relative iatAddr, since modules image base might shift around + } + else { + Process process; + process.pebAddress = ProcessLister::getPebAddressFromProcess(ProcessAccessHelp::hProcess); + ProcessLister::getProcessImageInformation(ProcessAccessHelp::hProcess, &process); + ProcessAccessHelp::targetImageBase = process.imageBase; + ProcessAccessHelp::targetSizeOfImage = process.imageSize; + } + +#ifdef DEBUG_COMMENTS + Scylla::debugLog.log(std::to_wstring(ProcessAccessHelp::targetImageBase).c_str()); + Scylla::debugLog.log(std::to_wstring(ProcessAccessHelp::targetSizeOfImage).c_str()); + Scylla::debugLog.log(std::to_wstring(iatAddr).c_str()); +#endif apiReader.readApisFromModuleList(); #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"read api from module list"); #endif apiReader.readAndParseIAT(iatAddr, iatSize, moduleList); #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"iat"); + Scylla::debugLog.log(std::to_wstring(moduleList.size()).c_str()); #endif //add IAT section to dump ImportRebuilder importRebuild(dumpFile); importRebuild.enableOFTSupport(); #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"rebuild"); #endif int retVal = SCY_ERROR_IATWRITE; if (importRebuild.rebuildImportTable(iatFixFile, moduleList)) { retVal = SCY_ERROR_SUCCESS; } #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"finishing"); #endif moduleList.clear(); ProcessAccessHelp::closeProcessHandle(); apiReader.clearAll(); #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"done"); #endif 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 e7664a6..06c78ae 100644 --- a/Scylla/FunctionExport.h +++ b/Scylla/FunctionExport.h @@ -1,55 +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 ScyllaStartGui(DWORD dwProcessId, HINSTANCE mod, DWORD_PTR entrypoint); 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); +int WINAPI ScyllaIatFixCurrentAutoW(DWORD_PTR iatAddr, DWORD iatSize, const WCHAR * dumpFile, const WCHAR * iatFixFile, const WCHAR * moduleName); /* 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/ProcessLister.h b/Scylla/ProcessLister.h index ddb32f2..69864e4 100644 --- a/Scylla/ProcessLister.h +++ b/Scylla/ProcessLister.h @@ -1,69 +1,69 @@ #pragma once #include #include #include #include #include "NativeWinApi.h" #include "DeviceNameResolver.h" typedef BOOL (WINAPI *def_IsWow64Process)(HANDLE hProcess,PBOOL Wow64Process); class Process { public: DWORD PID; DWORD sessionId; DWORD_PTR imageBase; DWORD_PTR pebAddress; DWORD entryPoint; //RVA without imagebase DWORD imageSize; WCHAR filename[MAX_PATH]; WCHAR fullPath[MAX_PATH]; Process() { PID = 0; } }; enum ProcessType { PROCESS_UNKNOWN, PROCESS_MISSING_RIGHTS, PROCESS_32, PROCESS_64 }; class ProcessLister { public: static def_IsWow64Process _IsWow64Process; ProcessLister() { deviceNameResolver = new DeviceNameResolver(); _IsWow64Process = (def_IsWow64Process)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "IsWow64Process"); } ~ProcessLister() { delete deviceNameResolver; } std::vector& getProcessList(); static bool isWindows64(); static DWORD setDebugPrivileges(); std::vector& getProcessListSnapshotNative(); static void getProcessImageInformation(HANDLE hProcess, Process* process); + static DWORD_PTR getPebAddressFromProcess(HANDLE hProcess); private: std::vector processList; DeviceNameResolver * deviceNameResolver; ProcessType checkIsProcess64(HANDLE hProcess); bool getAbsoluteFilePath(HANDLE hProcess, Process * process); void handleProcessInformationAndAddToList( PSYSTEM_PROCESS_INFORMATION pProcess ); - DWORD_PTR getPebAddressFromProcess( HANDLE hProcess ); }; \ No newline at end of file