Page Menu
Home
desp's stash
Search
Configure Global Search
Log In
Files
F202110
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
33 KB
Subscribers
None
View Options
diff --git a/Scylla/DumpMemoryGui.cpp b/Scylla/DumpMemoryGui.cpp
index 33f7aae..39c8647 100644
--- a/Scylla/DumpMemoryGui.cpp
+++ b/Scylla/DumpMemoryGui.cpp
@@ -1,571 +1,573 @@
#include "DumpMemoryGui.h"
#include "Architecture.h"
#include "ProcessAccessHelp.h"
#include <Psapi.h>
#include "PeParser.h"
WCHAR DumpMemoryGui::protectionString[100];
const WCHAR DumpMemoryGui::MemoryUndefined[] = L"UNDEF";
const WCHAR DumpMemoryGui::MemoryUnknown[] = L"UNKNOWN";
const WCHAR * DumpMemoryGui::MemoryStateValues[] = {L"COMMIT",L"FREE",L"RESERVE"};
const WCHAR * DumpMemoryGui::MemoryTypeValues[] = {L"IMAGE",L"MAPPED",L"PRIVATE"};
const WCHAR * DumpMemoryGui::MemoryProtectionValues[] = {L"EXECUTE",L"EXECUTE_READ",L"EXECUTE_READWRITE",L"EXECUTE_WRITECOPY",L"NOACCESS",L"READONLY",L"READWRITE",L"WRITECOPY",L"GUARD",L"NOCACHE",L"WRITECOMBINE"};
DumpMemoryGui::DumpMemoryGui()
{
dumpedMemory = 0;
dumpedMemorySize = 0;
deviceNameResolver = new DeviceNameResolver();
}
DumpMemoryGui::~DumpMemoryGui()
{
if (dumpedMemory)
{
delete [] dumpedMemory;
}
if (deviceNameResolver)
{
delete deviceNameResolver;
}
+
+ memoryList.clear();
}
BOOL DumpMemoryGui::OnInitDialog(CWindow wndFocus, LPARAM lInitParam)
{
DoDataExchange(); // attach controls
DlgResize_Init(true, true);
addColumnsToMemoryList(ListMemorySelect);
displayMemoryList(ListMemorySelect);
forceDump = false;
DoDataExchange(DDX_LOAD);
EditMemoryAddress.SetValue(ProcessAccessHelp::targetImageBase);
EditMemorySize.SetValue((DWORD)ProcessAccessHelp::targetSizeOfImage);
CenterWindow();
return TRUE;
}
void DumpMemoryGui::addColumnsToMemoryList(CListViewCtrl& list)
{
list.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
list.InsertColumn(COL_ADDRESS, L"Address", LVCFMT_CENTER);
list.InsertColumn(COL_SIZE, L"Size", LVCFMT_CENTER);
list.InsertColumn(COL_FILENAME, L"File", LVCFMT_LEFT);
list.InsertColumn(COL_PESECTION, L"PE Section", LVCFMT_LEFT);
list.InsertColumn(COL_TYPE, L"Type", LVCFMT_CENTER);
list.InsertColumn(COL_PROTECTION, L"Protection", LVCFMT_CENTER);
list.InsertColumn(COL_STATE, L"State", LVCFMT_CENTER);
list.InsertColumn(COL_MAPPED_FILE, L"Mapped File", LVCFMT_LEFT);
}
void DumpMemoryGui::displayMemoryList(CListViewCtrl& list)
{
int count = 0;
WCHAR temp[20];
list.DeleteAllItems();
getMemoryList();
std::vector<Memory>::const_iterator iter;
for( iter = memoryList.begin(); iter != memoryList.end(); iter++ , count++)
{
swprintf_s(temp, PRINTF_DWORD_PTR_FULL, iter->address);
list.InsertItem(count,temp);
swprintf_s(temp, L"%08X", iter->size);
list.SetItemText(count, COL_SIZE, temp);
list.SetItemText(count, COL_FILENAME, iter->filename);
list.SetItemText(count, COL_PESECTION, iter->peSection);
if (iter->state == MEM_FREE)
{
list.SetItemText(count, COL_TYPE, MemoryUndefined);
}
else
{
list.SetItemText(count, COL_TYPE, getMemoryTypeString(iter->type));
}
if ( (iter->state == MEM_RESERVE) || (iter->state == MEM_FREE) )
{
list.SetItemText(count, COL_PROTECTION, MemoryUndefined);
}
else
{
list.SetItemText(count, COL_PROTECTION, getMemoryProtectionString(iter->protect));
}
list.SetItemText(count, COL_STATE, getMemoryStateString(iter->state));
list.SetItemText(count, COL_MAPPED_FILE, iter->mappedFilename);
list.SetItemData(count, (DWORD_PTR)&(*iter));
}
list.SetColumnWidth(COL_ADDRESS, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_SIZE, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_FILENAME, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_PESECTION, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_TYPE, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_PROTECTION, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_STATE, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_MAPPED_FILE, LVSCW_AUTOSIZE_USEHEADER);
}
const WCHAR * DumpMemoryGui::getMemoryTypeString(DWORD value)
{
switch(value)
{
case MEM_IMAGE:
return MemoryTypeValues[TYPE_IMAGE];
case MEM_MAPPED:
return MemoryTypeValues[TYPE_MAPPED];
case MEM_PRIVATE:
return MemoryTypeValues[TYPE_PRIVATE];
default:
return MemoryUnknown;
}
}
const WCHAR * DumpMemoryGui::getMemoryStateString(DWORD value)
{
switch(value)
{
case MEM_COMMIT:
return MemoryStateValues[STATE_COMMIT];
case MEM_FREE:
return MemoryStateValues[STATE_FREE];
case MEM_RESERVE:
return MemoryStateValues[STATE_RESERVE];
default:
return MemoryUnknown;
}
}
WCHAR * DumpMemoryGui::getMemoryProtectionString(DWORD value)
{
protectionString[0] = 0;
if (value & PAGE_GUARD)
{
wcscpy_s(protectionString, MemoryProtectionValues[PROT_GUARD]);
wcscat_s(protectionString, L" | ");
value ^= PAGE_GUARD;
}
if (value & PAGE_NOCACHE)
{
wcscpy_s(protectionString, MemoryProtectionValues[PROT_NOCACHE]);
wcscat_s(protectionString, L" | ");
value ^= PAGE_NOCACHE;
}
if (value & PAGE_WRITECOMBINE)
{
wcscpy_s(protectionString, MemoryProtectionValues[PROT_WRITECOMBINE]);
wcscat_s(protectionString, L" | ");
value ^= PAGE_WRITECOMBINE;
}
switch(value)
{
case PAGE_EXECUTE:
{
wcscat_s(protectionString, MemoryProtectionValues[PROT_EXECUTE]);
break;
}
case PAGE_EXECUTE_READ:
{
wcscat_s(protectionString, MemoryProtectionValues[PROT_EXECUTE_READ]);
break;
}
case PAGE_EXECUTE_READWRITE:
{
wcscat_s(protectionString, MemoryProtectionValues[PROT_EXECUTE_READWRITE]);
break;
}
case PAGE_EXECUTE_WRITECOPY:
{
wcscat_s(protectionString, MemoryProtectionValues[PROT_EXECUTE_WRITECOPY]);
break;
}
case PAGE_NOACCESS:
{
wcscat_s(protectionString, MemoryProtectionValues[PROT_NOACCESS]);
break;
}
case PAGE_READONLY:
{
wcscat_s(protectionString, MemoryProtectionValues[PROT_READONLY]);
break;
}
case PAGE_READWRITE:
{
wcscat_s(protectionString, MemoryProtectionValues[PROT_READWRITE]);
break;
}
case PAGE_WRITECOPY:
{
wcscat_s(protectionString, MemoryProtectionValues[PROT_WRITECOPY]);
break;
}
default:
{
wcscat_s(protectionString, MemoryUnknown);
}
}
return protectionString;
}
LRESULT DumpMemoryGui::OnListMemoryColumnClicked(NMHDR* pnmh)
{
NMLISTVIEW* list = (NMLISTVIEW*)pnmh;
int column = list->iSubItem;
if(column == prevColumn)
{
ascending = !ascending;
}
else
{
prevColumn = column;
ascending = true;
}
// lo-byte: column, hi-byte: sort-order
ListMemorySelect.SortItems(&listviewCompareFunc, MAKEWORD(column, ascending));
return 0;
}
LRESULT DumpMemoryGui::OnListMemoryClick(NMHDR* pnmh)
{
int index = ListMemorySelect.GetSelectionMark();
if (index != -1)
{
selectedMemory = (Memory *)ListMemorySelect.GetItemData(index);
if (selectedMemory)
{
updateAddressAndSize(selectedMemory);
}
}
return 0;
}
void DumpMemoryGui::OnOK(UINT uNotifyCode, int nID, CWindow wndCtl)
{
DoDataExchange(DDX_SAVE);
if (EditMemoryAddress.GetValue() == 0 || EditMemorySize.GetValue() == 0)
{
wndCtl.MessageBoxW(L"Textbox is empty!",L"Error",MB_ICONERROR);
}
else
{
if (dumpMemory())
{
EndDialog(1);
}
else
{
wndCtl.MessageBoxW(L"Reading memory from process failed",L"Error",MB_ICONERROR);
}
}
}
void DumpMemoryGui::OnCancel(UINT uNotifyCode, int nID, CWindow wndCtl)
{
EndDialog(0);
}
void DumpMemoryGui::updateAddressAndSize( Memory * selectedMemory )
{
EditMemoryAddress.SetValue(selectedMemory->address);
EditMemorySize.SetValue(selectedMemory->size);
}
int DumpMemoryGui::listviewCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
const Memory * module1 = (Memory *)lParam1;
const Memory * module2 = (Memory *)lParam2;
int column = LOBYTE(lParamSort);
bool ascending = (HIBYTE(lParamSort) == TRUE);
int diff = 0;
switch(column)
{
case COL_ADDRESS:
diff = module1->address < module2->address ? -1 : 1;
break;
case COL_SIZE:
diff = module1->size < module2->size ? -1 : 1;
break;
case COL_FILENAME:
diff = _wcsicmp(module1->filename, module2->filename);
break;
case COL_PESECTION:
diff = _wcsicmp(module1->peSection, module2->peSection);
break;
case COL_TYPE:
diff = module1->type < module2->type ? -1 : 1;
break;
case COL_PROTECTION:
diff = module1->protect < module2->protect ? -1 : 1;
break;
case COL_STATE:
diff = _wcsicmp(getMemoryStateString(module1->state), getMemoryStateString(module2->state));
//diff = module1->state < module2->state ? -1 : 1;
break;
case COL_MAPPED_FILE:
diff = _wcsicmp(module1->mappedFilename, module2->mappedFilename);
break;
}
return ascending ? diff : -diff;
}
void DumpMemoryGui::getMemoryList()
{
DWORD count = 0;
DWORD_PTR address = 0;
MEMORY_BASIC_INFORMATION memBasic = {0};
Memory memory;
HMODULE * hMods = 0;
DWORD cbNeeded = 0;
bool notEnough = true;
WCHAR target[MAX_PATH];
count = 100;
hMods = new HMODULE[count];
if (memoryList.empty())
{
memoryList.reserve(20);
}
else
{
memoryList.clear();
}
memory.filename[0] = 0;
memory.peSection[0] = 0;
memory.mappedFilename[0] = 0;
while(VirtualQueryEx(ProcessAccessHelp::hProcess,(LPCVOID)address,&memBasic,sizeof(memBasic)))
{
memory.address = (DWORD_PTR)memBasic.BaseAddress;
memory.type = memBasic.Type;
memory.state = memBasic.State;
memory.size = (DWORD)memBasic.RegionSize;
memory.protect = memBasic.Protect;
if (memory.type == MEM_MAPPED)
{
if (!getMappedFilename(&memory))
{
memory.mappedFilename[0] = 0;
}
}
memoryList.push_back(memory);
memory.mappedFilename[0] = 0;
address += memBasic.RegionSize;
}
do
{
if (!EnumProcessModules(ProcessAccessHelp::hProcess, hMods, count * sizeof(HMODULE), &cbNeeded))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"getMemoryList :: EnumProcessModules failed count %d", count);
#endif
delete [] hMods;
return;
}
if ( (count * sizeof(HMODULE)) < cbNeeded )
{
delete [] hMods;
count += 100;
hMods = new HMODULE[count];
}
else
{
notEnough = false;
}
} while (notEnough);
for (DWORD i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
{
if (GetModuleFileNameExW(ProcessAccessHelp::hProcess, hMods[i], target, _countof(target)))
{
setModuleName((DWORD_PTR)hMods[i],target);
setAllSectionNames((DWORD_PTR)hMods[i],target);
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"getMemoryList :: GetModuleFileNameExW failed 0x%X", GetLastError());
#endif
}
}
delete [] hMods;
}
void DumpMemoryGui::setSectionName(DWORD_PTR sectionAddress, DWORD sectionSize, const WCHAR * sectionName)
{
bool found = false;
std::vector<Memory>::const_iterator iter;
for( iter = memoryList.begin(); iter != memoryList.end(); iter++)
{
if (!found)
{
if ( (iter->address <= sectionAddress) && (sectionAddress < (iter->address + iter->size)) )
{
if (wcslen(iter->peSection) == 0)
{
- wcscpy_s((WCHAR *)iter->peSection, IMAGE_SIZEOF_SHORT_NAME * 4, sectionName);
+ wcscpy_s((WCHAR *)iter->peSection, _countof(iter->peSection), sectionName);
}
else
{
- wcscat_s((WCHAR *)iter->peSection, IMAGE_SIZEOF_SHORT_NAME * 4, L"|");
- wcscat_s((WCHAR *)iter->peSection, IMAGE_SIZEOF_SHORT_NAME * 4, sectionName);
+ wcscat_s((WCHAR *)iter->peSection, _countof(iter->peSection), L"|");
+ wcscat_s((WCHAR *)iter->peSection, _countof(iter->peSection), sectionName);
}
found = true;
}
}
else
{
if ((sectionSize+sectionAddress) < iter->address)
{
break;
}
if (wcslen(iter->peSection) == 0)
{
- wcscpy_s((WCHAR *)iter->peSection, IMAGE_SIZEOF_SHORT_NAME * 4, sectionName);
+ wcscpy_s((WCHAR *)iter->peSection, _countof(iter->peSection), sectionName);
}
else
{
- wcscat_s((WCHAR *)iter->peSection, IMAGE_SIZEOF_SHORT_NAME * 4, L"|");
- wcscat_s((WCHAR *)iter->peSection, IMAGE_SIZEOF_SHORT_NAME * 4, sectionName);
+ wcscat_s((WCHAR *)iter->peSection, _countof(iter->peSection), L"|");
+ wcscat_s((WCHAR *)iter->peSection, _countof(iter->peSection), sectionName);
}
}
}
}
void DumpMemoryGui::setModuleName(DWORD_PTR moduleBase, const WCHAR * moduleName)
{
bool found = false;
std::vector<Memory>::const_iterator iter;
//get filename
const WCHAR* slash = wcsrchr(moduleName, L'\\');
if(slash)
{
moduleName = slash+1;
}
for( iter = memoryList.begin(); iter != memoryList.end(); iter++)
{
if (iter->address == moduleBase)
{
found = true;
}
if (found)
{
if (iter->type == MEM_IMAGE)
{
wcscpy_s((WCHAR *)iter->filename, MAX_PATH, moduleName);
}
else
{
break;
}
}
}
}
void DumpMemoryGui::setAllSectionNames( DWORD_PTR moduleBase, WCHAR * moduleName )
{
WCHAR sectionNameW[IMAGE_SIZEOF_SHORT_NAME + 1] = {0};
PeParser peFile(moduleName);
if (peFile.isValidPeFile())
{
std::vector<PeFileSection> & listSectionHeader = peFile.getSectionHeaderList();
for (WORD i = 0; i < peFile.getNumberOfSections(); i++)
{
peFile.getSectionNameUnicode(i, sectionNameW, _countof(sectionNameW));
setSectionName(moduleBase + listSectionHeader[i].sectionHeader.VirtualAddress, listSectionHeader[i].sectionHeader.Misc.VirtualSize, sectionNameW);
}
}
else
{
MessageBox(moduleName,L"Not a valid PE -> This should never happen",MB_ICONERROR);
}
}
bool DumpMemoryGui::dumpMemory()
{
DWORD_PTR address = EditMemoryAddress.GetValue();
dumpedMemorySize = EditMemorySize.GetValue();
swprintf_s(dumpFilename,TEXT("MEM_")TEXT(PRINTF_DWORD_PTR_FULL_S)TEXT("_")TEXT("%08X"),address,dumpedMemorySize);
dumpedMemory = new BYTE[dumpedMemorySize];
if (dumpedMemory)
{
if (forceDump)
{
return ProcessAccessHelp::readMemoryPartlyFromProcess(address,dumpedMemorySize,dumpedMemory);
}
else
{
return ProcessAccessHelp::readMemoryFromProcess(address,dumpedMemorySize,dumpedMemory);
}
}
else
{
return false;
}
}
bool DumpMemoryGui::getMappedFilename( Memory* memory )
{
WCHAR filename[MAX_PATH] = {0};
//TODO replace with Nt direct syscall
if (GetMappedFileNameW(ProcessAccessHelp::hProcess, (LPVOID)memory->address, filename, _countof(filename)) > 0)
{
return deviceNameResolver->resolveDeviceLongNameToShort(filename, memory->mappedFilename);
}
return false;
}
diff --git a/Scylla/DumpMemoryGui.h b/Scylla/DumpMemoryGui.h
index 63eec66..1b13cf4 100644
--- a/Scylla/DumpMemoryGui.h
+++ b/Scylla/DumpMemoryGui.h
@@ -1,169 +1,169 @@
#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 <atlframe.h> // WTL window frame helpers
#include <atlmisc.h> // WTL utility classes
#include <atlcrack.h> // WTL enhanced msg map macros
#include <atlctrls.h> // WTL controls
#include <atlddx.h> // WTL dialog data exchange
#include <vector>
#include "hexedit.h"
#include "DeviceNameResolver.h"
class Memory
{
public:
DWORD_PTR address;
DWORD size;
WCHAR filename[MAX_PATH];
WCHAR mappedFilename[MAX_PATH];
- WCHAR peSection[IMAGE_SIZEOF_SHORT_NAME *4];
- DWORD state;
- DWORD protect;
- DWORD type;
+ WCHAR peSection[IMAGE_SIZEOF_SHORT_NAME * 20];
+ DWORD state;
+ DWORD protect;
+ DWORD type;
};
class DumpMemoryGui : public CDialogImpl<DumpMemoryGui>, public CWinDataExchange<DumpMemoryGui>, public CDialogResize<DumpMemoryGui>
{
public:
enum { IDD = IDD_DLG_DUMPMEMORY };
BEGIN_DDX_MAP(DumpMemoryGui)
DDX_CONTROL_HANDLE(IDC_LIST_DUMPMEMORY, ListMemorySelect)
DDX_CONTROL(IDC_EDIT_DUMPADDRESS, EditMemoryAddress)
DDX_CONTROL(IDC_EDIT_DUMPSIZE, EditMemorySize)
DDX_CHECK(IDC_CHECK_FORCEDUMP, forceDump)
END_DDX_MAP()
BEGIN_MSG_MAP(DumpMemoryGui)
MSG_WM_INITDIALOG(OnInitDialog)
NOTIFY_HANDLER_EX(IDC_LIST_DUMPMEMORY, LVN_COLUMNCLICK, OnListMemoryColumnClicked)
NOTIFY_HANDLER_EX(IDC_LIST_DUMPMEMORY, NM_CLICK, OnListMemoryClick)
COMMAND_ID_HANDLER_EX(IDC_BTN_DUMPMEMORY_OK, OnOK)
COMMAND_ID_HANDLER_EX(IDC_BTN_DUMPMEMORY_CANCEL, OnCancel)
COMMAND_ID_HANDLER_EX(IDCANCEL, OnCancel)
CHAIN_MSG_MAP(CDialogResize<DumpMemoryGui>)
END_MSG_MAP()
BEGIN_DLGRESIZE_MAP(DumpMemoryGui)
DLGRESIZE_CONTROL(IDC_LIST_DUMPMEMORY, DLSZ_SIZE_X | DLSZ_SIZE_Y)
DLGRESIZE_CONTROL(IDC_BTN_DUMPMEMORY_OK, DLSZ_MOVE_X | DLSZ_MOVE_Y)
DLGRESIZE_CONTROL(IDC_BTN_DUMPMEMORY_CANCEL, DLSZ_MOVE_X | DLSZ_MOVE_Y)
DLGRESIZE_CONTROL(IDC_EDIT_DUMPADDRESS, DLSZ_MOVE_Y)
DLGRESIZE_CONTROL(IDC_EDIT_DUMPSIZE, DLSZ_MOVE_Y)
DLGRESIZE_CONTROL(IDC_STATIC_SIZE, DLSZ_MOVE_Y)
DLGRESIZE_CONTROL(IDC_STATIC_ADDRESS, DLSZ_MOVE_Y)
DLGRESIZE_CONTROL(IDC_CHECK_FORCEDUMP, DLSZ_MOVE_Y)
END_DLGRESIZE_MAP()
DumpMemoryGui();
~DumpMemoryGui();
BYTE * dumpedMemory;
DWORD dumpedMemorySize;
WCHAR dumpFilename[39];
protected:
CListViewCtrl ListMemorySelect;
CHexEdit<DWORD_PTR> EditMemoryAddress;
CHexEdit<DWORD> EditMemorySize;
std::vector<Memory> memoryList;
Memory * selectedMemory;
DeviceNameResolver * deviceNameResolver;
enum ListColumns {
COL_ADDRESS = 0,
COL_SIZE,
COL_FILENAME,
COL_PESECTION,
COL_TYPE,
COL_PROTECTION,
COL_STATE,
COL_MAPPED_FILE
};
int prevColumn;
bool ascending;
bool forceDump;
// Message handlers
BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam);
LRESULT OnListMemoryColumnClicked(NMHDR* pnmh);
LRESULT OnListMemoryClick(NMHDR* pnmh);
void OnOK(UINT uNotifyCode, int nID, CWindow wndCtl);
void OnCancel(UINT uNotifyCode, int nID, CWindow wndCtl);
// GUI functions
void addColumnsToMemoryList(CListViewCtrl& list);
void displayMemoryList(CListViewCtrl& list);
static int CALLBACK listviewCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
private:
enum enumMemoryStateValues {
STATE_COMMIT = 0,
STATE_FREE,
STATE_RESERVE
};
//"IMAGE",L"MAPPED",L"PRIVATE"
enum enumMemoryTypeValues {
TYPE_IMAGE = 0,
TYPE_MAPPED,
TYPE_PRIVATE
};
//"EXECUTE",L"EXECUTE_READ",L"EXECUTE_READWRITE",L"EXECUTE_WRITECOPY",L"NOACCESS",L"READONLY",L"READWRITE",L"WRITECOPY",L"GUARD",L"NOCACHE",L"WRITECOMBINE"
enum enumMemoryProtectionValues {
PROT_EXECUTE = 0,
PROT_EXECUTE_READ,
PROT_EXECUTE_READWRITE,
PROT_EXECUTE_WRITECOPY,
PROT_NOACCESS,
PROT_READONLY,
PROT_READWRITE,
PROT_WRITECOPY,
PROT_GUARD,
PROT_NOCACHE,
PROT_WRITECOMBINE
};
static const WCHAR * MemoryStateValues[];
static const WCHAR * MemoryTypeValues[];
static const WCHAR * MemoryProtectionValues[];
static const WCHAR MemoryUnknown[];
static const WCHAR MemoryUndefined[];
static WCHAR protectionString[100];
static const WCHAR * getMemoryTypeString(DWORD value);
static const WCHAR * getMemoryStateString(DWORD value);
static WCHAR * getMemoryProtectionString(DWORD value);
void updateAddressAndSize( Memory * selectedMemory );
void getMemoryList();
SIZE_T getSizeOfImage(DWORD_PTR moduleBase);
void setModuleName(DWORD_PTR moduleBase, const WCHAR * moduleName);
void setAllSectionNames( DWORD_PTR moduleBase, WCHAR * moduleName );
void setSectionName(DWORD_PTR sectionAddress, DWORD sectionSize, const WCHAR * sectionName);
bool dumpMemory();
bool getMappedFilename( Memory* memory );
};
diff --git a/Scylla/DumpSectionGui.cpp b/Scylla/DumpSectionGui.cpp
index 85785a9..7823f7c 100644
--- a/Scylla/DumpSectionGui.cpp
+++ b/Scylla/DumpSectionGui.cpp
@@ -1,382 +1,394 @@
#include "DumpSectionGui.h"
#include "Architecture.h"
#include "ProcessAccessHelp.h"
#include "PeParser.h"
bool PeSection::highlightVirtualSize()
{
//highlight big virtual sizes -> anti-dump protection
return (virtualSize > 0x2000000);
}
std::vector<PeSection> & DumpSectionGui::getSectionList()
{
return sectionList;
}
+DumpSectionGui::DumpSectionGui()
+{
+ imageBase = 0;
+ entryPoint = 0;
+ fullpath[0] = 0;
+}
+
+DumpSectionGui::~DumpSectionGui()
+{
+ sectionList.clear();
+}
+
BOOL DumpSectionGui::OnInitDialog(CWindow wndFocus, LPARAM lInitParam)
{
DoDataExchange(); // attach controls
DlgResize_Init(true, true);
addColumnsToSectionList(ListSectionSelect);
displaySectionList(ListSectionSelect);
selectOrDeselectAll();
isEditing = false;
selectedSection = 0;
CenterWindow();
return TRUE;
}
LRESULT DumpSectionGui::OnListSectionColumnClicked(NMHDR* pnmh)
{
NMLISTVIEW* list = (NMLISTVIEW*)pnmh;
int column = list->iSubItem;
if(column == prevColumn)
{
ascending = !ascending;
}
else
{
prevColumn = column;
ascending = true;
}
// lo-byte: column, hi-byte: sort-order
ListSectionSelect.SortItems(&listviewCompareFunc, MAKEWORD(column, ascending));
return 0;
}
LRESULT DumpSectionGui::OnListSectionClick(NMHDR* pnmh)
{
//int index = ListSectionSelect.GetSelectionMark();
//if (index != -1)
//{
//}
return 0;
}
LRESULT DumpSectionGui::OnListDoubleClick(NMHDR* pnmh)
{
LVHITTESTINFO hti;
RECT rect, rect1, rect2;
NMITEMACTIVATE* ia = (NMITEMACTIVATE*)pnmh;
editingSubItem = ia->iSubItem;
if (editingSubItem == COL_NAME || editingSubItem == COL_VA || editingSubItem == COL_RVA)
{
return 0;
}
hti.pt = ia->ptAction;
int clicked = ListSectionSelect.HitTest(&hti);
if(clicked != -1)
{
selectedSection = (PeSection *)ListSectionSelect.GetItemData(clicked);
}
ListSectionSelect.GetSubItemRect(ia->iItem,ia->iSubItem,LVIR_BOUNDS,&rect);
//Get the Rectange of the listControl
ListSectionSelect.GetWindowRect(&rect1);
//Get the Rectange of the Dialog
GetWindowRect(&rect2);
int x = rect1.left - rect2.left;
int y = rect1.top - rect2.top;
isEditing = true;
switch (editingSubItem)
{
case COL_VSize:
valueBeforeEditing = selectedSection->virtualSize;
break;
case COL_RSize:
valueBeforeEditing = selectedSection->rawSize;
break;
case COL_Characteristics:
valueBeforeEditing = selectedSection->characteristics;
break;
default:
valueBeforeEditing = 0;
}
EditListControl.SetValue(valueBeforeEditing);
EditListControl.SetWindowPos(HWND_TOP,rect.left + 7, rect.top + 7, rect.right - rect.left, rect.bottom - rect.top, NULL);
EditListControl.ShowWindow(SW_SHOW);
EditListControl.SetFocus();
return 0;
}
void DumpSectionGui::OnSectionSelectAll(UINT uNotifyCode, int nID, CWindow wndCtl)
{
selectOrDeselectAll();
}
void DumpSectionGui::OnEditList(UINT uNotifyCode, int nID, CWindow wndCtl)
{
switch (uNotifyCode)
{
case EN_KILLFOCUS:
{
isEditing = false;
updateEditedItem();
EditListControl.ShowWindow(SW_HIDE);
}
break;
}
}
void DumpSectionGui::OnOK(UINT uNotifyCode, int nID, CWindow wndCtl)
{
if (isEditing) //EN_KILLFOCUS not sent?
{
updateEditedItem();
}
updateCheckState();
EndDialog(1);
}
void DumpSectionGui::OnCancel(UINT uNotifyCode, int nID, CWindow wndCtl)
{
EndDialog(0);
}
int DumpSectionGui::listviewCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
const PeSection * module1 = (PeSection *)lParam1;
const PeSection * module2 = (PeSection *)lParam2;
int column = LOBYTE(lParamSort);
bool ascending = (HIBYTE(lParamSort) == TRUE);
int diff = 0;
switch(column)
{
case COL_NAME:
diff = _wcsicmp(module1->name, module2->name);
break;
case COL_VA:
diff = module1->virtualAddress < module2->virtualAddress ? -1 : 1;
break;
case COL_VSize:
diff = module1->virtualSize < module2->virtualSize ? -1 : 1;
break;
case COL_RVA:
diff = module1->rawAddress < module2->rawAddress ? -1 : 1;
break;
case COL_RSize:
diff = module1->rawSize < module2->rawSize ? -1 : 1;
break;
case COL_Characteristics:
diff = module1->characteristics < module2->characteristics ? -1 : 1;
break;
}
return ascending ? diff : -diff;
}
void DumpSectionGui::addColumnsToSectionList(CListViewCtrl& list)
{
list.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT|LVS_EX_CHECKBOXES|LVS_EX_GRIDLINES, LVS_EX_FULLROWSELECT|LVS_EX_CHECKBOXES|LVS_EX_GRIDLINES);
list.InsertColumn(COL_NAME, L"Name", LVCFMT_CENTER);
list.InsertColumn(COL_VA, L"Virtual Address", LVCFMT_CENTER);
list.InsertColumn(COL_VSize, L"Virtual Size", LVCFMT_CENTER);
list.InsertColumn(COL_RVA, L"Raw Address", LVCFMT_CENTER);
list.InsertColumn(COL_RSize, L"Raw Size", LVCFMT_CENTER);
list.InsertColumn(COL_Characteristics, L"Characteristics", LVCFMT_CENTER);
}
void DumpSectionGui::displaySectionList(CListViewCtrl& list)
{
int count = 0;
WCHAR temp[20];
list.DeleteAllItems();
if (sectionList.empty())
{
getAllSectionsFromFile();
}
std::vector<PeSection>::const_iterator iter;
for( iter = sectionList.begin(); iter != sectionList.end(); iter++ , count++)
{
list.InsertItem(count, iter->name);
swprintf_s(temp, PRINTF_DWORD_PTR_FULL, iter->virtualAddress);
list.SetItemText(count, COL_VA, temp);
swprintf_s(temp, L"%08X", iter->virtualSize);
list.SetItemText(count, COL_VSize, temp);
swprintf_s(temp, L"%08X", iter->rawAddress);
list.SetItemText(count, COL_RVA, temp);
swprintf_s(temp, L"%08X", iter->rawSize);
list.SetItemText(count, COL_RSize, temp);
swprintf_s(temp, L"%08X", iter->characteristics);
list.SetItemText(count, COL_Characteristics, temp);
list.SetItemData(count, (DWORD_PTR)&(*iter));
}
list.SetColumnWidth(COL_NAME, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_VA, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_VSize, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_RVA, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_RSize, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_Characteristics, LVSCW_AUTOSIZE_USEHEADER);
}
LRESULT DumpSectionGui::OnNMCustomdraw(NMHDR* pnmh)
{
LRESULT pResult = 0;
unsigned int vectorIndex = 0;
LPNMLVCUSTOMDRAW lpLVCustomDraw = (LPNMLVCUSTOMDRAW)(pnmh);
switch(lpLVCustomDraw->nmcd.dwDrawStage)
{
case CDDS_ITEMPREPAINT:
case CDDS_ITEMPREPAINT | CDDS_SUBITEM:
{
vectorIndex = (unsigned int)lpLVCustomDraw->nmcd.dwItemSpec;
if (lpLVCustomDraw->iSubItem == COL_VSize)
{
if (sectionList[vectorIndex].highlightVirtualSize())
{
lpLVCustomDraw->clrText = RGB(255,255,255); // white text
lpLVCustomDraw->clrTextBk = RGB(255,0,0); // red background
}
}
else
{
lpLVCustomDraw->clrText = CLR_DEFAULT;
lpLVCustomDraw->clrTextBk = CLR_DEFAULT;
}
}
break;
default:
break;
}
pResult |= CDRF_NOTIFYPOSTPAINT;
pResult |= CDRF_NOTIFYITEMDRAW;
pResult |= CDRF_NOTIFYSUBITEMDRAW;
return pResult;
}
void DumpSectionGui::getAllSectionsFromFile()
{
PeSection peSection;
if (sectionList.empty())
{
sectionList.reserve(3);
}
else
{
sectionList.clear();
}
PeParser peFile(fullpath);
if (peFile.isValidPeFile())
{
std::vector<PeFileSection> & listSectionHeader = peFile.getSectionHeaderList();
for (WORD i = 0; i < peFile.getNumberOfSections(); i++)
{
peFile.getSectionNameUnicode(i, peSection.name, _countof(peSection.name));
peSection.virtualAddress = imageBase + listSectionHeader[i].sectionHeader.VirtualAddress;
peSection.virtualSize = listSectionHeader[i].sectionHeader.Misc.VirtualSize;
peSection.rawAddress = listSectionHeader[i].sectionHeader.PointerToRawData;
peSection.rawSize = listSectionHeader[i].sectionHeader.SizeOfRawData;
peSection.characteristics = listSectionHeader[i].sectionHeader.Characteristics;
peSection.isDumped = true;
sectionList.push_back(peSection);
}
}
else
{
MessageBox(fullpath, L"Not a valid PE -> This should never happen", MB_ICONERROR);
}
}
void DumpSectionGui::updateEditedItem()
{
if (selectedSection)
{
DWORD newValue = EditListControl.GetValue();
if (valueBeforeEditing != newValue)
{
switch (editingSubItem)
{
case COL_VSize:
selectedSection->virtualSize = newValue;
break;
case COL_RSize:
selectedSection->rawSize = newValue;
break;
case COL_Characteristics:
selectedSection->characteristics = newValue;
break;
}
displaySectionList(ListSectionSelect);
selectOrDeselectAll();
}
}
}
void DumpSectionGui::updateCheckState()
{
PeSection * pesection;
for (size_t i = 0; i < sectionList.size(); i++)
{
pesection = (PeSection *)ListSectionSelect.GetItemData((int)i);
pesection->isDumped = ListSectionSelect.GetCheckState((int)i) == TRUE;
}
}
void DumpSectionGui::selectOrDeselectAll()
{
BOOL checkState = ListSectionSelect.GetCheckState((int)0) ? FALSE : TRUE;
for (size_t i = 0; i < sectionList.size(); i++)
{
ListSectionSelect.SetCheckState((int)i, checkState);
}
}
\ No newline at end of file
diff --git a/Scylla/DumpSectionGui.h b/Scylla/DumpSectionGui.h
index cfc8412..17bfe02 100644
--- a/Scylla/DumpSectionGui.h
+++ b/Scylla/DumpSectionGui.h
@@ -1,132 +1,127 @@
#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 <atlframe.h> // WTL window frame helpers
#include <atlmisc.h> // WTL utility classes
#include <atlcrack.h> // WTL enhanced msg map macros
#include <atlctrls.h> // WTL controls
#include <atlddx.h> // WTL dialog data exchange
#include <vector>
#include "hexedit.h"
class PeSection
{
public:
WCHAR name[IMAGE_SIZEOF_SHORT_NAME + 1];
DWORD_PTR virtualAddress;
DWORD virtualSize;
DWORD_PTR rawAddress;
DWORD rawSize;
DWORD characteristics;
bool isDumped;
bool highlightVirtualSize();
};
class DumpSectionGui : public CDialogImpl<DumpSectionGui>, public CWinDataExchange<DumpSectionGui>, public CDialogResize<DumpSectionGui>
{
public:
enum { IDD = IDD_DLG_DUMPSECTION };
BEGIN_DDX_MAP(DumpSectionGui)
DDX_CONTROL_HANDLE(IDC_LIST_DUMPSECTION, ListSectionSelect)
DDX_CONTROL(IDC_EDIT_LISTCONTROL, EditListControl)
END_DDX_MAP()
BEGIN_MSG_MAP(DumpSectionGui)
MSG_WM_INITDIALOG(OnInitDialog)
NOTIFY_HANDLER_EX(IDC_LIST_DUMPSECTION, LVN_COLUMNCLICK, OnListSectionColumnClicked)
NOTIFY_HANDLER_EX(IDC_LIST_DUMPSECTION, NM_CLICK, OnListSectionClick)
NOTIFY_HANDLER_EX(IDC_LIST_DUMPSECTION, NM_CUSTOMDRAW, OnNMCustomdraw)
NOTIFY_HANDLER_EX(IDC_LIST_DUMPSECTION, NM_DBLCLK, OnListDoubleClick)
COMMAND_ID_HANDLER_EX(IDC_BUTTON_SELECT_DESELECT, OnSectionSelectAll)
COMMAND_ID_HANDLER_EX(IDC_BTN_DUMPSECTION_OK, OnOK)
COMMAND_ID_HANDLER_EX(IDC_EDIT_LISTCONTROL, OnEditList)
COMMAND_ID_HANDLER_EX(IDC_BTN_DUMPSECTION_CANCEL, OnCancel)
COMMAND_ID_HANDLER_EX(IDCANCEL, OnCancel)
CHAIN_MSG_MAP(CDialogResize<DumpSectionGui>)
END_MSG_MAP()
BEGIN_DLGRESIZE_MAP(DumpSectionGui)
DLGRESIZE_CONTROL(IDC_LIST_DUMPSECTION, DLSZ_SIZE_X | DLSZ_SIZE_Y)
DLGRESIZE_CONTROL(IDC_BTN_DUMPSECTION_OK, DLSZ_MOVE_X | DLSZ_MOVE_Y)
DLGRESIZE_CONTROL(IDC_BTN_DUMPSECTION_CANCEL, DLSZ_MOVE_X | DLSZ_MOVE_Y)
DLGRESIZE_CONTROL(IDC_BUTTON_SELECT_DESELECT, DLSZ_MOVE_Y)
END_DLGRESIZE_MAP()
- DumpSectionGui()
- {
- imageBase = 0;
- entryPoint = 0;
- fullpath[0] = 0;
- }
- //~DumpSectionGui();
+ DumpSectionGui();
+ ~DumpSectionGui();
DWORD_PTR imageBase; //VA
DWORD_PTR entryPoint;
WCHAR fullpath[MAX_PATH];
std::vector<PeSection> & getSectionList();
private:
CListViewCtrl ListSectionSelect;
CHexEdit<DWORD> EditListControl;
std::vector<PeSection> sectionList;
PeSection *selectedSection;
bool isEditing;
int editingSubItem;
DWORD valueBeforeEditing;
enum ListColumns {
COL_NAME = 0,
COL_VA,
COL_VSize,
COL_RVA,
COL_RSize,
COL_Characteristics
};
int prevColumn;
bool ascending;
// Message handlers
BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam);
LRESULT OnListSectionColumnClicked(NMHDR* pnmh);
LRESULT OnListSectionClick(NMHDR* pnmh);
LRESULT OnNMCustomdraw(NMHDR* pnmh);
LRESULT OnListDoubleClick(NMHDR* pnmh);
void OnSectionSelectAll(UINT uNotifyCode, int nID, CWindow wndCtl);
void OnEditList(UINT uNotifyCode, int nID, CWindow wndCtl);
void OnOK(UINT uNotifyCode, int nID, CWindow wndCtl);
void OnCancel(UINT uNotifyCode, int nID, CWindow wndCtl);
// GUI functions
void addColumnsToSectionList(CListViewCtrl& list);
void displaySectionList(CListViewCtrl& list);
static int CALLBACK listviewCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
WCHAR * getCharacteristicsString( DWORD characteristics );
void getAllSectionsFromFile();
void updateEditedItem();
void updateCheckState();
void selectOrDeselectAll();
};
\ No newline at end of file
diff --git a/Scylla/Scylla.h b/Scylla/Scylla.h
index a14486f..5478853 100644
--- a/Scylla/Scylla.h
+++ b/Scylla/Scylla.h
@@ -1,31 +1,31 @@
#pragma once
#include "ConfigurationHolder.h"
#include "PluginLoader.h"
#include "ProcessLister.h"
#include "Logger.h"
#define APPNAME_S "Scylla"
-#define APPVERSION_S "v0.6"
+#define APPVERSION_S "v0.6a"
#define APPNAME TEXT(APPNAME_S)
#define APPVERSION TEXT(APPVERSION_S)
class Scylla
{
public:
static void init();
static ConfigurationHolder config;
static PluginLoader plugins;
static ProcessLister processLister;
static FileLog debugLog;
static ListboxLog windowLog;
private:
static const WCHAR DEBUG_LOG_FILENAME[];
};
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Nov 14, 12:13 PM (6 h, 42 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
4a/40/ad9992af575ee5c8f4ff13ea9a88
Attached To
rSCY Scylla
Event Timeline
Log In to Comment