Page MenuHomedesp's stash

No OneTemporary

diff --git a/Scylla/AboutGui.cpp b/Scylla/AboutGui.cpp
index 5fb88ed..614a7d5 100644
--- a/Scylla/AboutGui.cpp
+++ b/Scylla/AboutGui.cpp
@@ -1,125 +1,117 @@
#include "AboutGui.h"
#include "definitions.h"
const WCHAR AboutGui::TEXT_VISIT[] = L"Visit <a>http://kickme.to/grn</a> and <a>http://forum.tuts4you.com</a>";
const WCHAR AboutGui::TEXT_DEVELOPED[] = L"Developed with Microsoft Visual Studio, written in pure C/C++";
const WCHAR AboutGui::TEXT_CREDIT_DISTORM[] = L"This tool uses the <a>diStorm disassembler library</a> v3";
const WCHAR AboutGui::TEXT_CREDIT_YODA[] = L"The PE Rebuilder engine is based on Realign DLL v1.5 by yoda";
const WCHAR AboutGui::TEXT_CREDIT_SILK[] = L"The small icons are taken from the <a>Silk icon package</a>";
const WCHAR AboutGui::TEXT_CREDIT_WTL[] = L"<a>Windows Template Library</a> v8 is used for the GUI";
const WCHAR AboutGui::TEXT_GREETINGS[] = L"Greetz: metr0, G36KV and all from the gRn Team";
const WCHAR AboutGui::TEXT_LICENSE[] = L"Scylla is licensed under the <a>GNU General Public License v3</a>";
const WCHAR AboutGui::URL_VISIT1[] = L"http://kickme.to/grn";
const WCHAR AboutGui::URL_VISIT2[] = L"http://forum.tuts4you.com";
const WCHAR AboutGui::URL_DISTORM[] = L"http://code.google.com/p/distorm/";
const WCHAR AboutGui::URL_WTL[] = L"http://wtl.sourceforge.net";
const WCHAR AboutGui::URL_SILK[] = L"http://www.famfamfam.com";
const WCHAR AboutGui::URL_LICENSE[] = L"http://www.gnu.org/licenses/gpl-3.0.html";
BOOL AboutGui::OnInitDialog(CWindow wndFocus, LPARAM lInitParam)
{
- StaticTitle.Attach(GetDlgItem(IDC_STATIC_ABOUT_TITLE));
- StaticDeveloped.Attach(GetDlgItem(IDC_STATIC_DEVELOPED));
- StaticGreetings.Attach(GetDlgItem(IDC_STATIC_GREETINGS));
- StaticYoda.Attach(GetDlgItem(IDC_STATIC_YODA));
- LinkVisit.Attach(GetDlgItem(IDC_SYSLINK_VISIT));
- LinkDistorm.Attach(GetDlgItem(IDC_SYSLINK_DISTORM));
- LinkWTL.Attach(GetDlgItem(IDC_SYSLINK_WTL));
- LinkSilk.Attach(GetDlgItem(IDC_SYSLINK_SILK));
- LinkLicense.Attach(GetDlgItem(IDC_SYSLINK_LICENSE));
+ DoDataExchange(); // attach controls
// Create a bold font for the title
LOGFONT lf;
CFontHandle font = StaticTitle.GetFont();
font.GetLogFont(&lf);
lf.lfWeight = FW_BOLD;
FontBold.CreateFontIndirect(&lf);
StaticTitle.SetFont(FontBold, FALSE);
StaticTitle.SetWindowText(TEXT(APPNAME)TEXT(" ")TEXT(ARCHITECTURE)TEXT(" ")TEXT(APPVERSION));
StaticDeveloped.SetWindowText(TEXT_DEVELOPED);
StaticGreetings.SetWindowText(TEXT_GREETINGS);
StaticYoda.SetWindowText(TEXT_CREDIT_YODA);
setupLinks();
CenterWindow();
// Set focus to the OK button
GotoDlgCtrl(GetDlgItem(IDOK));
return FALSE;
}
void AboutGui::OnClose()
{
TooltipDistorm.DestroyWindow();
TooltipWTL.DestroyWindow();
TooltipSilk.DestroyWindow();
TooltipLicense.DestroyWindow();
FontBold.DeleteObject();
EndDialog(0);
}
LRESULT AboutGui::OnLink(NMHDR* pnmh)
{
const NMLINK* link = (NMLINK*)pnmh;
ShellExecute(NULL, L"open", link->item.szUrl, NULL, NULL, SW_SHOW);
return 0;
}
void AboutGui::OnExit(UINT uNotifyCode, int nID, CWindow wndCtl)
{
SendMessage(WM_CLOSE);
}
void AboutGui::setupLinks()
{
// Set link text (must be set before assigning URLs)
LinkVisit.SetWindowText(TEXT_VISIT);
LinkDistorm.SetWindowText(TEXT_CREDIT_DISTORM);
LinkWTL.SetWindowText(TEXT_CREDIT_WTL);
LinkSilk.SetWindowText(TEXT_CREDIT_SILK);
LinkLicense.SetWindowText(TEXT_LICENSE);
// Assign URLs to anchors in the link text
setLinkURL(LinkVisit, URL_VISIT1, 0);
setLinkURL(LinkVisit, URL_VISIT2, 1);
setLinkURL(LinkDistorm, URL_DISTORM);
setLinkURL(LinkWTL, URL_WTL);
setLinkURL(LinkSilk, URL_SILK);
setLinkURL(LinkLicense, URL_LICENSE);
// Create tooltips for the links
TooltipDistorm.Create(m_hWnd, NULL, NULL, TTS_NOPREFIX, WS_EX_TOPMOST);
TooltipWTL.Create(m_hWnd, NULL, NULL, TTS_NOPREFIX, WS_EX_TOPMOST);
TooltipSilk.Create(m_hWnd, NULL, NULL, TTS_NOPREFIX, WS_EX_TOPMOST);
TooltipLicense.Create(m_hWnd, NULL, NULL, TTS_NOPREFIX, WS_EX_TOPMOST);
// Assign control and text to the tooltips
setupTooltip(TooltipDistorm, LinkDistorm, URL_DISTORM);
setupTooltip(TooltipWTL, LinkWTL, URL_WTL);
setupTooltip(TooltipSilk, LinkSilk, URL_SILK);
setupTooltip(TooltipLicense, LinkLicense, URL_LICENSE);
}
void AboutGui::setLinkURL(CLinkCtrl& link, const WCHAR* url, int index)
{
LITEM item;
item.mask = LIF_ITEMINDEX | LIF_URL;
item.iLink = index;
wcscpy_s(item.szUrl, _countof(item.szUrl), url);
link.SetItem(&item);
}
void AboutGui::setupTooltip(CToolTipCtrl tooltip, CWindow window, const WCHAR* text)
{
CToolInfo ti(TTF_SUBCLASS, window);
window.GetClientRect(&ti.rect);
ti.lpszText = const_cast<WCHAR *>(text);
tooltip.AddTool(ti);
}
diff --git a/Scylla/AboutGui.h b/Scylla/AboutGui.h
index faedc53..4f38e77 100644
--- a/Scylla/AboutGui.h
+++ b/Scylla/AboutGui.h
@@ -1,93 +1,106 @@
#pragma once
#include <windows.h>
#include "resource.h"
// WTL
#include <atlbase.h> // base ATL classes
#include <atlapp.h> // base WTL classes
#include <atlwin.h> // ATL GUI classes
#include <atlcrack.h> // WTL enhanced msg map macros
#include <atlctrls.h> // WTL controls
+#include <atlddx.h> // WTL dialog data exchange
-class AboutGui : public CDialogImpl<AboutGui>
+class AboutGui : public CDialogImpl<AboutGui>, public CWinDataExchange<AboutGui>
{
public:
enum { IDD = IDD_DLG_ABOUT };
+ BEGIN_DDX_MAP(AboutGui)
+ DDX_CONTROL_HANDLE(IDC_STATIC_ABOUT_TITLE, StaticTitle)
+ DDX_CONTROL_HANDLE(IDC_STATIC_DEVELOPED, StaticDeveloped)
+ DDX_CONTROL_HANDLE(IDC_STATIC_GREETINGS, StaticGreetings)
+ DDX_CONTROL_HANDLE(IDC_STATIC_YODA, StaticYoda)
+ DDX_CONTROL_HANDLE(IDC_SYSLINK_VISIT, LinkVisit)
+ DDX_CONTROL_HANDLE(IDC_SYSLINK_DISTORM, LinkDistorm)
+ DDX_CONTROL_HANDLE(IDC_SYSLINK_WTL, LinkWTL)
+ DDX_CONTROL_HANDLE(IDC_SYSLINK_SILK, LinkSilk)
+ DDX_CONTROL_HANDLE(IDC_SYSLINK_LICENSE, LinkLicense)
+ END_DDX_MAP()
+
BEGIN_MSG_MAP(AboutGui)
MSG_WM_INITDIALOG(OnInitDialog)
MSG_WM_CLOSE(OnClose)
NOTIFY_HANDLER_EX(IDC_SYSLINK_DISTORM, NM_CLICK, OnLink)
NOTIFY_HANDLER_EX(IDC_SYSLINK_DISTORM, NM_RETURN, OnLink)
NOTIFY_HANDLER_EX(IDC_SYSLINK_WTL, NM_CLICK, OnLink)
NOTIFY_HANDLER_EX(IDC_SYSLINK_WTL, NM_RETURN, OnLink)
NOTIFY_HANDLER_EX(IDC_SYSLINK_SILK, NM_CLICK, OnLink)
NOTIFY_HANDLER_EX(IDC_SYSLINK_SILK, NM_RETURN, OnLink)
NOTIFY_HANDLER_EX(IDC_SYSLINK_VISIT, NM_CLICK, OnLink)
NOTIFY_HANDLER_EX(IDC_SYSLINK_VISIT, NM_RETURN, OnLink)
COMMAND_ID_HANDLER_EX(IDOK, OnExit)
COMMAND_ID_HANDLER_EX(IDCANCEL, OnExit)
END_MSG_MAP()
protected:
// Controls
CStatic StaticTitle;
CStatic StaticDeveloped;
CStatic StaticGreetings;
CStatic StaticYoda;
CLinkCtrl LinkVisit;
CLinkCtrl LinkDistorm;
CLinkCtrl LinkWTL;
CLinkCtrl LinkSilk;
CLinkCtrl LinkLicense;
CToolTipCtrl TooltipDistorm;
CToolTipCtrl TooltipWTL;
CToolTipCtrl TooltipSilk;
CToolTipCtrl TooltipLicense;
// Handles
CFontHandle FontBold;
// Texts
static const WCHAR TEXT_VISIT[];
static const WCHAR TEXT_DEVELOPED[];
static const WCHAR TEXT_CREDIT_DISTORM[];
static const WCHAR TEXT_CREDIT_YODA[];
static const WCHAR TEXT_CREDIT_WTL[];
static const WCHAR TEXT_CREDIT_SILK[];
static const WCHAR TEXT_GREETINGS[];
static const WCHAR TEXT_LICENSE[];
// URLs
static const WCHAR URL_VISIT1[];
static const WCHAR URL_VISIT2[];
static const WCHAR URL_DISTORM[];
static const WCHAR URL_WTL[];
static const WCHAR URL_SILK[];
static const WCHAR URL_LICENSE[];
protected:
// Message handlers
BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam);
void OnClose();
LRESULT OnLink(NMHDR* pnmh);
void OnExit(UINT uNotifyCode, int nID, CWindow wndCtl);
// GUI helpers
void setupLinks();
void setLinkURL(CLinkCtrl& link, const WCHAR* url, int index = 0);
void setupTooltip(CToolTipCtrl tooltip, CWindow window, const WCHAR* text);
};
diff --git a/Scylla/DisassemblerGui.cpp b/Scylla/DisassemblerGui.cpp
index cd0927a..bc48c85 100644
--- a/Scylla/DisassemblerGui.cpp
+++ b/Scylla/DisassemblerGui.cpp
@@ -1,145 +1,145 @@
#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));
+ DoDataExchange(); // attach controls
addColumnsToDisassembler(ListDisassembler);
displayDisassembly(ListDisassembler);
CenterWindow();
return TRUE;
}
void DisassemblerGui::OnContextMenu(CWindow wnd, CPoint point)
{
if (wnd.GetDlgCtrlID() == IDC_LIST_DISASSEMBLER)
{
int selection = ListDisassembler.GetSelectionMark();
if(selection == -1) // no item selected
return;
if(hMenuDisassembler)
{
if(point.x == -1 && point.y == -1) // invoked by keyboard
{
ListDisassembler.EnsureVisible(selection, TRUE);
ListDisassembler.GetItemPosition(selection, &point);
ListDisassembler.ClientToScreen(&point);
}
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)
{
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::OnExit(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);
list.InsertColumn(COL_INSTRUCTION_SIZE, L"Size", LVCFMT_CENTER);
list.InsertColumn(COL_OPCODES, L"Opcodes", LVCFMT_LEFT);
list.InsertColumn(COL_INSTRUCTION, L"Instructions", LVCFMT_LEFT);
}
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"%S",(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);
}
list.SetColumnWidth(COL_ADDRESS, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_INSTRUCTION_SIZE, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_OPCODES, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_INSTRUCTION, LVSCW_AUTOSIZE_USEHEADER);
}
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();
}
}
diff --git a/Scylla/DisassemblerGui.h b/Scylla/DisassemblerGui.h
index 8605352..5560782 100644
--- a/Scylla/DisassemblerGui.h
+++ b/Scylla/DisassemblerGui.h
@@ -1,69 +1,74 @@
#pragma once
#include <windows.h>
#include "resource.h"
// WTL
#include <atlbase.h> // base ATL classes
#include <atlapp.h> // base WTL classes
#include <atlwin.h> // ATL GUI classes
#include <atlmisc.h> // WTL utility classes like CString
#include <atlcrack.h> // WTL enhanced msg map macros
#include <atlctrls.h> // WTL controls
+#include <atlddx.h> // WTL dialog data exchange
-class DisassemblerGui : public CDialogImpl<DisassemblerGui>
+class DisassemblerGui : public CDialogImpl<DisassemblerGui>, public CWinDataExchange<DisassemblerGui>
{
public:
enum { IDD = IDD_DLG_DISASSEMBLER };
+ BEGIN_DDX_MAP(DisassemblerGui)
+ DDX_CONTROL_HANDLE(IDC_LIST_DISASSEMBLER, ListDisassembler)
+ END_DDX_MAP()
+
BEGIN_MSG_MAP(DisassemblerGui)
MSG_WM_INITDIALOG(OnInitDialog)
MSG_WM_CONTEXTMENU(OnContextMenu)
COMMAND_ID_HANDLER_EX(IDCANCEL, OnExit)
COMMAND_ID_HANDLER_EX(IDOK, OnExit)
END_MSG_MAP()
DisassemblerGui(DWORD_PTR 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 = 0,
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 OnExit(UINT uNotifyCode, int nID, CWindow wndCtl);
// GUI functions
void addColumnsToDisassembler(CListViewCtrl& list);
void displayDisassembly(CListViewCtrl& list);
// Misc
void copyToClipboard(const WCHAR * text);
};
diff --git a/Scylla/ImportsHandling.cpp b/Scylla/ImportsHandling.cpp
index 764e481..bbe7ab4 100644
--- a/Scylla/ImportsHandling.cpp
+++ b/Scylla/ImportsHandling.cpp
@@ -1,784 +1,784 @@
#include "ImportsHandling.h"
#include "Thunks.h"
#include "definitions.h"
#include "resource.h"
//#define DEBUG_COMMENTS
-ImportsHandling::ImportsHandling(CTreeViewCtrl& TreeImports) : TreeImports(TreeImports)
+ImportsHandling::ImportsHandling(CTreeViewCtrlEx& TreeImports) : TreeImports(TreeImports)
{
hIconCheck.LoadIcon(IDI_ICON_CHECK);
hIconWarning.LoadIcon(IDI_ICON_WARNING);
hIconError.LoadIcon(IDI_ICON_ERROR);
TreeIcons.Create(16, 16, ILC_COLOR32, 3, 1);
TreeIcons.AddIcon(hIconCheck);
TreeIcons.AddIcon(hIconWarning);
TreeIcons.AddIcon(hIconError);
}
ImportsHandling::~ImportsHandling()
{
TreeIcons.Destroy();
}
bool ImportModuleThunk::isValid() const
{
std::map<DWORD_PTR, ImportThunk>::const_iterator iterator = thunkList.begin();
while (iterator != thunkList.end())
{
if (iterator->second.valid == false)
{
return false;
}
iterator++;
}
return true;
}
DWORD_PTR ImportModuleThunk::getFirstThunk() const
{
if (thunkList.size() > 0)
{
const std::map<DWORD_PTR, ImportThunk>::const_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<DWORD_PTR,ImportModuleThunk>(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<DWORD_PTR, ImportModuleThunk>::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<DWORD_PTR,ImportThunk>(import.rva, import));
return true;
}*/
void ImportsHandling::displayAllImports()
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator it_module;
std::map<DWORD_PTR, ImportThunk>::iterator it_thunk;
ImportModuleThunk * moduleThunk;
ImportThunk * importThunk;
CTreeItem module;
CTreeItem apiFunction;
TreeImports.DeleteAllItems();
TreeImports.SetImageList(TreeIcons);
it_module = moduleList.begin();
while (it_module != moduleList.end())
{
moduleThunk = &(it_module->second);
module = addDllToTreeView(TreeImports,moduleThunk);
moduleThunk->hTreeItem = module;
it_thunk = moduleThunk->thunkList.begin();
while (it_thunk != moduleThunk->thunkList.end())
{
importThunk = &(it_thunk->second);
apiFunction = addApiToTreeView(TreeImports,module,importThunk);
importThunk->hTreeItem = apiFunction;
it_thunk++;
}
it_module++;
}
}
-CTreeItem ImportsHandling::addDllToTreeView(CTreeViewCtrl& idTreeView, const ImportModuleThunk * importThunk)
+CTreeItem ImportsHandling::addDllToTreeView(CTreeViewCtrlEx& idTreeView, const ImportModuleThunk * importThunk)
{
CTreeItem item = idTreeView.InsertItem(L"", NULL, TVI_ROOT);
updateModuleInTreeView(importThunk, item);
return item;
}
-CTreeItem ImportsHandling::addApiToTreeView(CTreeViewCtrl& idTreeView, CTreeItem parentDll, const ImportThunk * importThunk)
+CTreeItem ImportsHandling::addApiToTreeView(CTreeViewCtrlEx& idTreeView, CTreeItem parentDll, const ImportThunk * importThunk)
{
CTreeItem item = idTreeView.InsertItem(L"", parentDll, TVI_LAST);
updateImportInTreeView(importThunk, item);
return item;
}
void ImportsHandling::showImports(bool invalid, bool suspect)
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator iterator1;
std::map<DWORD_PTR, ImportThunk>::iterator iterator2;
ImportModuleThunk * moduleThunk;
ImportThunk * importThunk;
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(TreeImports, importThunk->hTreeItem);
+ selectItem(importThunk->hTreeItem);
setFocus(TreeImports, importThunk->hTreeItem);
}
else if (suspect && importThunk->suspect)
{
- selectItem(TreeImports, importThunk->hTreeItem);
+ selectItem(importThunk->hTreeItem);
setFocus(TreeImports, importThunk->hTreeItem);
}
else
{
- unselectItem(TreeImports, importThunk->hTreeItem);
+ unselectItem(importThunk->hTreeItem);
}
iterator2++;
}
iterator1++;
}
}
-bool ImportsHandling::isItemSelected(const CTreeViewCtrl& hwndTV, CTreeItem hItem)
+bool ImportsHandling::isItemSelected(CTreeItem hItem)
{
const UINT state = TVIS_SELECTED;
- return ((hwndTV.GetItemState(hItem, state) & state) == state);
+ return ((hItem.GetState(state) & state) == state);
}
-void ImportsHandling::unselectItem(CTreeViewCtrl& hwndTV, CTreeItem htItem)
+void ImportsHandling::unselectItem(CTreeItem htItem)
{
- selectItem(hwndTV, htItem, false);
+ selectItem(htItem, false);
}
-bool ImportsHandling::selectItem(CTreeViewCtrl& hwndTV, CTreeItem hItem, bool select)
+bool ImportsHandling::selectItem(CTreeItem hItem, bool select)
{
const UINT state = TVIS_SELECTED;
- return FALSE != hwndTV.SetItemState(hItem, (select ? state : 0), state);
+ return FALSE != hItem.SetState((select ? state : 0), state);
}
-void ImportsHandling::setFocus(CTreeViewCtrl& hwndTV, CTreeItem htItem)
+void ImportsHandling::setFocus(CTreeViewCtrlEx& hwndTV, CTreeItem htItem)
{
// the current focus
CTreeItem htFocus = hwndTV.GetSelectedItem();
if ( htItem )
{
// set the focus
if ( htItem != htFocus )
{
// remember the selection state of the item
- bool wasSelected = isItemSelected(hwndTV, htItem);
+ bool wasSelected = isItemSelected(htItem);
- if ( htFocus && isItemSelected(hwndTV, htFocus) )
+ if ( htFocus && isItemSelected(htFocus) )
{
// prevent the tree from unselecting the old focus which it
// would do by default (TreeView_SelectItem unselects the
// focused item)
hwndTV.SelectItem(NULL);
- selectItem(hwndTV, htFocus);
+ selectItem(htFocus);
}
hwndTV.SelectItem(htItem);
if ( !wasSelected )
{
// need to clear the selection which TreeView_SelectItem() gave
// us
- unselectItem(hwndTV, htItem);
+ unselectItem(htItem);
}
//else: was selected, still selected - ok
}
//else: nothing to do, focus already there
}
else
{
if ( htFocus )
{
- bool wasFocusSelected = isItemSelected(hwndTV, htFocus);
+ bool wasFocusSelected = isItemSelected(htFocus);
// just clear the focus
hwndTV.SelectItem(NULL);
if ( wasFocusSelected )
{
// restore the selection state
- selectItem(hwndTV, htFocus);
+ selectItem(htFocus);
}
}
//else: nothing to do, no focus already
}
}
bool ImportsHandling::invalidateFunction(CTreeItem selectedTreeNode)
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator iterator1;
std::map<DWORD_PTR, ImportThunk>::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)
{
importThunk->ordinal = 0;
importThunk->hint = 0;
importThunk->valid = false;
importThunk->suspect = false;
importThunk->moduleName[0] = 0;
importThunk->name[0] = 0;
updateImportInTreeView(importThunk, importThunk->hTreeItem);
updateModuleInTreeView(moduleThunk, moduleThunk->hTreeItem);
return true;
}
iterator2++;
}
iterator1++;
}
return false;
}
void ImportsHandling::updateImportInTreeView(const ImportThunk * importThunk, CTreeItem item)
{
if (importThunk->valid)
{
+ WCHAR tempString[300];
+
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(" rva: ")TEXT(PRINTF_DWORD_PTR_HALF)TEXT(" mod: %s %s"),importThunk->rva,importThunk->moduleName,tempString);
}
else
{
swprintf_s(stringBuffer, _countof(stringBuffer),TEXT(" rva: ")TEXT(PRINTF_DWORD_PTR_HALF)TEXT(" ptr: ")TEXT(PRINTF_DWORD_PTR_FULL),importThunk->rva,importThunk->apiAddressVA);
}
- TreeImports.SetItemText(item, stringBuffer);
+ item.SetText(stringBuffer);
Icon icon = getAppropiateIcon(importThunk);
- TreeImports.SetItemImage(item, icon, icon);
+ item.SetImage(icon, icon);
}
void ImportsHandling::updateModuleInTreeView(const ImportModuleThunk * importThunk, CTreeItem item)
{
- //swprintf_s(stringBuffer, _countof(stringBuffer),TEXT("%s FThunk: ")TEXT(PRINTF_DWORD_PTR_HALF)TEXT(" NbThunk: %d"),importThunk->moduleName,importThunk->firstThunk,importThunk->thunkList.size());
swprintf_s(stringBuffer, _countof(stringBuffer),TEXT("%s (%d) FThunk: ")TEXT(PRINTF_DWORD_PTR_HALF),importThunk->moduleName,importThunk->thunkList.size(), importThunk->firstThunk);
- TreeImports.SetItemText(item, stringBuffer);
+ item.SetText(stringBuffer);
Icon icon = getAppropiateIcon(importThunk->isValid());
- TreeImports.SetItemImage(item, icon, icon);
+ item.SetImage(icon, icon);
}
ImportsHandling::Icon ImportsHandling::getAppropiateIcon(const ImportThunk * importThunk)
{
if(importThunk->valid)
{
if(importThunk->suspect)
{
return iconWarning;
}
else
{
return iconCheck;
}
}
else
{
return iconError;
}
}
ImportsHandling::Icon ImportsHandling::getAppropiateIcon(bool valid)
{
if(valid)
{
return iconCheck;
}
else
{
return iconError;
}
}
bool ImportsHandling::cutThunk(CTreeItem selectedTreeNode)
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator iterator1;
std::map<DWORD_PTR, ImportThunk>::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)
{
- TreeImports.DeleteItem(importThunk->hTreeItem);
+ importThunk->hTreeItem.Delete();
moduleThunk->thunkList.erase(iterator2);
if (moduleThunk->thunkList.empty())
{
- TreeImports.DeleteItem(moduleThunk->hTreeItem);
+ moduleThunk->hTreeItem.Delete();
moduleList.erase(iterator1);
}
else
{
updateModuleInTreeView(moduleThunk, moduleThunk->hTreeItem);
}
return true;
}
iterator2++;
}
iterator1++;
}
return false;
}
bool ImportsHandling::deleteTreeNode(CTreeItem selectedTreeNode)
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator iterator1;
std::map<DWORD_PTR, ImportThunk>::iterator iterator2;
ImportModuleThunk * moduleThunk;
ImportThunk * importThunk;
iterator1 = moduleList.begin();
while (iterator1 != moduleList.end())
{
moduleThunk = &(iterator1->second);
if (moduleThunk->hTreeItem == selectedTreeNode)
{
- TreeImports.DeleteItem(moduleThunk->hTreeItem);
+ moduleThunk->hTreeItem.Delete();
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)
{
- TreeImports.DeleteItem(moduleThunk->hTreeItem);
+ moduleThunk->hTreeItem.Delete();
moduleThunk->thunkList.clear();
moduleList.erase(iterator1);
return true;
}
iterator2++;
}
}
iterator1++;
}
return false;
}
DWORD_PTR ImportsHandling::getApiAddressByNode(CTreeItem selectedTreeNode)
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator iterator1;
std::map<DWORD_PTR, ImportThunk>::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<DWORD_PTR, ImportModuleThunk>::iterator iterator1;
std::map<DWORD_PTR, ImportThunk>::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());
+ moduleList = moduleListNew;
moduleListNew.clear();
}
bool ImportsHandling::findNewModules(std::map<DWORD_PTR, ImportThunk> & 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<DWORD_PTR,ImportModuleThunk>(firstThunk,module));
return true;
}
bool ImportsHandling::isNewModule(const WCHAR * moduleName)
{
std::map<DWORD_PTR, ImportModuleThunk>::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, L"?");
moduleListNew.insert(std::pair<DWORD_PTR,ImportModuleThunk>(firstThunk,module));
}
bool ImportsHandling::addNotFoundApiToModuleList(const ImportThunk * apiNotFound)
{
ImportThunk import;
ImportModuleThunk * module = 0;
std::map<DWORD_PTR, ImportModuleThunk>::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, L"?");
strcpy_s(import.name, MAX_PATH, "?");
module->thunkList.insert(std::pair<DWORD_PTR,ImportThunk>(import.rva, import));
return true;
}
bool ImportsHandling::addFunctionToModuleList(const ImportThunk * apiFound)
{
ImportThunk import;
ImportModuleThunk * module = 0;
std::map<DWORD_PTR, ImportModuleThunk>::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<DWORD_PTR,ImportThunk>(import.rva, import));
return true;
}
void ImportsHandling::expandAllTreeNodes()
{
changeExpandStateOfTreeNodes(TVE_EXPAND);
}
void ImportsHandling::collapseAllTreeNodes()
{
changeExpandStateOfTreeNodes(TVE_COLLAPSE);
}
void ImportsHandling::changeExpandStateOfTreeNodes(UINT flag)
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator iterator1;
ImportModuleThunk * moduleThunk;
iterator1 = moduleList.begin();
while (iterator1 != moduleList.end())
{
moduleThunk = &(iterator1->second);
- TreeImports.Expand(moduleThunk->hTreeItem, flag);
+ moduleThunk->hTreeItem.Expand(flag);
iterator1++;
}
}
diff --git a/Scylla/ImportsHandling.h b/Scylla/ImportsHandling.h
index 2015c38..3c4f8ab 100644
--- a/Scylla/ImportsHandling.h
+++ b/Scylla/ImportsHandling.h
@@ -1,76 +1,75 @@
#pragma once
#include <map>
// WTL
#include <atlbase.h>
#include <atlapp.h>
-#include <atlctrls.h> // CTreeViewCtrl, CTreeItem
+#include <atlctrls.h> // CTreeViewCtrlEx, CTreeItem
class ImportThunk;
class ImportModuleThunk;
class ImportsHandling
{
public:
std::map<DWORD_PTR, ImportModuleThunk> moduleList;
std::map<DWORD_PTR, ImportModuleThunk> 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);
+ ImportsHandling(CTreeViewCtrlEx& TreeImports);
~ImportsHandling();
void displayAllImports();
void showImports(bool invalid, bool suspect);
bool invalidateFunction(CTreeItem selectedTreeNode);
bool cutThunk(CTreeItem selectedTreeNode);
bool deleteTreeNode(CTreeItem selectedTreeNode);
void updateImportInTreeView(const ImportThunk * importThunk, CTreeItem item);
void updateModuleInTreeView(const ImportModuleThunk * importThunk, CTreeItem item);
DWORD_PTR getApiAddressByNode(CTreeItem selectedTreeNode);
void scanAndFixModuleList();
void expandAllTreeNodes();
void collapseAllTreeNodes();
private:
DWORD numberOfFunctions;
- WCHAR stringBuffer[600]; // o_O
- WCHAR tempString[300];
+ WCHAR stringBuffer[600];
- CTreeViewCtrl& TreeImports;
+ CTreeViewCtrlEx& TreeImports;
CImageList TreeIcons;
CIcon hIconCheck;
CIcon hIconWarning;
CIcon hIconError;
// They have to be added to the image list in that order!
enum Icon {
iconCheck = 0,
iconWarning,
iconError
};
- CTreeItem addDllToTreeView(CTreeViewCtrl& idTreeView, const ImportModuleThunk * importThunk);
- CTreeItem addApiToTreeView(CTreeViewCtrl& idTreeView, CTreeItem parentDll, const ImportThunk * importThunk);
+ CTreeItem addDllToTreeView(CTreeViewCtrlEx& idTreeView, const ImportModuleThunk * importThunk);
+ CTreeItem addApiToTreeView(CTreeViewCtrlEx& idTreeView, CTreeItem parentDll, const ImportThunk * importThunk);
- bool isItemSelected(const CTreeViewCtrl& hwndTV, CTreeItem hItem);
- void unselectItem(CTreeViewCtrl& hwndTV, CTreeItem htItem);
- bool selectItem(CTreeViewCtrl& hwndTV, CTreeItem hItem, bool select = true);
- void setFocus(CTreeViewCtrl& hwndTV, CTreeItem htItem);
+ bool isItemSelected(CTreeItem hItem);
+ void unselectItem(CTreeItem htItem);
+ bool selectItem(CTreeItem hItem, bool select = true);
+ void setFocus(CTreeViewCtrlEx& hwndTV, CTreeItem htItem);
bool findNewModules(std::map<DWORD_PTR, ImportThunk> & thunkList);
Icon getAppropiateIcon(const ImportThunk * importThunk);
Icon getAppropiateIcon(bool valid);
bool addModuleToModuleList(const WCHAR * moduleName, DWORD_PTR firstThunk);
void addUnknownModuleToModuleList(DWORD_PTR firstThunk);
bool addNotFoundApiToModuleList(const ImportThunk * apiNotFound);
bool addFunctionToModuleList(const ImportThunk * apiFound);
bool isNewModule(const WCHAR * moduleName);
void changeExpandStateOfTreeNodes(UINT flag);
};
diff --git a/Scylla/Logger.h b/Scylla/Logger.h
index 2ff6a97..5e6a2e7 100644
--- a/Scylla/Logger.h
+++ b/Scylla/Logger.h
@@ -1,20 +1,20 @@
#pragma once
#include <windows.h>
#define DEBUG_LOG_FILENAME "Scylla_debug.log"
class Logger {
public:
static void debugLog(const WCHAR * format, ...);
static void debugLog(const CHAR * format, ...);
static void printfDialog(const WCHAR * format, ...);
static void getDebugLogFilePath();
private:
static WCHAR debugLogFile[MAX_PATH];
static WCHAR logbuf[300];
static char logbufChar[300];
-};
\ No newline at end of file
+};
diff --git a/Scylla/MainGui.cpp b/Scylla/MainGui.cpp
index 3bea1e5..73f39b4 100644
--- a/Scylla/MainGui.cpp
+++ b/Scylla/MainGui.cpp
@@ -1,1141 +1,1129 @@
#include "MainGui.h"
#include <atldlgs.h> // WTL common dialogs
#include "definitions.h"
#include "PluginLoader.h"
#include "ConfigurationHolder.h"
#include "PeDump.h"
#include "PeRebuild.h"
#include "DllInjectionPlugin.h"
#include "DisassemblerGui.h"
#include "PickApiGui.h"
#include "NativeWinApi.h"
#include "ImportRebuild.h"
#include "SystemInformation.h"
#include "AboutGui.h"
#include "OptionsGui.h"
#include "WindowDeferrer.h"
const WCHAR MainGui::filterExe[] = L"Executable (*.exe)\0*.exe\0All files\0*.*\0";
const WCHAR MainGui::filterDll[] = L"Dynamic Link Library (*.dll)\0*.dll\0All files\0*.*\0";
const WCHAR MainGui::filterExeDll[] = L"Executable (*.exe)\0*.exe\0Dynamic Link Library (*.dll)\0*.dll\0All files\0*.*\0";
const WCHAR MainGui::filterTxt[] = L"Text file (*.txt)\0*.txt\0All files\0*.*\0";
MainGui::MainGui() : selectedProcess(0), importsHandling(TreeImports)
{
Logger::getDebugLogFilePath();
ConfigurationHolder::loadConfiguration();
PluginLoader::findAllPlugins();
NativeWinApi::initialize();
SystemInformation::getSystemInformation();
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)
{
if(IDCANCEL == MessageBox(L"Operating System is not supported\r\nContinue anyway?", L"Scylla", MB_ICONWARNING | MB_OKCANCEL))
{
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));
+ DoDataExchange(); // attach controls
EditOEPAddress.LimitText(MAX_HEX_VALUE_EDIT_LENGTH);
EditIATAddress.LimitText(MAX_HEX_VALUE_EDIT_LENGTH);
EditIATSize.LimitText(MAX_HEX_VALUE_EDIT_LENGTH);
appendPluginListToMenu(CMenuHandle(GetMenu()).GetSubMenu(MenuImportsOffsetTrace));
enableDialogControls(FALSE);
setIconAndDialogCaption();
GetWindowRect(&minDlgSize);
return TRUE;
}
void MainGui::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
{
- lpMMI->ptMinTrackSize.x = minDlgSize.Width();
- lpMMI->ptMinTrackSize.y = minDlgSize.Height();
+ lpMMI->ptMinTrackSize = CPoint(minDlgSize.Size());
}
void MainGui::OnSizing(UINT fwSide, RECT* pRect)
{
// Get size difference
CRect rectOld;
GetWindowRect(&rectOld);
CRect rectNew = *pRect;
- int deltaX = rectNew.Width() - rectOld.Width();
- int deltaY = rectNew.Height() - rectOld.Height();
-
- CSize delta(deltaX, deltaY);
- sizeOffset = delta;
+ sizeOffset = rectNew.Size() - rectOld.Size();
}
void MainGui::OnSize(UINT nType, CSize size)
{
const 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_BTN_INVALIDIMPORTS, false, true, false, false},
{IDC_BTN_SUSPECTIMPORTS, false, true, false, false},
{IDC_BTN_SAVETREE, true, true, false, false},
{IDC_BTN_LOADTREE, true, true, false, false},
{IDC_BTN_CLEARIMPORTS, true, true, false, false},
{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_ACTIONS, false, true, false, false},
{IDC_BTN_AUTOTRACE, false, true, false, false},
{IDC_GROUP_DUMP, false, true, false, false},
{IDC_BTN_DUMP, false, true, false, false},
{IDC_BTN_PEREBUILD, false, true, false, false},
{IDC_BTN_FIXDUMP, false, true, false, false},
{IDC_GROUP_LOG, false, true, true, false},
{IDC_LIST_LOG, false, true, true, false}
};
if(nType == SIZE_RESTORED)
{
WindowDeferrer deferrer(m_hWnd, controls, _countof(controls));
deferrer.defer(sizeOffset.cx, sizeOffset.cy);
sizeOffset.SetSize(0, 0);
}
}
void MainGui::OnLButtonDown(UINT nFlags, CPoint point)
{
SetMsgHandled(false);
}
void MainGui::OnContextMenu(CWindow wnd, CPoint point)
{
// point = -1, -1 for keyboard invoked shortcut!
switch(wnd.GetDlgCtrlID())
{
case IDC_TREE_IMPORTS:
DisplayContextMenuImports(wnd, point);
return;
case IDC_LIST_LOG:
DisplayContextMenuLog(wnd, point);
return;
//default: // wnd == m_hWnd?
// DisplayContextMenu(wnd, point);
// return;
}
SetMsgHandled(false);
}
void MainGui::OnCommand(UINT uNotifyCode, int nID, CWindow wndCtl)
{
// Make sure it's a menu
if(uNotifyCode == 0 && !wndCtl.IsWindow())
{
if ((nID >= PLUGIN_MENU_BASE_ID) && (nID <= (int)(PluginLoader::getScyllaPluginList().size() + PluginLoader::getImprecPluginList().size() + PLUGIN_MENU_BASE_ID)))
{
pluginActionHandler(nID);
return;
}
}
SetMsgHandled(false);
}
LRESULT MainGui::OnTreeImportsClick(const NMHDR* pnmh)
{
SetMsgHandled(false);
return false;
}
LRESULT MainGui::OnTreeImportsDoubleClick(const NMHDR* pnmh)
{
- CPoint pt = GetMessagePos();
SetMsgHandled(false);
if(TreeImports.GetCount() < 1)
return false;
// Get item under cursor
CPoint client = GetMessagePos();
TreeImports.ScreenToClient(&client);
UINT flags;
CTreeItem over = TreeImports.HitTest(client, &flags);
CTreeItem parent;
if(over)
{
if(!(flags & TVHT_ONITEM))
{
over = NULL;
}
else
{
- parent = TreeImports.GetParentItem(over);
+ parent = over.GetParent();
}
}
if(!over.IsNull() && !parent.IsNull())
{
PickApiGui dlgPickApi(processAccessHelp.moduleList);
if(dlgPickApi.DoModal())
{
const ApiInfo* api = dlgPickApi.getSelectedApi();
if(api && api->module)
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator iterator1;
std::map<DWORD_PTR, ImportThunk>::iterator iterator2;
iterator1 = importsHandling.moduleList.begin();
while(iterator1 != importsHandling.moduleList.end())
{
if(iterator1->second.hTreeItem == parent)
{
iterator2 = iterator1->second.thunkList.begin();
while(iterator2 != iterator1->second.thunkList.end())
{
if(iterator2->second.hTreeItem == over)
{
ImportThunk &imp = iterator2->second;
wcscpy_s(imp.moduleName, MAX_PATH, api->module->getFilename());
strcpy_s(imp.name, MAX_PATH, api->name);
imp.ordinal = api->ordinal;
//imp.apiAddressVA = api->va;
imp.hint = api->hint;
imp.valid = true;
imp.suspect = api->isForwarded;
importsHandling.updateImportInTreeView(&imp, over);
break;
}
iterator2++;
}
break;
}
iterator1++;
}
}
}
}
return false;
}
LRESULT MainGui::OnTreeImportsRightClick(const NMHDR* pnmh)
{
/*
HTREEITEM selectedTreeNode = TreeImports.GetNextItem(NULL, TVGN_DROPHILITE);
if(selectedTreeNode != NULL)
{
TreeImports.Select(selectedTreeNode, TVGN_CARET);
}
*/
SetMsgHandled(false);
return false;
}
LRESULT MainGui::OnTreeImportsRightDoubleClick(const NMHDR* pnmh)
{
SetMsgHandled(false);
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)
{
clearImportsActionHandler();
}
void MainGui::OnInvalidateSelected(UINT uNotifyCode, int nID, CWindow wndCtl)
{
// TODO
}
void MainGui::OnCutSelected(UINT uNotifyCode, int nID, CWindow wndCtl)
{
// TODO
}
void MainGui::OnSaveTree(UINT uNotifyCode, int nID, CWindow wndCtl)
{
// TODO
}
void MainGui::OnLoadTree(UINT uNotifyCode, int nID, CWindow wndCtl)
{
// TODO
}
void MainGui::OnAutotrace(UINT uNotifyCode, int nID, CWindow wndCtl)
{
// TODO
}
void MainGui::OnExit(UINT uNotifyCode, int nID, CWindow wndCtl)
{
EndDialog(0);
}
void MainGui::OnAbout(UINT uNotifyCode, int nID, CWindow wndCtl)
{
showAboutDialog();
}
bool MainGui::showFileDialog(WCHAR * selectedFile, bool save, const WCHAR * defFileName, const WCHAR * filter, const WCHAR * defExtension, const WCHAR * directory)
{
OPENFILENAME ofn = {0};
// WTL doesn't support new explorer styles on Vista and up
// This is because it uses a custom hook, we could remove it or derive
// from CFileDialog but this solution is easier and allows more control anyway (e.g. initial dir)
if(defFileName)
{
wcscpy_s(selectedFile, MAX_PATH, defFileName);
}
else
{
selectedFile[0] = _T('\0');
}
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = m_hWnd;
ofn.lpstrFilter = filter;
ofn.lpstrDefExt = defExtension; // only first 3 chars are used, no dots!
ofn.lpstrFile = selectedFile;
ofn.lpstrInitialDir = directory;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
/*
*OFN_EXPLORER is automatically used, it only has to be specified
*if using a custom hook
*OFN_LONGNAMES is automatically used by explorer-style dialogs
*/
if(save)
ofn.Flags |= OFN_OVERWRITEPROMPT;
else
ofn.Flags |= OFN_FILEMUSTEXIST;
if(save)
return 0 != GetSaveFileName(&ofn);
else
return 0 != GetOpenFileName(&ofn);
}
void MainGui::setIconAndDialogCaption()
{
SetIcon(hIcon, TRUE);
SetIcon(hIcon, FALSE);
SetWindowText(TEXT(APPNAME)TEXT(" ")TEXT(ARCHITECTURE)TEXT(" ")TEXT(APPVERSION));
}
void MainGui::pickDllActionHandler()
{
if(!selectedProcess)
return;
PickDllGui dlgPickDll(processAccessHelp.moduleList);
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)
{
if(!selectedProcess)
return;
DWORD_PTR address = importsHandling.getApiAddressByNode(selectedTreeNode);
if (address)
{
BYTE test;
if(!ProcessAccessHelp::readMemoryFromProcess(address, sizeof(test), &test))
{
swprintf_s(stringBuffer, _countof(stringBuffer), TEXT("Can't read memory at ")TEXT(PRINTF_DWORD_PTR_FULL),address);
MessageBox(stringBuffer, L"Failure", MB_ICONERROR);
}
else
{
DisassemblerGui dlgDisassembler(address);
dlgDisassembler.DoModal();
}
}
}
void MainGui::processSelectedActionHandler(int index)
{
std::vector<Process>& processList = processLister.getProcessList();
Process &process = processList.at(index);
selectedProcess = 0;
clearImportsActionHandler();
Logger::printfDialog(TEXT("Analyzing %s"),process.fullPath);
if (processAccessHelp.hProcess != 0)
{
processAccessHelp.closeProcessHandle();
apiReader.clearAll();
}
if (!processAccessHelp.openProcessHandle(process.PID))
{
enableDialogControls(FALSE);
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);
process.entryPoint = ProcessAccessHelp::getEntryPointFromFile(process.fullPath);
swprintf_s(stringBuffer, _countof(stringBuffer),TEXT(PRINTF_DWORD_PTR_FULL),process.entryPoint + process.imageBase);
EditOEPAddress.SetWindowText(stringBuffer);
selectedProcess = &process;
enableDialogControls(TRUE);
}
void MainGui::fillProcessListComboBox(CComboBox& hCombo)
{
hCombo.ResetContent();
std::vector<Process>& processList = processLister.getProcessListSnapshot();
for (size_t i = 0; i < processList.size(); i++)
{
swprintf_s(stringBuffer, _countof(stringBuffer),TEXT("0x%04X - %s - %s"),processList[i].PID,processList[i].filename,processList[i].fullPath);
hCombo.AddString(stringBuffer);
}
}
void MainGui::addTextToOutputLog(const WCHAR * text)
{
if (m_hWnd)
{
ListLog.SetCurSel(ListLog.AddString(text));
}
}
void MainGui::clearOutputLog()
{
if (m_hWnd)
{
ListLog.ResetContent();
}
}
bool MainGui::saveLogToFile(const WCHAR * file)
{
const BYTE BOM[] = {0xFF, 0xFE}; // UTF-16 little-endian
const WCHAR newLine[] = L"\r\n";
bool success = true;
HANDLE hFile = CreateFile(file, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if(hFile != INVALID_HANDLE_VALUE)
{
ProcessAccessHelp::writeMemoryToFileEnd(hFile, sizeof(BOM), BOM);
WCHAR * buffer = 0;
int bufsize = 0;
for(int i = 0; i < ListLog.GetCount(); i++)
{
int size = ListLog.GetTextLen(i);
size += _countof(newLine)-1;
if(size+1 > bufsize)
{
bufsize = size+1;
delete[] buffer;
try
{
buffer = new WCHAR[bufsize];
}
catch(std::bad_alloc&)
{
buffer = 0;
success = false;
break;
}
}
ListLog.GetText(i, buffer);
wcscat_s(buffer, bufsize, newLine);
ProcessAccessHelp::writeMemoryToFileEnd(hFile, size * sizeof(WCHAR), buffer);
}
delete[] buffer;
CloseHandle(hFile);
}
return success;
}
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(!selectedProcess)
return;
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(!selectedProcess)
return;
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;
CTreeItem over, parent;
if(pt.x == -1 && pt.y == -1) // invoked by keyboard
{
CRect pos;
over = TreeImports.GetSelectedItem();
if(over)
{
- TreeImports.EnsureVisible(over);
- TreeImports.GetItemRect(over, &pos, TRUE);
+ over.EnsureVisible();
+ over.GetRect(&pos, TRUE);
TreeImports.ClientToScreen(&pos);
}
else
{
TreeImports.GetWindowRect(&pos);
}
pt = pos.TopLeft();
}
else
{
// Get item under cursor
CPoint client = pt;
TreeImports.ScreenToClient(&client);
UINT flags;
over = TreeImports.HitTest(client, &flags);
if(over && !(flags & TVHT_ONITEM))
{
over = NULL;
}
}
if(over)
{
- parent = TreeImports.GetParentItem(over);
+ parent = over.GetParent();
}
if (hMenuImports)
{
// Prepare hmenuImports
SetupImportsMenuItems(!over.IsNull(), !parent.IsNull());
CMenuHandle hSub = hMenuImports.GetSubMenu(0);
BOOL menuItem = hSub.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, hwnd);
if (menuItem)
{
if ((menuItem >= PLUGIN_MENU_BASE_ID) && (menuItem <= (int)(PluginLoader::getScyllaPluginList().size() + PluginLoader::getImprecPluginList().size() + PLUGIN_MENU_BASE_ID)))
{
//wsprintf(stringBuffer, L"%d %s\n",menuItem,pluginList[menuItem - PLUGIN_MENU_BASE_ID].pluginName);
//MessageBox(stringBuffer, L"plugin selection");
pluginActionHandler(menuItem);
return;
}
switch (menuItem)
{
case ID__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)
{
if (hMenuLog)
{
if(pt.x == -1 && pt.y == -1) // invoked by keyboard
{
CRect pos;
ListLog.GetWindowRect(&pos);
pt = pos.TopLeft();
}
CMenuHandle hSub = hMenuLog.GetSubMenu(0);
BOOL menuItem = hSub.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, hwnd);
if (menuItem)
{
switch (menuItem)
{
case ID__SAVE:
WCHAR selectedFilePath[MAX_PATH];
if(showFileDialog(selectedFilePath, true, NULL, filterTxt, L"txt"))
{
saveLogToFile(selectedFilePath);
}
break;
case ID__CLEAR:
clearOutputLog();
break;
}
}
}
}
void MainGui::appendPluginListToMenu(CMenuHandle hMenu)
{
std::vector<Plugin> &scyllaPluginList = PluginLoader::getScyllaPluginList();
std::vector<Plugin> &imprecPluginList = PluginLoader::getImprecPluginList();
if (scyllaPluginList.size() > 0)
{
CMenuHandle newMenu;
newMenu.CreatePopupMenu();
for (size_t i = 0; i < scyllaPluginList.size(); i++)
{
newMenu.AppendMenu(MF_STRING, i + PLUGIN_MENU_BASE_ID, scyllaPluginList[i].pluginName);
}
hMenu.AppendMenu(MF_MENUBARBREAK);
hMenu.AppendMenu(MF_POPUP, newMenu, L"Scylla Plugins");
}
if (imprecPluginList.size() > 0)
{
CMenuHandle newMenu;
newMenu.CreatePopupMenu();
for (size_t i = 0; i < imprecPluginList.size(); i++)
{
newMenu.AppendMenu(MF_STRING, scyllaPluginList.size() + i + PLUGIN_MENU_BASE_ID, imprecPluginList[i].pluginName);
}
hMenu.AppendMenu(MF_MENUBARBREAK);
hMenu.AppendMenu(MF_POPUP, newMenu, L"ImpREC Plugins");
}
}
void MainGui::dumpActionHandler()
{
if(!selectedProcess)
return;
WCHAR selectedFilePath[MAX_PATH];
const WCHAR * fileFilter;
const WCHAR * defExtension;
PeDump peDump;
if (processAccessHelp.selectedModule)
{
fileFilter = filterDll;
defExtension = L"dll";
}
else
{
fileFilter = filterExe;
defExtension = L"exe";
}
if(showFileDialog(selectedFilePath, true, NULL, fileFilter, defExtension))
{
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(selectedFilePath))
{
Logger::printfDialog(TEXT("Dump success %s"),selectedFilePath);
//MessageBox(L"Image dumped successfully.", L"Success");
}
else
{
Logger::printfDialog(TEXT("Error: Cannot dump image."));
MessageBox(L"Cannot dump image.", L"Failure", MB_ICONERROR);
}
}
}
DWORD_PTR MainGui::getOEPFromGui()
{
if (EditOEPAddress.GetWindowText(stringBuffer, _countof(stringBuffer)) > 0)
{
return stringToDwordPtr(stringBuffer);
}
else
{
return 0;
}
}
void MainGui::peRebuildActionHandler()
{
DWORD newSize = 0;
WCHAR selectedFilePath[MAX_PATH];
PeRebuild peRebuild;
if(showFileDialog(selectedFilePath, false, NULL, filterExeDll))
{
if (ConfigurationHolder::getConfigObject(CREATE_BACKUP)->isTrue())
{
if (!ProcessAccessHelp::createBackupFile(selectedFilePath))
{
Logger::printfDialog(TEXT("Creating backup file failed %s"), selectedFilePath);
}
}
LONGLONG fileSize = ProcessAccessHelp::getFileSize(selectedFilePath);
LPVOID mapped = peRebuild.createFileMappingViewFull(selectedFilePath);
newSize = peRebuild.realignPE(mapped, (DWORD)fileSize);
peRebuild.closeAllMappingHandles();
if (newSize < 10)
{
Logger::printfDialog(TEXT("Rebuild failed %s"), selectedFilePath);
MessageBox(L"Rebuild failed.", L"Failure", MB_ICONERROR);
}
else
{
peRebuild.truncateFile(selectedFilePath, newSize);
Logger::printfDialog(TEXT("Rebuild success %s"), selectedFilePath);
Logger::printfDialog(TEXT("-> Old file size 0x%08X new file size 0x%08X (%d %%)"), (DWORD)fileSize, newSize, (DWORD)((newSize * 100) / (DWORD)fileSize) );
//MessageBox(L"Image rebuilded successfully.", L"Success", MB_ICONINFORMATION);
}
}
}
void MainGui::dumpFixActionHandler()
{
if(!selectedProcess)
return;
if (TreeImports.GetCount() < 2)
{
Logger::printfDialog(TEXT("Nothing to rebuild"));
return;
}
WCHAR newFilePath[MAX_PATH];
WCHAR selectedFilePath[MAX_PATH];
const WCHAR * fileFilter;
ImportRebuild importRebuild;
if (processAccessHelp.selectedModule)
{
fileFilter = filterDll;
}
else
{
fileFilter = filterExe;
}
if (showFileDialog(selectedFilePath, false, NULL, fileFilter))
{
wcscpy_s(newFilePath,MAX_PATH,selectedFilePath);
const WCHAR * extension = 0;
WCHAR* dot = wcsrchr(newFilePath, L'.');
if (dot)
{
*dot = L'\0';
extension = selectedFilePath + (dot - newFilePath); //wcsrchr(selectedFilePath, L'.');
}
wcscat_s(newFilePath, MAX_PATH, L"_SCY");
if(extension)
{
wcscat_s(newFilePath, MAX_PATH, extension);
}
if (importRebuild.rebuildImportTable(selectedFilePath,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"), selectedFilePath);
MessageBox(L"Imports rebuilding failed", L"Failure", MB_ICONERROR);
}
}
}
void MainGui::enableDialogControls(BOOL value)
{
GetDlgItem(IDC_BTN_PICKDLL).EnableWindow(value);
GetDlgItem(IDC_BTN_DUMP).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);
menu.GetSubMenu(MenuImportsOffsetTrace).EnableMenuItem(MenuImportsTraceOffsetScylla, MF_BYPOSITION | (value ? MF_ENABLED : MF_GRAYED));
menu.GetSubMenu(MenuImportsOffsetTrace).EnableMenuItem(MenuImportsTraceOffsetImpRec, MF_BYPOSITION | (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_IMPORTS_INVALIDATESELECTED, MF_GRAYED);
menu.EnableMenuItem(ID_IMPORTS_CUTSELECTED, MF_GRAYED);
menu.EnableMenuItem(ID_IMPORTS_SAVETREE, MF_GRAYED);
menu.EnableMenuItem(ID_IMPORTS_SAVETREE, MF_GRAYED);
menu.EnableMenuItem(ID_IMPORTS_LOADTREE, MF_GRAYED);
menu.EnableMenuItem(ID_TRACE_AUTOTRACE, MF_GRAYED);
}
void MainGui::showAboutDialog()
{
AboutGui dlgAbout;
dlgAbout.DoModal();
}
void MainGui::dllInjectActionHandler()
{
if(!selectedProcess)
return;
WCHAR selectedFilePath[MAX_PATH];
HMODULE hMod = 0;
DllInjection dllInjection;
if (showFileDialog(selectedFilePath, false, NULL, filterDll))
{
hMod = dllInjection.dllInjection(ProcessAccessHelp::hProcess, selectedFilePath);
if (hMod && ConfigurationHolder::getConfigObject(DLL_INJECTION_AUTO_UNLOAD)->isTrue())
{
if (!dllInjection.unloadDllInProcess(ProcessAccessHelp::hProcess, hMod))
{
Logger::printfDialog(TEXT("DLL unloading failed, target %s"), selectedFilePath);
}
}
if (hMod)
{
Logger::printfDialog(TEXT("DLL Injection was successful, target %s"), selectedFilePath);
}
else
{
Logger::printfDialog(TEXT("DLL Injection failed, target %s"), selectedFilePath);
}
}
}
void MainGui::optionsActionHandler()
{
OptionsGui dlgOptions;
dlgOptions.DoModal();
}
void MainGui::clearImportsActionHandler()
{
TreeImports.DeleteAllItems();
importsHandling.moduleList.clear();
}
void MainGui::pluginActionHandler( int menuItem )
{
if(!selectedProcess)
return;
DllInjectionPlugin dllInjectionPlugin;
std::vector<Plugin> &scyllaPluginList = PluginLoader::getScyllaPluginList();
std::vector<Plugin> &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 e5e7315..b676982 100644
--- a/Scylla/MainGui.h
+++ b/Scylla/MainGui.h
@@ -1,207 +1,217 @@
#pragma once
#include <windows.h>
#include "resource.h"
// WTL
#include <atlbase.h> // base ATL classes
#include <atlapp.h> // base WTL classes
#include <atlwin.h> // ATL GUI classes
#include <atlmisc.h> // WTL utility classes like CString
#include <atlcrack.h> // WTL enhanced msg map macros
#include <atlctrls.h> // WTL controls
+#include <atlddx.h> // WTL dialog data exchange
//#define _CRTDBG_MAP_ALLOC
//#include <cstdlib>
//#include <crtdbg.h>
#include <cstdio>
#include "Logger.h"
#include "ProcessLister.h"
#include "IATSearch.h"
#include "PickDllGui.h"
#include "ImportsHandling.h"
-class MainGui : public CDialogImpl<MainGui>
+class MainGui : public CDialogImpl<MainGui>, public CWinDataExchange<MainGui>
{
public:
enum { IDD = IDD_DLG_MAIN };
+ BEGIN_DDX_MAP(MainGui)
+ DDX_CONTROL_HANDLE(IDC_TREE_IMPORTS, TreeImports)
+ DDX_CONTROL_HANDLE(IDC_CBO_PROCESSLIST, ComboProcessList)
+ DDX_CONTROL_HANDLE(IDC_LIST_LOG, ListLog)
+ DDX_CONTROL_HANDLE(IDC_EDIT_OEPADDRESS, EditOEPAddress)
+ DDX_CONTROL_HANDLE(IDC_EDIT_IATADDRESS, EditIATAddress)
+ DDX_CONTROL_HANDLE(IDC_EDIT_IATSIZE, EditIATSize)
+ END_DDX_MAP()
+
BEGIN_MSG_MAP(MainGui)
MSG_WM_INITDIALOG(OnInitDialog)
MSG_WM_GETMINMAXINFO(OnGetMinMaxInfo)
MSG_WM_SIZING(OnSizing)
MSG_WM_SIZE(OnSize)
MSG_WM_CONTEXTMENU(OnContextMenu)
MSG_WM_LBUTTONDOWN(OnLButtonDown)
MSG_WM_COMMAND(OnCommand)
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_IATAUTOSEARCH, OnIATAutoSearch)
COMMAND_ID_HANDLER_EX(IDC_BTN_GETIMPORTS, OnGetImports)
COMMAND_ID_HANDLER_EX(IDC_BTN_INVALIDIMPORTS, OnInvalidImports)
COMMAND_ID_HANDLER_EX(IDC_BTN_SUSPECTIMPORTS, OnSuspectImports)
COMMAND_ID_HANDLER_EX(IDC_BTN_CLEARIMPORTS, OnClearImports)
COMMAND_ID_HANDLER_EX(ID_FILE_DUMP, OnDump)
COMMAND_ID_HANDLER_EX(ID_FILE_PEREBUILD, OnPERebuild)
COMMAND_ID_HANDLER_EX(ID_FILE_FIXDUMP, OnFixDump)
COMMAND_ID_HANDLER_EX(ID_FILE_EXIT, OnExit)
COMMAND_ID_HANDLER_EX(ID_IMPORTS_SHOWINVALID, OnInvalidImports)
COMMAND_ID_HANDLER_EX(ID_IMPORTS_SHOWSUSPECT, OnSuspectImports)
COMMAND_ID_HANDLER_EX(ID_IMPORTS_INVALIDATESELECTED, OnInvalidateSelected)
COMMAND_ID_HANDLER_EX(ID_IMPORTS_CUTSELECTED, OnCutSelected)
COMMAND_ID_HANDLER_EX(ID_IMPORTS_CLEARIMPORTS, OnClearImports)
COMMAND_ID_HANDLER_EX(ID_IMPORTS_SAVETREE, OnSaveTree)
COMMAND_ID_HANDLER_EX(ID_IMPORTS_LOADTREE, OnLoadTree)
COMMAND_ID_HANDLER_EX(ID_TRACE_AUTOTRACE, OnAutotrace)
COMMAND_ID_HANDLER_EX(ID_MISC_DLLINJECTION, OnDLLInject)
COMMAND_ID_HANDLER_EX(ID_MISC_OPTIONS, OnOptions)
COMMAND_ID_HANDLER_EX(ID_HELP_ABOUT, OnAbout)
COMMAND_ID_HANDLER_EX(IDCANCEL, OnExit)
END_MSG_MAP()
MainGui();
void addTextToOutputLog(const WCHAR * text);
protected:
// Variables
ProcessLister processLister;
WCHAR stringBuffer[600];
ImportsHandling importsHandling;
ProcessAccessHelp processAccessHelp;
ApiReader apiReader;
Process * selectedProcess;
// File selection stuff
static const WCHAR filterExe[];
static const WCHAR filterDll[];
static const WCHAR filterExeDll[];
static const WCHAR filterTxt[];
// Controls
- CTreeViewCtrl TreeImports;
+ CTreeViewCtrlEx TreeImports;
CComboBox ComboProcessList;
CEdit EditOEPAddress;
CEdit EditIATAddress;
CEdit EditIATSize;
CListBox ListLog;
CRect minDlgSize;
CSize sizeOffset;
// Handles
CIcon hIcon;
CMenu hMenuImports;
CMenu hMenuLog;
static const int MenuImportsOffsetTrace = 2;
static const int MenuImportsTraceOffsetScylla = 2;
static const int MenuImportsTraceOffsetImpRec = 4;
protected:
// Message handlers
BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam);
void OnGetMinMaxInfo(MINMAXINFO* lpMMI);
void OnSizing(UINT fwSide, RECT* pRect);
void OnSize(UINT nType, CSize size);
void OnLButtonDown(UINT nFlags, CPoint point);
void OnContextMenu(CWindow wnd, CPoint point);
void OnCommand(UINT uNotifyCode, int nID, CWindow wndCtl);
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 OnInvalidateSelected(UINT uNotifyCode, int nID, CWindow wndCtl);
void OnCutSelected(UINT uNotifyCode, int nID, CWindow wndCtl);
void OnSaveTree(UINT uNotifyCode, int nID, CWindow wndCtl);
void OnLoadTree(UINT uNotifyCode, int nID, CWindow wndCtl);
void OnAutotrace(UINT uNotifyCode, int nID, CWindow wndCtl);
void OnExit(UINT uNotifyCode, int nID, CWindow wndCtl);
void OnAbout(UINT uNotifyCode, int nID, CWindow wndCtl);
// GUI functions
bool showFileDialog(WCHAR * selectedFile, bool save, const WCHAR * defFileName, const WCHAR * filter = NULL, const WCHAR * defExtension = NULL, const WCHAR * directory = NULL);
void fillProcessListComboBox(CComboBox& hCombo);
void setIconAndDialogCaption();
void enableDialogControls(BOOL value);
// Actions
void pickDllActionHandler();
void processSelectedActionHandler(int index);
void showInvalidImportsActionHandler();
void showSuspectImportsActionHandler();
void iatAutosearchActionHandler();
void getImportsActionHandler();
void dumpActionHandler();
void peRebuildActionHandler();
void startDisassemblerGui(CTreeItem selectedTreeNode);
void dumpFixActionHandler();
void showAboutDialog();
void dllInjectActionHandler();
void optionsActionHandler();
void clearImportsActionHandler();
void pluginActionHandler(int menuItem);
// Popup menu functions
void SetupImportsMenuItems(bool isItem, bool isThunk);
void appendPluginListToMenu(CMenuHandle hMenuTrackPopup);
void DisplayContextMenuImports(CWindow, CPoint);
void DisplayContextMenuLog(CWindow, CPoint);
// Log
void clearOutputLog();
bool saveLogToFile(const WCHAR * file);
// Misc
DWORD_PTR getOEPFromGui();
static DWORD_PTR stringToDwordPtr(const WCHAR * hexString);
};
diff --git a/Scylla/OptionsGui.cpp b/Scylla/OptionsGui.cpp
index c4b9b98..1176435 100644
--- a/Scylla/OptionsGui.cpp
+++ b/Scylla/OptionsGui.cpp
@@ -1,158 +1,159 @@
#include "OptionsGui.h"
#include "ConfigurationHolder.h"
#include "definitions.h"
BOOL OptionsGui::OnInitDialog(CWindow wndFocus, LPARAM lInitParam)
{
- EditSectionName.Attach(GetDlgItem(IDC_OPTIONS_SECTIONNAME));
+ DoDataExchange(); // attach controls
+
EditSectionName.LimitText(IMAGE_SIZEOF_SHORT_NAME);
loadOptions();
CenterWindow();
return TRUE;
}
void OptionsGui::OnOK(UINT uNotifyCode, int nID, CWindow wndCtl)
{
saveOptions();
ConfigurationHolder::saveConfiguration();
EndDialog(0);
}
void OptionsGui::OnCancel(UINT uNotifyCode, int nID, CWindow wndCtl)
{
EndDialog(0);
}
void OptionsGui::saveOptions()
{
std::map<Configuration, ConfigObject>::iterator mapIter;
for (mapIter = ConfigurationHolder::getConfigList().begin() ; mapIter != ConfigurationHolder::getConfigList().end(); mapIter++)
{
getConfigOptionsFromDlg((*mapIter).second);
}
}
void OptionsGui::loadOptions()
{
std::map<Configuration, ConfigObject>::iterator mapIter;
for (mapIter = ConfigurationHolder::getConfigList().begin() ; mapIter != ConfigurationHolder::getConfigList().end(); mapIter++)
{
displayConfigInDlg((*mapIter).second);
}
}
void OptionsGui::setCheckBox( int nIDDlgItem, bool bValue )
{
CButton Button(GetDlgItem(nIDDlgItem));
Button.SetCheck(bValue ? BST_CHECKED : BST_UNCHECKED);
}
void OptionsGui::displayConfigInDlg( ConfigObject & config )
{
switch (config.configType)
{
case String:
{
setEditControl(config.dialogItemValue, config.valueString);
}
break;
case Boolean:
{
setCheckBox(config.dialogItemValue, config.isTrue());
}
break;
case Decimal:
{
swprintf_s(config.valueString, CONFIG_OPTIONS_STRING_LENGTH, TEXT(PRINTF_INTEGER),config.valueNumeric);
setEditControl(config.dialogItemValue, config.valueString);
}
break;
case Hexadecimal:
{
swprintf_s(config.valueString, CONFIG_OPTIONS_STRING_LENGTH, TEXT(PRINTF_DWORD_PTR_FULL),config.valueNumeric);
setEditControl(config.dialogItemValue, config.valueString);
}
break;
}
}
void OptionsGui::setEditControl( int nIDDlgItem, const WCHAR * valueString )
{
CEdit Edit(GetDlgItem(nIDDlgItem));
Edit.SetWindowText(valueString);
}
void OptionsGui::getConfigOptionsFromDlg( ConfigObject & config )
{
switch (config.configType)
{
case String:
{
getEditControl(config.dialogItemValue, config.valueString);
}
break;
case Boolean:
{
getCheckBox(config.dialogItemValue, &config.valueNumeric);
}
break;
case Decimal:
{
getEditControlNumeric(config.dialogItemValue, &config.valueNumeric, 10);
}
break;
case Hexadecimal:
{
getEditControlNumeric(config.dialogItemValue, &config.valueNumeric, 16);
}
break;
}
}
bool OptionsGui::getEditControl( int nIDDlgItem, WCHAR * valueString )
{
CEdit Edit(GetDlgItem(nIDDlgItem));
return (Edit.GetWindowText(valueString, CONFIG_OPTIONS_STRING_LENGTH) > 0);
}
void OptionsGui::getCheckBox( int nIDDlgItem, DWORD_PTR * valueNumeric )
{
CButton Button(GetDlgItem(nIDDlgItem));
switch (Button.GetCheck())
{
case BST_CHECKED:
*valueNumeric = 1;
return;
case BST_UNCHECKED:
*valueNumeric = 0;
return;
default:
*valueNumeric = 0;
}
}
void OptionsGui::getEditControlNumeric( int nIDDlgItem, DWORD_PTR * valueNumeric, int nBase )
{
WCHAR temp[CONFIG_OPTIONS_STRING_LENGTH] = {0};
if (getEditControl(nIDDlgItem, temp))
{
#ifdef _WIN64
*valueNumeric = _wcstoui64(temp, NULL, nBase);
#else
*valueNumeric = wcstoul(temp, NULL, nBase);
#endif
}
else
{
*valueNumeric = 0;
}
}
diff --git a/Scylla/OptionsGui.h b/Scylla/OptionsGui.h
index fed16c8..c993c98 100644
--- a/Scylla/OptionsGui.h
+++ b/Scylla/OptionsGui.h
@@ -1,47 +1,52 @@
#pragma once
#include <windows.h>
#include "resource.h"
// WTL
#include <atlbase.h> // base ATL classes
#include <atlapp.h> // base WTL classes
#include <atlwin.h> // ATL GUI classes
#include <atlcrack.h> // WTL enhanced msg map macros
#include <atlctrls.h> // WTL controls
+#include <atlddx.h> // WTL dialog data exchange
class ConfigObject;
-class OptionsGui : public CDialogImpl<OptionsGui>
+class OptionsGui : public CDialogImpl<OptionsGui>, public CWinDataExchange<OptionsGui>
{
public:
enum { IDD = IDD_DLG_OPTIONS };
+ BEGIN_DDX_MAP(OptionsGui)
+ DDX_CONTROL_HANDLE(IDC_OPTIONS_SECTIONNAME, EditSectionName)
+ END_DDX_MAP()
+
BEGIN_MSG_MAP(OptionsGui)
MSG_WM_INITDIALOG(OnInitDialog)
COMMAND_ID_HANDLER_EX(IDC_BTN_OPTIONS_OK, OnOK)
COMMAND_ID_HANDLER_EX(IDC_BTN_OPTIONS_CANCEL, OnCancel)
COMMAND_ID_HANDLER_EX(IDCANCEL, OnCancel)
END_MSG_MAP()
private:
CEdit EditSectionName;
BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam);
void OnOK(UINT uNotifyCode, int nID, CWindow wndCtl);
void OnCancel(UINT uNotifyCode, int nID, CWindow wndCtl);
void saveOptions();
void loadOptions();
void setCheckBox( int nIDDlgItem, bool bValue );
void displayConfigInDlg( ConfigObject & config );
void setEditControl( int nIDDlgItem, const WCHAR * valueString );
void getConfigOptionsFromDlg( ConfigObject & config );
bool getEditControl( int nIDDlgItem, WCHAR * valueString );
void getCheckBox( int dialogItemValue, DWORD_PTR * valueNumeric );
void getEditControlNumeric( int nIDDlgItem, DWORD_PTR * valueNumeric, int nBase );
};
diff --git a/Scylla/PickApiGui.cpp b/Scylla/PickApiGui.cpp
index cd054b0..d08da45 100644
--- a/Scylla/PickApiGui.cpp
+++ b/Scylla/PickApiGui.cpp
@@ -1,175 +1,168 @@
#include "PickApiGui.h"
#include <atlconv.h> // string conversion
#include "WindowDeferrer.h"
PickApiGui::PickApiGui(const std::vector<ModuleInfo> &moduleList) : moduleList(moduleList)
{
selectedApi = 0;
hIcon.LoadIcon(IDI_ICON_SCYLLA);
}
BOOL PickApiGui::OnInitDialog(CWindow wndFocus, LPARAM lInitParam)
{
- ComboDllSelect.Attach(GetDlgItem(IDC_CBO_DLLSELECT));
- ListApiSelect.Attach(GetDlgItem(IDC_LIST_APISELECT));
- EditApiFilter.Attach(GetDlgItem(IDC_EDIT_APIFILTER));
+ DoDataExchange(); // attach controls
fillDllComboBox(ComboDllSelect);
CenterWindow();
SetIcon(hIcon, TRUE);
SetIcon(hIcon, FALSE);
GetWindowRect(&minDlgSize);
return TRUE;
}
void PickApiGui::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
{
- lpMMI->ptMinTrackSize.x = minDlgSize.Width();
- lpMMI->ptMinTrackSize.y = minDlgSize.Height();
+ lpMMI->ptMinTrackSize = CPoint(minDlgSize.Size());
}
void PickApiGui::OnSizing(UINT fwSide, RECT* pRect)
{
// Get size difference
CRect rectOld;
GetWindowRect(&rectOld);
CRect rectNew = *pRect;
- int deltaX = rectNew.Width() - rectOld.Width();
- int deltaY = rectNew.Height() - rectOld.Height();
-
- CSize delta(deltaX, deltaY);
- sizeOffset = delta;
+ sizeOffset = rectNew.Size() - rectOld.Size();
}
void PickApiGui::OnSize(UINT nType, CSize size)
{
const WindowDeferrer::Deferrable controls[] =
{
{IDC_GROUP_DLL, false, false, true, false},
{IDC_CBO_DLLSELECT, false, false, true, false},
{IDC_GROUP_APIS, false, false, true, true},
{IDC_LIST_APISELECT, false, false, true, true},
{IDC_STATIC_APIFILTER, false, true, false, false},
{IDC_EDIT_APIFILTER, false, true, true, false},
{IDC_BTN_PICKAPI_OK, true, true, false, false},
{IDC_BTN_PICKAPI_CANCEL, true, true, false, false}
};
if(nType == SIZE_RESTORED)
{
WindowDeferrer deferrer(m_hWnd, controls, _countof(controls));
deferrer.defer(sizeOffset.cx, sizeOffset.cy);
sizeOffset.SetSize(0, 0);
}
}
void PickApiGui::OnOK(UINT uNotifyCode, int nID, CWindow wndCtl)
{
int indexDll = ComboDllSelect.GetCurSel();
int indexApi = ListApiSelect.GetCurSel();
if (indexDll != CB_ERR && indexApi != CB_ERR)
{
selectedApi = apiListTemp[indexApi];
EndDialog(1);
}
}
void PickApiGui::OnCancel(UINT uNotifyCode, int nID, CWindow wndCtl)
{
EndDialog(0);
}
void PickApiGui::OnDllListSelected(UINT uNotifyCode, int nID, CWindow wndCtl)
{
int indexDll = ComboDllSelect.GetCurSel();
if (indexDll != CB_ERR)
{
apiListTemp = moduleList[indexDll].apiList;
fillApiListBox(ListApiSelect, apiListTemp);
EditApiFilter.SetWindowText(L"");
}
}
void PickApiGui::OnApiFilterUpdated(UINT uNotifyCode, int nID, CWindow wndCtl)
{
// remove from apiListTemp that don't fit
int indexDll = ComboDllSelect.GetCurSel();
if (indexDll != CB_ERR)
{
WCHAR filter[MAX_PATH];
int lenFilter = EditApiFilter.GetWindowText(filter, _countof(filter));
if(lenFilter > 0)
{
apiListTemp.clear();
const std::vector<ApiInfo *> &apis = moduleList[indexDll].apiList;
for (size_t i = 0; i < apis.size(); i++)
{
ApiInfo* api = apis[i];
if(api->name[0] != '\0')
{
CA2WEX<MAX_PATH> wStr(api->name);
if(!_wcsnicmp(wStr, filter, lenFilter))
{
apiListTemp.push_back(api);
}
}
else
{
WCHAR buf[6];
swprintf_s(buf, _countof(buf), L"#%04X", api->ordinal);
if(!_wcsnicmp(buf, filter, lenFilter))
{
apiListTemp.push_back(api);
}
}
}
}
else
{
apiListTemp = moduleList[indexDll].apiList;
}
fillApiListBox(ListApiSelect, apiListTemp);
}
}
void PickApiGui::fillDllComboBox(CComboBox& combo)
{
combo.ResetContent();
for (size_t i = 0; i < moduleList.size(); i++)
{
combo.AddString(moduleList[i].fullPath);
}
}
void PickApiGui::fillApiListBox(CListBox& list, const std::vector<ApiInfo *> &apis)
{
list.ResetContent();
for (size_t i = 0; i < apis.size(); i++)
{
const ApiInfo* api = apis[i];
if(api->name[0] != '\0')
{
CA2WEX<MAX_PATH> wStr(api->name);
list.AddString(wStr);
}
else
{
WCHAR buf[6];
swprintf_s(buf, _countof(buf), L"#%04X", api->ordinal);
list.AddString(buf);
}
}
}
diff --git a/Scylla/PickApiGui.h b/Scylla/PickApiGui.h
index 07023de..8b152dc 100644
--- a/Scylla/PickApiGui.h
+++ b/Scylla/PickApiGui.h
@@ -1,80 +1,85 @@
#pragma once
#include <windows.h>
#include "resource.h"
// WTL
#include <atlbase.h> // base ATL classes
#include <atlapp.h> // base WTL classes
#include <atlwin.h> // ATL GUI classes
#include <atlmisc.h> // WTL utility classes like CString
#include <atlcrack.h> // WTL enhanced msg map macros
#include <atlctrls.h> // WTL controls
+#include <atlddx.h> // WTL dialog data exchange
#include <vector>
#include "ProcessAccessHelp.h"
-class PickApiGui : public CDialogImpl<PickApiGui>
+class PickApiGui : public CDialogImpl<PickApiGui>, public CWinDataExchange<PickApiGui>
{
public:
enum { IDD = IDD_DLG_PICKAPI };
+ BEGIN_DDX_MAP(PickApiGui)
+ DDX_CONTROL_HANDLE(IDC_CBO_DLLSELECT, ComboDllSelect)
+ DDX_CONTROL_HANDLE(IDC_LIST_APISELECT, ListApiSelect)
+ DDX_CONTROL_HANDLE(IDC_EDIT_APIFILTER, EditApiFilter)
+ END_DDX_MAP()
+
BEGIN_MSG_MAP(PickDllGui)
MSG_WM_INITDIALOG(OnInitDialog)
MSG_WM_GETMINMAXINFO(OnGetMinMaxInfo)
MSG_WM_SIZING(OnSizing)
MSG_WM_SIZE(OnSize)
COMMAND_HANDLER_EX(IDC_CBO_DLLSELECT, CBN_SELENDOK, OnDllListSelected)
COMMAND_HANDLER_EX(IDC_EDIT_APIFILTER, EN_UPDATE, OnApiFilterUpdated)
COMMAND_ID_HANDLER_EX(IDC_BTN_PICKAPI_OK, OnOK)
COMMAND_ID_HANDLER_EX(IDC_BTN_PICKAPI_CANCEL, OnCancel)
COMMAND_ID_HANDLER_EX(IDCANCEL, OnCancel)
END_MSG_MAP()
PickApiGui(const std::vector<ModuleInfo> &moduleList);
ApiInfo* getSelectedApi() const { return selectedApi; }
protected:
// Variables
const std::vector<ModuleInfo> &moduleList;
std::vector<ApiInfo *> apiListTemp;
ApiInfo* selectedApi;
// Controls
CComboBox ComboDllSelect;
CListBox ListApiSelect;
CEdit EditApiFilter;
CRect minDlgSize;
CSize sizeOffset;
// Handles
CIcon hIcon;
protected:
// Message handlers
BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam);
void OnGetMinMaxInfo(MINMAXINFO* lpMMI);
void OnSizing(UINT fwSide, RECT* pRect);
void OnSize(UINT nType, CSize size);
void OnOK(UINT uNotifyCode, int nID, CWindow wndCtl);
void OnCancel(UINT uNotifyCode, int nID, CWindow wndCtl);
void OnDllListSelected(UINT uNotifyCode, int nID, CWindow wndCtl);
void OnApiFilterUpdated(UINT uNotifyCode, int nID, CWindow wndCtl);
// GUI functions
void fillDllComboBox(CComboBox& combo);
void fillApiListBox(CListBox& list, const std::vector<ApiInfo *> &apis);
-
- //void displayModuleList(CListViewCtrl& list);
};
diff --git a/Scylla/PickDllGui.cpp b/Scylla/PickDllGui.cpp
index 2262b95..1808c18 100644
--- a/Scylla/PickDllGui.cpp
+++ b/Scylla/PickDllGui.cpp
@@ -1,176 +1,171 @@
#include "PickDllGui.h"
#include "WindowDeferrer.h"
PickDllGui::PickDllGui(std::vector<ModuleInfo> &moduleList) : moduleList(moduleList)
{
prevColumn = -1;
ascending = true;
selectedModule = 0;
hIcon.LoadIcon(IDI_ICON_SCYLLA);
}
BOOL PickDllGui::OnInitDialog(CWindow wndFocus, LPARAM lInitParam)
{
- ListDLLSelect.Attach(GetDlgItem(IDC_LIST_DLLSELECT));
+ DoDataExchange(); // attach controls
addColumnsToModuleList(ListDLLSelect);
displayModuleList(ListDLLSelect);
CenterWindow();
SetIcon(hIcon, TRUE);
SetIcon(hIcon, FALSE);
GetWindowRect(&minDlgSize);
return TRUE;
}
void PickDllGui::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
{
- lpMMI->ptMinTrackSize.x = minDlgSize.Width();
- lpMMI->ptMinTrackSize.y = minDlgSize.Height();
+ lpMMI->ptMinTrackSize = CPoint(minDlgSize.Size());
}
void PickDllGui::OnSizing(UINT fwSide, RECT* pRect)
{
// Get size difference
CRect rectOld;
GetWindowRect(&rectOld);
CRect rectNew = *pRect;
- int deltaX = rectNew.Width() - rectOld.Width();
- int deltaY = rectNew.Height() - rectOld.Height();
-
- CSize delta(deltaX, deltaY);
- sizeOffset = delta;
+ sizeOffset = rectNew.Size() - rectOld.Size();
}
void PickDllGui::OnSize(UINT nType, CSize size)
{
const 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},
};
if(nType == SIZE_RESTORED)
{
WindowDeferrer deferrer(m_hWnd, controls, _countof(controls));
deferrer.defer(sizeOffset.cx, sizeOffset.cy);
sizeOffset.SetSize(0, 0);
}
}
LRESULT PickDllGui::OnListDllColumnClicked(NMHDR* pnmh)
{
NMLISTVIEW* list = (NMLISTVIEW*)pnmh;
int column = list->iSubItem;
- if(column == prevColumn)
+ if(column == prevColumn)
{
- ascending = !ascending;
+ ascending = !ascending;
}
- else
- {
+ else
+ {
prevColumn = column;
- ascending = true;
- }
+ ascending = true;
+ }
// lo-byte: column, hi-byte: sort-order
ListDLLSelect.SortItems(&listviewCompareFunc, MAKEWORD(column, ascending));
return 0;
}
void PickDllGui::OnOK(UINT uNotifyCode, int nID, CWindow wndCtl)
{
int index = ListDLLSelect.GetSelectionMark();
if (index != -1)
{
selectedModule = (ModuleInfo *)ListDLLSelect.GetItemData(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_NAME, L"Name", LVCFMT_LEFT);
list.InsertColumn(COL_IMAGEBASE, L"ImageBase", LVCFMT_CENTER);
list.InsertColumn(COL_IMAGESIZE, L"ImageSize", LVCFMT_CENTER);
list.InsertColumn(COL_PATH, L"Path", LVCFMT_LEFT);
}
void PickDllGui::displayModuleList(CListViewCtrl& list)
{
WCHAR temp[20];
list.DeleteAllItems();
std::vector<ModuleInfo>::const_iterator iter;
int count = 0;
for( iter = moduleList.begin(); iter != moduleList.end(); iter++ , count++)
{
list.InsertItem(count, iter->getFilename());
#ifdef _WIN64
swprintf_s(temp, _countof(temp), L"%016I64X", iter->modBaseAddr);
#else
swprintf_s(temp, _countof(temp), L"%08X", iter->modBaseAddr);
#endif
list.SetItemText(count, COL_IMAGEBASE, temp);
swprintf_s(temp, _countof(temp),L"%08X",iter->modBaseSize);
list.SetItemText(count, COL_IMAGESIZE, temp);
list.SetItemText(count, COL_PATH, iter->fullPath);
list.SetItemData(count, (DWORD_PTR)&(*iter));
}
list.SetColumnWidth(COL_NAME, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_IMAGEBASE, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_IMAGESIZE, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_PATH, LVSCW_AUTOSIZE_USEHEADER);
}
// lParamSort - lo-byte: column, hi-byte: sort-order
int PickDllGui::listviewCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
const ModuleInfo * module1 = (ModuleInfo *)lParam1;
const ModuleInfo * module2 = (ModuleInfo *)lParam2;
int column = LOBYTE(lParamSort);
bool ascending = HIBYTE(lParamSort) == true;
int diff = 0;
switch(column)
{
case COL_NAME:
diff = _wcsicmp(module1->getFilename(), module2->getFilename());
break;
case COL_IMAGEBASE:
diff = module1->modBaseAddr < module2->modBaseAddr ? -1 : 1;
break;
case COL_IMAGESIZE:
diff = module1->modBaseSize < module2->modBaseSize ? -1 : 1;
break;
case COL_PATH:
diff = _wcsicmp(module1->fullPath, module2->fullPath);
break;
}
return ascending ? diff : -diff;
}
diff --git a/Scylla/PickDllGui.h b/Scylla/PickDllGui.h
index 9197b4c..c494c78 100644
--- a/Scylla/PickDllGui.h
+++ b/Scylla/PickDllGui.h
@@ -1,85 +1,90 @@
#pragma once
#include <windows.h>
#include "resource.h"
// WTL
#include <atlbase.h> // base ATL classes
#include <atlapp.h> // base WTL classes
#include <atlwin.h> // ATL GUI classes
#include <atlmisc.h> // WTL utility classes like CString
#include <atlcrack.h> // WTL enhanced msg map macros
#include <atlctrls.h> // WTL controls
+#include <atlddx.h> // WTL dialog data exchange
#include <vector>
#include "ProcessAccessHelp.h"
-class PickDllGui : public CDialogImpl<PickDllGui>
+class PickDllGui : public CDialogImpl<PickDllGui>, public CWinDataExchange<PickDllGui>
{
public:
enum { IDD = IDD_DLG_PICKDLL };
+ BEGIN_DDX_MAP(PickDllGui)
+ DDX_CONTROL_HANDLE(IDC_LIST_DLLSELECT, ListDLLSelect)
+ END_DDX_MAP()
+
BEGIN_MSG_MAP(PickDllGui)
MSG_WM_INITDIALOG(OnInitDialog)
MSG_WM_GETMINMAXINFO(OnGetMinMaxInfo)
MSG_WM_SIZING(OnSizing)
MSG_WM_SIZE(OnSize)
NOTIFY_HANDLER_EX(IDC_LIST_DLLSELECT, LVN_COLUMNCLICK, OnListDllColumnClicked)
COMMAND_ID_HANDLER_EX(IDC_BTN_PICKDLL_OK, OnOK)
COMMAND_ID_HANDLER_EX(IDC_BTN_PICKDLL_CANCEL, OnCancel)
COMMAND_ID_HANDLER_EX(IDCANCEL, OnCancel)
END_MSG_MAP()
PickDllGui(std::vector<ModuleInfo> &moduleList);
ModuleInfo* getSelectedModule() const { return selectedModule; }
protected:
// Variables
std::vector<ModuleInfo> &moduleList;
ModuleInfo* selectedModule;
// Controls
CListViewCtrl ListDLLSelect;
enum ListColumns {
COL_NAME = 0,
COL_IMAGEBASE,
COL_IMAGESIZE,
COL_PATH
};
int prevColumn;
bool ascending;
CRect minDlgSize;
CSize sizeOffset;
// Handles
CIcon hIcon;
protected:
// Message handlers
BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam);
void OnGetMinMaxInfo(MINMAXINFO* lpMMI);
void OnSizing(UINT fwSide, RECT* pRect);
void OnSize(UINT nType, CSize size);
LRESULT OnListDllColumnClicked(NMHDR* pnmh);
void OnOK(UINT uNotifyCode, int nID, CWindow wndCtl);
void OnCancel(UINT uNotifyCode, int nID, CWindow wndCtl);
// GUI functions
void addColumnsToModuleList(CListViewCtrl& list);
void displayModuleList(CListViewCtrl& list);
static int CALLBACK listviewCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
};

File Metadata

Mime Type
text/x-diff
Expires
Thu, Nov 14, 7:19 PM (2 h, 19 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
8b/d7/7679164aa4a3dcee3f9d3093261b

Event Timeline