diff --git a/Scylla/ConfigurationHolder.cpp b/Scylla/ConfigurationHolder.cpp index 0717204..ca0a579 100644 --- a/Scylla/ConfigurationHolder.cpp +++ b/Scylla/ConfigurationHolder.cpp @@ -1,207 +1,207 @@ #include "ConfigurationHolder.h" #include #include "Architecture.h" const WCHAR ConfigurationHolder::CONFIG_FILE_SECTION_NAME[] = L"SCYLLA_CONFIG"; //#define DEBUG_COMMENTS ConfigurationHolder::ConfigurationHolder(const WCHAR* fileName) { config[USE_PE_HEADER_FROM_DISK] = Configuration(L"USE_PE_HEADER_FROM_DISK", Configuration::Boolean); config[DEBUG_PRIVILEGE] = Configuration(L"DEBUG_PRIVILEGE", Configuration::Boolean); config[CREATE_BACKUP] = Configuration(L"CREATE_BACKUP", Configuration::Boolean); config[DLL_INJECTION_AUTO_UNLOAD] = Configuration(L"DLL_INJECTION_AUTO_UNLOAD", Configuration::Boolean); config[UPDATE_HEADER_CHECKSUM] = Configuration(L"UPDATE_HEADER_CHECKSUM", Configuration::Boolean); config[IAT_SECTION_NAME] = Configuration(L"IAT_SECTION_NAME", Configuration::String); config[REMOVE_DOS_HEADER_STUB] = Configuration(L"REMOVE_DOS_HEADER_STUB", Configuration::Boolean); config[IAT_FIX_AND_OEP_FIX] = Configuration(L"IAT_FIX_AND_OEP_FIX", Configuration::Boolean); config[SUSPEND_PROCESS_FOR_DUMPING] = Configuration(L"SUSPEND_PROCESS_FOR_DUMPING", Configuration::Boolean); config[OriginalFirstThunk_SUPPORT] = Configuration(L"OriginalFirstThunk_SUPPORT", Configuration::Boolean); config[USE_ADVANCED_IAT_SEARCH] = Configuration(L"USE_ADVANCED_IAT_SEARCH", Configuration::Boolean); config[SCAN_DIRECT_IMPORTS] = Configuration(L"SCAN_DIRECT_IMPORTS", Configuration::Boolean); config[FIX_DIRECT_IMPORTS_NORMAL] = Configuration(L"FIX_DIRECT_IMPORTS_NORMAL", Configuration::Boolean); config[FIX_DIRECT_IMPORTS_UNIVERSAL] = Configuration(L"FIX_DIRECT_IMPORTS_UNIVERSAL", Configuration::Boolean); config[CREATE_NEW_IAT_IN_SECTION] = Configuration(L"CREATE_NEW_IAT_IN_SECTION", Configuration::Boolean); buildConfigFilePath(fileName); } bool ConfigurationHolder::loadConfiguration() { std::map::iterator mapIter; if (configPath[0] == '\0') { return false; } for (mapIter = config.begin() ; mapIter != config.end(); mapIter++) { Configuration& configObject = mapIter->second; loadConfig(configObject); } return true; } bool ConfigurationHolder::saveConfiguration() const { std::map::const_iterator mapIter; if (configPath[0] == '\0') { return false; } for (mapIter = config.begin() ; mapIter != config.end(); mapIter++) { const Configuration& configObject = mapIter->second; if (!saveConfig(configObject)) { return false; } } return true; } Configuration& ConfigurationHolder::operator[](ConfigOption option) { return config[option]; } const Configuration& ConfigurationHolder::operator[](ConfigOption option) const { static const Configuration dummy; std::map::const_iterator found = config.find(option); if(found != config.end()) { return found->second; } else { return dummy; } } bool ConfigurationHolder::saveNumericToConfigFile(const Configuration & configObject, int nBase) const { WCHAR buf[21]; // UINT64_MAX in dec has 20 digits if (nBase == 16) { swprintf_s(buf, PRINTF_DWORD_PTR_FULL, configObject.getNumeric()); } else { swprintf_s(buf, PRINTF_INTEGER, configObject.getNumeric()); } BOOL ret = WritePrivateProfileString(CONFIG_FILE_SECTION_NAME, configObject.getName(), buf, configPath); - return ret == TRUE; + return !!ret; } bool ConfigurationHolder::readNumericFromConfigFile(Configuration & configObject, int nBase) { WCHAR buf[21]; // UINT64_MAX in dec has 20 digits DWORD read = GetPrivateProfileString(CONFIG_FILE_SECTION_NAME, configObject.getName(), L"", buf, _countof(buf), configPath); if (read > 0 && wcslen(buf) > 0) { #ifdef _WIN64 configObject.setNumeric(_wcstoui64(buf, NULL, nBase)); #else configObject.setNumeric(wcstoul(buf, NULL, nBase)); #endif return true; } return false; } bool ConfigurationHolder::saveStringToConfigFile(const Configuration & configObject) const { BOOL ret = WritePrivateProfileString(CONFIG_FILE_SECTION_NAME, configObject.getName(), configObject.getString(), configPath); - return ret == TRUE; + return !!ret; } bool ConfigurationHolder::readStringFromConfigFile(Configuration & configObject) { WCHAR buf[Configuration::CONFIG_STRING_LENGTH]; DWORD read = GetPrivateProfileString(CONFIG_FILE_SECTION_NAME, configObject.getName(), L"", buf, _countof(buf), configPath); if(read > 0 && wcslen(buf) > 0) { configObject.setString(buf); return true; } return false; } bool ConfigurationHolder::readBooleanFromConfigFile(Configuration & configObject) { UINT val = GetPrivateProfileInt(CONFIG_FILE_SECTION_NAME, configObject.getName(), 0, configPath); configObject.setBool(val != 0); return true; } bool ConfigurationHolder::saveBooleanToConfigFile(const Configuration & configObject) const { const WCHAR *boolValue = configObject.isTrue() ? L"1" : L"0"; BOOL ret = WritePrivateProfileString(CONFIG_FILE_SECTION_NAME, configObject.getName(), boolValue, configPath); - return ret == TRUE; + return !!ret; } bool ConfigurationHolder::loadConfig(Configuration & configObject) { switch (configObject.getType()) { case Configuration::String: return readStringFromConfigFile(configObject); case Configuration::Boolean: return readBooleanFromConfigFile(configObject); case Configuration::Decimal: return readNumericFromConfigFile(configObject, 10); case Configuration::Hexadecimal: return readNumericFromConfigFile(configObject, 16); default: return false; } } bool ConfigurationHolder::saveConfig(const Configuration & configObject) const { switch (configObject.getType()) { case Configuration::String: return saveStringToConfigFile(configObject); case Configuration::Boolean: return saveBooleanToConfigFile(configObject); case Configuration::Decimal: return saveNumericToConfigFile(configObject, 10); case Configuration::Hexadecimal: return saveNumericToConfigFile(configObject, 16); default: return false; } } bool ConfigurationHolder::buildConfigFilePath(const WCHAR* fileName) { ZeroMemory(configPath, sizeof(configPath)); if (!GetModuleFileName(0, configPath, _countof(configPath))) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"buildConfigFilePath :: GetModuleFileName failed %d", GetLastError()); #endif return false; } PathRemoveFileSpec(configPath); PathAppend(configPath, fileName); return true; } diff --git a/Scylla/DeviceNameResolver.cpp b/Scylla/DeviceNameResolver.cpp index 58c94f1..4c831bb 100644 --- a/Scylla/DeviceNameResolver.cpp +++ b/Scylla/DeviceNameResolver.cpp @@ -1,98 +1,101 @@ #include "DeviceNameResolver.h" #include "NativeWinApi.h" DeviceNameResolver::DeviceNameResolver() { NativeWinApi::initialize(); initDeviceNameList(); } DeviceNameResolver::~DeviceNameResolver() { deviceNameList.clear(); } void DeviceNameResolver::initDeviceNameList() { TCHAR shortName[3] = {0}; TCHAR longName[MAX_PATH] = {0}; HardDisk hardDisk; shortName[1] = TEXT(':'); deviceNameList.reserve(3); for ( TCHAR shortD = TEXT('a'); shortD < TEXT('z'); shortD++ ) { shortName[0] = shortD; if (QueryDosDevice( shortName, longName, MAX_PATH ) > 0) { hardDisk.shortName[0] = _totupper(shortD); hardDisk.shortName[1] = TEXT(':'); hardDisk.shortName[2] = 0; hardDisk.longNameLength = _tcslen(longName); _tcscpy_s(hardDisk.longName, longName); deviceNameList.push_back(hardDisk); } } fixVirtualDevices(); } bool DeviceNameResolver::resolveDeviceLongNameToShort(const TCHAR * sourcePath, TCHAR * targetPath) { for (unsigned int i = 0; i < deviceNameList.size(); i++) { if (!_tcsnicmp(deviceNameList[i].longName, sourcePath, deviceNameList[i].longNameLength)) { _tcscpy_s(targetPath, MAX_PATH, deviceNameList[i].shortName); _tcscat_s(targetPath, MAX_PATH, sourcePath + deviceNameList[i].longNameLength); return true; } } return false; } void DeviceNameResolver::fixVirtualDevices() { WCHAR longCopy[MAX_PATH] = {0}; OBJECT_ATTRIBUTES oa = {0}; UNICODE_STRING unicodeInput = {0}; UNICODE_STRING unicodeOutput = {0}; HANDLE hFile = 0; ULONG retLen = 0; HardDisk hardDisk; unicodeOutput.Length = MAX_PATH * 2 * sizeof(WCHAR); unicodeOutput.MaximumLength = unicodeOutput.Length; unicodeOutput.Buffer = (PWSTR)calloc(unicodeOutput.Length, 1); for (unsigned int i = 0; i < deviceNameList.size(); i++) { wcscpy_s(longCopy, deviceNameList[i].longName); NativeWinApi::RtlInitUnicodeString(&unicodeInput, longCopy); InitializeObjectAttributes(&oa, &unicodeInput, 0, 0, 0); if(NT_SUCCESS(NativeWinApi::NtOpenSymbolicLinkObject(&hFile, SYMBOLIC_LINK_QUERY, &oa))) { + unicodeOutput.Length = MAX_PATH * 2 * sizeof(WCHAR); + unicodeOutput.MaximumLength = unicodeOutput.Length; + if (NT_SUCCESS(NativeWinApi::NtQuerySymbolicLinkObject(hFile, &unicodeOutput, &retLen))) { hardDisk.longNameLength = wcslen(unicodeOutput.Buffer); wcscpy_s(hardDisk.shortName, deviceNameList[i].shortName); wcscpy_s(hardDisk.longName, unicodeOutput.Buffer); deviceNameList.push_back(hardDisk); } NativeWinApi::NtClose(hFile); } } free(unicodeOutput.Buffer); } diff --git a/Scylla/DisassemblerGui.h b/Scylla/DisassemblerGui.h index c57a405..4bb3ae5 100644 --- a/Scylla/DisassemblerGui.h +++ b/Scylla/DisassemblerGui.h @@ -1,134 +1,134 @@ #pragma once #include #include "resource.h" // WTL #include // base ATL classes #include // base WTL classes #include // ATL GUI classes #include // WTL window frame helpers #include // WTL utility classes like CString #include // WTL enhanced msg map macros #include // WTL controls #include // WTL dialog data exchange #include #include "hexedit.h" #include "ApiReader.h" enum DisassemblerAddressType { ADDRESS_TYPE_MODULE, ADDRESS_TYPE_API, ADDRESS_TYPE_SPECIAL }; class DisassemblerAddressComment { public: DWORD_PTR address; WCHAR comment[MAX_PATH]; DisassemblerAddressType type; DWORD moduleSize; - bool operator<(DisassemblerAddressComment rhs) { return address < rhs.address; } + bool operator<(const DisassemblerAddressComment& rhs) { return address < rhs.address; } }; class DisassemblerGui : public CDialogImpl, public CWinDataExchange, public CDialogResize { public: enum { IDD = IDD_DLG_DISASSEMBLER }; BEGIN_DDX_MAP(DisassemblerGui) DDX_CONTROL_HANDLE(IDC_LIST_DISASSEMBLER, ListDisassembler) DDX_CONTROL(IDC_EDIT_ADDRESS_DISASSEMBLE, EditAddress) END_DDX_MAP() BEGIN_MSG_MAP(DisassemblerGui) MSG_WM_INITDIALOG(OnInitDialog) MSG_WM_CONTEXTMENU(OnContextMenu) NOTIFY_HANDLER_EX(IDC_LIST_DISASSEMBLER, NM_CUSTOMDRAW, OnNMCustomdraw) COMMAND_ID_HANDLER_EX(IDC_BUTTON_DISASSEMBLE, OnDisassemble) COMMAND_ID_HANDLER_EX(IDC_BUTTON_DISASSEMBLER_BACK, OnDisassembleBack) COMMAND_ID_HANDLER_EX(IDC_BUTTON_DISASSEMBLER_FORWARD, OnDisassembleForward) COMMAND_ID_HANDLER_EX(IDCANCEL, OnExit) COMMAND_ID_HANDLER_EX(IDOK, OnExit) CHAIN_MSG_MAP(CDialogResize) END_MSG_MAP() BEGIN_DLGRESIZE_MAP(DisassemblerGui) DLGRESIZE_CONTROL(IDC_LIST_DISASSEMBLER, DLSZ_SIZE_X | DLSZ_SIZE_Y) DLGRESIZE_CONTROL(IDC_BUTTON_DISASSEMBLE, DLSZ_MOVE_X | DLSZ_MOVE_Y) DLGRESIZE_CONTROL(IDC_BUTTON_DISASSEMBLER_BACK, DLSZ_MOVE_X | DLSZ_MOVE_Y) DLGRESIZE_CONTROL(IDC_BUTTON_DISASSEMBLER_FORWARD, DLSZ_MOVE_X | DLSZ_MOVE_Y) DLGRESIZE_CONTROL(IDC_EDIT_ADDRESS_DISASSEMBLE, DLSZ_MOVE_Y) DLGRESIZE_CONTROL(IDC_STATIC_ADDRESS_DISASSEMBLE, DLSZ_MOVE_Y) END_DLGRESIZE_MAP() DisassemblerGui(DWORD_PTR startAddress, ApiReader * apiReaderObject); protected: // Variables static const size_t DISASSEMBLER_GUI_MEMORY_SIZE = 0x120; WCHAR tempBuffer[500]; int addressHistoryIndex; std::vector addressHistory; std::vector addressCommentList; // Controls CListViewCtrl ListDisassembler; CHexEdit EditAddress; enum DisassemblerColumns { COL_ADDRESS = 0, COL_INSTRUCTION_SIZE, COL_OPCODES, COL_INSTRUCTION, COL_COMMENT }; // Handles CMenu hMenuDisassembler; // Message handlers BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam); void OnContextMenu(CWindow wnd, CPoint point); void OnExit(UINT uNotifyCode, int nID, CWindow wndCtl); LRESULT OnNMCustomdraw(NMHDR* pnmh); void OnDisassemble(UINT uNotifyCode, int nID, CWindow wndCtl); void OnDisassembleBack(UINT uNotifyCode, int nID, CWindow wndCtl); void OnDisassembleForward(UINT uNotifyCode, int nID, CWindow wndCtl); // GUI functions void addColumnsToDisassembler(CListViewCtrl& list); bool displayDisassembly(); // Misc void copyToClipboard(const WCHAR * text); private: ApiReader * apiReader; BYTE data[DISASSEMBLER_GUI_MEMORY_SIZE]; void toUpperCase(WCHAR * lowercase); void doColorInstruction( LPNMLVCUSTOMDRAW lpLVCustomDraw, DWORD_PTR itemIndex ); void followInstruction(int index); bool getDisassemblyComment(unsigned int index); void disassembleNewAddress(DWORD_PTR address); void initAddressCommentList(); void addModuleAddressCommentEntry( DWORD_PTR address, DWORD moduleSize, const WCHAR * modulePath ); void analyzeAddress( DWORD_PTR address, WCHAR * comment ); };