diff --git a/Scylla/DisassemblerGui.cpp b/Scylla/DisassemblerGui.cpp index 1018a05..b781e83 100644 --- a/Scylla/DisassemblerGui.cpp +++ b/Scylla/DisassemblerGui.cpp @@ -1,138 +1,133 @@ #include "DisassemblerGui.h" #include "ProcessAccessHelp.h" +DisassemblerGui::DisassemblerGui(DWORD_PTR startAddress) : startAddress(startAddress) +{ + hMenuDisassembler.LoadMenu(IDR_MENU_DISASSEMBLER); +} + BOOL DisassemblerGui::OnInitDialog(CWindow wndFocus, LPARAM lInitParam) { ListDisassembler.Attach(GetDlgItem(IDC_LIST_DISASSEMBLER)); addColumnsToDisassembler(ListDisassembler); displayDisassembly(ListDisassembler); CenterWindow(); return TRUE; } void DisassemblerGui::OnContextMenu(CWindow wnd, CPoint point) { if (wnd.GetDlgCtrlID() == IDC_LIST_DISASSEMBLER) { - CMenuHandle hmenuTrackPopup = getCorrectSubMenu(IDR_MENU_DISASSEMBLER, 0); - - BOOL menuItem = hmenuTrackPopup.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, point.x, point.y, wnd); - hmenuTrackPopup.DestroyMenu(); - - if (menuItem) + if(hMenuDisassembler) { - int selection = ListDisassembler.GetSelectionMark(); - if (selection != -1) //valid selection? + CMenuHandle hSub = hMenuDisassembler.GetSubMenu(0); + + BOOL menuItem = hSub.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, point.x, point.y, wnd); + if (menuItem) { - int column = -1; - switch (menuItem) + int selection = ListDisassembler.GetSelectionMark(); + if (selection != -1) //valid selection? { - case ID__DIS_ADDRESS: - column = COL_ADDRESS; - break; - case ID__DIS_SIZE: - column = COL_INSTRUCTION_SIZE; - break; - case ID__DIS_OPCODES: - column = COL_OPCODES; - break; - case ID__DIS_INSTRUCTIONS: - column = COL_INSTRUCTION; - break; - } - if(column != -1) - { - tempBuffer[0] = '\0'; - ListDisassembler.GetItemText(selection, column, tempBuffer, _countof(tempBuffer)); - copyToClipboard(tempBuffer); + int column = -1; + switch (menuItem) + { + case ID__DIS_ADDRESS: + column = COL_ADDRESS; + break; + case ID__DIS_SIZE: + column = COL_INSTRUCTION_SIZE; + break; + case ID__DIS_OPCODES: + column = COL_OPCODES; + break; + case ID__DIS_INSTRUCTIONS: + column = COL_INSTRUCTION; + break; + } + if(column != -1) + { + tempBuffer[0] = '\0'; + ListDisassembler.GetItemText(selection, column, tempBuffer, _countof(tempBuffer)); + copyToClipboard(tempBuffer); + } } } } } } void DisassemblerGui::OnCancel(UINT uNotifyCode, int nID, CWindow wndCtl) { EndDialog(0); } void DisassemblerGui::addColumnsToDisassembler(CListViewCtrl& list) { list.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT); list.InsertColumn(COL_ADDRESS, L"Address", LVCFMT_LEFT, 105); list.InsertColumn(COL_INSTRUCTION_SIZE, L"Size", LVCFMT_CENTER, 40); list.InsertColumn(COL_OPCODES, L"OpCodes", LVCFMT_LEFT, 130); list.InsertColumn(COL_INSTRUCTION, L"Instructions", LVCFMT_LEFT, 200); } void DisassemblerGui::displayDisassembly(CListViewCtrl& list) { BYTE data[DISASSEMBLER_GUI_MEMORY_SIZE]; list.DeleteAllItems(); if(!ProcessAccessHelp::readMemoryFromProcess(startAddress, sizeof(data), data)) return; ProcessAccessHelp::disassembleMemory(data, sizeof(data), startAddress); for (unsigned int i = 0; i < ProcessAccessHelp::decodedInstructionsCount; i++) { #ifdef _WIN64 swprintf_s(tempBuffer, _countof(tempBuffer),L"%016I64X",ProcessAccessHelp::decodedInstructions[i].offset); #else swprintf_s(tempBuffer, _countof(tempBuffer),L"%08X",ProcessAccessHelp::decodedInstructions[i].offset); #endif list.InsertItem(i, tempBuffer); swprintf_s(tempBuffer, _countof(tempBuffer),L"%02d",ProcessAccessHelp::decodedInstructions[i].size); list.SetItemText(i, COL_INSTRUCTION_SIZE, tempBuffer); swprintf_s(tempBuffer, _countof(tempBuffer),L"%-24S",(char *)ProcessAccessHelp::decodedInstructions[i].instructionHex.p); list.SetItemText(i, COL_OPCODES, tempBuffer); swprintf_s(tempBuffer, _countof(tempBuffer),L"%S%S%S",(char*)ProcessAccessHelp::decodedInstructions[i].mnemonic.p, ProcessAccessHelp::decodedInstructions[i].operands.length != 0 ? " " : "", (char*)ProcessAccessHelp::decodedInstructions[i].operands.p); list.SetItemText(i, COL_INSTRUCTION, tempBuffer); } } void DisassemblerGui::copyToClipboard(const WCHAR * text) { if(OpenClipboard()) { EmptyClipboard(); size_t len = wcslen(text); HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, (len+1)*sizeof(WCHAR)); if(hMem) { wcscpy_s((WCHAR *)GlobalLock(hMem), len+1, text); GlobalUnlock(hMem); if(!SetClipboardData(CF_UNICODETEXT, hMem)) { GlobalFree(hMem); } } CloseClipboard(); } } - -CMenuHandle DisassemblerGui::getCorrectSubMenu(int menuItem, int subMenuItem) -{ - CMenuHandle hmenu; // top-level menu - - // Load the menu resource. - if (!hmenu.LoadMenu(menuItem)) - return NULL; - - return hmenu.GetSubMenu(subMenuItem); -} diff --git a/Scylla/DisassemblerGui.h b/Scylla/DisassemblerGui.h index 9a769cc..db6c388 100644 --- a/Scylla/DisassemblerGui.h +++ b/Scylla/DisassemblerGui.h @@ -1,68 +1,68 @@ #pragma once #include #include "resource.h" // WTL #include // base ATL classes #include // base WTL classes #include // ATL GUI classes #include // WTL utility classes like CString #include // WTL enhanced msg map macros #include // WTL controls class DisassemblerGui : public CDialogImpl { public: enum { IDD = IDD_DLG_DISASSEMBLER }; BEGIN_MSG_MAP(DisassemblerGui) MSG_WM_INITDIALOG(OnInitDialog) MSG_WM_CONTEXTMENU(OnContextMenu) COMMAND_ID_HANDLER_EX(IDCANCEL, OnCancel) END_MSG_MAP() DisassemblerGui(DWORD_PTR startAddress) : startAddress(startAddress) { } protected: // Variables static const size_t DISASSEMBLER_GUI_MEMORY_SIZE = 0x100; WCHAR tempBuffer[100]; DWORD_PTR startAddress; // Controls CListViewCtrl ListDisassembler; enum DisassemblerColumns { COL_ADDRESS, COL_INSTRUCTION_SIZE, COL_OPCODES, COL_INSTRUCTION }; + // Handles + + CMenu hMenuDisassembler; + protected: // Message handlers BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam); void OnContextMenu(CWindow wnd, CPoint point); void OnCancel(UINT uNotifyCode, int nID, CWindow wndCtl); // GUI functions void addColumnsToDisassembler(CListViewCtrl& list); void displayDisassembly(CListViewCtrl& list); - // Popup menu functions - - CMenuHandle getCorrectSubMenu(int menuItem, int subMenuItem); - // Misc void copyToClipboard(const WCHAR * text); }; diff --git a/Scylla/MainGui.cpp b/Scylla/MainGui.cpp index 1d12619..b67fbb8 100644 --- a/Scylla/MainGui.cpp +++ b/Scylla/MainGui.cpp @@ -1,915 +1,918 @@ #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 "NativeWinApi.h" #include "ImportRebuild.h" #include "SystemInformation.h" #include "AboutGui.h" #include "OptionsGui.h" #include "WindowDeferrer.h" MainGui::MainGui() : selectedProcess(0), importsHandling(TreeImports) { Logger::getDebugLogFilePath(); ConfigurationHolder::loadConfiguration(); PluginLoader::findAllPlugins(); NativeWinApi::initialize(); SystemInformation::getSystemInformation(); - hIcon.LoadIcon(IDI_ICON_SCYLLA1); + hIcon.LoadIcon(IDI_ICON_SCYLLA); + hMenuImports.LoadMenu(IDR_MENU_IMPORTS); + hMenuLog.LoadMenu(IDR_MENU_LOG); + + if(hMenuImports) + { + appendPluginListToMenu(hMenuImports.GetSubMenu(0)); + } } BOOL MainGui::OnInitDialog(CWindow wndFocus, LPARAM lInitParam) { if (SystemInformation::currenOS == UNKNOWN_OS) { MessageBox(L"Operating System is not supported", L"Error Operating System", MB_ICONERROR); EndDialog(0); return FALSE; } if(ConfigurationHolder::getConfigObject(DEBUG_PRIVILEGE)->isTrue()) { processLister.setDebugPrivileges(); } processAccessHelp.getProcessModules(GetCurrentProcessId(), processAccessHelp.ownModuleList); TreeImports.Attach(GetDlgItem(IDC_TREE_IMPORTS)); ComboProcessList.Attach(GetDlgItem(IDC_CBO_PROCESSLIST)); ListLog.Attach(GetDlgItem(IDC_LIST_LOG)); EditOEPAddress.Attach(GetDlgItem(IDC_EDIT_OEPADDRESS)); EditIATAddress.Attach(GetDlgItem(IDC_EDIT_IATADDRESS)); EditIATSize.Attach(GetDlgItem(IDC_EDIT_IATSIZE)); EditOEPAddress.LimitText(MAX_HEX_VALUE_EDIT_LENGTH); EditIATAddress.LimitText(MAX_HEX_VALUE_EDIT_LENGTH); EditIATSize.LimitText(MAX_HEX_VALUE_EDIT_LENGTH); enableDialogControls(FALSE); setIconAndDialogCaption(); GetWindowRect(&MinSize); return TRUE; } void MainGui::OnGetMinMaxInfo(MINMAXINFO* lpMMI) { lpMMI->ptMinTrackSize.x = MinSize.right - MinSize.left; lpMMI->ptMinTrackSize.y = MinSize.bottom - MinSize.top; } void MainGui::OnSizing(UINT fwSide, RECT* pRect) { WindowDeferrer::Deferrable controls[] = { {IDC_GROUP_ATTACH, false, false, true, false}, {IDC_CBO_PROCESSLIST, false, false, true, false}, {IDC_BTN_PICKDLL, true, false, false, false}, {IDC_GROUP_IMPORTS, false, false, true, true}, {IDC_TREE_IMPORTS, false, false, true, true}, {IDC_GROUP_IATINFO, false, true, false, false}, {IDC_STATIC_OEPADDRESS, false, true, false, false}, {IDC_STATIC_IATADDRESS, false, true, false, false}, {IDC_STATIC_IATSIZE, false, true, false, false}, {IDC_EDIT_OEPADDRESS, false, true, false, false}, {IDC_EDIT_IATADDRESS, false, true, false, false}, {IDC_EDIT_IATSIZE, false, true, false, false}, {IDC_BTN_IATAUTOSEARCH, false, true, false, false}, {IDC_BTN_GETIMPORTS, false, true, false, false}, {IDC_GROUP_IMPORTSOPTIONS, true, true, false, false}, {IDC_BTN_INVALIDIMPORTS, true, true, false, false}, {IDC_BTN_SUSPECTIMPORTS, true, true, false, false}, {IDC_BTN_CLEARIMPORTS, true, true, false, false}, {IDC_BTN_AUTOTRACE, true, true, false, false}, {IDC_BTN_SAVETREE, true, true, false, false}, {IDC_BTN_LOADTREE, true, true, false, false}, {IDC_GROUP_LOG, false, true, true, false}, {IDC_LIST_LOG, false, true, true, false}, {IDC_GROUP_MISC, true, false, false, true}, {IDC_BTN_DUMP, true, false, false, false}, {IDC_BTN_PEREBUILD, true, false, false, false}, {IDC_BTN_DLLINJECT, true, false, false, false}, {IDC_BTN_FIXDUMP, true, false, false, false} }; // Get size difference RECT rectOld; GetWindowRect(&rectOld); long deltaX = (pRect->right - pRect->left) - (rectOld.right - rectOld.left); long deltaY = (pRect->bottom - pRect->top) - (rectOld.bottom - rectOld.top); WindowDeferrer deferrer(m_hWnd, controls, _countof(controls)); deferrer.defer(deltaX, deltaY); } void MainGui::OnLButtonDown(UINT nFlags, CPoint point) { } void MainGui::OnContextMenu(CWindow wnd, CPoint point) { switch(wnd.GetDlgCtrlID()) { case IDC_TREE_IMPORTS: DisplayContextMenuImports(wnd, point); break; break; case IDC_LIST_LOG: DisplayContextMenuLog(wnd, point); break; //default: // DisplayContextMenu(wnd, point); // break; } } LRESULT MainGui::OnTreeImportsClick(const NMHDR* pnmh) { //Logger::printfDialog(L"NM_CLICK"); return FALSE; } LRESULT MainGui::OnTreeImportsDoubleClick(const NMHDR* pnmh) { //Logger::printfDialog(L"NM_DBLCLK"); return FALSE; } LRESULT MainGui::OnTreeImportsRightClick(const NMHDR* pnmh) { //Logger::printfDialog(L"NM_RCLICK"); /* HTREEITEM selectedTreeNode = TreeImports.GetNextItem(NULL, TVGN_DROPHILITE); if(selectedTreeNode != NULL) { TreeImports.Select(selectedTreeNode, TVGN_CARET); } */ return FALSE; } LRESULT MainGui::OnTreeImportsRightDoubleClick(const NMHDR* pnmh) { //Logger::printfDialog(L"NM_RDBLCLK"); return FALSE; } 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) { - TreeImports.DeleteAllItems(); - importsHandling.moduleList.clear(); + clearImportsActionHandler(); } void MainGui::OnClearLog(UINT uNotifyCode, int nID, CWindow wndCtl) { clearOutputLog(); } void MainGui::OnExit(UINT uNotifyCode, int nID, CWindow wndCtl) { EndDialog(0); } void MainGui::OnAbout(UINT uNotifyCode, int nID, CWindow wndCtl) { showAboutDialog(); } void MainGui::setIconAndDialogCaption() { if(hIcon) { SetIcon(hIcon, TRUE); SetIcon(hIcon, FALSE); } SetWindowText(TEXT(APPNAME)TEXT(" ")TEXT(ARCHITECTURE)TEXT(" ")TEXT(APPVERSION)); } void MainGui::pickDllActionHandler() { PickDllGui dlgPickDll(processAccessHelp.moduleList); if(dlgPickDll.DoModal()) { //get selected module processAccessHelp.selectedModule = dlgPickDll.getSelectedModule(); 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; } } void MainGui::startDisassemblerGui(CTreeItem selectedTreeNode) { DWORD_PTR address = importsHandling.getApiAddressByNode(selectedTreeNode); if (address) { DisassemblerGui dlgDisassembler(address); dlgDisassembler.DoModal(); } } void MainGui::processSelectedActionHandler(int index) { std::vector& processList = processLister.getProcessList(); Process &process = processList.at(index); selectedProcess = &process; + clearImportsActionHandler(); enableDialogControls(TRUE); Logger::printfDialog(TEXT("Analyzing %s"),process.fullPath); if (processAccessHelp.hProcess != 0) { processAccessHelp.closeProcessHandle(); apiReader.clearAll(); } if (!processAccessHelp.openProcessHandle(process.PID)) { Logger::printfDialog(TEXT("Error: Cannot open process handle.")); return; } 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::getSizeOfImageCurrentProcess(); process.imageSize = (DWORD)processAccessHelp.targetSizeOfImage; Logger::printfDialog(TEXT("Imagebase: ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT(" Size: %08X"),process.imageBase, process.imageSize); selectedProcess->entryPoint = ProcessAccessHelp::getEntryPointFromFile(selectedProcess->fullPath); swprintf_s(stringBuffer, _countof(stringBuffer),TEXT(PRINTF_DWORD_PTR_FULL),selectedProcess->entryPoint + selectedProcess->imageBase); EditOEPAddress.SetWindowText(stringBuffer); } 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(); } } void MainGui::showInvalidImportsActionHandler() { importsHandling.showImports(true, false); } void MainGui::showSuspectImportsActionHandler() { importsHandling.showImports(false, true); } void MainGui::iatAutosearchActionHandler() { DWORD_PTR searchAddress = 0; DWORD_PTR addressIAT = 0; DWORD sizeIAT = 0; IATSearch iatSearch; if(EditOEPAddress.GetWindowText(stringBuffer, _countof(stringBuffer)) > 1) { searchAddress = stringToDwordPtr(stringBuffer); 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); swprintf_s(stringBuffer, _countof(stringBuffer),TEXT(PRINTF_DWORD_PTR_FULL),addressIAT); EditIATAddress.SetWindowText(stringBuffer); swprintf_s(stringBuffer, _countof(stringBuffer),TEXT("%08X"),sizeIAT); EditIATSize.SetWindowText(stringBuffer); swprintf_s(stringBuffer, _countof(stringBuffer),TEXT("IAT found! Start Address ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT(" Size 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() { DWORD_PTR addressIAT = 0; DWORD sizeIAT = 0; if (EditIATAddress.GetWindowText(stringBuffer, _countof(stringBuffer)) > 0) { addressIAT = stringToDwordPtr(stringBuffer); } if (EditIATSize.GetWindowText(stringBuffer, _countof(stringBuffer)) > 0) { sizeIAT = wcstoul(stringBuffer, NULL, 16); } if (addressIAT && sizeIAT) { apiReader.readAndParseIAT(addressIAT, sizeIAT,importsHandling.moduleList); importsHandling.displayAllImports(); } } DWORD_PTR MainGui::stringToDwordPtr(const WCHAR * hexString) { DWORD_PTR address = 0; #ifdef _WIN64 address = _wcstoui64(hexString, NULL, 16); #else address = wcstoul(hexString, NULL, 16); #endif if (address == 0) { #ifdef DEBUG_COMMENTS Logger::debugLog(L"stringToDwordPtr :: address == 0, %s",hexString); #endif return 0; } else { return address; } } +void MainGui::SetupImportsMenuItems(bool isItem, bool isThunk) +{ + // assert(!(!isItem && isThunk)); + + CMenuHandle hSub = hMenuImports.GetSubMenu(0); + + UINT itemOnly = isItem ? MF_ENABLED : MF_GRAYED; + UINT thunkOnly = isThunk ? MF_ENABLED : MF_GRAYED; + + hSub.EnableMenuItem(ID__INVALIDATEFUNCTION, thunkOnly); + hSub.EnableMenuItem(ID__DISASSEMBLE, thunkOnly); + hSub.EnableMenuItem(ID__CUTTHUNK, thunkOnly); + + hSub.EnableMenuItem(ID__DELETETREENODE, itemOnly); +} + void MainGui::DisplayContextMenuImports(CWindow hwnd, CPoint pt) { if(TreeImports.GetCount() < 1) return; // Get item under cursor CPoint client(pt); CWindow(GetDesktopWindow()).MapWindowPoints(TreeImports, &client, 1); // pt is screen, we need client UINT flags; CTreeItem over = TreeImports.HitTest(client, &flags); CTreeItem parent; if(over) { if(!(flags & TVHT_ONITEM)) { over = NULL; } else { parent = TreeImports.GetParentItem(over); } } - CMenuHandle hmenuTrackPopup = getCorrectSubMenu(IDR_MENU_IMPORTS, 0); - if (hmenuTrackPopup) + if (hMenuImports) { - if(!over) - { - hmenuTrackPopup.EnableMenuItem(ID__INVALIDATEFUNCTION, MF_GRAYED); - hmenuTrackPopup.EnableMenuItem(ID__DISASSEMBLE, MF_GRAYED); - hmenuTrackPopup.EnableMenuItem(ID__CUTTHUNK, MF_GRAYED); - hmenuTrackPopup.EnableMenuItem(ID__DELETETREENODE, MF_GRAYED); - } - else if(!parent) // root element - { - hmenuTrackPopup.EnableMenuItem(ID__INVALIDATEFUNCTION, MF_GRAYED); - hmenuTrackPopup.EnableMenuItem(ID__DISASSEMBLE, MF_GRAYED); - hmenuTrackPopup.EnableMenuItem(ID__CUTTHUNK, MF_GRAYED); - } + // Prepare hmenuImports + SetupImportsMenuItems(!over.IsNull(), !parent.IsNull()); - appendPluginListToMenu(hmenuTrackPopup); + CMenuHandle hSub = hMenuImports.GetSubMenu(0); - BOOL menuItem = hmenuTrackPopup.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, hwnd); - hmenuTrackPopup.DestroyMenu(); + 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__INVALIDATEFUNCTION: importsHandling.invalidateFunction(over); break; case ID__DISASSEMBLE: startDisassemblerGui(over); break; case ID__EXPANDALLNODES: importsHandling.expandAllTreeNodes(); break; case ID__COLLAPSEALLNODES: importsHandling.collapseAllTreeNodes(); break; case ID__CUTTHUNK: importsHandling.cutThunk(over); break; case ID__DELETETREENODE: importsHandling.deleteTreeNode(parent ? parent : over); break; } } } } void MainGui::DisplayContextMenuLog(CWindow hwnd, CPoint pt) { - CMenuHandle hmenuTrackPopup = getCorrectSubMenu(IDR_MENU_LOG, 0); - if (hmenuTrackPopup) + if (hMenuLog) { - BOOL menuItem = hmenuTrackPopup.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, hwnd); - hmenuTrackPopup.DestroyMenu(); + 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__CLEAR: clearOutputLog(); break; } } } } -CMenuHandle MainGui::getCorrectSubMenu(int menuItem, int subMenuItem) -{ - CMenuHandle hmenu; // top-level menu - - // Load the menu resource. - if (!hmenu.LoadMenu(menuItem)) - return NULL; - - return hmenu.GetSubMenu(subMenuItem); -} - /* void MainGui::DisplayContextMenu(CWindow hwnd, CPoint pt) { CMenu hmenu; // top-level menu CMenuHandle hmenuTrackPopup; // shortcut menu int menuItem; // selected menu item // Load the menu resource. if (!hmenu.LoadMenu(IDR_MENU_IMPORTS)) return; // TrackPopupMenu cannot display the menu bar so get // a handle to the first shortcut menu. hmenuTrackPopup = hmenu.GetSubMenu(0); // Display the shortcut menu. Track the right mouse // button. if (!hmenuTrackPopup) { MessageBox(L"hmenuTrackPopup == null", L"hmenuTrackPopup"); } menuItem = hmenuTrackPopup.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, hwnd); if (menuItem) { if (menuItem == ID_LISTCONTROL_SHOWEXPORTS) { //MessageBox(L"exports",L"dshhhhh"); } } } */ void MainGui::appendPluginListToMenu(CMenuHandle hMenuTrackPopup) { 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); } hMenuTrackPopup.AppendMenu(MF_MENUBARBREAK); hMenuTrackPopup.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); } hMenuTrackPopup.AppendMenu(MF_MENUBARBREAK); hMenuTrackPopup.AppendMenu(MF_POPUP, newMenu, L"ImpREC Plugins"); } } void MainGui::dumpActionHandler() { if(!selectedProcess) return; WCHAR * targetFile = 0; PeDump peDump; if (processAccessHelp.selectedModule) { targetFile = ProcessAccessHelp::selectFile(ProcessAccessHelp::fileDll, true); } else { targetFile = ProcessAccessHelp::selectFile(ProcessAccessHelp::fileExe, true); } if (targetFile) { if (processAccessHelp.selectedModule) { //dump DLL peDump.imageBase = processAccessHelp.selectedModule->modBaseAddr; peDump.sizeOfImage = processAccessHelp.selectedModule->modBaseSize; //get it from gui peDump.entryPoint = getOEPFromGui(); wcscpy_s(peDump.fullpath, MAX_PATH, processAccessHelp.selectedModule->fullPath); } else { peDump.imageBase = ProcessAccessHelp::targetImageBase; peDump.sizeOfImage = (DWORD)ProcessAccessHelp::targetSizeOfImage; //get it from gui peDump.entryPoint = getOEPFromGui(); wcscpy_s(peDump.fullpath, MAX_PATH, selectedProcess->fullPath); } peDump.useHeaderFromDisk = ConfigurationHolder::getConfigObject(USE_PE_HEADER_FROM_DISK)->isTrue(); if (peDump.dumpCompleteProcessToDisk(targetFile)) { Logger::printfDialog(TEXT("Dump success %s"),targetFile); //MessageBox(L"Image dumped successfully.", L"Success"); } else { Logger::printfDialog(TEXT("Error: Cannot dump image.")); MessageBox(L"Cannot dump image.", L"Failure", MB_ICONERROR); } delete [] targetFile; } } DWORD_PTR MainGui::getOEPFromGui() { if (EditOEPAddress.GetWindowText(stringBuffer, _countof(stringBuffer)) > 0) { return stringToDwordPtr(stringBuffer); } else { return 0; } } void MainGui::peRebuildActionHandler() { DWORD newSize = 0; WCHAR * targetFile = 0; PeRebuild peRebuild; targetFile = ProcessAccessHelp::selectFile(ProcessAccessHelp::fileExeDll, false); if (targetFile) { if (ConfigurationHolder::getConfigObject(CREATE_BACKUP)->isTrue()) { if (!ProcessAccessHelp::createBackupFile(targetFile)) { Logger::printfDialog(TEXT("Creating backup file failed %s"), targetFile); } } LONGLONG fileSize = ProcessAccessHelp::getFileSize(targetFile); LPVOID mapped = peRebuild.createFileMappingViewFull(targetFile); newSize = peRebuild.realignPE(mapped, (DWORD)fileSize); peRebuild.closeAllMappingHandles(); if (newSize < 10) { Logger::printfDialog(TEXT("Rebuild failed %s"), targetFile); MessageBox(L"Rebuild failed.", L"Failure", MB_ICONERROR); } else { peRebuild.truncateFile(targetFile, newSize); Logger::printfDialog(TEXT("Rebuild success %s"), targetFile); Logger::printfDialog(TEXT("-> Old file size 0x%08X new file size 0x%08X (%d %%)"), (DWORD)fileSize, newSize, (DWORD)((newSize * 100) / (DWORD)fileSize) ); //MessageBox(L"Image rebuilded successfully.", L"Success", MB_ICONINFORMATION); } delete [] targetFile; } } void MainGui::dumpFixActionHandler() { if(!selectedProcess) return; WCHAR * targetFile = 0; WCHAR newFilePath[MAX_PATH]; ImportRebuild importRebuild; if (TreeImports.GetCount() < 2) { Logger::printfDialog(TEXT("Nothing to rebuild")); return; } if (processAccessHelp.selectedModule) { targetFile = ProcessAccessHelp::selectFile(ProcessAccessHelp::fileDll, false); } else { targetFile = ProcessAccessHelp::selectFile(ProcessAccessHelp::fileExe, false); } if (targetFile) { wcscpy_s(newFilePath,MAX_PATH,targetFile); WCHAR* dot = wcsrchr(newFilePath, L'.'); if (dot) { *dot = L'\0'; } if (processAccessHelp.selectedModule) { wcscat_s(newFilePath,MAX_PATH, L"_SCY.dll"); } else { wcscat_s(newFilePath,MAX_PATH, L"_SCY.exe"); } - if (importRebuild.rebuildImportTable(targetFile,newFilePath,importsHandling.moduleList)) { //MessageBox(L"Imports rebuilding successful", L"Success", MB_ICONINFORMATION); Logger::printfDialog(TEXT("Import Rebuild success %s"), newFilePath); } else { Logger::printfDialog(TEXT("Import Rebuild failed, target %s"), targetFile); MessageBox(L"Imports rebuilding failed", L"Failure", MB_ICONERROR); } delete [] targetFile; } } void MainGui::enableDialogControls(BOOL value) { GetDlgItem(IDC_BTN_PICKDLL).EnableWindow(value); GetDlgItem(IDC_BTN_DUMP).EnableWindow(value); GetDlgItem(IDC_BTN_DLLINJECT).EnableWindow(value); GetDlgItem(IDC_BTN_FIXDUMP).EnableWindow(value); GetDlgItem(IDC_BTN_IATAUTOSEARCH).EnableWindow(value); GetDlgItem(IDC_BTN_GETIMPORTS).EnableWindow(value); GetDlgItem(IDC_BTN_SUSPECTIMPORTS).EnableWindow(value); GetDlgItem(IDC_BTN_INVALIDIMPORTS).EnableWindow(value); GetDlgItem(IDC_BTN_CLEARIMPORTS).EnableWindow(value); CMenuHandle menu = GetMenu(); menu.EnableMenuItem(ID_FILE_DUMP, value ? MF_ENABLED : MF_GRAYED); menu.EnableMenuItem(ID_FILE_FIXDUMP, value ? MF_ENABLED : MF_GRAYED); menu.EnableMenuItem(ID_MISC_DLLINJECTION, value ? MF_ENABLED : MF_GRAYED); //not yet implemented GetDlgItem(IDC_BTN_AUTOTRACE).EnableWindow(FALSE); GetDlgItem(IDC_BTN_SAVETREE).EnableWindow(FALSE); GetDlgItem(IDC_BTN_LOADTREE).EnableWindow(FALSE); menu.EnableMenuItem(ID_MISC_SAVETREE, MF_GRAYED); menu.EnableMenuItem(ID_MISC_LOADTREE, MF_GRAYED); } void MainGui::showAboutDialog() { AboutGui dlgAbout; dlgAbout.DoModal(); } void MainGui::dllInjectActionHandler() { if(!selectedProcess) return; WCHAR * targetFile = 0; HMODULE hMod = 0; DllInjection dllInjection; targetFile = ProcessAccessHelp::selectFile(ProcessAccessHelp::fileDll, false); if (targetFile) { hMod = dllInjection.dllInjection(ProcessAccessHelp::hProcess, targetFile); if (hMod && ConfigurationHolder::getConfigObject(DLL_INJECTION_AUTO_UNLOAD)->isTrue()) { if (!dllInjection.unloadDllInProcess(ProcessAccessHelp::hProcess, hMod)) { Logger::printfDialog(TEXT("DLL unloading failed, target %s"), targetFile); } } if (hMod) { Logger::printfDialog(TEXT("DLL Injection was successful, target %s"), targetFile); } else { Logger::printfDialog(TEXT("DLL Injection failed, target %s"), targetFile); } delete [] targetFile; } } void MainGui::optionsActionHandler() { OptionsGui dlgOptions; dlgOptions.DoModal(); } +void MainGui::clearImportsActionHandler() +{ + TreeImports.DeleteAllItems(); + importsHandling.moduleList.clear(); +} + 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(); } diff --git a/Scylla/MainGui.h b/Scylla/MainGui.h index 7d73dbe..8a0b7a6 100644 --- a/Scylla/MainGui.h +++ b/Scylla/MainGui.h @@ -1,182 +1,185 @@ #pragma once #include #include "resource.h" // WTL #include // base ATL classes #include // base WTL classes #include // ATL GUI classes #include // WTL utility classes like CString #include // WTL enhanced msg map macros #include // WTL controls //#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: enum { IDD = IDD_DLG_MAIN }; BEGIN_MSG_MAP(MainGui) MSG_WM_INITDIALOG(OnInitDialog) MSG_WM_GETMINMAXINFO(OnGetMinMaxInfo) MSG_WM_SIZING(OnSizing) MSG_WM_CONTEXTMENU(OnContextMenu) MSG_WM_LBUTTONDOWN(OnLButtonDown) //MSG_WM_ENTERSIZEMOVE(OnEnterSizeMove) //MSG_WM_EXITSIZEMOVE(OnExitSizeMove) NOTIFY_HANDLER_EX(IDC_TREE_IMPORTS, NM_CLICK, OnTreeImportsClick) NOTIFY_HANDLER_EX(IDC_TREE_IMPORTS, NM_DBLCLK, OnTreeImportsDoubleClick) NOTIFY_HANDLER_EX(IDC_TREE_IMPORTS, NM_RCLICK, OnTreeImportsRightClick) NOTIFY_HANDLER_EX(IDC_TREE_IMPORTS, NM_RDBLCLK, OnTreeImportsRightDoubleClick) 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_DLLINJECT, OnDLLInject) 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_MISC_DLLINJECTION, OnDLLInject) COMMAND_ID_HANDLER_EX(ID_MISC_PREFERENCES, OnOptions) COMMAND_ID_HANDLER_EX(ID_HELP_ABOUT, OnAbout) COMMAND_ID_HANDLER_EX(IDCANCEL, OnExit) END_MSG_MAP() MainGui(); //Output Window void addTextToOutputLog(const WCHAR * text); protected: // Variables ProcessLister processLister; WCHAR stringBuffer[600]; ImportsHandling importsHandling; ProcessAccessHelp processAccessHelp; ApiReader apiReader; Process * selectedProcess; // Controls CTreeViewCtrl TreeImports; CComboBox ComboProcessList; CEdit EditOEPAddress; CEdit EditIATAddress; CEdit EditIATSize; CListBox ListLog; RECT MinSize; // Handles CIcon hIcon; + CMenu hMenuImports; + CMenu hMenuLog; protected: // Message handlers BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam); void OnGetMinMaxInfo(MINMAXINFO* lpMMI); void OnSizing(UINT fwSide, RECT* pRect); //void OnEnterSizeMove(); //void OnExitSizeMove(); void OnLButtonDown(UINT nFlags, CPoint point); void OnContextMenu(CWindow wnd, CPoint point); LRESULT OnTreeImportsClick(const NMHDR* pnmh); LRESULT OnTreeImportsDoubleClick(const NMHDR* pnmh); LRESULT OnTreeImportsRightClick(const NMHDR* pnmh); LRESULT OnTreeImportsRightDoubleClick(const NMHDR* pnmh); 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 OnClearLog(UINT uNotifyCode, int nID, CWindow wndCtl); void OnExit(UINT uNotifyCode, int nID, CWindow wndCtl); void OnAbout(UINT uNotifyCode, int nID, CWindow wndCtl); // GUI functions void setIconAndDialogCaption(); void fillProcessListComboBox(CComboBox& hCombo); //static bool displayModuleList(HWND hWndDlg, HWND hList, LRESULT index); // Actions void pickDllActionHandler(); void processSelectedActionHandler(int index); void showInvalidImportsActionHandler(); void showSuspectImportsActionHandler(); void iatAutosearchActionHandler(); void getImportsActionHandler(); void appendPluginListToMenu(CMenuHandle hMenuTrackPopup); void dumpActionHandler(); DWORD_PTR getOEPFromGui(); void peRebuildActionHandler(); void startDisassemblerGui(CTreeItem selectedTreeNode); void dumpFixActionHandler(); void enableDialogControls(BOOL value); void showAboutDialog(); void dllInjectActionHandler(); void optionsActionHandler(); + void clearImportsActionHandler(); void pluginActionHandler(int menuItem); // Popup menu functions //void DisplayContextMenu(CWindow, CPoint); + void SetupImportsMenuItems(bool isItem, bool isThunk); void DisplayContextMenuImports(CWindow, CPoint); void DisplayContextMenuLog(CWindow, CPoint); - CMenuHandle getCorrectSubMenu(int, int); // Misc - + void clearOutputLog();//Output Window static DWORD_PTR stringToDwordPtr(const WCHAR * hexString); }; diff --git a/Scylla/PickDllGui.cpp b/Scylla/PickDllGui.cpp index 076a0c9..f5905ed 100644 --- a/Scylla/PickDllGui.cpp +++ b/Scylla/PickDllGui.cpp @@ -1,113 +1,113 @@ #include "PickDllGui.h" #include "WindowDeferrer.h" PickDllGui::PickDllGui(std::vector &moduleList) : moduleList(moduleList) { selectedModule = 0; - hIcon.LoadIcon(IDI_ICON_SCYLLA1); + hIcon.LoadIcon(IDI_ICON_SCYLLA); } BOOL PickDllGui::OnInitDialog(CWindow wndFocus, LPARAM lInitParam) { ListDLLSelect.Attach(GetDlgItem(IDC_LIST_DLLSELECT)); addColumnsToModuleList(ListDLLSelect); displayModuleList(ListDLLSelect); CenterWindow(); if(hIcon) { SetIcon(hIcon, TRUE); SetIcon(hIcon, FALSE); } GetWindowRect(&MinSize); return TRUE; } void PickDllGui::OnGetMinMaxInfo(MINMAXINFO* lpMMI) { lpMMI->ptMinTrackSize.x = MinSize.right - MinSize.left; lpMMI->ptMinTrackSize.y = MinSize.bottom - MinSize.top; } void PickDllGui::OnSizing(UINT fwSide, RECT* pRect) { int toResize[] = {IDC_LIST_DLLSELECT}; int toMove[] = {IDC_BTN_PICKDLL_OK, IDC_BTN_PICKDLL_CANCEL}; WindowDeferrer::Deferrable controls[] = { {IDC_LIST_DLLSELECT, false, false, true, true}, {IDC_BTN_PICKDLL_OK, true, true, false, false}, {IDC_BTN_PICKDLL_CANCEL, true, true, false, false}, }; // Get size difference RECT rectOld; GetWindowRect(&rectOld); long deltaX = (pRect->right - pRect->left) - (rectOld.right - rectOld.left); long deltaY = (pRect->bottom - pRect->top) - (rectOld.bottom - rectOld.top); WindowDeferrer deferrer(m_hWnd, controls, _countof(controls)); deferrer.defer(deltaX, deltaY); } void PickDllGui::OnOK(UINT uNotifyCode, int nID, CWindow wndCtl) { int index = ListDLLSelect.GetSelectionMark(); if (index != -1) { selectedModule = &moduleList[index]; EndDialog(1); } } void PickDllGui::OnCancel(UINT uNotifyCode, int nID, CWindow wndCtl) { EndDialog(0); } void PickDllGui::addColumnsToModuleList(CListViewCtrl& list) { list.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT); list.InsertColumn(COL_PATH, L"Path", LVCFMT_LEFT, 210); list.InsertColumn(COL_NAME, L"Name", LVCFMT_CENTER, 130); list.InsertColumn(COL_IMAGEBASE, L"ImageBase", LVCFMT_CENTER, 70); list.InsertColumn(COL_IMAGESIZE, L"ImageSize", LVCFMT_CENTER, 70); } void PickDllGui::displayModuleList(CListViewCtrl& list) { WCHAR temp[20]; list.DeleteAllItems(); std::vector::const_iterator iter; int count = 0; for( iter = moduleList.begin(); iter != moduleList.end(); iter++ , count++) { list.InsertItem(count, iter->fullPath); list.SetItemText(count, COL_NAME, iter->getFilename()); swprintf_s(temp,_countof(temp),L"%08X",iter->modBaseAddr); list.SetItemText(count, COL_IMAGEBASE, temp); swprintf_s(temp,_countof(temp),L"%08X",iter->modBaseSize); list.SetItemText(count, COL_IMAGESIZE, temp); } //list.SetColumnWidth(COL_PATH, LVSCW_AUTOSIZE); list.SetColumnWidth(COL_NAME, LVSCW_AUTOSIZE); //list.SetColumnWidth(COL_IMAGEBASE, LVSCW_AUTOSIZE); list.SetColumnWidth(COL_IMAGESIZE, LVSCW_AUTOSIZE_USEHEADER); //m_hotkeysListView.SetColumnWidth(1, LVSCW_AUTOSIZE_USEHEADER); } diff --git a/Scylla/resource.h b/Scylla/resource.h index 8b10590..93d0ba8 100644 Binary files a/Scylla/resource.h and b/Scylla/resource.h differ