diff --git a/Scylla/MainGui.cpp b/Scylla/MainGui.cpp index 9cdec9d..8d652e8 100644 --- a/Scylla/MainGui.cpp +++ b/Scylla/MainGui.cpp @@ -1,1240 +1,1239 @@ #include "MainGui.h" #include "definitions.h" #include "PluginLoader.h" #include "ConfigurationHolder.h" #include "PeDump.h" #include "PeRebuild.h" #include "DllInjectionPlugin.h" #include "DisassemblerGui.h" #include "PickApiGui.h" #include "NativeWinApi.h" #include "ImportRebuild.h" #include "SystemInformation.h" #include "AboutGui.h" #include "OptionsGui.h" #include "TreeImportExport.h" extern CAppModule _Module; // o_O const WCHAR MainGui::filterExe[] = L"Executable (*.exe)\0*.exe\0All files\0*.*\0"; const WCHAR MainGui::filterDll[] = L"Dynamic Link Library (*.dll)\0*.dll\0All files\0*.*\0"; const WCHAR MainGui::filterExeDll[] = L"Executable (*.exe)\0*.exe\0Dynamic Link Library (*.dll)\0*.dll\0All files\0*.*\0"; const WCHAR MainGui::filterTxt[] = L"Text file (*.txt)\0*.txt\0All files\0*.*\0"; const WCHAR MainGui::filterXml[] = L"XML file (*.xml)\0*.xml\0All files\0*.*\0"; MainGui::MainGui() : selectedProcess(0), importsHandling(TreeImports), TreeImportsSubclass(this, IDC_TREE_IMPORTS) { Logger::getDebugLogFilePath(); ConfigurationHolder::loadConfiguration(); PluginLoader::findAllPlugins(); NativeWinApi::initialize(); SystemInformation::getSystemInformation(); if(ConfigurationHolder::getConfigObject(DEBUG_PRIVILEGE)->isTrue()) { processLister.setDebugPrivileges(); } - processAccessHelp.getProcessModules(GetCurrentProcessId(), processAccessHelp.ownModuleList); + ProcessAccessHelp::getProcessModules(GetCurrentProcessId(), ProcessAccessHelp::ownModuleList); hIcon.LoadIcon(IDI_ICON_SCYLLA); hMenuImports.LoadMenu(IDR_MENU_IMPORTS); hMenuLog.LoadMenu(IDR_MENU_LOG); accelerators.LoadAccelerators(IDR_ACCELERATOR_MAIN); hIconCheck.LoadIcon(IDI_ICON_CHECK, 16, 16); hIconWarning.LoadIcon(IDI_ICON_WARNING, 16, 16); hIconError.LoadIcon(IDI_ICON_ERROR, 16, 16); appendPluginListToMenu(hMenuImports.GetSubMenu(0)); } BOOL MainGui::PreTranslateMessage(MSG* pMsg) { if(accelerators.TranslateAccelerator(m_hWnd, pMsg)) { return TRUE; // handled keyboard shortcuts } else if(IsDialogMessage(pMsg)) { return TRUE; // handled dialog messages } return FALSE; } BOOL MainGui::OnInitDialog(CWindow wndFocus, LPARAM lInitParam) { if (SystemInformation::currenOS == UNKNOWN_OS) { if(IDCANCEL == MessageBox(L"Operating System is not supported\r\nContinue anyway?", L"Scylla", MB_ICONWARNING | MB_OKCANCEL)) { SendMessage(WM_CLOSE); return FALSE; } } // register ourselves to receive PreTranslateMessage CMessageLoop* pLoop = _Module.GetMessageLoop(); pLoop->AddMessageFilter(this); setupStatusBar(); DoDataExchange(); // attach controls DlgResize_Init(true, true); // init CDialogResize appendPluginListToMenu(CMenuHandle(GetMenu()).GetSubMenu(MenuImportsOffsetTrace)); enableDialogControls(FALSE); setIconAndDialogCaption(); return TRUE; } void MainGui::OnDestroy() { PostQuitMessage(0); } void MainGui::OnSize(UINT nType, CSize size) { StatusBar.SendMessage(WM_SIZE); SetMsgHandled(FALSE); } void MainGui::OnContextMenu(CWindow wnd, CPoint point) { switch(wnd.GetDlgCtrlID()) { case IDC_TREE_IMPORTS: DisplayContextMenuImports(wnd, point); return; case IDC_LIST_LOG: DisplayContextMenuLog(wnd, point); return; } SetMsgHandled(FALSE); } void MainGui::OnCommand(UINT uNotifyCode, int nID, CWindow wndCtl) { // Handle plugin trace menu selection if(uNotifyCode == 0 && !wndCtl.IsWindow()) // make sure it's a menu { if ((nID >= PLUGIN_MENU_BASE_ID) && (nID <= (int)(PluginLoader::getScyllaPluginList().size() + PluginLoader::getImprecPluginList().size() + PLUGIN_MENU_BASE_ID))) { pluginActionHandler(nID); return; } } SetMsgHandled(FALSE); } LRESULT MainGui::OnTreeImportsDoubleClick(const NMHDR* pnmh) { if(TreeImports.GetCount() < 1) return 0; // Get item under cursor CTreeItem over = findTreeItem(CPoint(GetMessagePos()), true); if(over && importsHandling.isImport(over)) { pickApiActionHandler(over); } return 0; } LRESULT MainGui::OnTreeImportsKeyDown(const NMHDR* pnmh) { const NMTVKEYDOWN * tkd = (NMTVKEYDOWN *)pnmh; switch(tkd->wVKey) { case VK_RETURN: { CTreeItem selected = TreeImports.GetFocusItem(); if(!selected.IsNull() && importsHandling.isImport(selected)) { pickApiActionHandler(selected); } } return 1; case VK_DELETE: deleteSelectedImportsActionHandler(); return 1; } SetMsgHandled(FALSE); return 0; } UINT MainGui::OnTreeImportsSubclassGetDlgCode(const MSG * lpMsg) { if(lpMsg) { switch(lpMsg->wParam) { case VK_RETURN: return DLGC_WANTMESSAGE; } } SetMsgHandled(FALSE); return 0; } void MainGui::OnTreeImportsSubclassChar(UINT nChar, UINT nRepCnt, UINT nFlags) { switch(nChar) { case VK_RETURN: break; default: SetMsgHandled(FALSE); break; } } void MainGui::OnProcessListDrop(UINT uNotifyCode, int nID, CWindow wndCtl) { fillProcessListComboBox(ComboProcessList); } void MainGui::OnProcessListSelected(UINT uNotifyCode, int nID, CWindow wndCtl) { processSelectedActionHandler(ComboProcessList.GetCurSel()); } void MainGui::OnPickDLL(UINT uNotifyCode, int nID, CWindow wndCtl) { pickDllActionHandler(); } void MainGui::OnOptions(UINT uNotifyCode, int nID, CWindow wndCtl) { optionsActionHandler(); } void MainGui::OnDump(UINT uNotifyCode, int nID, CWindow wndCtl) { dumpActionHandler(); } void MainGui::OnFixDump(UINT uNotifyCode, int nID, CWindow wndCtl) { dumpFixActionHandler(); } void MainGui::OnPERebuild(UINT uNotifyCode, int nID, CWindow wndCtl) { peRebuildActionHandler(); } void MainGui::OnDLLInject(UINT uNotifyCode, int nID, CWindow wndCtl) { dllInjectActionHandler(); } void MainGui::OnIATAutoSearch(UINT uNotifyCode, int nID, CWindow wndCtl) { iatAutosearchActionHandler(); } void MainGui::OnGetImports(UINT uNotifyCode, int nID, CWindow wndCtl) { getImportsActionHandler(); } void MainGui::OnInvalidImports(UINT uNotifyCode, int nID, CWindow wndCtl) { showInvalidImportsActionHandler(); } void MainGui::OnSuspectImports(UINT uNotifyCode, int nID, CWindow wndCtl) { showSuspectImportsActionHandler(); } void MainGui::OnClearImports(UINT uNotifyCode, int nID, CWindow wndCtl) { clearImportsActionHandler(); } void MainGui::OnInvalidateSelected(UINT uNotifyCode, int nID, CWindow wndCtl) { invalidateSelectedImportsActionHandler(); } void MainGui::OnCutSelected(UINT uNotifyCode, int nID, CWindow wndCtl) { deleteSelectedImportsActionHandler(); } void MainGui::OnSaveTree(UINT uNotifyCode, int nID, CWindow wndCtl) { saveTreeActionHandler(); } void MainGui::OnLoadTree(UINT uNotifyCode, int nID, CWindow wndCtl) { loadTreeActionHandler(); } void MainGui::OnAutotrace(UINT uNotifyCode, int nID, CWindow wndCtl) { // TODO } void MainGui::OnExit(UINT uNotifyCode, int nID, CWindow wndCtl) { DestroyWindow(); } void MainGui::OnAbout(UINT uNotifyCode, int nID, CWindow wndCtl) { showAboutDialog(); } void MainGui::setupStatusBar() { StatusBar.Create(m_hWnd, NULL, L"", WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_TOOLTIPS, NULL, IDC_STATUS_BAR); CRect rcMain, rcStatus; GetClientRect(&rcMain); StatusBar.GetWindowRect(&rcStatus); const int PARTS = 4; int widths[PARTS]; widths[PART_COUNT] = rcMain.Width() / 5; widths[PART_INVALID] = widths[PART_COUNT] + rcMain.Width() / 5; widths[PART_IMAGEBASE] = widths[PART_INVALID] + rcMain.Width() / 3; widths[PART_MODULE] = -1; StatusBar.SetParts(PARTS, widths); ResizeClient(rcMain.Width(), rcMain.Height() + rcStatus.Height(), FALSE); } void MainGui::updateStatusBar() { // Rewrite ImportsHandling so we get these easily unsigned int totalImports = importsHandling.thunkCount(); unsigned int invalidImports = importsHandling.invalidThunkCount(); // \t = center, \t\t = right-align swprintf_s(stringBuffer, _countof(stringBuffer), TEXT("\tImports: %u"), totalImports); StatusBar.SetText(PART_COUNT, stringBuffer); if(invalidImports > 0) { StatusBar.SetIcon(PART_INVALID, hIconError); } else { StatusBar.SetIcon(PART_INVALID, hIconCheck); } swprintf_s(stringBuffer, _countof(stringBuffer), TEXT("\tInvalid: %u"), invalidImports); StatusBar.SetText(PART_INVALID, stringBuffer); if(selectedProcess) { DWORD_PTR imageBase = 0; const WCHAR * fileName = 0; - if(processAccessHelp.selectedModule) + if(ProcessAccessHelp::selectedModule) { - imageBase = processAccessHelp.selectedModule->modBaseAddr; - fileName = processAccessHelp.selectedModule->getFilename(); + imageBase = ProcessAccessHelp::selectedModule->modBaseAddr; + fileName = ProcessAccessHelp::selectedModule->getFilename(); } else { imageBase = selectedProcess->imageBase; fileName = selectedProcess->filename; } swprintf_s(stringBuffer, _countof(stringBuffer), TEXT("\tImagebase: ")TEXT(PRINTF_DWORD_PTR_FULL), imageBase); StatusBar.SetText(PART_IMAGEBASE, stringBuffer); StatusBar.SetText(PART_MODULE, fileName); StatusBar.SetTipText(PART_MODULE, fileName); } else { StatusBar.SetText(PART_IMAGEBASE, L""); StatusBar.SetText(PART_MODULE, L""); } } bool MainGui::showFileDialog(WCHAR * selectedFile, bool save, const WCHAR * defFileName, const WCHAR * filter, const WCHAR * defExtension, const WCHAR * directory) { OPENFILENAME ofn = {0}; // WTL doesn't support new explorer styles on Vista and up // This is because it uses a custom hook, we could remove it or derive // from CFileDialog but this solution is easier and allows more control anyway (e.g. initial dir) if(defFileName) { wcscpy_s(selectedFile, MAX_PATH, defFileName); } else { selectedFile[0] = _T('\0'); } ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = m_hWnd; ofn.lpstrFilter = filter; ofn.lpstrDefExt = defExtension; // only first 3 chars are used, no dots! ofn.lpstrFile = selectedFile; ofn.lpstrInitialDir = directory; ofn.nMaxFile = MAX_PATH; ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY; /* *OFN_EXPLORER is automatically used, it only has to be specified *if using a custom hook *OFN_LONGNAMES is automatically used by explorer-style dialogs */ if(save) ofn.Flags |= OFN_OVERWRITEPROMPT; else ofn.Flags |= OFN_FILEMUSTEXIST; if(save) return 0 != GetSaveFileName(&ofn); else return 0 != GetOpenFileName(&ofn); } void MainGui::setIconAndDialogCaption() { SetIcon(hIcon, TRUE); SetIcon(hIcon, FALSE); SetWindowText(TEXT(APPNAME)TEXT(" ")TEXT(ARCHITECTURE)TEXT(" ")TEXT(APPVERSION)); } void MainGui::pickDllActionHandler() { if(!selectedProcess) return; - PickDllGui dlgPickDll(processAccessHelp.moduleList); + PickDllGui dlgPickDll(ProcessAccessHelp::moduleList); if(dlgPickDll.DoModal()) { //get selected module - processAccessHelp.selectedModule = dlgPickDll.getSelectedModule(); + ProcessAccessHelp::selectedModule = dlgPickDll.getSelectedModule(); - processAccessHelp.targetImageBase = processAccessHelp.selectedModule->modBaseAddr; + ProcessAccessHelp::targetImageBase = ProcessAccessHelp::selectedModule->modBaseAddr; - Logger::printfDialog(TEXT("->>> Module %s selected."), processAccessHelp.selectedModule->getFilename()); - Logger::printfDialog(TEXT("Imagebase: ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT(" Size: %08X"),processAccessHelp.selectedModule->modBaseAddr,processAccessHelp.selectedModule->modBaseSize); + Logger::printfDialog(TEXT("->>> Module %s selected."), ProcessAccessHelp::selectedModule->getFilename()); + Logger::printfDialog(TEXT("Imagebase: ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT(" Size: %08X"),ProcessAccessHelp::selectedModule->modBaseAddr,ProcessAccessHelp::selectedModule->modBaseSize); } else { - processAccessHelp.selectedModule = 0; + ProcessAccessHelp::selectedModule = 0; } updateStatusBar(); } void MainGui::pickApiActionHandler(CTreeItem item) { if(!importsHandling.isImport(item)) return; // TODO: new node when user picked an API from another DLL? - PickApiGui dlgPickApi(processAccessHelp.moduleList); + PickApiGui dlgPickApi(ProcessAccessHelp::moduleList); if(dlgPickApi.DoModal()) { const ApiInfo* api = dlgPickApi.getSelectedApi(); if(api && api->module) { importsHandling.setImport(item, api->module->getFilename(), api->name, api->ordinal, api->hint, true, api->isForwarded); } } updateStatusBar(); } void MainGui::startDisassemblerGui(CTreeItem selectedTreeNode) { if(!selectedProcess) return; DWORD_PTR address = importsHandling.getApiAddressByNode(selectedTreeNode); if (address) { BYTE test; if(!ProcessAccessHelp::readMemoryFromProcess(address, sizeof(test), &test)) { swprintf_s(stringBuffer, _countof(stringBuffer), TEXT("Can't read memory at ")TEXT(PRINTF_DWORD_PTR_FULL),address); MessageBox(stringBuffer, L"Failure", MB_ICONERROR); } else { DisassemblerGui dlgDisassembler(address); dlgDisassembler.DoModal(); } } } void MainGui::processSelectedActionHandler(int index) { std::vector& processList = processLister.getProcessList(); Process &process = processList.at(index); selectedProcess = 0; clearImportsActionHandler(); Logger::printfDialog(TEXT("Analyzing %s"),process.fullPath); - if (processAccessHelp.hProcess != 0) + if (ProcessAccessHelp::hProcess != 0) { - processAccessHelp.closeProcessHandle(); + ProcessAccessHelp::closeProcessHandle(); apiReader.clearAll(); } - if (!processAccessHelp.openProcessHandle(process.PID)) + if (!ProcessAccessHelp::openProcessHandle(process.PID)) { enableDialogControls(FALSE); Logger::printfDialog(TEXT("Error: Cannot open process handle.")); updateStatusBar(); return; } - processAccessHelp.getProcessModules(process.PID, processAccessHelp.moduleList); + ProcessAccessHelp::getProcessModules(process.PID, ProcessAccessHelp::moduleList); apiReader.readApisFromModuleList(); Logger::printfDialog(TEXT("Loading modules done.")); //TODO improve - processAccessHelp.selectedModule = 0; - processAccessHelp.targetSizeOfImage = process.imageSize; - processAccessHelp.targetImageBase = process.imageBase; + ProcessAccessHelp::selectedModule = 0; + ProcessAccessHelp::targetSizeOfImage = process.imageSize; + ProcessAccessHelp::targetImageBase = process.imageBase; ProcessAccessHelp::getSizeOfImageCurrentProcess(); - process.imageSize = (DWORD)processAccessHelp.targetSizeOfImage; + process.imageSize = (DWORD)ProcessAccessHelp::targetSizeOfImage; Logger::printfDialog(TEXT("Imagebase: ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT(" Size: %08X"),process.imageBase, process.imageSize); process.entryPoint = ProcessAccessHelp::getEntryPointFromFile(process.fullPath); EditOEPAddress.SetValue(process.entryPoint + process.imageBase); selectedProcess = &process; enableDialogControls(TRUE); updateStatusBar(); } void MainGui::fillProcessListComboBox(CComboBox& hCombo) { hCombo.ResetContent(); std::vector& processList = processLister.getProcessListSnapshot(); for (size_t i = 0; i < processList.size(); i++) { swprintf_s(stringBuffer, _countof(stringBuffer),TEXT("0x%04X - %s - %s"),processList[i].PID,processList[i].filename,processList[i].fullPath); hCombo.AddString(stringBuffer); } } void MainGui::addTextToOutputLog(const WCHAR * text) { if (m_hWnd) { ListLog.SetCurSel(ListLog.AddString(text)); } } void MainGui::clearOutputLog() { if (m_hWnd) { ListLog.ResetContent(); } } bool MainGui::saveLogToFile(const WCHAR * file) { const BYTE BOM[] = {0xFF, 0xFE}; // UTF-16 little-endian const WCHAR newLine[] = L"\r\n"; bool success = true; HANDLE hFile = CreateFile(file, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if(hFile != INVALID_HANDLE_VALUE) { ProcessAccessHelp::writeMemoryToFileEnd(hFile, sizeof(BOM), BOM); WCHAR * buffer = 0; size_t bufsize = 0; for(int i = 0; i < ListLog.GetCount(); i++) { size_t size = ListLog.GetTextLen(i); size += _countof(newLine)-1; if(size+1 > bufsize) { bufsize = size+1; delete[] buffer; try { buffer = new WCHAR[bufsize]; } catch(std::bad_alloc&) { buffer = 0; success = false; break; } } ListLog.GetText(i, buffer); wcscat_s(buffer, bufsize, newLine); ProcessAccessHelp::writeMemoryToFileEnd(hFile, (DWORD)(size * sizeof(WCHAR)), buffer); } delete[] buffer; CloseHandle(hFile); } return success; } void MainGui::showInvalidImportsActionHandler() { importsHandling.selectImports(true, false); GotoDlgCtrl(TreeImports); } void MainGui::showSuspectImportsActionHandler() { importsHandling.selectImports(false, true); GotoDlgCtrl(TreeImports); } void MainGui::deleteSelectedImportsActionHandler() { CTreeItem selected = TreeImports.GetFirstSelectedItem(); while(!selected.IsNull()) { if(importsHandling.isModule(selected)) { importsHandling.cutModule(selected); } else { importsHandling.cutImport(selected); } selected = TreeImports.GetNextSelectedItem(selected); } updateStatusBar(); } void MainGui::invalidateSelectedImportsActionHandler() { CTreeItem selected = TreeImports.GetFirstSelectedItem(); while(!selected.IsNull()) { if(importsHandling.isImport(selected)) { importsHandling.invalidateImport(selected); } selected = TreeImports.GetNextSelectedItem(selected); } updateStatusBar(); } void MainGui::loadTreeActionHandler() { if(!selectedProcess) return; WCHAR selectedFilePath[MAX_PATH]; TreeImportExport treeIO; DWORD_PTR addrOEP = 0; DWORD_PTR addrIAT = 0; DWORD sizeIAT = 0; getCurrentModulePath(stringBuffer, _countof(stringBuffer)); if(showFileDialog(selectedFilePath, false, NULL, filterXml, NULL, stringBuffer)) { if(!treeIO.importTreeList(selectedFilePath, importsHandling.moduleList, &addrOEP, &addrIAT, &sizeIAT)) { Logger::printfDialog(TEXT("Loading tree file failed %s"), selectedFilePath); MessageBox(L"Loading tree file failed.", L"Failure", MB_ICONERROR); } else { EditOEPAddress.SetValue(addrOEP); EditIATAddress.SetValue(addrIAT); EditIATSize.SetValue(sizeIAT); importsHandling.displayAllImports(); updateStatusBar(); Logger::printfDialog(TEXT("Loaded tree file %s"), selectedFilePath); Logger::printfDialog(TEXT("-> OEP: ")TEXT(PRINTF_DWORD_PTR_FULL), addrOEP); Logger::printfDialog(TEXT("-> IAT: ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT(" Size: ")TEXT(PRINTF_DWORD_PTR), addrIAT, sizeIAT); } } } void MainGui::saveTreeActionHandler() { if(!selectedProcess) return; WCHAR selectedFilePath[MAX_PATH]; TreeImportExport treeIO; DWORD_PTR addrOEP; DWORD_PTR addrIAT; DWORD sizeIAT; getCurrentModulePath(stringBuffer, _countof(stringBuffer)); if(showFileDialog(selectedFilePath, true, NULL, filterXml, L"xml", stringBuffer)) { addrOEP = EditOEPAddress.GetValue(); addrIAT = EditIATAddress.GetValue(); sizeIAT = EditIATSize.GetValue(); if(!treeIO.exportTreeList(selectedFilePath, importsHandling.moduleList, selectedProcess, addrOEP, addrIAT, sizeIAT)) { Logger::printfDialog(TEXT("Saving tree file failed %s"), selectedFilePath); MessageBox(L"Saving tree file failed.", L"Failure", MB_ICONERROR); } else { Logger::printfDialog(TEXT("Saved tree file %s"), selectedFilePath); } } } void MainGui::iatAutosearchActionHandler() { DWORD_PTR searchAddress = 0; DWORD_PTR addressIAT = 0; DWORD sizeIAT = 0; IATSearch iatSearch; if(!selectedProcess) return; if(EditOEPAddress.GetWindowTextLength() > 0) { searchAddress = EditOEPAddress.GetValue(); if (searchAddress) { if (iatSearch.searchImportAddressTableInProcess(searchAddress, &addressIAT, &sizeIAT)) { - Logger::printfDialog(TEXT("IAT found at VA ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT(" RVA ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT(" Size 0x%04X (%d)"),addressIAT, addressIAT - processAccessHelp.targetImageBase,sizeIAT,sizeIAT); + Logger::printfDialog(TEXT("IAT found at VA ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT(" RVA ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT(" Size 0x%04X (%d)"),addressIAT, addressIAT - ProcessAccessHelp::targetImageBase,sizeIAT,sizeIAT); EditIATAddress.SetValue(addressIAT); EditIATSize.SetValue(sizeIAT); swprintf_s(stringBuffer, _countof(stringBuffer),TEXT("IAT found:\r\n\r\nStart: ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT("\r\nSize: 0x%04X (%d) "),addressIAT,sizeIAT,sizeIAT); MessageBox(stringBuffer, L"IAT found", MB_ICONINFORMATION); } else { Logger::printfDialog(TEXT("IAT not found at OEP ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT("!"),searchAddress); } } } } void MainGui::getImportsActionHandler() { if(!selectedProcess) return; DWORD_PTR addressIAT = EditIATAddress.GetValue(); DWORD sizeIAT = EditIATSize.GetValue(); if (addressIAT && sizeIAT) { apiReader.readAndParseIAT(addressIAT, sizeIAT,importsHandling.moduleList); importsHandling.displayAllImports(); updateStatusBar(); } } void MainGui::SetupImportsMenuItems(CTreeItem item) { bool isItem, isImport = false; isItem = !item.IsNull(); if(isItem) { isImport = importsHandling.isImport(item); } CMenuHandle hSub = hMenuImports.GetSubMenu(0); UINT itemOnly = isItem ? MF_ENABLED : MF_GRAYED; UINT importOnly = isImport ? MF_ENABLED : MF_GRAYED; hSub.EnableMenuItem(ID__INVALIDATE, itemOnly); hSub.EnableMenuItem(ID__DISASSEMBLE, importOnly); hSub.EnableMenuItem(ID__CUTTHUNK, importOnly); hSub.EnableMenuItem(ID__DELETETREENODE, itemOnly); } void MainGui::DisplayContextMenuImports(CWindow hwnd, CPoint pt) { if(TreeImports.GetCount() < 1) return; CTreeItem over, parent; if(pt.x == -1 && pt.y == -1) // invoked by keyboard { CRect pos; over = TreeImports.GetFocusItem(); if(over) { over.EnsureVisible(); over.GetRect(&pos, TRUE); TreeImports.ClientToScreen(&pos); } else { TreeImports.GetWindowRect(&pos); } pt = pos.TopLeft(); } else { // Get item under cursor over = findTreeItem(pt, true); } SetupImportsMenuItems(over); CMenuHandle hSub = hMenuImports.GetSubMenu(0); BOOL menuItem = hSub.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, hwnd); if (menuItem) { if ((menuItem >= PLUGIN_MENU_BASE_ID) && (menuItem <= (int)(PluginLoader::getScyllaPluginList().size() + PluginLoader::getImprecPluginList().size() + PLUGIN_MENU_BASE_ID))) { //wsprintf(stringBuffer, L"%d %s\n",menuItem,pluginList[menuItem - PLUGIN_MENU_BASE_ID].pluginName); //MessageBox(stringBuffer, L"plugin selection"); pluginActionHandler(menuItem); return; } switch (menuItem) { case ID__INVALIDATE: if(importsHandling.isModule(over)) importsHandling.invalidateModule(over); else importsHandling.invalidateImport(over); break; case ID__DISASSEMBLE: startDisassemblerGui(over); break; case ID__EXPANDALLNODES: importsHandling.expandAllTreeNodes(); break; case ID__COLLAPSEALLNODES: importsHandling.collapseAllTreeNodes(); break; case ID__CUTTHUNK: importsHandling.cutImport(over); break; case ID__DELETETREENODE: importsHandling.cutModule(importsHandling.isImport(over) ? over.GetParent() : over); break; } } updateStatusBar(); } void MainGui::DisplayContextMenuLog(CWindow hwnd, CPoint pt) { if(pt.x == -1 && pt.y == -1) // invoked by keyboard { CRect pos; ListLog.GetWindowRect(&pos); pt = pos.TopLeft(); } CMenuHandle hSub = hMenuLog.GetSubMenu(0); BOOL menuItem = hSub.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, hwnd); if (menuItem) { switch (menuItem) { case ID__SAVE: WCHAR selectedFilePath[MAX_PATH]; getCurrentModulePath(stringBuffer, _countof(stringBuffer)); if(showFileDialog(selectedFilePath, true, NULL, filterTxt, L"txt", stringBuffer)) { saveLogToFile(selectedFilePath); } break; case ID__CLEAR: clearOutputLog(); break; } } } void MainGui::appendPluginListToMenu(CMenuHandle hMenu) { std::vector &scyllaPluginList = PluginLoader::getScyllaPluginList(); std::vector &imprecPluginList = PluginLoader::getImprecPluginList(); if (scyllaPluginList.size() > 0) { CMenuHandle newMenu; newMenu.CreatePopupMenu(); for (size_t i = 0; i < scyllaPluginList.size(); i++) { newMenu.AppendMenu(MF_STRING, i + PLUGIN_MENU_BASE_ID, scyllaPluginList[i].pluginName); } hMenu.AppendMenu(MF_MENUBARBREAK); hMenu.AppendMenu(MF_POPUP, newMenu, L"Scylla Plugins"); } if (imprecPluginList.size() > 0) { CMenuHandle newMenu; newMenu.CreatePopupMenu(); for (size_t i = 0; i < imprecPluginList.size(); i++) { newMenu.AppendMenu(MF_STRING, scyllaPluginList.size() + i + PLUGIN_MENU_BASE_ID, imprecPluginList[i].pluginName); } hMenu.AppendMenu(MF_MENUBARBREAK); hMenu.AppendMenu(MF_POPUP, newMenu, L"ImpREC Plugins"); } } void MainGui::dumpActionHandler() { if(!selectedProcess) return; WCHAR selectedFilePath[MAX_PATH]; const WCHAR * fileFilter; const WCHAR * defExtension; PeDump peDump; - if (processAccessHelp.selectedModule) + if (ProcessAccessHelp::selectedModule) { fileFilter = filterDll; defExtension = L"dll"; } else { fileFilter = filterExe; defExtension = L"exe"; } getCurrentModulePath(stringBuffer, _countof(stringBuffer)); if(showFileDialog(selectedFilePath, true, NULL, fileFilter, defExtension, stringBuffer)) { - if (processAccessHelp.selectedModule) + if (ProcessAccessHelp::selectedModule) { //dump DLL - peDump.imageBase = processAccessHelp.selectedModule->modBaseAddr; - peDump.sizeOfImage = processAccessHelp.selectedModule->modBaseSize; + peDump.imageBase = ProcessAccessHelp::selectedModule->modBaseAddr; + peDump.sizeOfImage = ProcessAccessHelp::selectedModule->modBaseSize; //get it from gui peDump.entryPoint = EditOEPAddress.GetValue(); - wcscpy_s(peDump.fullpath, _countof(peDump.fullpath), processAccessHelp.selectedModule->fullPath); + wcscpy_s(peDump.fullpath, _countof(peDump.fullpath), ProcessAccessHelp::selectedModule->fullPath); } else { peDump.imageBase = ProcessAccessHelp::targetImageBase; peDump.sizeOfImage = (DWORD)ProcessAccessHelp::targetSizeOfImage; //get it from gui peDump.entryPoint = EditOEPAddress.GetValue(); wcscpy_s(peDump.fullpath, _countof(peDump.fullpath), selectedProcess->fullPath); } peDump.useHeaderFromDisk = ConfigurationHolder::getConfigObject(USE_PE_HEADER_FROM_DISK)->isTrue(); if (peDump.dumpCompleteProcessToDisk(selectedFilePath)) { Logger::printfDialog(TEXT("Dump success %s"),selectedFilePath); } else { Logger::printfDialog(TEXT("Error: Cannot dump image.")); MessageBox(L"Cannot dump image.", L"Failure", MB_ICONERROR); } } } void MainGui::peRebuildActionHandler() { DWORD newSize = 0; WCHAR selectedFilePath[MAX_PATH]; PeRebuild peRebuild; getCurrentModulePath(stringBuffer, _countof(stringBuffer)); if(showFileDialog(selectedFilePath, false, NULL, filterExeDll, NULL, stringBuffer)) { if (ConfigurationHolder::getConfigObject(CREATE_BACKUP)->isTrue()) { if (!ProcessAccessHelp::createBackupFile(selectedFilePath)) { Logger::printfDialog(TEXT("Creating backup file failed %s"), selectedFilePath); } } LONGLONG fileSize = ProcessAccessHelp::getFileSize(selectedFilePath); LPVOID mapped = peRebuild.createFileMappingViewFull(selectedFilePath); newSize = peRebuild.realignPE(mapped, (DWORD)fileSize); peRebuild.closeAllMappingHandles(); if (newSize < 10) { Logger::printfDialog(TEXT("Rebuild failed %s"), selectedFilePath); MessageBox(L"Rebuild failed.", L"Failure", MB_ICONERROR); } else { peRebuild.truncateFile(selectedFilePath, newSize); Logger::printfDialog(TEXT("Rebuild success %s"), selectedFilePath); Logger::printfDialog(TEXT("-> Old file size 0x%08X new file size 0x%08X (%d %%)"), (DWORD)fileSize, newSize, (DWORD)((newSize * 100) / (DWORD)fileSize) ); } } } void MainGui::dumpFixActionHandler() { if(!selectedProcess) return; if (TreeImports.GetCount() < 2) { Logger::printfDialog(TEXT("Nothing to rebuild")); return; } WCHAR newFilePath[MAX_PATH]; WCHAR selectedFilePath[MAX_PATH]; const WCHAR * fileFilter; - ImportRebuild importRebuild; - - if (processAccessHelp.selectedModule) + if (ProcessAccessHelp::selectedModule) { fileFilter = filterDll; } else { fileFilter = filterExe; } getCurrentModulePath(stringBuffer, _countof(stringBuffer)); if (showFileDialog(selectedFilePath, false, NULL, fileFilter, NULL, stringBuffer)) { wcscpy_s(newFilePath,_countof(newFilePath),selectedFilePath); const WCHAR * extension = 0; WCHAR* dot = wcsrchr(newFilePath, L'.'); if (dot) { *dot = L'\0'; extension = selectedFilePath + (dot - newFilePath); //wcsrchr(selectedFilePath, L'.'); } wcscat_s(newFilePath, _countof(newFilePath), L"_SCY"); if(extension) { wcscat_s(newFilePath, _countof(newFilePath), extension); } + ImportRebuild importRebuild; if (importRebuild.rebuildImportTable(selectedFilePath,newFilePath,importsHandling.moduleList)) { Logger::printfDialog(TEXT("Import Rebuild success %s"), newFilePath); } else { Logger::printfDialog(TEXT("Import Rebuild failed %s"), selectedFilePath); MessageBox(L"Import Rebuild failed", L"Failure", MB_ICONERROR); } } } void MainGui::enableDialogControls(BOOL value) { BOOL valButton = value ? TRUE : FALSE; GetDlgItem(IDC_BTN_PICKDLL).EnableWindow(valButton); GetDlgItem(IDC_BTN_DUMP).EnableWindow(valButton); GetDlgItem(IDC_BTN_FIXDUMP).EnableWindow(valButton); GetDlgItem(IDC_BTN_IATAUTOSEARCH).EnableWindow(valButton); GetDlgItem(IDC_BTN_GETIMPORTS).EnableWindow(valButton); GetDlgItem(IDC_BTN_SUSPECTIMPORTS).EnableWindow(valButton); GetDlgItem(IDC_BTN_INVALIDIMPORTS).EnableWindow(valButton); GetDlgItem(IDC_BTN_CLEARIMPORTS).EnableWindow(valButton); CMenuHandle menu = GetMenu(); UINT valMenu = value ? MF_ENABLED : MF_GRAYED; menu.EnableMenuItem(ID_FILE_DUMP, valMenu); menu.EnableMenuItem(ID_FILE_FIXDUMP, valMenu); menu.EnableMenuItem(ID_IMPORTS_INVALIDATESELECTED, valMenu); menu.EnableMenuItem(ID_IMPORTS_CUTSELECTED, valMenu); menu.EnableMenuItem(ID_IMPORTS_SAVETREE, valMenu); menu.EnableMenuItem(ID_IMPORTS_LOADTREE, valMenu); menu.EnableMenuItem(ID_MISC_DLLINJECTION, valMenu); menu.GetSubMenu(MenuImportsOffsetTrace).EnableMenuItem(MenuImportsTraceOffsetScylla, MF_BYPOSITION | valMenu); menu.GetSubMenu(MenuImportsOffsetTrace).EnableMenuItem(MenuImportsTraceOffsetImpRec, MF_BYPOSITION | valMenu); //not yet implemented GetDlgItem(IDC_BTN_AUTOTRACE).EnableWindow(FALSE); menu.EnableMenuItem(ID_TRACE_AUTOTRACE, MF_GRAYED); } CTreeItem MainGui::findTreeItem(CPoint pt, bool screenCoordinates) { if(screenCoordinates) { TreeImports.ScreenToClient(&pt); } UINT flags; CTreeItem over = TreeImports.HitTest(pt, &flags); if(over) { if(!(flags & TVHT_ONITEM)) { over.m_hTreeItem = NULL; } } return over; } void MainGui::showAboutDialog() { AboutGui dlgAbout; dlgAbout.DoModal(); } void MainGui::dllInjectActionHandler() { if(!selectedProcess) return; WCHAR selectedFilePath[MAX_PATH]; HMODULE hMod = 0; DllInjection dllInjection; getCurrentModulePath(stringBuffer, _countof(stringBuffer)); if (showFileDialog(selectedFilePath, false, NULL, filterDll, NULL, stringBuffer)) { hMod = dllInjection.dllInjection(ProcessAccessHelp::hProcess, selectedFilePath); if (hMod && ConfigurationHolder::getConfigObject(DLL_INJECTION_AUTO_UNLOAD)->isTrue()) { if (!dllInjection.unloadDllInProcess(ProcessAccessHelp::hProcess, hMod)) { Logger::printfDialog(TEXT("DLL unloading failed, target %s"), selectedFilePath); } } if (hMod) { Logger::printfDialog(TEXT("DLL Injection was successful, target %s"), selectedFilePath); } else { Logger::printfDialog(TEXT("DLL Injection failed, target %s"), selectedFilePath); } } } void MainGui::optionsActionHandler() { OptionsGui dlgOptions; dlgOptions.DoModal(); } void MainGui::clearImportsActionHandler() { importsHandling.clearAllImports(); updateStatusBar(); } void MainGui::pluginActionHandler( int menuItem ) { if(!selectedProcess) return; DllInjectionPlugin dllInjectionPlugin; std::vector &scyllaPluginList = PluginLoader::getScyllaPluginList(); std::vector &imprecPluginList = PluginLoader::getImprecPluginList(); menuItem -= PLUGIN_MENU_BASE_ID; dllInjectionPlugin.hProcess = ProcessAccessHelp::hProcess; dllInjectionPlugin.apiReader = &apiReader; if (menuItem < (int)scyllaPluginList.size()) { //scylla plugin dllInjectionPlugin.injectPlugin(scyllaPluginList[menuItem], importsHandling.moduleList,selectedProcess->imageBase, selectedProcess->imageSize); } else { #ifndef _WIN64 menuItem -= (int)scyllaPluginList.size(); //imprec plugin dllInjectionPlugin.injectImprecPlugin(imprecPluginList[menuItem], importsHandling.moduleList,selectedProcess->imageBase, selectedProcess->imageSize); #endif } importsHandling.scanAndFixModuleList(); importsHandling.displayAllImports(); updateStatusBar(); } bool MainGui::getCurrentModulePath(TCHAR * buffer, size_t bufferSize) { if(!selectedProcess) return false; - if(processAccessHelp.selectedModule) + if(ProcessAccessHelp::selectedModule) { - wcscpy_s(buffer, bufferSize, processAccessHelp.selectedModule->fullPath); + wcscpy_s(buffer, bufferSize, ProcessAccessHelp::selectedModule->fullPath); } else { wcscpy_s(buffer, bufferSize, selectedProcess->fullPath); } WCHAR * slash = wcsrchr(buffer, L'\\'); if(slash) { *(slash+1) = L'\0'; } return true; } diff --git a/Scylla/MainGui.h b/Scylla/MainGui.h index 926d065..6c6a199 100644 --- a/Scylla/MainGui.h +++ b/Scylla/MainGui.h @@ -1,297 +1,297 @@ #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 #include // WTL enhanced msg map macros #include // WTL controls #include // WTL dialog data exchange #include "multitree.h" #include "hexedit.h" //#define _CRTDBG_MAP_ALLOC //#include //#include //#include #include "Logger.h" #include "ProcessLister.h" #include "IATSearch.h" #include "PickDllGui.h" #include "ImportsHandling.h" class MainGui : public CDialogImpl, public CWinDataExchange, public CDialogResize, public CMessageFilter { public: enum { IDD = IDD_DLG_MAIN }; // Dialog Data eXchange, attaches/subclasses child controls to wrappers // DDX_CONTROL : subclass // DDX_CONTROL_HANDLE : attach BEGIN_DDX_MAP(MainGui) DDX_CONTROL(IDC_TREE_IMPORTS, TreeImportsSubclass) // needed for message reflection DDX_CONTROL(IDC_TREE_IMPORTS, TreeImports) DDX_CONTROL_HANDLE(IDC_CBO_PROCESSLIST, ComboProcessList) DDX_CONTROL_HANDLE(IDC_LIST_LOG, ListLog) DDX_CONTROL(IDC_EDIT_OEPADDRESS, EditOEPAddress) DDX_CONTROL(IDC_EDIT_IATADDRESS, EditIATAddress) DDX_CONTROL(IDC_EDIT_IATSIZE, EditIATSize) END_DDX_MAP() // Our message map // Messages are passed from top to bottom // The first handler that doesn't call SetMsgHandled(FALSE) aborts the chain // If none signals the message as handled, it will be passed to mixins (CHAIN_MSG_MAP) // or ultimately passed to DefWindowProc BEGIN_MSG_MAP_EX(MainGui) MSG_WM_INITDIALOG(OnInitDialog) MSG_WM_DESTROY(OnDestroy) MSG_WM_SIZE(OnSize) MSG_WM_CONTEXTMENU(OnContextMenu) MSG_WM_COMMAND(OnCommand) NOTIFY_HANDLER_EX(IDC_TREE_IMPORTS, NM_DBLCLK, OnTreeImportsDoubleClick) NOTIFY_HANDLER_EX(IDC_TREE_IMPORTS, TVN_KEYDOWN, OnTreeImportsKeyDown) COMMAND_HANDLER_EX(IDC_CBO_PROCESSLIST, CBN_DROPDOWN, OnProcessListDrop) COMMAND_HANDLER_EX(IDC_CBO_PROCESSLIST, CBN_SELENDOK, OnProcessListSelected) COMMAND_ID_HANDLER_EX(IDC_BTN_PICKDLL, OnPickDLL) COMMAND_ID_HANDLER_EX(IDC_BTN_OPTIONS, OnOptions) COMMAND_ID_HANDLER_EX(IDC_BTN_DUMP, OnDump) COMMAND_ID_HANDLER_EX(IDC_BTN_FIXDUMP, OnFixDump) COMMAND_ID_HANDLER_EX(IDC_BTN_PEREBUILD, OnPERebuild) COMMAND_ID_HANDLER_EX(IDC_BTN_IATAUTOSEARCH, OnIATAutoSearch) COMMAND_ID_HANDLER_EX(IDC_BTN_GETIMPORTS, OnGetImports) COMMAND_ID_HANDLER_EX(IDC_BTN_INVALIDIMPORTS, OnInvalidImports) COMMAND_ID_HANDLER_EX(IDC_BTN_SUSPECTIMPORTS, OnSuspectImports) COMMAND_ID_HANDLER_EX(IDC_BTN_CLEARIMPORTS, OnClearImports) COMMAND_ID_HANDLER_EX(ID_FILE_DUMP, OnDump) COMMAND_ID_HANDLER_EX(ID_FILE_PEREBUILD, OnPERebuild) COMMAND_ID_HANDLER_EX(ID_FILE_FIXDUMP, OnFixDump) COMMAND_ID_HANDLER_EX(ID_FILE_EXIT, OnExit) COMMAND_ID_HANDLER_EX(ID_IMPORTS_SHOWINVALID, OnInvalidImports) COMMAND_ID_HANDLER_EX(ID_IMPORTS_SHOWSUSPECT, OnSuspectImports) COMMAND_ID_HANDLER_EX(ID_IMPORTS_INVALIDATESELECTED, OnInvalidateSelected) COMMAND_ID_HANDLER_EX(ID_IMPORTS_CUTSELECTED, OnCutSelected) COMMAND_ID_HANDLER_EX(ID_IMPORTS_CLEARIMPORTS, OnClearImports) COMMAND_ID_HANDLER_EX(ID_IMPORTS_SAVETREE, OnSaveTree) COMMAND_ID_HANDLER_EX(ID_IMPORTS_LOADTREE, OnLoadTree) COMMAND_ID_HANDLER_EX(ID_TRACE_AUTOTRACE, OnAutotrace) COMMAND_ID_HANDLER_EX(ID_MISC_DLLINJECTION, OnDLLInject) COMMAND_ID_HANDLER_EX(ID_MISC_OPTIONS, OnOptions) COMMAND_ID_HANDLER_EX(ID_HELP_ABOUT, OnAbout) COMMAND_ID_HANDLER_EX(IDCANCEL, OnExit) REFLECT_NOTIFY_ID(IDC_TREE_IMPORTS) // pass WM_NOTIFY to child control CHAIN_MSG_MAP(CDialogResize) // Message map for subclassed treeview // CContainedWindow forwards all messages to this map ALT_MSG_MAP(IDC_TREE_IMPORTS) MSG_WM_GETDLGCODE(OnTreeImportsSubclassGetDlgCode) MSG_WM_CHAR(OnTreeImportsSubclassChar) END_MSG_MAP() // Dialog resize 'table' // States if child controls move or resize or center in a specific direction // when the parent dialog is resized BEGIN_DLGRESIZE_MAP(MainGui) DLGRESIZE_CONTROL(IDC_GROUP_ATTACH, DLSZ_SIZE_X) DLGRESIZE_CONTROL(IDC_CBO_PROCESSLIST, DLSZ_SIZE_X) DLGRESIZE_CONTROL(IDC_BTN_PICKDLL, DLSZ_MOVE_X) DLGRESIZE_CONTROL(IDC_GROUP_IMPORTS, DLSZ_SIZE_X | DLSZ_SIZE_Y) DLGRESIZE_CONTROL(IDC_TREE_IMPORTS, DLSZ_SIZE_X | DLSZ_SIZE_Y) DLGRESIZE_CONTROL(IDC_BTN_INVALIDIMPORTS, DLSZ_MOVE_Y) DLGRESIZE_CONTROL(IDC_BTN_SUSPECTIMPORTS, DLSZ_MOVE_Y) DLGRESIZE_CONTROL(IDC_BTN_CLEARIMPORTS, DLSZ_MOVE_X | DLSZ_MOVE_Y) DLGRESIZE_CONTROL(IDC_GROUP_IATINFO, DLSZ_MOVE_Y) DLGRESIZE_CONTROL(IDC_STATIC_OEPADDRESS, DLSZ_MOVE_Y) DLGRESIZE_CONTROL(IDC_STATIC_IATADDRESS, DLSZ_MOVE_Y) DLGRESIZE_CONTROL(IDC_STATIC_IATSIZE, DLSZ_MOVE_Y) DLGRESIZE_CONTROL(IDC_EDIT_OEPADDRESS, DLSZ_MOVE_Y) DLGRESIZE_CONTROL(IDC_EDIT_IATADDRESS, DLSZ_MOVE_Y) DLGRESIZE_CONTROL(IDC_EDIT_IATSIZE, DLSZ_MOVE_Y) DLGRESIZE_CONTROL(IDC_BTN_IATAUTOSEARCH, DLSZ_MOVE_Y) DLGRESIZE_CONTROL(IDC_BTN_GETIMPORTS, DLSZ_MOVE_Y) DLGRESIZE_CONTROL(IDC_GROUP_ACTIONS, DLSZ_MOVE_Y) DLGRESIZE_CONTROL(IDC_BTN_AUTOTRACE, DLSZ_MOVE_Y) DLGRESIZE_CONTROL(IDC_GROUP_DUMP, DLSZ_MOVE_Y) DLGRESIZE_CONTROL(IDC_BTN_DUMP, DLSZ_MOVE_Y) DLGRESIZE_CONTROL(IDC_BTN_PEREBUILD, DLSZ_MOVE_Y) DLGRESIZE_CONTROL(IDC_BTN_FIXDUMP, DLSZ_MOVE_Y) DLGRESIZE_CONTROL(IDC_GROUP_LOG, DLSZ_MOVE_Y | DLSZ_SIZE_X) DLGRESIZE_CONTROL(IDC_LIST_LOG, DLSZ_MOVE_Y | DLSZ_SIZE_X) END_DLGRESIZE_MAP() MainGui(); void addTextToOutputLog(const WCHAR * text); protected: // Variables ProcessLister processLister; WCHAR stringBuffer[600]; ImportsHandling importsHandling; - ProcessAccessHelp processAccessHelp; + //ProcessAccessHelp processAccessHelp; ApiReader apiReader; Process * selectedProcess; // File selection filters static const WCHAR filterExe[]; static const WCHAR filterDll[]; static const WCHAR filterExeDll[]; static const WCHAR filterTxt[]; static const WCHAR filterXml[]; // Controls CMultiSelectTreeViewCtrl TreeImports; CComboBox ComboProcessList; CHexEdit EditOEPAddress; CHexEdit EditIATAddress; CHexEdit EditIATSize; CListBox ListLog; CStatusBarCtrl StatusBar; enum StatusParts { PART_COUNT = 0, PART_INVALID, PART_IMAGEBASE, PART_MODULE }; CContainedWindow TreeImportsSubclass; // Handles CIcon hIcon; CMenu hMenuImports; CMenu hMenuLog; CAccelerator accelerators; CIcon hIconCheck; CIcon hIconWarning; CIcon hIconError; static const int MenuImportsOffsetTrace = 2; static const int MenuImportsTraceOffsetScylla = 2; static const int MenuImportsTraceOffsetImpRec = 4; protected: virtual BOOL PreTranslateMessage(MSG* pMsg); // Message handlers BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam); void OnDestroy(); void OnSize(UINT nType, CSize size); void OnContextMenu(CWindow wnd, CPoint point); void OnCommand(UINT uNotifyCode, int nID, CWindow wndCtl); // WM_NOTIFY handlers LRESULT OnTreeImportsDoubleClick(const NMHDR* pnmh); LRESULT OnTreeImportsKeyDown(const NMHDR* pnmh); // Forwarded messages from subclassed treeview UINT OnTreeImportsSubclassGetDlgCode(const MSG * lpMsg); void OnTreeImportsSubclassChar(UINT nChar, UINT nRepCnt, UINT nFlags); // WM_COMMAND handlers void OnProcessListDrop(UINT uNotifyCode, int nID, CWindow wndCtl); void OnProcessListSelected(UINT uNotifyCode, int nID, CWindow wndCtl); void OnPickDLL(UINT uNotifyCode, int nID, CWindow wndCtl); void OnOptions(UINT uNotifyCode, int nID, CWindow wndCtl); void OnDump(UINT uNotifyCode, int nID, CWindow wndCtl); void OnFixDump(UINT uNotifyCode, int nID, CWindow wndCtl); void OnPERebuild(UINT uNotifyCode, int nID, CWindow wndCtl); void OnDLLInject(UINT uNotifyCode, int nID, CWindow wndCtl); void OnIATAutoSearch(UINT uNotifyCode, int nID, CWindow wndCtl); void OnGetImports(UINT uNotifyCode, int nID, CWindow wndCtl); void OnInvalidImports(UINT uNotifyCode, int nID, CWindow wndCtl); void OnSuspectImports(UINT uNotifyCode, int nID, CWindow wndCtl); void OnClearImports(UINT uNotifyCode, int nID, CWindow wndCtl); void OnInvalidateSelected(UINT uNotifyCode, int nID, CWindow wndCtl); void OnCutSelected(UINT uNotifyCode, int nID, CWindow wndCtl); void OnSaveTree(UINT uNotifyCode, int nID, CWindow wndCtl); void OnLoadTree(UINT uNotifyCode, int nID, CWindow wndCtl); void OnAutotrace(UINT uNotifyCode, int nID, CWindow wndCtl); void OnExit(UINT uNotifyCode, int nID, CWindow wndCtl); void OnAbout(UINT uNotifyCode, int nID, CWindow wndCtl); // GUI functions bool showFileDialog(WCHAR * selectedFile, bool save, const WCHAR * defFileName, const WCHAR * filter = NULL, const WCHAR * defExtension = NULL, const WCHAR * directory = NULL); void setupStatusBar(); void updateStatusBar(); void fillProcessListComboBox(CComboBox& hCombo); void setIconAndDialogCaption(); void enableDialogControls(BOOL value); CTreeItem findTreeItem(CPoint pt, bool screenCoordinates); // Actions void pickDllActionHandler(); void pickApiActionHandler(CTreeItem item); void processSelectedActionHandler(int index); void showInvalidImportsActionHandler(); void showSuspectImportsActionHandler(); void deleteSelectedImportsActionHandler(); void invalidateSelectedImportsActionHandler(); void loadTreeActionHandler(); void saveTreeActionHandler(); void iatAutosearchActionHandler(); void getImportsActionHandler(); void dumpActionHandler(); void peRebuildActionHandler(); void startDisassemblerGui(CTreeItem selectedTreeNode); void dumpFixActionHandler(); void showAboutDialog(); void dllInjectActionHandler(); void optionsActionHandler(); void clearImportsActionHandler(); void pluginActionHandler(int menuItem); // Popup menu functions void SetupImportsMenuItems(CTreeItem item); void appendPluginListToMenu(CMenuHandle hMenuTrackPopup); void DisplayContextMenuImports(CWindow, CPoint); void DisplayContextMenuLog(CWindow, CPoint); // Log void clearOutputLog(); bool saveLogToFile(const WCHAR * file); // Misc bool getCurrentModulePath(TCHAR * buffer, size_t bufferSize); }; diff --git a/Scylla/ProcessAccessHelp.h b/Scylla/ProcessAccessHelp.h index 2d3e63d..5eb3a93 100644 --- a/Scylla/ProcessAccessHelp.h +++ b/Scylla/ProcessAccessHelp.h @@ -1,202 +1,202 @@ #pragma once #include #include #include #include #include /************************************************************************/ /* distorm */ /************************************************************************/ #include "distorm.h" // The number of the array of instructions the decoder function will use to return the disassembled instructions. // Play with this value for performance... #define MAX_INSTRUCTIONS (200) /************************************************************************/ class ApiInfo; class ModuleInfo { public: WCHAR fullPath[MAX_PATH]; DWORD_PTR modBaseAddr; DWORD modBaseSize; bool isAlreadyParsed; bool parsing; /* for iat rebuilding with duplicate entries: ntdll = low priority kernelbase = low priority SHLWAPI = low priority kernel32 = high priority priority = 1 -> normal/high priority priority = 0 -> low priority */ int priority; std::vector apiList; ModuleInfo() { modBaseAddr = 0; modBaseSize = 0; priority = 1; isAlreadyParsed = false; parsing = false; } const WCHAR * getFilename() const { const WCHAR* slash = wcsrchr(fullPath, L'\\'); if(slash) { return slash+1; } return fullPath; } }; class ApiInfo { public: char name[MAX_PATH]; WORD hint; DWORD_PTR va; DWORD_PTR rva; WORD ordinal; bool isForwarded; ModuleInfo * module; }; class ProcessAccessHelp { public: static HANDLE hProcess; //OpenProcess handle to target process static DWORD_PTR targetImageBase; static DWORD_PTR targetSizeOfImage; static DWORD_PTR maxValidAddress; static ModuleInfo * selectedModule; static std::vector moduleList; //target process module list static std::vector ownModuleList; //own module list static const int PE_HEADER_BYTES_COUNT = 2000; static BYTE fileHeaderFromDisk[PE_HEADER_BYTES_COUNT]; //for decomposer static _DInst decomposerResult[MAX_INSTRUCTIONS]; static unsigned int decomposerInstructionsCount; static _CodeInfo decomposerCi; //distorm :: Decoded instruction information. static _DecodedInst decodedInstructions[MAX_INSTRUCTIONS]; static unsigned int decodedInstructionsCount; #ifdef _WIN64 static const _DecodeType dt = Decode64Bits; #else static const _DecodeType dt = Decode32Bits; #endif /* * Open a new process handle */ static bool openProcessHandle(DWORD dwPID); static HANDLE NativeOpenProcess(DWORD dwDesiredAccess, DWORD dwProcessId); static void closeProcessHandle(); /* * Get all modules from a process */ static bool getProcessModules(DWORD dwPID, std::vector &moduleList); /* * file mapping view with different access level */ static LPVOID createFileMappingViewRead(const WCHAR * filePath); static LPVOID createFileMappingViewFull(const WCHAR * filePath); /* * Create a file mapping view of a file */ static LPVOID createFileMappingView(const WCHAR * filePath, DWORD accessFile, DWORD flProtect, DWORD accessMap); /* * Read memory from target process */ static bool readMemoryFromProcess(DWORD_PTR address, SIZE_T size, LPVOID dataBuffer); /* * Read memory from file */ static bool readMemoryFromFile(HANDLE hFile, LONG offset, DWORD size, LPVOID dataBuffer); /* * Write memory to file */ static bool writeMemoryToFile(HANDLE hFile, LONG offset, DWORD size, LPCVOID dataBuffer); /* * Write memory to file end */ static bool writeMemoryToFileEnd(HANDLE hFile, DWORD size, LPCVOID dataBuffer); /* * Disassemble Memory */ static bool disassembleMemory(BYTE * dataBuffer, SIZE_T bufferSize, DWORD_PTR startOffset); static bool decomposeMemory(BYTE * dataBuffer, SIZE_T bufferSize, DWORD_PTR startAddress); /* * Search for pattern */ static DWORD_PTR findPattern(DWORD_PTR startOffset, DWORD size, BYTE * pattern, const char * mask); /* * Get process ID by process name */ static DWORD getProcessByName(const WCHAR * processName); /* * Get memory region from address */ - bool getMemoryRegionFromAddress(DWORD_PTR address, DWORD_PTR * memoryRegionBase, SIZE_T * memoryRegionSize); + static bool getMemoryRegionFromAddress(DWORD_PTR address, DWORD_PTR * memoryRegionBase, SIZE_T * memoryRegionSize); /* * Read PE Header from file */ static bool readHeaderFromFile(BYTE * buffer, DWORD bufferSize, const WCHAR * filePath); static bool readHeaderFromCurrentFile(const WCHAR * filePath); /* * Get real sizeOfImage value */ static SIZE_T getSizeOfImageProcess(HANDLE processHandle, DWORD_PTR moduleBase); /* * Get real sizeOfImage value current process */ static bool getSizeOfImageCurrentProcess(); static LONGLONG getFileSize(HANDLE hFile); static LONGLONG getFileSize(const WCHAR * filePath); static DWORD getEntryPointFromFile(const WCHAR * filePath); static bool createBackupFile(const WCHAR * filePath); };