diff --git a/Scylla/ImportsHandling.cpp b/Scylla/ImportsHandling.cpp index 246c871..6576f9f 100644 --- a/Scylla/ImportsHandling.cpp +++ b/Scylla/ImportsHandling.cpp @@ -1,825 +1,834 @@ #include "ImportsHandling.h" #include "definitions.h" //#define DEBUG_COMMENTS bool ImportModuleThunk::isValid() { std::map::iterator iterator = thunkList.begin(); while (iterator != thunkList.end()) { if (iterator->second.valid == false) { return false; } iterator++; } return true; } DWORD_PTR ImportModuleThunk::getFirstThunk() { if (thunkList.size() > 0) { std::map::iterator iterator = thunkList.begin(); return iterator->first; } else { return 0; } } /*bool ImportsHandling::addModule(WCHAR * moduleName, DWORD_PTR firstThunk) { ImportModuleThunk module; module.firstThunk = firstThunk; wcscpy_s(module.moduleName, MAX_PATH, moduleName); moduleList.insert(std::pair(firstThunk,module)); return true; }*/ /*bool ImportsHandling::addFunction(WCHAR * moduleName, char * name, DWORD_PTR va, DWORD_PTR rva, DWORD_PTR ordinal, bool valid, bool suspect) { ImportThunk import; ImportModuleThunk * module = 0; std::map::iterator iterator1; if (moduleList.size() > 1) { iterator1 = moduleList.begin(); while (iterator1 != moduleList.end()) { if (rva >= iterator1->second.firstThunk) { iterator1++; if (iterator1 == moduleList.end()) { iterator1--; module = &(iterator1->second); break; } else if (rva < iterator1->second.firstThunk) { iterator1--; module = &(iterator1->second); break; } } } } else { iterator1 = moduleList.begin(); module = &(iterator1->second); } if (!module) { Logger::debugLog(TEXT("ImportsHandling::addFunction module not found rva ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT(""),rva); return false; } //TODO import.suspect = true; import.valid = false; import.va = va; import.rva = rva; import.ordinal = ordinal; wcscpy_s(import.moduleName, MAX_PATH, moduleName); strcpy_s(import.name, MAX_PATH, name); module->thunkList.insert(std::pair(import.rva, import)); return true; }*/ void ImportsHandling::displayAllImports() { std::map::iterator iterator1; std::map::iterator iterator2; ImportModuleThunk * moduleThunk; ImportThunk * importThunk; HTREEITEM module; HTREEITEM apiFunction; - HWND idTreeView = GetDlgItem(hWndMainDlg, IDC_TREE_IMPORTS); + //HWND idTreeView = GetDlgItem(hWndMainDlg, IDC_TREE_IMPORTS); - TreeView_DeleteAllItems(idTreeView); + //TreeView_DeleteAllItems(idTreeView); + + TreeImports.DeleteAllItems(); iterator1 = moduleList.begin(); while (iterator1 != moduleList.end()) { moduleThunk = &(iterator1->second); - module = addDllToTreeView(idTreeView,moduleThunk->moduleName,moduleThunk->firstThunk,moduleThunk->thunkList.size(),moduleThunk->isValid()); + module = addDllToTreeView(TreeImports/*idTreeView*/,moduleThunk->moduleName,moduleThunk->firstThunk,moduleThunk->thunkList.size(),moduleThunk->isValid()); moduleThunk->hTreeItem = module; iterator2 = moduleThunk->thunkList.begin(); while (iterator2 != moduleThunk->thunkList.end()) { importThunk = &(iterator2->second); - apiFunction = addApiToTreeView(idTreeView,module,importThunk); + apiFunction = addApiToTreeView(TreeImports/*idTreeView*/,module,importThunk); importThunk->hTreeItem = apiFunction; iterator2++; } iterator1++; } } -HTREEITEM ImportsHandling::addDllToTreeView(HWND idTreeView, const WCHAR * dllName, DWORD_PTR firstThunk, size_t numberOfFunctions, bool valid) +HTREEITEM ImportsHandling::addDllToTreeView(CTreeViewCtrl& idTreeView, const WCHAR * dllName, DWORD_PTR firstThunk, size_t numberOfFunctions, bool valid) { WCHAR validString[4]; if (valid) { wcscpy_s(validString,_countof(validString),TEXT("YES")); } else { wcscpy_s(validString,_countof(validString),TEXT("NO")); } swprintf_s(stringBuffer, _countof(stringBuffer),TEXT("%s FThunk: ")TEXT(PRINTF_DWORD_PTR_HALF)TEXT(" NbThunk: %02X (dec: %02d) valid: %s"),dllName,firstThunk,numberOfFunctions,numberOfFunctions,validString); tvInsert.hParent = NULL; tvInsert.hInsertAfter = TVI_ROOT; tvInsert.item.mask = TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE; tvInsert.item.pszText = stringBuffer; - return TreeView_InsertItem(idTreeView, &tvInsert); + //return TreeView_InsertItem(idTreeView, &tvInsert); + return idTreeView.InsertItem(&tvInsert); } -HTREEITEM ImportsHandling::addApiToTreeView(HWND idTreeView, HTREEITEM parentDll, ImportThunk * importThunk) +HTREEITEM ImportsHandling::addApiToTreeView(CTreeViewCtrl& idTreeView, HTREEITEM parentDll, ImportThunk * importThunk) { if (importThunk->ordinal != 0) { if (importThunk->name[0] != 0x00) { swprintf_s(tempString, _countof(tempString),TEXT("ord: %04X name: %S"),importThunk->ordinal,importThunk->name); } else { swprintf_s(tempString, _countof(tempString),TEXT("ord: %04X"),importThunk->ordinal); } swprintf_s(stringBuffer, _countof(stringBuffer),TEXT("va: ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT(" rva: ")TEXT(PRINTF_DWORD_PTR_HALF)TEXT(" mod: %s %s"),importThunk->va,importThunk->rva,importThunk->moduleName,tempString); } else { swprintf_s(stringBuffer, _countof(stringBuffer),TEXT("va: ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT(" rva: ")TEXT(PRINTF_DWORD_PTR_HALF)TEXT(" ptr: ")TEXT(PRINTF_DWORD_PTR_HALF)TEXT(""),importThunk->va,importThunk->rva,importThunk->apiAddressVA); } tvInsert.hParent = parentDll; tvInsert.hInsertAfter = TVI_LAST; tvInsert.item.mask = TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE; tvInsert.item.pszText = stringBuffer; - return TreeView_InsertItem(idTreeView, &tvInsert); + //return TreeView_InsertItem(idTreeView, &tvInsert); + return idTreeView.InsertItem(&tvInsert); } void ImportsHandling::showImports(bool invalid, bool suspect) { std::map::iterator iterator1; std::map::iterator iterator2; ImportModuleThunk * moduleThunk; ImportThunk * importThunk; - HWND idTreeView = GetDlgItem(hWndMainDlg, IDC_TREE_IMPORTS); + //HWND idTreeView = GetDlgItem(hWndMainDlg, IDC_TREE_IMPORTS); + + //SetFocus(idTreeView); + //TreeView_SelectItem(idTreeView,0); //remove selection - SetFocus(idTreeView); - TreeView_SelectItem(idTreeView,0); //remove selection + TreeImports.SetFocus(); + TreeImports.SelectItem(NULL); //remove selection iterator1 = moduleList.begin(); while (iterator1 != moduleList.end()) { moduleThunk = &(iterator1->second); iterator2 = moduleThunk->thunkList.begin(); while (iterator2 != moduleThunk->thunkList.end()) { importThunk = &(iterator2->second); if (invalid && !importThunk->valid) { - selectItem(idTreeView, importThunk->hTreeItem); - setFocus(idTreeView,importThunk->hTreeItem); + selectItem(TreeImports, importThunk->hTreeItem); + setFocus(TreeImports, importThunk->hTreeItem); } else if (suspect && importThunk->suspect) { - selectItem(idTreeView, importThunk->hTreeItem); - setFocus(idTreeView,importThunk->hTreeItem); + selectItem(TreeImports, importThunk->hTreeItem); + setFocus(TreeImports, importThunk->hTreeItem); } else { - unselectItem(idTreeView, importThunk->hTreeItem); + unselectItem(TreeImports, importThunk->hTreeItem); } iterator2++; } iterator1++; } } -bool ImportsHandling::isItemSelected(HWND hwndTV, HTREEITEM hItem) +bool ImportsHandling::isItemSelected(CTreeViewCtrl& hwndTV, HTREEITEM hItem) { TV_ITEM tvi; tvi.mask = TVIF_STATE | TVIF_HANDLE; tvi.stateMask = TVIS_SELECTED; tvi.hItem = hItem; - TreeView_GetItem(hwndTV, &tvi); + //TreeView_GetItem(hwndTV, &tvi); + hwndTV.GetItem(&tvi); return (tvi.state & TVIS_SELECTED) != 0; } -void ImportsHandling::unselectItem(HWND hwndTV, HTREEITEM htItem) +void ImportsHandling::unselectItem(CTreeViewCtrl& hwndTV, HTREEITEM htItem) { selectItem(hwndTV, htItem, false); } -bool ImportsHandling::selectItem(HWND hwndTV, HTREEITEM hItem, bool select) +bool ImportsHandling::selectItem(CTreeViewCtrl& hwndTV, HTREEITEM hItem, bool select) { TV_ITEM tvi; tvi.mask = TVIF_STATE | TVIF_HANDLE; tvi.stateMask = TVIS_SELECTED; tvi.state = select ? TVIS_SELECTED : 0; tvi.hItem = hItem; - if ( TreeView_SetItem(hwndTV, &tvi) == -1 ) + //*if ( TreeView_SetItem(hwndTV, &tvi) == -1 ) + if ( hwndTV.SetItem(&tvi) == -1 ) { return false; } return true; } -void ImportsHandling::setFocus(HWND hwndTV, HTREEITEM htItem) +void ImportsHandling::setFocus(CTreeViewCtrl& hwndTV, HTREEITEM htItem) { // the current focus - HTREEITEM htFocus = (HTREEITEM)TreeView_GetSelection(hwndTV); + HTREEITEM htFocus = hwndTV.GetSelectedItem(); //(HTREEITEM)TreeView_GetSelection(hwndTV); if ( htItem ) { // set the focus if ( htItem != htFocus ) { // remember the selection state of the item bool wasSelected = isItemSelected(hwndTV, htItem); if ( htFocus && isItemSelected(hwndTV, htFocus) ) { // prevent the tree from unselecting the old focus which it // would do by default (TreeView_SelectItem unselects the // focused item) - TreeView_SelectItem(hwndTV, 0); + hwndTV.SelectItem(NULL); //TreeView_SelectItem(hwndTV, 0); selectItem(hwndTV, htFocus); } - TreeView_SelectItem(hwndTV, htItem); + hwndTV.SelectItem(htItem); //TreeView_SelectItem(hwndTV, htItem); if ( !wasSelected ) { // need to clear the selection which TreeView_SelectItem() gave // us unselectItem(hwndTV, htItem); } //else: was selected, still selected - ok } //else: nothing to do, focus already there } else { if ( htFocus ) { bool wasFocusSelected = isItemSelected(hwndTV, htFocus); // just clear the focus - TreeView_SelectItem(hwndTV, 0); + hwndTV.SelectItem(NULL); //TreeView_SelectItem(hwndTV, 0); if ( wasFocusSelected ) { // restore the selection state selectItem(hwndTV, htFocus); } } //else: nothing to do, no focus already } } bool ImportsHandling::invalidateFunction( HTREEITEM selectedTreeNode ) { std::map::iterator iterator1; std::map::iterator iterator2; ImportModuleThunk * moduleThunk; ImportThunk * importThunk; TV_ITEM tvi = {0}; iterator1 = moduleList.begin(); while (iterator1 != moduleList.end()) { moduleThunk = &(iterator1->second); iterator2 = moduleThunk->thunkList.begin(); while (iterator2 != moduleThunk->thunkList.end()) { importThunk = &(iterator2->second); if (importThunk->hTreeItem == selectedTreeNode) { importThunk->ordinal = 0; importThunk->hint = 0; importThunk->valid = false; importThunk->suspect = false; importThunk->moduleName[0] = 0; importThunk->name[0] = 0; updateImportInTreeView(importThunk); updateModuleInTreeView(moduleThunk); return true; } iterator2++; } iterator1++; } return false; } void ImportsHandling::updateImportInTreeView(ImportThunk * importThunk) { TV_ITEM tvi = {0}; - HWND treeControl = GetDlgItem(hWndMainDlg,IDC_TREE_IMPORTS); + //HWND treeControl = GetDlgItem(hWndMainDlg, IDC_TREE_IMPORTS); if (importThunk->ordinal != 0) { if (importThunk->name[0] != 0x00) { swprintf_s(tempString, _countof(tempString),TEXT("ord: %04X name: %S"),importThunk->ordinal,importThunk->name); } else { swprintf_s(tempString, _countof(tempString),TEXT("ord: %04X"),importThunk->ordinal); } swprintf_s(stringBuffer, _countof(stringBuffer),TEXT("va: ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT(" rva: ")TEXT(PRINTF_DWORD_PTR_HALF)TEXT(" mod: %s %s"),importThunk->va,importThunk->rva,importThunk->moduleName,tempString); } else { swprintf_s(stringBuffer, _countof(stringBuffer),TEXT("va: ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT(" rva: ")TEXT(PRINTF_DWORD_PTR_HALF)TEXT(" prt: ")TEXT(PRINTF_DWORD_PTR_HALF)TEXT(""),importThunk->va,importThunk->rva,importThunk->apiAddressVA); } tvi.pszText = stringBuffer; tvi.cchTextMax = 260; tvi.hItem = importThunk->hTreeItem; tvi.mask = TVIF_TEXT; - TreeView_SetItem(treeControl,&tvi); + TreeImports.SetItem(&tvi); //TreeView_SetItem(treeControl,&tvi); } void ImportsHandling::updateModuleInTreeView(ImportModuleThunk * importThunk) { TV_ITEM tvi = {0}; - HWND treeControl = GetDlgItem(hWndMainDlg,IDC_TREE_IMPORTS); + //HWND treeControl = GetDlgItem(hWndMainDlg,IDC_TREE_IMPORTS); WCHAR validString[4]; if (importThunk->isValid()) { wcscpy_s(validString,_countof(validString),TEXT("YES")); } else { wcscpy_s(validString,_countof(validString),TEXT("NO")); } swprintf_s(stringBuffer, _countof(stringBuffer),TEXT("%s FThunk: ")TEXT(PRINTF_DWORD_PTR_HALF)TEXT(" NbThunk: %02X (dec: %02d) valid: %s"),importThunk->moduleName,importThunk->firstThunk,importThunk->thunkList.size(),importThunk->thunkList.size(),validString); tvi.pszText = stringBuffer; tvi.cchTextMax = 260; tvi.hItem = importThunk->hTreeItem; tvi.mask = TVIF_TEXT; - TreeView_SetItem(treeControl,&tvi); + TreeImports.SetItem(&tvi); //TreeView_SetItem(treeControl,&tvi); } bool ImportsHandling::cutThunk( HTREEITEM selectedTreeNode ) { std::map::iterator iterator1; std::map::iterator iterator2; ImportModuleThunk * moduleThunk; ImportThunk * importThunk; TV_ITEM tvi = {0}; - HWND treeControl = GetDlgItem(hWndMainDlg,IDC_TREE_IMPORTS); + //HWND treeControl = GetDlgItem(hWndMainDlg,IDC_TREE_IMPORTS); iterator1 = moduleList.begin(); while (iterator1 != moduleList.end()) { moduleThunk = &(iterator1->second); iterator2 = moduleThunk->thunkList.begin(); while (iterator2 != moduleThunk->thunkList.end()) { importThunk = &(iterator2->second); if (importThunk->hTreeItem == selectedTreeNode) { - TreeView_DeleteItem(treeControl,importThunk->hTreeItem); + TreeImports.DeleteItem(importThunk->hTreeItem); //TreeView_DeleteItem(treeControl,importThunk->hTreeItem); moduleThunk->thunkList.erase(iterator2); if (moduleThunk->thunkList.empty()) { - TreeView_DeleteItem(treeControl,moduleThunk->hTreeItem); + TreeImports.DeleteItem(moduleThunk->hTreeItem); //TreeView_DeleteItem(treeControl,moduleThunk->hTreeItem); moduleList.erase(iterator1); } else { updateModuleInTreeView(moduleThunk); } return true; } iterator2++; } iterator1++; } return false; } bool ImportsHandling::deleteTreeNode( HTREEITEM selectedTreeNode ) { std::map::iterator iterator1; std::map::iterator iterator2; ImportModuleThunk * moduleThunk; ImportThunk * importThunk; TV_ITEM tvi = {0}; - HWND treeControl = GetDlgItem(hWndMainDlg,IDC_TREE_IMPORTS); + //HWND treeControl = GetDlgItem(hWndMainDlg,IDC_TREE_IMPORTS); iterator1 = moduleList.begin(); while (iterator1 != moduleList.end()) { moduleThunk = &(iterator1->second); if (moduleThunk->hTreeItem == selectedTreeNode) { - TreeView_DeleteItem(treeControl,moduleThunk->hTreeItem); + TreeImports.DeleteItem(moduleThunk->hTreeItem); //TreeView_DeleteItem(treeControl,moduleThunk->hTreeItem); moduleThunk->thunkList.clear(); moduleList.erase(iterator1); return true; } else { iterator2 = moduleThunk->thunkList.begin(); while (iterator2 != moduleThunk->thunkList.end()) { importThunk = &(iterator2->second); if (importThunk->hTreeItem == selectedTreeNode) { - TreeView_DeleteItem(treeControl,moduleThunk->hTreeItem); + TreeImports.DeleteItem(moduleThunk->hTreeItem); //TreeView_DeleteItem(treeControl,moduleThunk->hTreeItem); moduleThunk->thunkList.clear(); moduleList.erase(iterator1); return true; } iterator2++; } } iterator1++; } return false; } DWORD_PTR ImportsHandling::getApiAddressByNode( HTREEITEM selectedTreeNode ) { std::map::iterator iterator1; std::map::iterator iterator2; ImportModuleThunk * moduleThunk; ImportThunk * importThunk; iterator1 = moduleList.begin(); while (iterator1 != moduleList.end()) { moduleThunk = &(iterator1->second); iterator2 = moduleThunk->thunkList.begin(); while (iterator2 != moduleThunk->thunkList.end()) { importThunk = &(iterator2->second); if (importThunk->hTreeItem == selectedTreeNode) { return importThunk->apiAddressVA; } iterator2++; } iterator1++; } return 0; } void ImportsHandling::scanAndFixModuleList() { std::map::iterator iterator1; std::map::iterator iterator2; ImportModuleThunk * moduleThunk; ImportThunk * importThunk; iterator1 = moduleList.begin(); while (iterator1 != moduleList.end()) { moduleThunk = &(iterator1->second); iterator2 = moduleThunk->thunkList.begin(); while (iterator2 != moduleThunk->thunkList.end()) { importThunk = &(iterator2->second); if (importThunk->moduleName[0] == 0 || importThunk->moduleName[0] == L'?') { addNotFoundApiToModuleList(importThunk); } else { if (isNewModule(importThunk->moduleName)) { addModuleToModuleList(importThunk->moduleName, importThunk->rva); } addFunctionToModuleList(importThunk); } iterator2++; } moduleThunk->thunkList.clear(); iterator1++; } moduleList.clear(); moduleList.insert(moduleListNew.begin(), moduleListNew.end()); moduleListNew.clear(); } bool ImportsHandling::findNewModules( std::map & thunkList ) { throw std::exception("The method or operation is not implemented."); } bool ImportsHandling::addModuleToModuleList(const WCHAR * moduleName, DWORD_PTR firstThunk) { ImportModuleThunk module; module.firstThunk = firstThunk; wcscpy_s(module.moduleName, MAX_PATH, moduleName); moduleListNew.insert(std::pair(firstThunk,module)); return true; } bool ImportsHandling::isNewModule(const WCHAR * moduleName) { std::map::iterator iterator1; iterator1 = moduleListNew.begin(); while (iterator1 != moduleListNew.end()) { if (!_wcsicmp(iterator1->second.moduleName, moduleName)) { return false; } iterator1++; } return true; } void ImportsHandling::addUnknownModuleToModuleList(DWORD_PTR firstThunk) { ImportModuleThunk module; module.firstThunk = firstThunk; wcscpy_s(module.moduleName, MAX_PATH, TEXT("?")); moduleListNew.insert(std::pair(firstThunk,module)); } bool ImportsHandling::addNotFoundApiToModuleList(ImportThunk * apiNotFound) { ImportThunk import; ImportModuleThunk * module = 0; std::map::iterator iterator1; DWORD_PTR rva = apiNotFound->rva; if (moduleListNew.size() > 0) { iterator1 = moduleListNew.begin(); while (iterator1 != moduleListNew.end()) { if (rva >= iterator1->second.firstThunk) { iterator1++; if (iterator1 == moduleListNew.end()) { iterator1--; //new unknown module if (iterator1->second.moduleName[0] == L'?') { module = &(iterator1->second); } else { addUnknownModuleToModuleList(apiNotFound->rva); module = &(moduleListNew.find(rva)->second); } break; } else if (rva < iterator1->second.firstThunk) { iterator1--; module = &(iterator1->second); break; } } else { #ifdef DEBUG_COMMENTS Logger::debugLog("Error iterator1 != (*moduleThunkList).end()\r\n"); #endif break; } } } else { //new unknown module addUnknownModuleToModuleList(apiNotFound->rva); module = &(moduleListNew.find(rva)->second); } if (!module) { #ifdef DEBUG_COMMENTS Logger::debugLog(TEXT("ImportsHandling::addFunction module not found rva ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT("\r\n"),rva); #endif return false; } import.suspect = true; import.valid = false; import.va = apiNotFound->va; import.rva = apiNotFound->rva; import.apiAddressVA = apiNotFound->apiAddressVA; import.ordinal = 0; wcscpy_s(import.moduleName, MAX_PATH, TEXT("?")); strcpy_s(import.name, MAX_PATH, "?"); module->thunkList.insert(std::pair(import.rva, import)); return true; } bool ImportsHandling::addFunctionToModuleList(ImportThunk * apiFound) { ImportThunk import; ImportModuleThunk * module = 0; std::map::iterator iterator1; if (moduleListNew.size() > 1) { iterator1 = moduleListNew.begin(); while (iterator1 != moduleListNew.end()) { if (apiFound->rva >= iterator1->second.firstThunk) { iterator1++; if (iterator1 == moduleListNew.end()) { iterator1--; module = &(iterator1->second); break; } else if (apiFound->rva < iterator1->second.firstThunk) { iterator1--; module = &(iterator1->second); break; } } else { #ifdef DEBUG_COMMENTS Logger::debugLog(TEXT("Error iterator1 != moduleListNew.end()\r\n")); #endif break; } } } else { iterator1 = moduleListNew.begin(); module = &(iterator1->second); } if (!module) { #ifdef DEBUG_COMMENTS Logger::debugLog(TEXT("ImportsHandling::addFunction module not found rva ")TEXT(PRINTF_DWORD_PTR_FULL)TEXT("\r\n"),apiFound->rva); #endif return false; } import.suspect = apiFound->suspect; import.valid = apiFound->valid; import.va = apiFound->va; import.rva = apiFound->rva; import.apiAddressVA = apiFound->apiAddressVA; import.ordinal = apiFound->ordinal; import.hint = apiFound->hint; wcscpy_s(import.moduleName, MAX_PATH, apiFound->moduleName); strcpy_s(import.name, MAX_PATH, apiFound->name); module->thunkList.insert(std::pair(import.rva, import)); return true; } void ImportsHandling::expandAllTreeNodes() { changeExpandStateOfTreeNodes(TVE_EXPAND); } void ImportsHandling::collapseAllTreeNodes() { changeExpandStateOfTreeNodes(TVE_COLLAPSE); } void ImportsHandling::changeExpandStateOfTreeNodes(UINT flag) { std::map::iterator iterator1; ImportModuleThunk * moduleThunk; - HWND treeControl = GetDlgItem(hWndMainDlg,IDC_TREE_IMPORTS); + //HWND treeControl = GetDlgItem(hWndMainDlg,IDC_TREE_IMPORTS); iterator1 = moduleList.begin(); while (iterator1 != moduleList.end()) { moduleThunk = &(iterator1->second); - TreeView_Expand(treeControl, moduleThunk->hTreeItem, flag); + TreeImports.Expand(moduleThunk->hTreeItem, flag); //TreeView_Expand(treeControl, moduleThunk->hTreeItem, flag); iterator1++; } } diff --git a/Scylla/ImportsHandling.h b/Scylla/ImportsHandling.h index 8310733..aa2a002 100644 --- a/Scylla/ImportsHandling.h +++ b/Scylla/ImportsHandling.h @@ -1,54 +1,64 @@ #pragma once #include "Thunks.h" -#include "MainGui.h" -class ImportsHandling : public MainGui { +#include +#include +#include + +class ImportsHandling +{ public: std::map moduleList; std::map moduleListNew; //bool addFunction(WCHAR * moduleName, char * name, DWORD_PTR va, DWORD_PTR rva, DWORD_PTR ordinal, bool valid, bool suspect); //bool addModule(WCHAR * moduleName, DWORD_PTR firstThunk); + // + ImportsHandling(CTreeViewCtrl& TreeImports) : TreeImports(TreeImports) { } void displayAllImports(); void showImports(bool invalid, bool suspect); bool invalidateFunction(HTREEITEM selectedTreeNode); bool cutThunk( HTREEITEM selectedTreeNode ); bool deleteTreeNode( HTREEITEM selectedTreeNode ); void updateImportInTreeView(ImportThunk * importThunk); void updateModuleInTreeView(ImportModuleThunk * importThunk); DWORD_PTR getApiAddressByNode( HTREEITEM selectedTreeNode ); void scanAndFixModuleList(); void expandAllTreeNodes(); void collapseAllTreeNodes(); private: DWORD numberOfFunctions; + WCHAR stringBuffer[600]; // o_O + WCHAR tempString[300]; + CTreeViewCtrl& TreeImports; + TV_INSERTSTRUCT tvInsert; HTREEITEM m_hItemFirstSel; - HTREEITEM addDllToTreeView(HWND idTreeView, const WCHAR * dllName, DWORD_PTR firstThunk, size_t numberOfFunctions, bool valid); - HTREEITEM addApiToTreeView(HWND idTreeView, HTREEITEM parentDll, ImportThunk * importThunk); + HTREEITEM addDllToTreeView(CTreeViewCtrl& idTreeView, const WCHAR * dllName, DWORD_PTR firstThunk, size_t numberOfFunctions, bool valid); + HTREEITEM addApiToTreeView(CTreeViewCtrl& idTreeView, HTREEITEM parentDll, ImportThunk * importThunk); - bool isItemSelected(HWND hwndTV, HTREEITEM hItem); - void unselectItem(HWND hwndTV, HTREEITEM htItem); - bool selectItem(HWND hwndTV, HTREEITEM hItem, bool select = true); - void setFocus(HWND hwndTV, HTREEITEM htItem); + bool isItemSelected(CTreeViewCtrl& hwndTV, HTREEITEM hItem); + void unselectItem(CTreeViewCtrl& hwndTV, HTREEITEM htItem); + bool selectItem(CTreeViewCtrl& hwndTV, HTREEITEM hItem, bool select = true); + void setFocus(CTreeViewCtrl& hwndTV, HTREEITEM htItem); bool findNewModules( std::map & thunkList ); bool addModuleToModuleList(const WCHAR * moduleName, DWORD_PTR firstThunk); void addUnknownModuleToModuleList(DWORD_PTR firstThunk); bool addNotFoundApiToModuleList(ImportThunk * apiNotFound); bool addFunctionToModuleList(ImportThunk * apiFound); bool isNewModule(const WCHAR * moduleName); void changeExpandStateOfTreeNodes(UINT flag); }; \ No newline at end of file diff --git a/Scylla/Logger.cpp b/Scylla/Logger.cpp index 0b08567..120eeae 100644 --- a/Scylla/Logger.cpp +++ b/Scylla/Logger.cpp @@ -1,90 +1,92 @@ #include "Logger.h" #include "MainGui.h" +extern MainGui* pMainGui; + WCHAR Logger::debugLogFile[MAX_PATH]; WCHAR Logger::logbuf[300]; char Logger::logbufChar[300]; void Logger::getDebugLogFilePath() { GetModuleFileName(0, debugLogFile, MAX_PATH); for(size_t i = wcslen(debugLogFile); i > 0; i--) { if(debugLogFile[i] == L'\\') { debugLogFile[i+1] = 0x00; break; } } wcscat_s(debugLogFile, _countof(debugLogFile), TEXT(DEBUG_LOG_FILENAME)); } void Logger::debugLog(const WCHAR * format, ...) { FILE * pFile; va_list va_alist; if (!format) { return; } ZeroMemory(logbuf, sizeof(logbuf)); va_start (va_alist, format); _vsnwprintf_s(logbuf, _countof(logbuf), _countof(logbuf) - 1, format, va_alist); va_end (va_alist); if (_wfopen_s(&pFile,debugLogFile,L"a") == NULL) { fputws(logbuf,pFile); fclose (pFile); } } void Logger::debugLog(const char * format, ...) { FILE * pFile; va_list va_alist; if (!format) { return; } ZeroMemory(logbufChar, sizeof(logbufChar)); va_start (va_alist, format); _vsnprintf_s(logbufChar, _countof(logbufChar), _countof(logbufChar) - 1, format, va_alist); va_end (va_alist); if (_wfopen_s(&pFile,debugLogFile,L"a") == NULL) { fputs(logbufChar,pFile); fclose (pFile); } } void Logger::printfDialog(const WCHAR * format, ...) { va_list va_alist; if (!format) { return; } ZeroMemory(logbuf, sizeof(logbuf)); va_start (va_alist, format); _vsnwprintf_s(logbuf, _countof(logbuf), _countof(logbuf) - 1, format, va_alist); va_end (va_alist); - MainGui::addTextToOutputLog(logbuf); - UpdateWindow(MainGui::hWndMainDlg); + pMainGui->addTextToOutputLog(logbuf); + UpdateWindow(pMainGui->m_hWnd); } \ No newline at end of file diff --git a/Scylla/MainGui.cpp b/Scylla/MainGui.cpp index 1037389..a801971 100644 --- a/Scylla/MainGui.cpp +++ b/Scylla/MainGui.cpp @@ -1,930 +1,911 @@ #include "MainGui.h" -#include "ImportsHandling.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" -HINSTANCE MainGui::hInstance = 0; -HWND MainGui::hWndParent = 0; -HWND MainGui::hWndMainDlg = 0; -Process * MainGui::selectedProcess = 0; - -WCHAR MainGui::stringBuffer[600] = {0}; - -ProcessLister MainGui::processLister; -ImportsHandling MainGui::importsHandling; -ProcessAccessHelp MainGui::processAccessHelp; -ApiReader MainGui::apiReader; - -void MainGui::initDialog(HINSTANCE hInstance) +MainGui::MainGui(HINSTANCE hInstance) : selectedProcess(0), importsHandling(TreeImports) { - hInstance = hInstance; + this->hInstance = hInstance; + Logger::getDebugLogFilePath(); ConfigurationHolder::loadConfiguration(); PluginLoader::findAllPlugins(); NativeWinApi::initialize(); SystemInformation::getSystemInformation(); +} - +BOOL MainGui::OnInitDialog(CWindow wndFocus, LPARAM lInitParam) +{ if (SystemInformation::currenOS == UNKNOWN_OS) { - MessageBox(0, TEXT("Operating System is not supported"), TEXT("Error Operating System"),MB_OK); - return; + ::MessageBox(0, TEXT("Operating System is not supported"), TEXT("Error Operating System"), MB_OK); + EndDialog(0); + return TRUE; + } + + if(ConfigurationHolder::getConfigObject(DEBUG_PRIVILEGE)->isTrue()) + { + processLister.setDebugPrivileges(); } - processAccessHelp.getProcessModules(GetCurrentProcessId(), processAccessHelp.ownModuleList); - //Register controls, required for Windows XP - InitCommonControls(); + 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)); - DialogBox(hInstance, MAKEINTRESOURCE(IDD_DLG_MAIN),hWndParent, (DLGPROC)mainDlgProc); + EditOEPAddress.LimitText(MAX_HEX_VALUE_EDIT_LENGTH); + EditOEPAddress.LimitText(MAX_HEX_VALUE_EDIT_LENGTH); + EditOEPAddress.LimitText(MAX_HEX_VALUE_EDIT_LENGTH); - //ConfigurationHolder::saveConfiguration(); + enableDialogButtons(FALSE); + + setIconAndDialogCaption(); + + return TRUE; } -LRESULT CALLBACK MainGui::mainDlgProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +void MainGui::OnLButtonDown(UINT nFlags, CPoint point) { - hWndMainDlg = hWndDlg; - HTREEITEM selectedTreeNode = 0; - switch(uMsg) - { - case WM_INITDIALOG: - //init dialog elements - dialogInitActionHandler(); - return TRUE; - case WM_NOTIFY: - switch(LOWORD(wParam)) - { - case IDC_TREE_IMPORTS: - { - if(((LPNMHDR)lParam)->code == NM_CLICK) - { - //Logger::printfDialog(L"NM_CLICK"); - } - if(((LPNMHDR)lParam)->code == NM_DBLCLK) - { - //Logger::printfDialog(L"NM_DBLCLK"); - } - if(((LPNMHDR)lParam)->code == NM_RCLICK) - { - //Logger::printfDialog(L"NM_RCLICK"); +} - selectedTreeNode=(HTREEITEM)SendDlgItemMessage (hWndMainDlg,IDC_TREE_IMPORTS,TVM_GETNEXTITEM,TVGN_DROPHILITE,0); - if(selectedTreeNode != NULL) - { - SendDlgItemMessage(hWndMainDlg,IDC_TREE_IMPORTS,TVM_SELECTITEM,TVGN_CARET,(LPARAM)selectedTreeNode); - } - } - if(((LPNMHDR)lParam)->code == NM_RDBLCLK) - { - //Logger::printfDialog(L"NM_RDBLCLK"); - } - } - break; - /*case IDC_MODULELIST: - LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam; - if (pnmv->uChanged & LVIF_STATE) - { - if ((pnmv->uNewState & LVIS_SELECTED) && (!(pnmv->uOldState & LVIS_SELECTED)) && (pnmv->hdr.code == LVN_ITEMCHANGED)) - { - - //sprintf(stringBuffer,"%X",i); - //MessageBox(hWndDlg, text,"Display Notification", MB_OK); - break; - } - }*/ - } - return TRUE; - case WM_COMMAND: - switch(LOWORD(wParam)) +void MainGui::OnContextMenu(CWindow wnd, CPoint point) +{ + HWND hwnd = 0; + //POINT pt = { x, y }; // location of mouse click + //TV_ITEM tvi; + //WCHAR ttt[260] = {0}; + //HTREEITEM selectedTreeNode = 0; + + if ((hwnd = mouseInDialogItem(IDC_TREE_IMPORTS, point)) != NULL) + { + if(TreeImports.GetCount()) //module list should not be empty { - case IDC_CBO_PROCESSLIST: - switch(HIWORD(wParam)) - { - case CBN_DROPDOWN: //list is about to display - fillProcessListComboBox(GetDlgItem(hWndDlg, IDC_CBO_PROCESSLIST)); - break; - case CBN_SELENDOK: //item selected - processSelectedActionHandler(SendMessage(GetDlgItem(hWndDlg, IDC_CBO_PROCESSLIST),CB_GETCURSEL,0,0)); - break; - } + /*selectedTreeNode = (HTREEITEM)SendDlgItemMessage(hWndMainDlg,IDC_TREE_IMPORTS,TVM_GETNEXTITEM,TVGN_CARET,(LPARAM)selectedTreeNode); + tvi.mask=TVIF_TEXT; // item text attrivute - return TRUE; - - case IDC_BTN_PICKDLL: - pickDllActionHandler(); - return TRUE; - case IDC_BTN_OPTIONS: - optionsActionHandler(); - return TRUE; - case IDC_BTN_DUMP: - dumpActionHandler(); - return TRUE; - case IDC_BTN_FIXDUMP: - dumpFixActionHandler(); - return TRUE; - case IDC_BTN_PEREBUILD: - peRebuildActionHandler(); - return TRUE; - case IDC_BTN_DLLINJECT: - dllInjectActionHandler(); - return TRUE; - case ID_MISC_DLLINJECTION: - dllInjectActionHandler(); - return TRUE; - case ID_MISC_PREFERENCES: - optionsActionHandler(); - return TRUE; - case IDC_BTN_IATAUTOSEARCH: - iatAutosearchActionHandler(); - return TRUE; - case IDC_BTN_GETIMPORTS: - getImportsActionHandler(); - return TRUE; - case IDC_BTN_INVALIDIMPORTS: - showInvalidImportsActionHandler(); - return TRUE; - case IDC_BTN_SUSPECTIMPORTS: - showSuspectImportsActionHandler(); - return TRUE; - case IDC_BTN_CLEARIMPORTS: - TreeView_DeleteAllItems(GetDlgItem(hWndDlg, IDC_TREE_IMPORTS)); - importsHandling.moduleList.clear(); - return TRUE; - case IDC_BTN_CLEARLOG: - clearOutputLog(); - return TRUE; - /*case IDC_BTN_ABOUT: - showAboutDialog(); - return TRUE;*/ - case ID_HELP_ABOUT: - showAboutDialog(); - return TRUE; - /*case IDC_BTN_EXIT: - PostQuitMessage(0); - EndDialog(hWndDlg, 0); - return TRUE;*/ - case ID_FILE_EXIT: - PostQuitMessage(0); - EndDialog(hWndDlg, 0); - return TRUE; - case IDCANCEL: - PostQuitMessage(0); - EndDialog(hWndDlg, 0); - return TRUE; + tvi.pszText=ttt; // Text is the pointer to the text + + tvi.cchTextMax=260; // size of text to retrieve. + + tvi.hItem=selectedTreeNode; // the selected item + + SendDlgItemMessage(hWndMainDlg,IDC_TREE_IMPORTS,TVM_GETITEM,TVGN_CARET,(LPARAM)&tvi); + Logger::printfDialog(L"selected %s",tvi.pszText);*/ + DisplayContextMenuImports(hwnd, point); } - return TRUE; + //return true; + } + //if (PtInRect(&rc, pt)) + //{ + // ClientToScreen(hwnd, &pt); + // DisplayContextMenu(hwnd, pt); + // return TRUE; + //} + + // Return FALSE if no menu is displayed. + + //return false; +} + +LRESULT MainGui::OnTreeImportsClick(const NMHDR* pnmh) +{ + //Logger::printfDialog(L"NM_CLICK"); + return FALSE; +} - case WM_LBUTTONDOWN: - //leftButtonDownActionHandler(); - //return TRUE; +LRESULT MainGui::OnTreeImportsDoubleClick(const NMHDR* pnmh) +{ + //Logger::printfDialog(L"NM_DBLCLK"); + return FALSE; +} - case WM_CONTEXTMENU: - return OnContextMenu(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); - default: - 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 TRUE; +} + +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()); + //processSelectedActionHandler(SendMessage(GetDlgItem(hWndDlg, IDC_CBO_PROCESSLIST),CB_GETCURSEL,0,0)); +} + +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(); + //TreeView_DeleteAllItems(GetDlgItem(hWndDlg, IDC_TREE_IMPORTS)); + importsHandling.moduleList.clear(); +} + +void MainGui::OnClearLog(UINT uNotifyCode, int nID, CWindow wndCtl) +{ + clearOutputLog(); +} + +void MainGui::OnExit(UINT uNotifyCode, int nID, CWindow wndCtl) +{ + //PostQuitMessage(0); + + EndDialog(0); + //EndDialog(hWndDlg, 0); +} + +void MainGui::OnAbout(UINT uNotifyCode, int nID, CWindow wndCtl) +{ + showAboutDialog(); } void MainGui::setIconAndDialogCaption() { - if (hWndMainDlg) + if (m_hWnd)//if (hWndMainDlg) { - HICON hicon = LoadIcon(GetModuleHandle(0),MAKEINTRESOURCE(IDI_ICON_SCYLLA1)); - SendMessage(hWndMainDlg, WM_SETICON, ICON_BIG, (LPARAM)hicon); - SendMessage(hWndMainDlg, WM_SETICON, ICON_SMALL, (LPARAM)hicon); + HICON hicon = LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(IDI_ICON_SCYLLA1)); + //SendMessage(hWndMainDlg, WM_SETICON, ICON_BIG, (LPARAM)hicon); + //SendMessage(hWndMainDlg, WM_SETICON, ICON_SMALL, (LPARAM)hicon); + + SetIcon(hicon, TRUE); + SetIcon(hicon, FALSE); swprintf_s(stringBuffer, _countof(stringBuffer),TEXT(APPNAME)TEXT(" ")TEXT(ARCHITECTURE)TEXT(" ")TEXT(APPVERSION)TEXT(" ")); - SetWindowText(hWndMainDlg,stringBuffer); + //SetWindowText(hWndMainDlg,stringBuffer); + SetWindowText(stringBuffer); } } - void MainGui::leftButtonDownActionHandler(WPARAM wParam, LPARAM lParam) { if(wParam & MK_CONTROL) { } else if(wParam & MK_SHIFT) { } else { } } -void MainGui::dialogInitActionHandler() -{ - setIconAndDialogCaption(); - - if (ConfigurationHolder::getConfigObject(DEBUG_PRIVILEGE)->isTrue()) - { - processLister.setDebugPrivileges(); - } - - - enableDialogButtons(FALSE); - - Edit_LimitText(GetDlgItem(hWndMainDlg,IDC_EDIT_OEPADDRESS), MAX_HEX_VALUE_EDIT_LENGTH); - Edit_LimitText(GetDlgItem(hWndMainDlg,IDC_EDIT_IATADDRESS), MAX_HEX_VALUE_EDIT_LENGTH); - Edit_LimitText(GetDlgItem(hWndMainDlg,IDC_EDIT_IATSIZE), MAX_HEX_VALUE_EDIT_LENGTH); -} - void MainGui::pickDllActionHandler() { - if (PickDllGui::initDialog(hInstance,hWndMainDlg, processAccessHelp.moduleList)) + if (PickDllGui::initDialog(hInstance,m_hWnd, processAccessHelp.moduleList)) { //get selected module processAccessHelp.selectedModule = PickDllGui::selectedModule; 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(HTREEITEM selectedTreeNode) { DWORD_PTR address = importsHandling.getApiAddressByNode(selectedTreeNode); if (address) { - DisassemblerGui::initDialog(hInstance,hWndMainDlg,address); + DisassemblerGui::initDialog(hInstance,m_hWnd,address); } } void MainGui::processSelectedActionHandler(LRESULT index) { std::vector& processList = processLister.getProcessList(); Process &process = processList.at(index); selectedProcess = &process; enableDialogButtons(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); - SetDlgItemText(hWndMainDlg, IDC_EDIT_OEPADDRESS, stringBuffer); + //SetDlgItemText(hWndMainDlg, IDC_EDIT_OEPADDRESS, stringBuffer); + + EditOEPAddress.SetWindowText(stringBuffer); } -void MainGui::fillProcessListComboBox(HWND hCombo) +void MainGui::fillProcessListComboBox(CComboBox& hCombo) { - if (hCombo) - { - SendMessage(hCombo,CB_RESETCONTENT,0,0); + hCombo.ResetContent(); - std::vector& processList = processLister.getProcessListSnapshot(); + 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); - SendMessage(hCombo,CB_ADDSTRING,0,(LPARAM)stringBuffer); - } + 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 (hWndMainDlg) + if (m_hWnd) { - HWND hList = GetDlgItem(hWndMainDlg,IDC_LIST_LOG); + //HWND hList = GetDlgItem(hWndMainDlg,IDC_LIST_LOG); + + //ListBox_SetCurSel(hList, ListBox_AddString(hList,text)); - ListBox_SetCurSel(hList, ListBox_AddString(hList,text)); + ListLog.SetCurSel(ListLog.AddString(text)); } } void MainGui::clearOutputLog() { - if (hWndMainDlg) + if (m_hWnd) { - SendDlgItemMessage(hWndMainDlg, IDC_LIST_LOG, LB_RESETCONTENT, 0, 0); + ListLog.ResetContent(); + //SendDlgItemMessage(hWndMainDlg, IDC_LIST_LOG, LB_RESETCONTENT, 0, 0); } } 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; - GetDlgItemText(hWndMainDlg, IDC_EDIT_OEPADDRESS, stringBuffer, _countof(stringBuffer)); + EditOEPAddress.GetWindowText(stringBuffer, _countof(stringBuffer)); + //GetDlgItemText(hWndMainDlg, IDC_EDIT_OEPADDRESS, stringBuffer, _countof(stringBuffer)); if (wcslen(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); - SetDlgItemText(hWndMainDlg,IDC_EDIT_IATADDRESS,stringBuffer); + EditIATAddress.SetWindowText(stringBuffer); + //SetDlgItemText(hWndMainDlg,IDC_EDIT_IATADDRESS,stringBuffer); swprintf_s(stringBuffer, _countof(stringBuffer),TEXT("%08X"),sizeIAT); - SetDlgItemText(hWndMainDlg,IDC_EDIT_IATSIZE,stringBuffer); + EditIATSize.SetWindowText(stringBuffer); + //SetDlgItemText(hWndMainDlg,IDC_EDIT_IATSIZE,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(hWndMainDlg,stringBuffer, TEXT("IAT found"), MB_OK); + MessageBox(stringBuffer, TEXT("IAT found")); } 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; - GetDlgItemText(hWndMainDlg, IDC_EDIT_IATADDRESS, stringBuffer, sizeof(stringBuffer)); + EditIATAddress.GetWindowText(stringBuffer, _countof(stringBuffer)); + //GetDlgItemText(hWndMainDlg, IDC_EDIT_IATADDRESS, stringBuffer, sizeof(stringBuffer)); addressIAT = stringToDwordPtr(stringBuffer); - GetDlgItemText(hWndMainDlg, IDC_EDIT_IATSIZE, stringBuffer, sizeof(stringBuffer)); + EditIATSize.GetWindowText(stringBuffer, _countof(stringBuffer)); + //GetDlgItemText(hWndMainDlg, IDC_EDIT_IATSIZE, stringBuffer, sizeof(stringBuffer)); sizeIAT = wcstoul(stringBuffer, NULL, 16); if (addressIAT && sizeIAT) { apiReader.readAndParseIAT(addressIAT, sizeIAT,importsHandling.moduleList); importsHandling.displayAllImports(); } } DWORD_PTR MainGui::stringToDwordPtr(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; } } -bool MainGui::OnContextMenu(int x, int y) -{ - HWND hwnd = 0; - POINT pt = { x, y }; // location of mouse click - //TV_ITEM tvi; - //WCHAR ttt[260] = {0}; - //HTREEITEM selectedTreeNode = 0; - - if ((hwnd = mouseInDialogItem(IDC_TREE_IMPORTS, pt)) != NULL) - { - if (TreeView_GetCount(hwnd)) //module list should not be empty - { - /*selectedTreeNode = (HTREEITEM)SendDlgItemMessage(hWndMainDlg,IDC_TREE_IMPORTS,TVM_GETNEXTITEM,TVGN_CARET,(LPARAM)selectedTreeNode); - tvi.mask=TVIF_TEXT; // item text attrivute - - tvi.pszText=ttt; // Text is the pointer to the text - - tvi.cchTextMax=260; // size of text to retrieve. - - tvi.hItem=selectedTreeNode; // the selected item - - SendDlgItemMessage(hWndMainDlg,IDC_TREE_IMPORTS,TVM_GETITEM,TVGN_CARET,(LPARAM)&tvi); - Logger::printfDialog(L"selected %s",tvi.pszText);*/ - DisplayContextMenuImports(hwnd, pt); - } - return true; - } - //if (PtInRect(&rc, pt)) - //{ - // ClientToScreen(hwnd, &pt); - // DisplayContextMenu(hwnd, pt); - // return TRUE; - //} - - // Return FALSE if no menu is displayed. - - return false; -} - void MainGui::DisplayContextMenuImports(HWND hwnd, POINT pt) { BOOL menuItem = 0; HTREEITEM selectedTreeNode = 0; std::vector &pluginList = PluginLoader::getScyllaPluginList(); HMENU hmenuTrackPopup = getCorrectSubMenu(IDR_MENU_IMPORTS, 0); appendPluginListToMenu(hmenuTrackPopup); if (hmenuTrackPopup) { menuItem = TrackPopupMenu(hmenuTrackPopup, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, 0, hwnd, 0); 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(0,stringBuffer,L"plugin selection",0); pluginActionHandler(menuItem); return; } - selectedTreeNode = (HTREEITEM)SendDlgItemMessage(hWndMainDlg,IDC_TREE_IMPORTS,TVM_GETNEXTITEM,TVGN_CARET,(LPARAM)selectedTreeNode); + selectedTreeNode = TreeImports.GetNextItem(selectedTreeNode, TVGN_CARET); + //selectedTreeNode = (HTREEITEM)SendDlgItemMessage(hWndMainDlg,IDC_TREE_IMPORTS,TVM_GETNEXTITEM,TVGN_CARET,(LPARAM)selectedTreeNode); switch (menuItem) { case ID__INVALIDATEFUNCTION: { importsHandling.invalidateFunction(selectedTreeNode); } break; case ID__DISASSEMBLE: { startDisassemblerGui(selectedTreeNode); } break; case ID__CUTTHUNK: { importsHandling.cutThunk(selectedTreeNode); } break; case ID__DELETETREENODE: { importsHandling.deleteTreeNode(selectedTreeNode); } break; case ID__EXPANDALLNODES: { importsHandling.expandAllTreeNodes(); } break; case ID__COLLAPSEALLNODES: { importsHandling.collapseAllTreeNodes(); } break; } } } } HWND MainGui::mouseInDialogItem(int dlgItem, POINT pt) { RECT rc; - HWND hwnd = GetDlgItem(hWndMainDlg, dlgItem); + HWND hwnd = GetDlgItem(dlgItem);//GetDlgItem(hWndMainDlg, dlgItem); if (hwnd) { // Get the bounding rectangle of the client area. - GetClientRect(hwnd, &rc); + GetClientRect(&rc); //GetClientRect(hwnd, &rc); // Convert the mouse position to client coordinates. - ScreenToClient(hwnd, &pt); + ScreenToClient(&pt); //ScreenToClient(hwnd, &pt); // If the position is in the client area, display a // shortcut menu. - if (PtInRect(&rc, pt)) + if(PtInRect(&rc, pt)) { return hwnd; } else { return 0; } } else { return 0; } } HMENU MainGui::getCorrectSubMenu(int menuItem, int subMenuItem) { HMENU hmenu; // top-level menu HMENU hmenuTrackPopup; // shortcut menu // Load the menu resource. if ((hmenu = LoadMenu(hInstance, MAKEINTRESOURCE(menuItem))) == NULL) return 0; hmenuTrackPopup = GetSubMenu(hmenu, subMenuItem); if (hmenuTrackPopup) { return hmenuTrackPopup; } else { return 0; } } void MainGui::DisplayContextMenu(HWND hwnd, POINT pt) { HMENU hmenu; // top-level menu HMENU hmenuTrackPopup; // shortcut menu int menuItem; // selected menu item // Load the menu resource. if ((hmenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU_IMPORTS))) == NULL) return; // TrackPopupMenu cannot display the menu bar so get // a handle to the first shortcut menu. hmenuTrackPopup = GetSubMenu(hmenu, 0); // Display the shortcut menu. Track the right mouse // button. if (!hmenuTrackPopup) { MessageBoxA(0,"hmenuTrackPopup == null","hmenuTrackPopup",0); } menuItem = TrackPopupMenu(hmenuTrackPopup, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, 0, hwnd, NULL); if (menuItem) { /*if (menuItem == ID_LISTCONTROL_SHOWEXPORTS) { MessageBox(0,"exports","dshhhhh",0); }*/ } // Destroy the menu. DestroyMenu(hmenu); } void MainGui::appendPluginListToMenu(HMENU hMenuTrackPopup) { - HMENU newMenu = CreatePopupMenu(); + CMenu newMenu = CreatePopupMenu(); //HMENU newMenu = CreatePopupMenu(); std::vector &scyllaPluginList = PluginLoader::getScyllaPluginList(); std::vector &imprecPluginList = PluginLoader::getImprecPluginList(); if (scyllaPluginList.size() > 0) { for (size_t i = 0; i < scyllaPluginList.size(); i++) { + AppendMenu(newMenu, MF_STRING, i + PLUGIN_MENU_BASE_ID, scyllaPluginList[i].pluginName); } AppendMenu(hMenuTrackPopup,MF_MENUBARBREAK,0,0); - AppendMenu(hMenuTrackPopup,MF_POPUP,(UINT_PTR)newMenu,TEXT("Scylla Plugins")); + AppendMenu(hMenuTrackPopup,MF_POPUP,(UINT_PTR)(HMENU)newMenu,TEXT("Scylla Plugins")); } newMenu = CreatePopupMenu(); if (imprecPluginList.size() > 0) { for (size_t i = 0; i < imprecPluginList.size(); i++) { AppendMenu(newMenu, MF_STRING, scyllaPluginList.size() + i + PLUGIN_MENU_BASE_ID, imprecPluginList[i].pluginName); } AppendMenu(hMenuTrackPopup,MF_MENUBARBREAK,0,0); - AppendMenu(hMenuTrackPopup,MF_POPUP,(UINT_PTR)newMenu,TEXT("ImpREC Plugins")); + AppendMenu(hMenuTrackPopup,MF_POPUP,(UINT_PTR)(HMENU)newMenu,TEXT("ImpREC Plugins")); } } void MainGui::dumpActionHandler() { WCHAR * targetFile = 0; PeDump peDump; if (processAccessHelp.selectedModule) { targetFile = ProcessAccessHelp::selectFileToSave(0, 0); } else { targetFile = ProcessAccessHelp::selectFileToSave(0, 1); } 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(hWndMainDlg,TEXT("Image dumped successfully."),TEXT("Success"),MB_OK); } else { Logger::printfDialog(TEXT("Error: Cannot dump image.")); - MessageBox(hWndMainDlg,TEXT("Cannot dump image."),TEXT("Failure"),MB_OK); + MessageBox(TEXT("Cannot dump image."),TEXT("Failure")); } delete [] targetFile; } } DWORD_PTR MainGui::getOEPFromGui() { - if (GetDlgItemText(hWndMainDlg, IDC_EDIT_OEPADDRESS, stringBuffer, _countof(stringBuffer))) + //if (GetDlgItemText(hWndMainDlg, IDC_EDIT_OEPADDRESS, stringBuffer, _countof(stringBuffer))) + 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::selectFileToSave(OFN_FILEMUSTEXIST, 2); 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(hWndMainDlg,TEXT("Rebuild failed."),TEXT("Failure"),MB_OK); + MessageBox(TEXT("Rebuild failed."),TEXT("Failure")); } 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(hWndMainDlg,TEXT("Image rebuilded successfully."),TEXT("Success"),MB_OK); } delete [] targetFile; } } void MainGui::dumpFixActionHandler() { WCHAR * targetFile = 0; WCHAR newFilePath[MAX_PATH]; ImportRebuild importRebuild; - if (TreeView_GetCount(GetDlgItem(hWndMainDlg, IDC_TREE_IMPORTS)) < 2) + //if (TreeView_GetCount(GetDlgItem(hWndMainDlg, IDC_TREE_IMPORTS)) < 2) + if (TreeImports.GetCount() < 2) { Logger::printfDialog(TEXT("Nothing to rebuild")); return; } if (processAccessHelp.selectedModule) { targetFile = ProcessAccessHelp::selectFileToSave(OFN_FILEMUSTEXIST, 0); } else { targetFile = ProcessAccessHelp::selectFileToSave(OFN_FILEMUSTEXIST, 1); } if (targetFile) { wcscpy_s(newFilePath,MAX_PATH,targetFile); for (size_t i = wcslen(newFilePath) - 1; i >= 0; i--) { if (newFilePath[i] == L'.') { newFilePath[i] = 0; break; } } 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(hWndMainDlg,L"Imports rebuilding successful",L"Success",MB_OK); Logger::printfDialog(TEXT("Import Rebuild success %s"), newFilePath); } else { Logger::printfDialog(TEXT("Import Rebuild failed, target %s"), targetFile); - MessageBox(hWndMainDlg,L"Imports rebuilding failed",L"Failure",MB_OK); + MessageBox(L"Imports rebuilding failed",L"Failure"); } delete [] targetFile; } } void MainGui::enableDialogButtons(BOOL value) { - EnableWindow(GetDlgItem(hWndMainDlg, IDC_BTN_PICKDLL), value); - EnableWindow(GetDlgItem(hWndMainDlg, IDC_BTN_DUMP), value); - EnableWindow(GetDlgItem(hWndMainDlg, IDC_BTN_DLLINJECT), value); - EnableWindow(GetDlgItem(hWndMainDlg, IDC_BTN_FIXDUMP), value); - EnableWindow(GetDlgItem(hWndMainDlg, IDC_BTN_IATAUTOSEARCH), value); - EnableWindow(GetDlgItem(hWndMainDlg, IDC_BTN_GETIMPORTS), value); - EnableWindow(GetDlgItem(hWndMainDlg, IDC_BTN_SUSPECTIMPORTS), value); - EnableWindow(GetDlgItem(hWndMainDlg, IDC_BTN_INVALIDIMPORTS), value); - EnableWindow(GetDlgItem(hWndMainDlg, IDC_BTN_CLEARIMPORTS), value); - EnableWindow(GetDlgItem(hWndMainDlg, IDC_BTN_OPTIONS), TRUE); + 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); + + GetDlgItem(IDC_BTN_OPTIONS).EnableWindow(TRUE); //not yet implemented - EnableWindow(GetDlgItem(hWndMainDlg, IDC_BTN_AUTOTRACE), FALSE); - EnableWindow(GetDlgItem(hWndMainDlg, IDC_BTN_SAVETREE), FALSE); - EnableWindow(GetDlgItem(hWndMainDlg, IDC_BTN_LOADTREE), FALSE); + GetDlgItem(IDC_BTN_AUTOTRACE).EnableWindow(FALSE); + GetDlgItem(IDC_BTN_SAVETREE).EnableWindow(FALSE); + GetDlgItem(IDC_BTN_LOADTREE).EnableWindow(FALSE); } void MainGui::showAboutDialog() { - AboutGui::initDialog(hInstance,hWndMainDlg); + AboutGui::initDialog(hInstance, m_hWnd); } void MainGui::dllInjectActionHandler() { WCHAR * targetFile = 0; HMODULE hMod = 0; DllInjection dllInjection; targetFile = ProcessAccessHelp::selectFileToSave(OFN_FILEMUSTEXIST, 0); 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::initOptionsDialog(hInstance, hWndMainDlg); + OptionsGui::initOptionsDialog(hInstance, m_hWnd); } void MainGui::pluginActionHandler( int menuItem ) { 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 9ff22a1..cebd964 100644 --- a/Scylla/MainGui.h +++ b/Scylla/MainGui.h @@ -1,96 +1,174 @@ #pragma once //#define _CRTDBG_MAP_ALLOC //#include //#include #include #include #include #include #include +// WTL + +#include // base ATL classes +#include // base WTL classes +#include // ATL GUI classes +#include // WTL frame window classes +#include // WTL utility classes like CString +#include // WTL enhanced msg map macros + +#include + #include "resource.h" #include "Logger.h" #include "ProcessLister.h" #include "IATSearch.h" #include "PickDllGui.h" +#include "ImportsHandling.h" -#pragma comment(lib, "comctl32.lib") - - -#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp)) -#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp)) +//#pragma comment(lib, "comctl32.lib") class ImportsHandling; -class MainGui +class MainGui : public CDialogImpl { public: - static HWND hWndMainDlg; - static Process * selectedProcess; - - static void initDialog(HINSTANCE hInstance); + enum { IDD = IDD_DLG_MAIN }; + + BEGIN_MSG_MAP(MainGui) + MSG_WM_INITDIALOG(OnInitDialog) + MSG_WM_CONTEXTMENU(OnContextMenu) + MSG_WM_LBUTTONDOWN(OnLButtonDown) + + 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(IDC_BTN_CLEARLOG, OnClearLog) + + 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(HINSTANCE hInstance); + + Process * selectedProcess; //Output Window - static void addTextToOutputLog(const WCHAR * text); + void addTextToOutputLog(const WCHAR * text); static DWORD_PTR stringToDwordPtr(WCHAR * hexString); protected: - static HWND hWndParent; + HINSTANCE hInstance; - static HINSTANCE hInstance; - static ProcessLister processLister; - static WCHAR stringBuffer[600]; + // Controls + CTreeViewCtrl TreeImports; + CComboBox ComboProcessList; + CEdit EditOEPAddress; + CEdit EditIATAddress; + CEdit EditIATSize; + CListBox ListLog; - static ImportsHandling importsHandling; - static ProcessAccessHelp processAccessHelp; - static ApiReader apiReader; + ProcessLister processLister; + WCHAR stringBuffer[600]; + + ImportsHandling importsHandling; + ProcessAccessHelp processAccessHelp; + ApiReader apiReader; private: - static LRESULT CALLBACK mainDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + //Message handlers - static void setIconAndDialogCaption(); - + BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam); + void OnLButtonDown(UINT nFlags, CPoint point); + void OnContextMenu(CWindow wnd, CPoint point); - static void fillProcessListComboBox(HWND hCombo); - static void getModuleListItem(int column, int iItem, char * buffer); + 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); - static void leftButtonDownActionHandler(WPARAM wParam, LPARAM lParam); - static void dialogInitActionHandler(); - static void pickDllActionHandler(); - static void processSelectedActionHandler(LRESULT index); + 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); - //static bool displayModuleList(HWND hWndDlg, HWND hList, LRESULT index); + 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); + + // --- + + void setIconAndDialogCaption(); + void fillProcessListComboBox(CComboBox& hCombo); + void getModuleListItem(int column, int iItem, char * buffer); + + void leftButtonDownActionHandler(WPARAM wParam, LPARAM lParam); + void dialogInitActionHandler(); + void pickDllActionHandler(); + void processSelectedActionHandler(LRESULT index); + + //static bool displayModuleList(HWND hWndDlg, HWND hList, LRESULT index); // POPUP MENU Prototypes - static bool OnContextMenu(int, int); - static void DisplayContextMenu(HWND, POINT); - static HWND mouseInDialogItem(int, POINT); - static void DisplayContextMenuImports(HWND, POINT); - static HMENU getCorrectSubMenu(int, int); + //bool OnContextMenu(int, int); + void DisplayContextMenu(HWND, POINT); + HWND mouseInDialogItem(int, POINT); + void DisplayContextMenuImports(HWND, POINT); + HMENU getCorrectSubMenu(int, int); - static void clearOutputLog();//Output Window - static void showInvalidImportsActionHandler(); - static void showSuspectImportsActionHandler(); - static void iatAutosearchActionHandler(); - static void getImportsActionHandler(); - static void appendPluginListToMenu( HMENU hMenuTrackPopup ); - static void dumpActionHandler(); - static DWORD_PTR getOEPFromGui(); - static void peRebuildActionHandler(); - - static void startDisassemblerGui(HTREEITEM selectedTreeNode); - static void dumpFixActionHandler(); - static void enableDialogButtons( BOOL value ); - static void showAboutDialog(); - static void dllInjectActionHandler(); - static void optionsActionHandler(); - static void pluginActionHandler( int menuItem ); + void clearOutputLog();//Output Window + void showInvalidImportsActionHandler(); + void showSuspectImportsActionHandler(); + void iatAutosearchActionHandler(); + void getImportsActionHandler(); + void appendPluginListToMenu( HMENU hMenuTrackPopup ); + void dumpActionHandler(); + DWORD_PTR getOEPFromGui(); + void peRebuildActionHandler(); + + void startDisassemblerGui(HTREEITEM selectedTreeNode); + void dumpFixActionHandler(); + void enableDialogButtons( BOOL value ); + void showAboutDialog(); + void dllInjectActionHandler(); + void optionsActionHandler(); + void pluginActionHandler( int menuItem ); }; \ No newline at end of file diff --git a/Scylla/MainGui.rc b/Scylla/MainGui.rc index 7f30fce..ef51c1c 100644 Binary files a/Scylla/MainGui.rc and b/Scylla/MainGui.rc differ diff --git a/Scylla/ProcessAccessHelp.h b/Scylla/ProcessAccessHelp.h index 81ee0c3..02bfb04 100644 --- a/Scylla/ProcessAccessHelp.h +++ b/Scylla/ProcessAccessHelp.h @@ -1,215 +1,217 @@ #pragma once #include #include #include #include #include /************************************************************************/ /* distorm */ /************************************************************************/ #include "distorm.h" +/* #ifdef _WIN64 #pragma comment(lib, "distorm_x64.lib") #else #pragma comment(lib, "distorm_x86.lib") #endif +*/ // 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; } WCHAR * getFilename() { for (size_t i = wcslen(fullPath) - 1; i >= 0; i--) { if (fullPath[i] == L'\\') { return (&fullPath[i] + 1); } } return fullPath; } }; class ApiInfo { public: char name[MAX_PATH]; DWORD hint; DWORD_PTR va; DWORD_PTR rva; DWORD_PTR 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, LPVOID dataBuffer); /* * Write memory to file end */ static bool writeMemoryToFileEnd(HANDLE hFile, DWORD size, LPVOID 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); /* * 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 WCHAR * selectFileToSave(DWORD flags, int type); static DWORD getEntryPointFromFile(const WCHAR * filePath); static bool createBackupFile(const WCHAR * filePath); }; diff --git a/Scylla/main.cpp b/Scylla/main.cpp index be84b32..9626fed 100644 --- a/Scylla/main.cpp +++ b/Scylla/main.cpp @@ -1,8 +1,40 @@ +#include // base ATL classes +#include // base WTL classes + +CAppModule _Module; + #include "MainGui.h" -int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) +MainGui* pMainGui = NULL; // for Logger + +int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { - //start main dialog - MainGui::initDialog(hInstance); - return 0; -} \ No newline at end of file + HRESULT hRes = CoInitialize(NULL); + // If you are running on NT 4.0 or higher you can use the following call instead to + // make the EXE free threaded. This means that calls come in on a random RPC thread. + //HRESULT hRes = ::CoInitializeEx(NULL, COINIT_MULTITHREADED); + ATLASSERT(SUCCEEDED(hRes)); + + // this resolves ATL window thunking problem when Microsoft Layer for Unicode (MSLU) is used + DefWindowProc(NULL, 0, 0, 0L); + + AtlInitCommonControls(ICC_BAR_CLASSES); // add flags to support other controls + + hRes = _Module.Init(NULL, hInstance); + ATLASSERT(SUCCEEDED(hRes)); + + int nRet = 0; + // BLOCK: Run application + { + MainGui dlgMain(hInstance); + + pMainGui = &dlgMain; // o_O + + nRet = dlgMain.DoModal(); + } + + _Module.Term(); + CoUninitialize(); + + return nRet; +}