Page MenuHomedesp's stash

No OneTemporary

diff --git a/Scylla/DumpMemoryGui.cpp b/Scylla/DumpMemoryGui.cpp
index 38e355b..8e492cd 100644
--- a/Scylla/DumpMemoryGui.cpp
+++ b/Scylla/DumpMemoryGui.cpp
@@ -1,605 +1,605 @@
#include "DumpMemoryGui.h"
#include "Architecture.h"
#include "ProcessAccessHelp.h"
#include <Psapi.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;
}
}
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);
}
else
{
wcscat_s((WCHAR *)iter->peSection, IMAGE_SIZEOF_SHORT_NAME * 4, L"|");
wcscat_s((WCHAR *)iter->peSection, IMAGE_SIZEOF_SHORT_NAME * 4, 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);
}
else
{
wcscat_s((WCHAR *)iter->peSection, IMAGE_SIZEOF_SHORT_NAME * 4, L"|");
wcscat_s((WCHAR *)iter->peSection, IMAGE_SIZEOF_SHORT_NAME * 4, 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 )
{
WORD numSections = 0;
PIMAGE_DOS_HEADER pDos = 0;
PIMAGE_NT_HEADERS pNT = 0;
PIMAGE_SECTION_HEADER pSec = 0;
DWORD size = sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS) + 200;
DWORD correctSize = 0;
WCHAR sectionNameW[IMAGE_SIZEOF_SHORT_NAME + 1] = {0};
CHAR sectionNameA[IMAGE_SIZEOF_SHORT_NAME + 1] = {0};
BYTE * buffer = new BYTE[size];
if (ProcessAccessHelp::readMemoryFromProcess(moduleBase,size,buffer))
{
pDos = (PIMAGE_DOS_HEADER)buffer;
if (pDos->e_magic == IMAGE_DOS_SIGNATURE)
{
pNT = (PIMAGE_NT_HEADERS)((DWORD_PTR)pDos + pDos->e_lfanew);
if (pNT->Signature == IMAGE_NT_SIGNATURE)
{
numSections = pNT->FileHeader.NumberOfSections;
correctSize = (numSections*sizeof(IMAGE_SECTION_HEADER)) + sizeof(IMAGE_NT_HEADERS) + pDos->e_lfanew;
if (size < correctSize)
{
size = correctSize;
delete [] buffer;
buffer = new BYTE[size];
if (!ProcessAccessHelp::readMemoryFromProcess(moduleBase,size,buffer))
{
delete [] buffer;
return;
}
pDos = (PIMAGE_DOS_HEADER)buffer;
pNT = (PIMAGE_NT_HEADERS)((DWORD_PTR)pDos + pDos->e_lfanew);
}
pSec = IMAGE_FIRST_SECTION(pNT);
for (WORD i = 0; i < numSections; i++)
{
ZeroMemory(sectionNameA, sizeof(sectionNameA));
memcpy(sectionNameA,pSec->Name,8);
swprintf_s(sectionNameW,L"%S",sectionNameA);
setSectionName(moduleBase + pSec->VirtualAddress, pSec->Misc.VirtualSize,sectionNameW);
pSec++;
}
}
}
}
delete [] buffer;
}
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 deviceNameResolver->resolveDeviceLongNameToShort(filename, memory->mappedFilename);
}
return false;
}
diff --git a/Scylla/DumpSectionGui.cpp b/Scylla/DumpSectionGui.cpp
index a8ab9a6..a985ce1 100644
--- a/Scylla/DumpSectionGui.cpp
+++ b/Scylla/DumpSectionGui.cpp
@@ -1,329 +1,391 @@
#include "DumpSectionGui.h"
#include "Architecture.h"
#include "ProcessAccessHelp.h"
bool PeSection::highlightVirtualSize()
{
- //highlight too big virtual sizes -> anti-dump protection
+ //highlight big virtual sizes -> anti-dump protection
if (virtualSize > 0x2000000)
{
return true;
}
else
{
return false;
}
}
+std::vector<PeSection> & DumpSectionGui::getSectionList()
+{
+ return sectionList;
+}
+
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)
- {
- //selectedMemory = (Memory *)ListMemorySelect.GetItemData(index);
- //if (selectedMemory)
- //{
- // //updateAddressAndSize(selectedMemory);
- //}
+ //int index = ListSectionSelect.GetSelectionMark();
+ //if (index != -1)
+ //{
- }
+ //}
return 0;
}
LRESULT DumpSectionGui::OnListDoubleClick(NMHDR* pnmh)
{
RECT rect;
RECT rect1,rect2;
NMITEMACTIVATE* ia = (NMITEMACTIVATE*)pnmh;
if (ia->iSubItem != COL_VSize)
{
return 0;
}
-
LVHITTESTINFO hti;
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;
+
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();
//Draw a Rectangle around the SubItem
//Rectangle(ListSectionSelect.GetDC(),rect.left,rect.top-1,rect.right,rect.bottom);
//Set the listItem text in the EditBox
EditListControl.SetValue(selectedSection->virtualSize);
return 0;
}
void DumpSectionGui::OnSectionSelectAll(UINT uNotifyCode, int nID, CWindow wndCtl)
{
- for (size_t i = 0; i < sectionList.size(); i++)
+ selectOrDeselectAll();
+}
+
+void DumpSectionGui::OnEditList(UINT uNotifyCode, int nID, CWindow wndCtl)
+{
+ switch (uNotifyCode)
{
- ListSectionSelect.SetCheckState((int)i, ListSectionSelect.GetCheckState((int)i) ? FALSE : TRUE);
+ 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();
- getAllSectionsFromFile();
+ 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()
{
PIMAGE_DOS_HEADER pDos = 0;
PIMAGE_SECTION_HEADER pSec = 0;
PIMAGE_NT_HEADERS pNT = 0;
DWORD size = sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS) + 200;
DWORD correctSize = 0;
CHAR sectionNameA[IMAGE_SIZEOF_SHORT_NAME + 1] = {0};
PeSection peSection;
if (sectionList.empty())
{
sectionList.reserve(3);
}
else
{
sectionList.clear();
}
BYTE * buffer = new BYTE[size];
if (ProcessAccessHelp::readHeaderFromFile(buffer,size,fullpath))
{
pDos = (PIMAGE_DOS_HEADER)buffer;
if (pDos->e_magic == IMAGE_DOS_SIGNATURE)
{
pNT = (PIMAGE_NT_HEADERS)((DWORD_PTR)pDos + pDos->e_lfanew);
if (pNT->Signature == IMAGE_NT_SIGNATURE)
{
correctSize = (pNT->FileHeader.NumberOfSections*sizeof(IMAGE_SECTION_HEADER)) + sizeof(IMAGE_NT_HEADERS) + pDos->e_lfanew + 50;
if (size < correctSize)
{
size = correctSize;
delete [] buffer;
buffer = new BYTE[size];
if (!ProcessAccessHelp::readHeaderFromFile(buffer,size,fullpath))
{
delete [] buffer;
return;
}
pDos = (PIMAGE_DOS_HEADER)buffer;
pNT = (PIMAGE_NT_HEADERS)((DWORD_PTR)pDos + pDos->e_lfanew);
}
pSec = IMAGE_FIRST_SECTION(pNT);
for (WORD i = 0; i < pNT->FileHeader.NumberOfSections; i++)
{
ZeroMemory(sectionNameA, sizeof(sectionNameA));
memcpy(sectionNameA,pSec->Name,8);
swprintf_s(peSection.name,L"%S",sectionNameA);
peSection.virtualAddress = imageBase + pSec->VirtualAddress;
peSection.virtualSize = pSec->Misc.VirtualSize;
peSection.rawAddress = pSec->PointerToRawData;
peSection.rawSize = pSec->SizeOfRawData;
peSection.characteristics = pSec->Characteristics;
+ peSection.isDumped = true;
sectionList.push_back(peSection);
pSec++;
}
}
}
}
delete [] buffer;
}
+
+void DumpSectionGui::updateEditedItem()
+{
+ if (selectedSection)
+ {
+ selectedSection->virtualSize = EditListControl.GetValue();
+
+ displaySectionList(ListSectionSelect);
+ }
+}
+
+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);
+ }
+}
diff --git a/Scylla/DumpSectionGui.h b/Scylla/DumpSectionGui.h
index 3975be7..79a14d8 100644
--- a/Scylla/DumpSectionGui.h
+++ b/Scylla/DumpSectionGui.h
@@ -1,118 +1,130 @@
#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;
sizeOfImage = 0;
fullpath[0] = 0;
}
//~DumpSectionGui();
DWORD_PTR imageBase; //VA
DWORD sizeOfImage;
WCHAR fullpath[MAX_PATH];
+
+ std::vector<PeSection> & getSectionList();
+
private:
CListViewCtrl ListSectionSelect;
CHexEdit<DWORD> EditListControl;
std::vector<PeSection> sectionList;
PeSection *selectedSection;
+ bool isEditing;
+
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/ProcessAccessHelp.cpp b/Scylla/ProcessAccessHelp.cpp
index abe4a93..86324b9 100644
--- a/Scylla/ProcessAccessHelp.cpp
+++ b/Scylla/ProcessAccessHelp.cpp
@@ -1,802 +1,802 @@
#include "ProcessAccessHelp.h"
#include "Scylla.h"
#include "NativeWinApi.h"
HANDLE ProcessAccessHelp::hProcess = 0;
ModuleInfo * ProcessAccessHelp::selectedModule;
DWORD_PTR ProcessAccessHelp::targetImageBase = 0;
DWORD_PTR ProcessAccessHelp::targetSizeOfImage = 0;
DWORD_PTR ProcessAccessHelp::maxValidAddress = 0;
std::vector<ModuleInfo> ProcessAccessHelp::moduleList; //target process module list
std::vector<ModuleInfo> ProcessAccessHelp::ownModuleList; //own module list
_DInst ProcessAccessHelp::decomposerResult[MAX_INSTRUCTIONS];
unsigned int ProcessAccessHelp::decomposerInstructionsCount = 0;
_CodeInfo ProcessAccessHelp::decomposerCi = {0};
_DecodedInst ProcessAccessHelp::decodedInstructions[MAX_INSTRUCTIONS];
unsigned int ProcessAccessHelp::decodedInstructionsCount = 0;
BYTE ProcessAccessHelp::fileHeaderFromDisk[PE_HEADER_BYTES_COUNT];
//#define DEBUG_COMMENTS
bool ProcessAccessHelp::openProcessHandle(DWORD dwPID)
{
if (dwPID > 0)
{
if (hProcess)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"openProcessHandle :: There is already a process handle, HANDLE %X", hProcess);
#endif
return false;
}
else
{
//hProcess = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_QUERY_INFORMATION|PROCESS_VM_READ|PROCESS_VM_WRITE, 0, dwPID);
//if (!NT_SUCCESS(NativeWinApi::NtOpenProcess(&hProcess,PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_QUERY_INFORMATION|PROCESS_VM_READ|PROCESS_VM_WRITE,&ObjectAttributes, &cid)))
hProcess = NativeOpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_QUERY_INFORMATION|PROCESS_VM_READ|PROCESS_VM_WRITE, dwPID);
if (hProcess)
{
return true;
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"openProcessHandle :: Failed to open handle, PID %X", dwPID);
#endif
return false;
}
}
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"openProcessHandle :: Wrong PID, PID %X", dwPID);
#endif
return false;
}
}
HANDLE ProcessAccessHelp::NativeOpenProcess(DWORD dwDesiredAccess, DWORD dwProcessId)
{
HANDLE hProcess = 0;
CLIENT_ID cid = {0};
OBJECT_ATTRIBUTES ObjectAttributes;
NTSTATUS ntStatus = 0;
InitializeObjectAttributes(&ObjectAttributes, 0, 0, 0, 0);
cid.UniqueProcess = (HANDLE)dwProcessId;
ntStatus = NativeWinApi::NtOpenProcess(&hProcess,dwDesiredAccess,&ObjectAttributes, &cid);
if (NT_SUCCESS(ntStatus))
{
return hProcess;
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"NativeOpenProcess :: Failed to open handle, PID %X Error 0x%X", dwProcessId, NativeWinApi::RtlNtStatusToDosError(ntStatus));
#endif
return 0;
}
}
void ProcessAccessHelp::closeProcessHandle()
{
CloseHandle(hProcess);
hProcess = 0;
moduleList.clear();
targetImageBase = 0;
selectedModule = 0;
}
bool ProcessAccessHelp::readMemoryPartlyFromProcess(DWORD_PTR address, SIZE_T size, LPVOID dataBuffer)
{
DWORD_PTR addressPart = 0;
DWORD_PTR readBytes = 0;
DWORD_PTR bytesToRead = 0;
MEMORY_BASIC_INFORMATION memBasic = {0};
bool returnValue = false;
if (!hProcess)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryPartlyFromProcess :: hProcess == NULL");
#endif
return returnValue;
}
if (!readMemoryFromProcess(address, size, dataBuffer))
{
addressPart = address;
do
{
if (!VirtualQueryEx(ProcessAccessHelp::hProcess,(LPCVOID)addressPart,&memBasic,sizeof(memBasic)))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryPartlyFromProcess :: Error VirtualQueryEx %X %X err: %u", addressPart,size, GetLastError());
#endif
break;
}
bytesToRead = memBasic.RegionSize;
if ( (readBytes+bytesToRead) > size)
{
bytesToRead = size - readBytes;
}
- if (memBasic.State != MEM_FREE && memBasic.State != MEM_RESERVE)
+ if (memBasic.State == MEM_COMMIT)
{
- if (!readMemoryFromProcess(addressPart, bytesToRead, (LPVOID)((DWORD_PTR)dataBuffer + readBytes)) )
+ if (!readMemoryFromProcess(addressPart, bytesToRead, (LPVOID)((DWORD_PTR)dataBuffer + readBytes)))
{
break;
}
}
else
{
ZeroMemory((LPVOID)((DWORD_PTR)dataBuffer + readBytes),bytesToRead);
}
readBytes += bytesToRead;
addressPart += memBasic.RegionSize;
} while (readBytes < size);
if (readBytes == size)
{
returnValue = true;
}
}
else
{
returnValue = true;
}
return returnValue;
}
bool ProcessAccessHelp::readMemoryFromProcess(DWORD_PTR address, SIZE_T size, LPVOID dataBuffer)
{
SIZE_T lpNumberOfBytesRead = 0;
DWORD dwProtect = 0;
bool returnValue = false;
if (!hProcess)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryFromProcess :: hProcess == NULL");
#endif
return returnValue;
}
if (!ReadProcessMemory(hProcess, (LPVOID)address, dataBuffer, size, &lpNumberOfBytesRead))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryFromProcess :: Error ReadProcessMemory %X %X err: %u", address, size, GetLastError());
#endif
if (!VirtualProtectEx(hProcess, (LPVOID)address, size, PAGE_READWRITE, &dwProtect))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryFromProcess :: Error VirtualProtectEx %X %X err: %u", address,size, GetLastError());
#endif
returnValue = false;
}
else
{
if (!ReadProcessMemory(hProcess, (LPVOID)address, dataBuffer, size, &lpNumberOfBytesRead))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryFromProcess :: Error ReadProcessMemory %X %X err: %u", address, size, GetLastError());
#endif
returnValue = false;
}
else
{
returnValue = true;
}
VirtualProtectEx(hProcess, (LPVOID)address, size, dwProtect, &dwProtect);
}
}
else
{
returnValue = true;
}
if (returnValue)
{
if (size != lpNumberOfBytesRead)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryFromProcess :: Error ReadProcessMemory read %d bytes requested %d bytes", lpNumberOfBytesRead, size);
#endif
returnValue = false;
}
else
{
returnValue = true;
}
}
return returnValue;
}
bool ProcessAccessHelp::decomposeMemory(BYTE * dataBuffer, SIZE_T bufferSize, DWORD_PTR startAddress)
{
ZeroMemory(&decomposerCi, sizeof(_CodeInfo));
decomposerCi.code = dataBuffer;
decomposerCi.codeLen = (int)bufferSize;
decomposerCi.dt = dt;
decomposerCi.codeOffset = startAddress;
decomposerInstructionsCount = 0;
if (distorm_decompose(&decomposerCi, decomposerResult, sizeof(decomposerResult)/sizeof(decomposerResult[0]), &decomposerInstructionsCount) == DECRES_INPUTERR)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"decomposeMemory :: distorm_decompose == DECRES_INPUTERR");
#endif
return false;
}
else
{
return true;
}
}
bool ProcessAccessHelp::disassembleMemory(BYTE * dataBuffer, SIZE_T bufferSize, DWORD_PTR startOffset)
{
// Holds the result of the decoding.
_DecodeResult res;
// next is used for instruction's offset synchronization.
// decodedInstructionsCount holds the count of filled instructions' array by the decoder.
decodedInstructionsCount = 0;
_OffsetType offset = startOffset;
res = distorm_decode(offset, dataBuffer, (int)bufferSize, dt, decodedInstructions, MAX_INSTRUCTIONS, &decodedInstructionsCount);
/* for (unsigned int i = 0; i < decodedInstructionsCount; i++) {
#ifdef SUPPORT_64BIT_OFFSET
printf("%0*I64x (%02d) %-24s %s%s%s\n", dt != Decode64Bits ? 8 : 16, decodedInstructions[i].offset, decodedInstructions[i].size, (char*)decodedInstructions[i].instructionHex.p, (char*)decodedInstructions[i].mnemonic.p, decodedInstructions[i].operands.length != 0 ? " " : "", (char*)decodedInstructions[i].operands.p);
#else
printf("%08x (%02d) %-24s %s%s%s\n", decodedInstructions[i].offset, decodedInstructions[i].size, (char*)decodedInstructions[i].instructionHex.p, (char*)decodedInstructions[i].mnemonic.p, decodedInstructions[i].operands.length != 0 ? " " : "", (char*)decodedInstructions[i].operands.p);
#endif
}*/
if (res == DECRES_INPUTERR)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"disassembleMemory :: res == DECRES_INPUTERR");
#endif
return false;
}
else if (res == DECRES_SUCCESS)
{
//printf("disassembleMemory :: res == DECRES_SUCCESS\n");
return true;
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"disassembleMemory :: res == %d", res);
#endif
return false;
}
}
DWORD_PTR ProcessAccessHelp::findPattern(DWORD_PTR startOffset, DWORD size, BYTE * pattern, const char * mask)
{
DWORD pos = 0;
size_t searchLen = strlen(mask) - 1;
for(DWORD_PTR retAddress = startOffset; retAddress < startOffset + size; retAddress++)
{
if( *(BYTE*)retAddress == pattern[pos] || mask[pos] == '?' )
{
if(mask[pos+1] == 0x00)
{
return (retAddress - searchLen);
}
pos++;
} else {
pos = 0;
}
}
return 0;
}
bool ProcessAccessHelp::readHeaderFromCurrentFile(const WCHAR * filePath)
{
return readHeaderFromFile(fileHeaderFromDisk, sizeof(fileHeaderFromDisk), filePath);
}
LONGLONG ProcessAccessHelp::getFileSize(const WCHAR * filePath)
{
LONGLONG fileSize = 0;
HANDLE hFile = CreateFile(filePath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if (hFile != INVALID_HANDLE_VALUE)
{
fileSize = getFileSize(hFile);
CloseHandle(hFile);
hFile = 0;
}
return fileSize;
}
LONGLONG ProcessAccessHelp::getFileSize(HANDLE hFile)
{
LARGE_INTEGER lpFileSize = {0};
if ((hFile != INVALID_HANDLE_VALUE) && (hFile != 0))
{
if (!GetFileSizeEx(hFile, &lpFileSize))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"ProcessAccessHelp::getFileSize :: GetFileSizeEx failed %u", GetLastError());
#endif
return 0;
}
else
{
return lpFileSize.QuadPart;
}
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"ProcessAccessHelp::getFileSize hFile invalid");
#endif
return 0;
}
}
bool ProcessAccessHelp::readMemoryFromFile(HANDLE hFile, LONG offset, DWORD size, LPVOID dataBuffer)
{
DWORD lpNumberOfBytesRead = 0;
DWORD retValue = 0;
DWORD dwError = 0;
if ((hFile != INVALID_HANDLE_VALUE) && (hFile != 0))
{
retValue = SetFilePointer(hFile, offset, NULL, FILE_BEGIN);
dwError = GetLastError();
if ((retValue == INVALID_SET_FILE_POINTER) && (dwError != NO_ERROR))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryFromFile :: SetFilePointer failed error %u", dwError);
#endif
return false;
}
else
{
if (ReadFile(hFile, dataBuffer, size, &lpNumberOfBytesRead, 0))
{
return true;
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryFromFile :: ReadFile failed - size %d - error %u", size, GetLastError());
#endif
return false;
}
}
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryFromFile :: hFile invalid");
#endif
return false;
}
}
bool ProcessAccessHelp::writeMemoryToNewFile(const WCHAR * file,DWORD size, LPCVOID dataBuffer)
{
HANDLE hFile = CreateFile(file, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
if (hFile != INVALID_HANDLE_VALUE)
{
return writeMemoryToFile(hFile,0,size,dataBuffer);
}
else
{
return false;
}
}
bool ProcessAccessHelp::writeMemoryToFile(HANDLE hFile, LONG offset, DWORD size, LPCVOID dataBuffer)
{
DWORD lpNumberOfBytesWritten = 0;
DWORD retValue = 0;
DWORD dwError = 0;
if ((hFile != INVALID_HANDLE_VALUE) && (hFile != 0))
{
retValue = SetFilePointer(hFile, offset, NULL, FILE_BEGIN);
dwError = GetLastError();
if ((retValue == INVALID_SET_FILE_POINTER) && (dwError != NO_ERROR))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"writeMemoryToFile :: SetFilePointer failed error %u", dwError);
#endif
return false;
}
else
{
if (WriteFile(hFile, dataBuffer, size, &lpNumberOfBytesWritten, 0))
{
return true;
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"writeMemoryToFile :: WriteFile failed - size %d - error %u", size, GetLastError());
#endif
return false;
}
}
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"writeMemoryToFile :: hFile invalid");
#endif
return false;
}
}
bool ProcessAccessHelp::writeMemoryToFileEnd(HANDLE hFile, DWORD size, LPCVOID dataBuffer)
{
DWORD lpNumberOfBytesWritten = 0;
DWORD retValue = 0;
if ((hFile != INVALID_HANDLE_VALUE) && (hFile != 0))
{
SetFilePointer(hFile, 0, 0, FILE_END);
if (WriteFile(hFile, dataBuffer, size, &lpNumberOfBytesWritten, 0))
{
return true;
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"writeMemoryToFileEnd :: WriteFile failed - size %d - error %u", size, GetLastError());
#endif
return false;
}
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"writeMemoryToFileEnd :: hFile invalid");
#endif
return false;
}
}
bool ProcessAccessHelp::readHeaderFromFile(BYTE * buffer, DWORD bufferSize, const WCHAR * filePath)
{
DWORD lpNumberOfBytesRead = 0;
LONGLONG fileSize = 0;
DWORD dwSize = 0;
bool returnValue = 0;
HANDLE hFile = CreateFile(filePath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if( hFile == INVALID_HANDLE_VALUE )
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readHeaderFromFile :: INVALID_HANDLE_VALUE %u", GetLastError());
#endif
returnValue = false;
}
else
{
fileSize = getFileSize(hFile);
if (fileSize > 0)
{
if (fileSize > bufferSize)
{
dwSize = bufferSize;
}
else
{
dwSize = (DWORD)(fileSize - 1);
}
returnValue = readMemoryFromFile(hFile, 0, dwSize, buffer);
}
CloseHandle(hFile);
}
return returnValue;
}
LPVOID ProcessAccessHelp::createFileMappingViewRead(const WCHAR * filePath)
{
return createFileMappingView(filePath, GENERIC_READ, PAGE_READONLY | SEC_IMAGE, FILE_MAP_READ);
}
LPVOID ProcessAccessHelp::createFileMappingViewFull(const WCHAR * filePath)
{
return createFileMappingView(filePath, GENERIC_ALL, PAGE_EXECUTE_READWRITE, FILE_MAP_ALL_ACCESS);
}
LPVOID ProcessAccessHelp::createFileMappingView(const WCHAR * filePath, DWORD accessFile, DWORD flProtect, DWORD accessMap)
{
HANDLE hFile = CreateFile(filePath, accessFile, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if( hFile == INVALID_HANDLE_VALUE )
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"createFileMappingView :: INVALID_HANDLE_VALUE %u", GetLastError());
#endif
return NULL;
}
HANDLE hMappedFile = CreateFileMapping(hFile, NULL, flProtect, 0, 0, NULL);
CloseHandle(hFile);
if( hMappedFile == NULL )
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"createFileMappingView :: hMappedFile == NULL");
#endif
return NULL;
}
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"createFileMappingView :: GetLastError() == ERROR_ALREADY_EXISTS");
#endif
return NULL;
}
LPVOID addrMappedDll = MapViewOfFile(hMappedFile, accessMap, 0, 0, 0);
if( addrMappedDll == NULL )
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"createFileMappingView :: addrMappedDll == NULL");
#endif
CloseHandle(hMappedFile);
return NULL;
}
CloseHandle(hMappedFile);
return addrMappedDll;
}
DWORD ProcessAccessHelp::getProcessByName(const WCHAR * processName)
{
DWORD dwPID = 0;
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32W pe32;
pe32.dwSize = sizeof(PROCESSENTRY32W);
if( !Process32FirstW( hProcessSnap, &pe32 ) )
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"getProcessByName :: Error getting first Process");
#endif
CloseHandle( hProcessSnap );
return 0;
}
do
{
if(!_wcsicmp(pe32.szExeFile, processName))
{
dwPID = pe32.th32ProcessID;
break;
}
} while(Process32NextW(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
return dwPID;
}
bool ProcessAccessHelp::getProcessModules(DWORD dwPID, std::vector<ModuleInfo> &moduleList)
{
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
MODULEENTRY32 me32;
ModuleInfo module;
// Take a snapshot of all modules in the specified process.
hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwPID );
if( hModuleSnap == INVALID_HANDLE_VALUE )
{
return false;
}
// Set the size of the structure before using it.
me32.dwSize = sizeof( MODULEENTRY32 );
// Retrieve information about the first module,
// and exit if unsuccessful
if( !Module32First( hModuleSnap, &me32 ) )
{
CloseHandle( hModuleSnap );
return false;
}
// Now walk the module list of the process,
// and display information about each module
//the first is always the .exe
if (!Module32Next(hModuleSnap, &me32))
{
CloseHandle( hModuleSnap );
return false;
}
moduleList.reserve(20);
do
{
//printf(L"\n MODULE NAME: %s", me32.szModule);
module.modBaseAddr = (DWORD_PTR)me32.modBaseAddr;
module.modBaseSize = me32.modBaseSize;
module.isAlreadyParsed = false;
module.parsing = false;
wcscpy_s(module.fullPath, me32.szExePath);
moduleList.push_back(module);
} while(Module32Next(hModuleSnap, &me32));
CloseHandle( hModuleSnap );
return true;
}
bool ProcessAccessHelp::getMemoryRegionFromAddress(DWORD_PTR address, DWORD_PTR * memoryRegionBase, SIZE_T * memoryRegionSize)
{
MEMORY_BASIC_INFORMATION memBasic;
if (VirtualQueryEx(hProcess,(LPCVOID)address,&memBasic,sizeof(MEMORY_BASIC_INFORMATION)) != sizeof(MEMORY_BASIC_INFORMATION))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"getMemoryRegionFromAddress :: VirtualQueryEx error %u", GetLastError());
#endif
return false;
}
else
{
*memoryRegionBase = (DWORD_PTR)memBasic.BaseAddress;
*memoryRegionSize = memBasic.RegionSize;
return true;
}
}
bool ProcessAccessHelp::getSizeOfImageCurrentProcess()
{
DWORD_PTR newSizeOfImage = getSizeOfImageProcess(ProcessAccessHelp::hProcess, ProcessAccessHelp::targetImageBase);
if (newSizeOfImage != 0)
{
ProcessAccessHelp::targetSizeOfImage = newSizeOfImage;
return true;
}
else
{
return false;
}
}
SIZE_T ProcessAccessHelp::getSizeOfImageProcess(HANDLE processHandle, DWORD_PTR moduleBase)
{
SIZE_T sizeOfImage = 0;
MEMORY_BASIC_INFORMATION lpBuffer = {0};
SIZE_T dwLength = sizeof(MEMORY_BASIC_INFORMATION);
do
{
moduleBase = (DWORD_PTR)((SIZE_T)moduleBase + lpBuffer.RegionSize);
sizeOfImage += lpBuffer.RegionSize;
//printf("Query 0x"PRINTF_DWORD_PTR_FULL" size 0x%08X\n",moduleBase,sizeOfImage);
if (!VirtualQueryEx(processHandle, (LPCVOID)moduleBase, &lpBuffer, dwLength))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"getSizeOfImageProcess :: VirtualQuery failed %X", GetLastError());
#endif
lpBuffer.Type = 0;
sizeOfImage = 0;
}
/*else
{
printf("\nAllocationBase %X\n",lpBuffer.AllocationBase);
printf("AllocationProtect %X\n",lpBuffer.AllocationProtect);
printf("BaseAddress %X\n",lpBuffer.BaseAddress);
printf("Protect %X\n",lpBuffer.Protect);
printf("RegionSize %X\n",lpBuffer.RegionSize);
printf("State %X\n",lpBuffer.State);
printf("Type %X\n",lpBuffer.Type);
}*/
} while (lpBuffer.Type == MEM_IMAGE);
//printf("Real sizeOfImage %X\n",sizeOfImage);
return sizeOfImage;
}
DWORD ProcessAccessHelp::getEntryPointFromFile(const WCHAR * filePath)
{
PIMAGE_NT_HEADERS pNtHeader = 0;
PIMAGE_DOS_HEADER pDosHeader = 0;
readHeaderFromCurrentFile(filePath);
pDosHeader = (PIMAGE_DOS_HEADER)fileHeaderFromDisk;
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
{
return 0;
}
pNtHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)fileHeaderFromDisk + (DWORD_PTR)(pDosHeader->e_lfanew));
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE)
{
return 0;
}
return pNtHeader->OptionalHeader.AddressOfEntryPoint;
}
bool ProcessAccessHelp::createBackupFile(const WCHAR * filePath)
{
size_t fileNameLength = wcslen(filePath) + 5; //.bak + null
BOOL retValue = 0;
WCHAR * backupFile = new WCHAR[fileNameLength];
wcscpy_s(backupFile, fileNameLength, filePath);
wcscat_s(backupFile, fileNameLength, L".bak");
retValue = CopyFile(filePath, backupFile, FALSE);
if (!retValue)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"createBackupFile :: CopyFile failed with error 0x%X", GetLastError());
#endif
}
delete [] backupFile;
return retValue != 0;
}

File Metadata

Mime Type
text/x-diff
Expires
Sat, Jul 5, 11:54 AM (14 h, 15 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
fe/7d/b84ba99ad4c158baa424313759a1

Event Timeline