Page MenuHomedesp's stash

No OneTemporary

diff --git a/Scylla/DeviceNameResolver.cpp b/Scylla/DeviceNameResolver.cpp
new file mode 100644
index 0000000..c0d1787
--- /dev/null
+++ b/Scylla/DeviceNameResolver.cpp
@@ -0,0 +1,55 @@
+
+#include "DeviceNameResolver.h"
+
+DeviceNameResolver::DeviceNameResolver()
+{
+ initDeviceNameList();
+}
+
+DeviceNameResolver::~DeviceNameResolver()
+{
+ deviceNameList.clear();
+}
+
+void DeviceNameResolver::initDeviceNameList()
+{
+ TCHAR shortName[3] = {0};
+ TCHAR longName[MAX_PATH] = {0};
+ HardDisk hardDisk;
+
+ shortName[1] = L':';
+
+ deviceNameList.reserve(3);
+
+ for ( TCHAR shortD = TEXT('a'); shortD < TEXT('z'); shortD++ )
+ {
+ shortName[0] = shortD;
+ if (QueryDosDevice( shortName, longName, MAX_PATH ) > 0)
+ {
+ hardDisk.shortName[0] = _totupper(shortD);
+ hardDisk.shortName[1] = TEXT(':');
+ hardDisk.shortName[2] = 0;
+
+ hardDisk.longNameLength = _tcslen(longName);
+
+
+ _tcscpy_s(hardDisk.longName, longName);
+ deviceNameList.push_back(hardDisk);
+ }
+ }
+}
+
+bool DeviceNameResolver::resolveDeviceLongNameToShort( WCHAR * sourcePath, WCHAR * targetPath )
+{
+ for (unsigned int i = 0; i < deviceNameList.size(); i++)
+ {
+ if (!_tcsnicmp(deviceNameList[i].longName, sourcePath, deviceNameList[i].longNameLength))
+ {
+ _tcscpy_s(targetPath, MAX_PATH, deviceNameList[i].shortName);
+ _tcscat_s(targetPath, MAX_PATH, sourcePath + deviceNameList[i].longNameLength);
+ return true;
+ }
+ }
+
+ return false;
+}
\ No newline at end of file
diff --git a/Scylla/DeviceNameResolver.h b/Scylla/DeviceNameResolver.h
new file mode 100644
index 0000000..32ba924
--- /dev/null
+++ b/Scylla/DeviceNameResolver.h
@@ -0,0 +1,27 @@
+#include <Windows.h>
+
+
+#pragma once
+
+#include <Windows.h>
+#include <vector>
+#include <tchar.h>
+
+class HardDisk {
+public:
+ WCHAR shortName[3];
+ WCHAR longName[MAX_PATH];
+ size_t longNameLength;
+};
+
+class DeviceNameResolver
+{
+public:
+ DeviceNameResolver();
+ ~DeviceNameResolver();
+ bool resolveDeviceLongNameToShort( WCHAR * sourcePath, WCHAR * targetPath );
+private:
+ std::vector<HardDisk> deviceNameList;
+
+ void initDeviceNameList();
+};
\ No newline at end of file
diff --git a/Scylla/DumpMemoryGui.cpp b/Scylla/DumpMemoryGui.cpp
index a15443e..142db46 100644
--- a/Scylla/DumpMemoryGui.cpp
+++ b/Scylla/DumpMemoryGui.cpp
@@ -1,540 +1,604 @@
#include "DumpMemoryGui.h"
-#include "definitions.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", L"NONE"};
+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, TEXT(PRINTF_DWORD_PTR_FULL), iter->address);
+ 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);
- list.SetItemText(count, COL_TYPE, getMemoryTypeString(iter->type));
- list.SetItemText(count, COL_PROTECTION, getMemoryProtectionString(iter->protect));
+
+ 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 0:
- return MemoryTypeValues[TYPE_NONE];
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,_countof(protectionString), MemoryProtectionValues[PROT_GUARD]);
wcscat_s(protectionString,_countof(protectionString), L" | ");
value ^= PAGE_GUARD;
}
if (value & PAGE_NOCACHE)
{
wcscpy_s(protectionString,_countof(protectionString), MemoryProtectionValues[PROT_NOCACHE]);
wcscat_s(protectionString,_countof(protectionString), L" | ");
value ^= PAGE_NOCACHE;
}
if (value & PAGE_WRITECOMBINE)
{
wcscpy_s(protectionString,_countof(protectionString), MemoryProtectionValues[PROT_WRITECOMBINE]);
wcscat_s(protectionString,_countof(protectionString), L" | ");
value ^= PAGE_WRITECOMBINE;
}
switch(value)
{
- case 0:
- {
- wcscat_s(protectionString,_countof(protectionString), MemoryProtectionValues[PROT_NOACCESS]);
- break;
- }
case PAGE_EXECUTE:
{
wcscat_s(protectionString,_countof(protectionString), MemoryProtectionValues[PROT_EXECUTE]);
break;
}
case PAGE_EXECUTE_READ:
{
wcscat_s(protectionString,_countof(protectionString), MemoryProtectionValues[PROT_EXECUTE_READ]);
break;
}
case PAGE_EXECUTE_READWRITE:
{
wcscat_s(protectionString,_countof(protectionString), MemoryProtectionValues[PROT_EXECUTE_READWRITE]);
break;
}
case PAGE_EXECUTE_WRITECOPY:
{
wcscat_s(protectionString,_countof(protectionString), MemoryProtectionValues[PROT_EXECUTE_WRITECOPY]);
break;
}
case PAGE_NOACCESS:
{
wcscat_s(protectionString,_countof(protectionString), MemoryProtectionValues[PROT_NOACCESS]);
break;
}
case PAGE_READONLY:
{
wcscat_s(protectionString,_countof(protectionString), MemoryProtectionValues[PROT_READONLY]);
break;
}
case PAGE_READWRITE:
{
wcscat_s(protectionString,_countof(protectionString), MemoryProtectionValues[PROT_READWRITE]);
break;
}
case PAGE_WRITECOPY:
{
wcscat_s(protectionString,_countof(protectionString), MemoryProtectionValues[PROT_WRITECOPY]);
break;
}
default:
{
wcscat_s(protectionString,_countof(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"Read 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 = 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 + 1, 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 + 1, 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++)
{
memcpy(sectionNameA,pSec->Name,8);
swprintf_s(sectionNameW,_countof(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,_countof(dumpFilename),TEXT("MEM_")TEXT(PRINTF_DWORD_PTR_FULL)TEXT("_")TEXT("%08X"),address,dumpedMemorySize);
+ swprintf_s(dumpFilename,_countof(dumpFilename),TEXT("MEM_")TEXT(PRINTF_DWORD_PTR_FULL_S)TEXT("_")TEXT("%08X"),address,dumpedMemorySize);
dumpedMemory = new BYTE[dumpedMemorySize];
if (dumpedMemory)
{
- return ProcessAccessHelp::readMemoryFromProcess(address,dumpedMemorySize,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 5c24147..f841e16 100644
--- a/Scylla/DumpMemoryGui.h
+++ b/Scylla/DumpMemoryGui.h
@@ -1,159 +1,168 @@
#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;
};
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_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,
- TYPE_NONE
+ 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];
const WCHAR * getMemoryTypeString(DWORD value);
const WCHAR * getMemoryStateString(DWORD value);
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/MainGui.rc b/Scylla/MainGui.rc
index 91abd3c..3806cec 100644
Binary files a/Scylla/MainGui.rc and b/Scylla/MainGui.rc differ
diff --git a/Scylla/NativeWinApi.cpp b/Scylla/NativeWinApi.cpp
index b4e1779..c1da6ba 100644
--- a/Scylla/NativeWinApi.cpp
+++ b/Scylla/NativeWinApi.cpp
@@ -1,66 +1,68 @@
#include "NativeWinApi.h"
def_NtCreateThreadEx NativeWinApi::NtCreateThreadEx = 0;
def_NtDuplicateObject NativeWinApi::NtDuplicateObject = 0;
def_NtOpenProcess NativeWinApi::NtOpenProcess = 0;
def_NtOpenThread NativeWinApi::NtOpenThread = 0;
def_NtQueryObject NativeWinApi::NtQueryObject = 0;
def_NtQueryInformationFile NativeWinApi::NtQueryInformationFile = 0;
def_NtQueryInformationProcess NativeWinApi::NtQueryInformationProcess = 0;
def_NtQueryInformationThread NativeWinApi::NtQueryInformationThread = 0;
def_NtQuerySystemInformation NativeWinApi::NtQuerySystemInformation = 0;
+def_NtQueryVirtualMemory NativeWinApi::NtQueryVirtualMemory = 0;
def_NtResumeThread NativeWinApi::NtResumeThread = 0;
def_NtSetInformationThread NativeWinApi::NtSetInformationThread = 0;
def_NtTerminateProcess NativeWinApi::NtTerminateProcess = 0;
def_RtlNtStatusToDosError NativeWinApi::RtlNtStatusToDosError = 0;
void NativeWinApi::initialize()
{
HMODULE hModuleNtdll = GetModuleHandle(L"ntdll.dll");
if (!hModuleNtdll)
{
return;
}
NtCreateThreadEx = (def_NtCreateThreadEx)GetProcAddress(hModuleNtdll, "NtCreateThreadEx");
NtDuplicateObject = (def_NtDuplicateObject)GetProcAddress(hModuleNtdll, "NtDuplicateObject");
NtOpenProcess = (def_NtOpenProcess)GetProcAddress(hModuleNtdll, "NtOpenProcess");
NtOpenThread = (def_NtOpenThread)GetProcAddress(hModuleNtdll, "NtOpenThread");
NtQueryObject = (def_NtQueryObject)GetProcAddress(hModuleNtdll, "NtQueryObject");
NtQueryInformationFile = (def_NtQueryInformationFile)GetProcAddress(hModuleNtdll, "NtQueryInformationFile");
NtQueryInformationProcess = (def_NtQueryInformationProcess)GetProcAddress(hModuleNtdll, "NtQueryInformationProcess");
NtQueryInformationThread = (def_NtQueryInformationThread)GetProcAddress(hModuleNtdll, "NtQueryInformationThread");
NtQuerySystemInformation = (def_NtQuerySystemInformation)GetProcAddress(hModuleNtdll, "NtQuerySystemInformation");
+ NtQueryVirtualMemory = (def_NtQueryVirtualMemory)GetProcAddress(hModuleNtdll, "NtQueryVirtualMemory");
NtResumeThread = (def_NtResumeThread)GetProcAddress(hModuleNtdll, "NtResumeThread");
NtSetInformationThread = (def_NtSetInformationThread)GetProcAddress(hModuleNtdll, "NtSetInformationThread");
NtTerminateProcess = (def_NtTerminateProcess)GetProcAddress(hModuleNtdll, "NtTerminateProcess");
RtlNtStatusToDosError = (def_RtlNtStatusToDosError)GetProcAddress(hModuleNtdll, "RtlNtStatusToDosError");
}
PPEB NativeWinApi::getCurrentProcessEnvironmentBlock()
{
return getProcessEnvironmentBlockAddress(GetCurrentProcess());
}
PPEB NativeWinApi::getProcessEnvironmentBlockAddress(HANDLE processHandle)
{
ULONG lReturnLength = 0;
PROCESS_BASIC_INFORMATION processBasicInformation;
if ((NtQueryInformationProcess(processHandle,ProcessBasicInformation,&processBasicInformation,sizeof(PROCESS_BASIC_INFORMATION),&lReturnLength) >= 0) && (lReturnLength == sizeof(PROCESS_BASIC_INFORMATION)))
{
//printf("NtQueryInformationProcess success %d\n",sizeof(PROCESS_BASIC_INFORMATION));
return processBasicInformation.PebBaseAddress;
}
else
{
//printf("NtQueryInformationProcess failed %d vs %d\n",lReturnLength,sizeof(PROCESS_BASIC_INFORMATION));
return 0;
}
}
\ No newline at end of file
diff --git a/Scylla/NativeWinApi.h b/Scylla/NativeWinApi.h
index d356994..d53d4ec 100644
--- a/Scylla/NativeWinApi.h
+++ b/Scylla/NativeWinApi.h
@@ -1,261 +1,284 @@
#pragma once
#include <windows.h>
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#define DUPLICATE_SAME_ATTRIBUTES 0x00000004
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
typedef enum _SYSTEM_INFORMATION_CLASS {
SystemBasicInformation,
SystemProcessorInformation,
SystemPerformanceInformation,
SystemTimeOfDayInformation,
SystemPathInformation,
SystemProcessInformation,
SystemCallCountInformation,
SystemDeviceInformation,
SystemProcessorPerformanceInformation,
SystemFlagsInformation,
SystemCallTimeInformation,
SystemModuleInformation,
SystemLocksInformation,
SystemStackTraceInformation,
SystemPagedPoolInformation,
SystemNonPagedPoolInformation,
SystemHandleInformation,
SystemObjectInformation,
SystemPageFileInformation,
SystemVdmInstemulInformation,
SystemVdmBopInformation,
SystemFileCacheInformation,
SystemPoolTagInformation,
SystemInterruptInformation,
SystemDpcBehaviorInformation,
SystemFullMemoryInformation,
SystemLoadGdiDriverInformation,
SystemUnloadGdiDriverInformation,
SystemTimeAdjustmentInformation,
SystemSummaryMemoryInformation,
SystemNextEventIdInformation,
SystemEventIdsInformation,
SystemCrashDumpInformation,
SystemExceptionInformation,
SystemCrashDumpStateInformation,
SystemKernelDebuggerInformation,
SystemContextSwitchInformation,
SystemRegistryQuotaInformation,
SystemExtendServiceTableInformation,
SystemPrioritySeperation,
SystemPlugPlayBusInformation,
SystemDockInformation,
SystemPowerInformation2,
SystemProcessorSpeedInformation,
SystemCurrentTimeZoneInformation,
SystemLookasideInformation
} SYSTEM_INFORMATION_CLASS;
typedef struct _IO_STATUS_BLOCK {
union {
NTSTATUS Status;
PVOID Pointer;
};
ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
typedef struct _FILE_NAME_INFORMATION { // Information Classes 9 and 21
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_NAME_INFORMATION;
typedef enum _FILE_INFORMATION_CLASS {
FileNameInformation=9,
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct _CLIENT_ID{
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID, *PCLIENT_ID;
#define InitializeObjectAttributes(p,n,a,r,s) \
{ \
(p)->Length = sizeof(OBJECT_ATTRIBUTES); \
(p)->ObjectName = n; \
(p)->Attributes = a; \
(p)->RootDirectory = r; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}
typedef struct _OBJECT_ATTRIBUTES
{
ULONG Length;
PVOID RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
typedef enum _OBJECT_INFORMATION_CLASS {
ObjectBasicInformation,
ObjectNameInformation,
ObjectTypeInformation,
ObjectAllInformation,
ObjectDataInformation
} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;
typedef enum _THREADINFOCLASS {
ThreadBasicInformation,
ThreadTimes,
ThreadPriority,
ThreadBasePriority,
ThreadAffinityMask,
ThreadImpersonationToken,
ThreadDescriptorTableEntry,
ThreadEnableAlignmentFaultFixup,
ThreadEventPair_Reusable,
ThreadQuerySetWin32StartAddress,
ThreadZeroTlsCell,
ThreadPerformanceCount,
ThreadAmILastThread,
ThreadIdealProcessor,
ThreadPriorityBoost,
ThreadSetTlsArrayAddress,
ThreadIsIoPending,
ThreadHideFromDebugger,
ThreadBreakOnTermination,
MaxThreadInfoClass
} THREADINFOCLASS;
+//
+// Memory Information Classes for NtQueryVirtualMemory
+//
+typedef enum _MEMORY_INFORMATION_CLASS {
+ MemoryBasicInformation,
+ MemoryWorkingSetList,
+ MemorySectionName,
+ MemoryBasicVlmInformation
+} MEMORY_INFORMATION_CLASS;
+
typedef enum _PROCESSINFOCLASS {
ProcessBasicInformation,
ProcessQuotaLimits,
ProcessIoCounters,
ProcessVmCounters,
ProcessTimes,
ProcessBasePriority,
ProcessRaisePriority,
ProcessDebugPort,
ProcessExceptionPort,
ProcessAccessToken,
ProcessLdtInformation,
ProcessLdtSize,
ProcessDefaultHardErrorMode,
ProcessIoPortHandlers,
ProcessPooledUsageAndLimits,
ProcessWorkingSetWatch,
ProcessUserModeIOPL,
ProcessEnableAlignmentFaultFixup,
ProcessPriorityClass,
ProcessWx86Information,
ProcessHandleCount,
ProcessAffinityMask,
ProcessPriorityBoost,
ProcessDeviceMap,
ProcessSessionInformation,
ProcessForegroundInformation,
ProcessWow64Information,
ProcessImageFileName,
ProcessLUIDDeviceMapsEnabled,
ProcessBreakOnTermination,
ProcessDebugObjectHandle,
ProcessDebugFlags,
ProcessHandleTracing,
ProcessIoPriority,
ProcessExecuteFlags,
ProcessResourceManagement,
ProcessCookie,
ProcessImageInformation,
MaxProcessInfoClass
} PROCESSINFOCLASS;
typedef struct _PEB_LDR_DATA {
BYTE Reserved1[8];
PVOID Reserved2[3];
LIST_ENTRY InMemoryOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;
typedef struct _RTL_USER_PROCESS_PARAMETERS {
BYTE Reserved1[16];
PVOID Reserved2[10];
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
typedef struct _PEB {
BYTE Reserved1[2];
BYTE BeingDebugged;
BYTE Reserved2[1];
PVOID Reserved3[2];
PPEB_LDR_DATA Ldr;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
BYTE Reserved4[104];
PVOID Reserved5[52];
PVOID PostProcessInitRoutine;
BYTE Reserved6[128];
PVOID Reserved7[1];
ULONG SessionId;
} PEB, *PPEB;
typedef struct _PROCESS_BASIC_INFORMATION {
PVOID Reserved1;
PPEB PebBaseAddress;
PVOID Reserved2[2];
ULONG_PTR UniqueProcessId;
PVOID Reserved3;
} PROCESS_BASIC_INFORMATION;
+typedef struct _MEMORY_WORKING_SET_LIST
+{
+ ULONG NumberOfPages;
+ ULONG WorkingSetList[1];
+} MEMORY_WORKING_SET_LIST, *PMEMORY_WORKING_SET_LIST;
+
+typedef struct _MEMORY_SECTION_NAME
+{
+ UNICODE_STRING SectionFileName;
+} MEMORY_SECTION_NAME, *PMEMORY_SECTION_NAME;
+
+
typedef NTSTATUS (WINAPI *def_NtTerminateProcess)(HANDLE ProcessHandle, NTSTATUS ExitStatus);
typedef NTSTATUS (WINAPI *def_NtQueryObject)(HANDLE Handle,OBJECT_INFORMATION_CLASS ObjectInformationClass,PVOID ObjectInformation,ULONG ObjectInformationLength,PULONG ReturnLength);
typedef NTSTATUS (WINAPI *def_NtDuplicateObject)(HANDLE SourceProcessHandle, HANDLE SourceHandle, HANDLE TargetProcessHandle, PHANDLE TargetHandle, ACCESS_MASK DesiredAccess, BOOLEAN InheritHandle, ULONG Options );
typedef NTSTATUS (WINAPI *def_NtQueryInformationFile)(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass);
typedef NTSTATUS (WINAPI *def_NtQueryInformationThread)(HANDLE ThreadHandle,THREADINFOCLASS ThreadInformationClass,PVOID ThreadInformation,ULONG ThreadInformationLength,PULONG ReturnLength);
typedef NTSTATUS (WINAPI *def_NtQueryInformationProcess)(HANDLE ProcessHandle,PROCESSINFOCLASS ProcessInformationClass,PVOID ProcessInformation,ULONG ProcessInformationLength,PULONG ReturnLength);
typedef NTSTATUS (WINAPI *def_NtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS SystemInformationClass,PVOID SystemInformation,ULONG SystemInformationLength, PULONG ReturnLength);
+typedef NTSTATUS (WINAPI *def_NtQueryVirtualMemory)(HANDLE ProcessHandle, PVOID BaseAddress, MEMORY_INFORMATION_CLASS MemoryInformationClass, PVOID Buffer, ULONG Length, PULONG ResultLength);
typedef NTSTATUS (WINAPI *def_NtOpenProcess)(PHANDLE ProcessHandle, ACCESS_MASK AccessMask, PVOID ObjectAttributes, PCLIENT_ID ClientId );
typedef NTSTATUS (WINAPI *def_NtOpenThread)(PHANDLE ThreadHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId);
typedef NTSTATUS (WINAPI *def_NtResumeThread)(HANDLE ThreadHandle, PULONG SuspendCount);
typedef NTSTATUS (WINAPI *def_NtSetInformationThread)(HANDLE ThreadHandle,THREADINFOCLASS ThreadInformationClass,PVOID ThreadInformation,ULONG ThreadInformationLength);
typedef NTSTATUS (WINAPI *def_NtCreateThreadEx)(PHANDLE hThread,ACCESS_MASK DesiredAccess,LPVOID ObjectAttributes,HANDLE ProcessHandle,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,BOOL CreateSuspended,ULONG StackZeroBits,LPVOID SizeOfStackCommit,LPVOID SizeOfStackReserve,LPVOID lpBytesBuffer);
-
typedef ULONG (WINAPI *def_RtlNtStatusToDosError)(NTSTATUS Status);
class NativeWinApi {
public:
static def_NtCreateThreadEx NtCreateThreadEx;
static def_NtDuplicateObject NtDuplicateObject;
static def_NtOpenProcess NtOpenProcess;
static def_NtOpenThread NtOpenThread;
static def_NtQueryObject NtQueryObject;
static def_NtQueryInformationFile NtQueryInformationFile;
static def_NtQueryInformationProcess NtQueryInformationProcess;
static def_NtQueryInformationThread NtQueryInformationThread;
static def_NtQuerySystemInformation NtQuerySystemInformation;
+ static def_NtQueryVirtualMemory NtQueryVirtualMemory;
static def_NtResumeThread NtResumeThread;
static def_NtSetInformationThread NtSetInformationThread;
static def_NtTerminateProcess NtTerminateProcess;
static def_RtlNtStatusToDosError RtlNtStatusToDosError;
static void initialize();
static PPEB getCurrentProcessEnvironmentBlock();
static PPEB getProcessEnvironmentBlockAddress(HANDLE processHandle);
};
diff --git a/Scylla/PeDump.cpp b/Scylla/PeDump.cpp
index 27aab73..86d9fb7 100644
--- a/Scylla/PeDump.cpp
+++ b/Scylla/PeDump.cpp
@@ -1,437 +1,437 @@
#include "PeDump.h"
#include "ProcessAccessHelp.h"
#include "Scylla.h"
#include "Architecture.h"
bool PeDump::useHeaderFromDisk = true;
bool PeDump::appendOverlayData = true;
//#define DEBUG_COMMENTS
bool PeDump::fillPeHeaderStructs(bool fromDisk)
{
DWORD dwSize = ProcessAccessHelp::PE_HEADER_BYTES_COUNT;
if (dwSize > sizeOfImage)
{
dwSize = (DWORD)sizeOfImage;
}
headerData = new BYTE[dwSize];
if (!headerData)
return false;
if (fromDisk)
{
//from disk
if (!ProcessAccessHelp::readHeaderFromFile(headerData, dwSize, fullpath))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"fillPeHeaderStructs -> ProcessAccessHelp::readHeaderFromFile failed - %X %s", dwSize, fullpath);
#endif
return false;
}
}
else
{
//from memory
if (!ProcessAccessHelp::readMemoryFromProcess(imageBase, dwSize, headerData))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"fillPeHeaderStructs -> ProcessAccessHelp::readMemoryFromProcess failed - " PRINTF_DWORD_PTR_FULL L" %X " PRINTF_DWORD_PTR_FULL, imageBase, dwSize, headerData);
#endif
return false;
}
}
pDOSHeader = (PIMAGE_DOS_HEADER)headerData;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)headerData + (DWORD_PTR)pDOSHeader->e_lfanew);
pSectionHeader = IMAGE_FIRST_SECTION(pNTHeader);
return true;
}
bool PeDump::validateHeaders()
{
if ((pDOSHeader != 0) && (pDOSHeader->e_magic == IMAGE_DOS_SIGNATURE) && (pNTHeader->Signature == IMAGE_NT_SIGNATURE))
{
#ifdef _WIN64
if (pNTHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
#else
if (pNTHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
#endif
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
bool PeDump::dumpCompleteProcessToDisk(const WCHAR * dumpFilePath)
{
if (!fillPeHeaderStructs(useHeaderFromDisk))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"dumpCompleteProcessToDisk -> fillPeHeaderStructs failed");
#endif
return false;
}
if (!validateHeaders())
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"dumpCompleteProcessToDisk -> validateHeaders failed");
#endif
return false;
}
dumpData = new BYTE[sizeOfImage];
if (dumpData)
{
- if (!ProcessAccessHelp::readMemoryFromProcess(imageBase,sizeOfImage,dumpData))
+ if (!ProcessAccessHelp::readMemoryPartlyFromProcess(imageBase,sizeOfImage,dumpData))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"dumpCompleteProcessToDisk -> readMemoryFromProcess failed");
#endif
return false;
}
else
{
fixDump(dumpData);
if (saveDumpToDisk(dumpFilePath, dumpData, (DWORD)sizeOfImage))
{
if (appendOverlayData)
{
appendOverlayDataToDump(dumpFilePath);
}
//printf("dump success\n");
return true;
}
else
{
return false;
}
}
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"dumpCompleteProcessToDisk -> new BYTE[sizeOfImage] failed %X", sizeOfImage);
#endif
return false;
}
}
bool PeDump::appendOverlayDataToDump(const WCHAR *dumpFilePath)
{
DWORD_PTR offset = 0;
DWORD size = 0;
if (getOverlayData(fullpath,&offset,&size))
{
if (offset == 0)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"appendOverlayDataToDump :: No overlay exists");
#endif
return true;
}
else
{
if (copyFileDataFromOffset(fullpath, dumpFilePath, offset, size))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"appendOverlayDataToDump :: appending overlay success");
#endif
return true;
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"appendOverlayDataToDump :: appending overlay failed");
#endif
return false;
}
}
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"appendOverlayDataToDump :: getOverlayData failed");
#endif
return false;
}
}
bool PeDump::copyFileDataFromOffset(const WCHAR * sourceFile, const WCHAR * destFile, DWORD_PTR fileOffset, DWORD dwSize)
{
HANDLE hSourceFile, hDestFile;
BYTE * dataBuffer = 0;
bool retValue = false;
hSourceFile = CreateFile(sourceFile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if(hSourceFile == INVALID_HANDLE_VALUE)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"copyFileDataFromOffset :: failed to open source file");
#endif
return false;
}
hDestFile = CreateFile(destFile, GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
if(hSourceFile == INVALID_HANDLE_VALUE)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"copyFileDataFromOffset :: failed to open destination file");
#endif
CloseHandle(hSourceFile);
return false;
}
dataBuffer = new BYTE[dwSize];
if (ProcessAccessHelp::readMemoryFromFile(hSourceFile, (LONG)fileOffset, dwSize, dataBuffer))
{
if (ProcessAccessHelp::writeMemoryToFileEnd(hDestFile,dwSize,dataBuffer))
{
retValue = true;
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"copyFileDataFromOffset :: writeMemoryToFileEnd failed");
#endif
retValue = false;
}
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"copyFileDataFromOffset :: readMemoryFromFile failed to read from source file");
#endif
retValue = false;
}
delete [] dataBuffer;
CloseHandle(hSourceFile);
CloseHandle(hDestFile);
return retValue;
}
void PeDump::fixDump(BYTE * dumpBuffer)
{
int counter = 0;
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)dumpBuffer;
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)((DWORD_PTR)dumpBuffer + pDos->e_lfanew);
PIMAGE_SECTION_HEADER pSec = IMAGE_FIRST_SECTION(pNt);
fixNtHeaderForDump(pNt, pNTHeader);
do
{
fixSectionHeaderForDump(pSec, pSectionHeader);
pSectionHeader++;
pSec++;
counter++;
} while (counter < pNt->FileHeader.NumberOfSections);
}
void PeDump::fixBadNtHeaderValues(PIMAGE_NT_HEADERS pNtHead)
{
//maybe imagebase in process is not real imagebase
pNtHead->OptionalHeader.ImageBase = imageBase;
pNtHead->OptionalHeader.AddressOfEntryPoint = (DWORD)(entryPoint - imageBase);
pNtHead->OptionalHeader.SizeOfImage = sizeOfImage;
}
void PeDump::fixSectionHeaderForDump(PIMAGE_SECTION_HEADER oldSecHead, PIMAGE_SECTION_HEADER newSecHead)
{
memcpy_s(oldSecHead->Name, IMAGE_SIZEOF_SHORT_NAME, newSecHead->Name, IMAGE_SIZEOF_SHORT_NAME);
oldSecHead->Characteristics = newSecHead->Characteristics;
oldSecHead->Misc.VirtualSize = newSecHead->Misc.VirtualSize;
oldSecHead->VirtualAddress = newSecHead->VirtualAddress;
oldSecHead->SizeOfRawData = newSecHead->Misc.VirtualSize;
oldSecHead->PointerToRawData = newSecHead->VirtualAddress;
}
void PeDump::fixNtHeaderForDump(PIMAGE_NT_HEADERS oldNtHead, PIMAGE_NT_HEADERS newNtHead)
{
//some special
fixBadNtHeaderValues(newNtHead);
//fix FileHeader
oldNtHead->FileHeader.NumberOfSections = newNtHead->FileHeader.NumberOfSections;
//fix OptionalHeader
oldNtHead->OptionalHeader.ImageBase = newNtHead->OptionalHeader.ImageBase;
oldNtHead->OptionalHeader.SizeOfImage = newNtHead->OptionalHeader.SizeOfImage;
oldNtHead->OptionalHeader.BaseOfCode = newNtHead->OptionalHeader.BaseOfCode;
oldNtHead->OptionalHeader.AddressOfEntryPoint = newNtHead->OptionalHeader.AddressOfEntryPoint;
oldNtHead->OptionalHeader.SectionAlignment = newNtHead->OptionalHeader.SectionAlignment;
oldNtHead->OptionalHeader.FileAlignment = newNtHead->OptionalHeader.SectionAlignment;
//deleted in x64 PE
#ifndef _WIN64
oldNtHead->OptionalHeader.BaseOfData = newNtHead->OptionalHeader.BaseOfData;
#endif
}
bool PeDump::saveDumpToDisk(const WCHAR * dumpFilePath, BYTE *dumpBuffer, DWORD dumpSize)
{
DWORD lpNumberOfBytesWritten = 0;
bool retValue = false;
HANDLE hFile = CreateFile(dumpFilePath, GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if(hFile == INVALID_HANDLE_VALUE)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"saveDumpToDisk :: INVALID_HANDLE_VALUE %u", GetLastError());
#endif
retValue = false;
}
else
{
if (WriteFile(hFile, dumpBuffer, dumpSize, &lpNumberOfBytesWritten, 0))
{
if (lpNumberOfBytesWritten != dumpSize)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"saveDumpToDisk :: lpNumberOfBytesWritten != dumpSize %d %d", lpNumberOfBytesWritten,dumpSize);
#endif
retValue = false;
}
else
{
retValue = true;
}
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"saveDumpToDisk :: WriteFile failed %u",GetLastError());
#endif
retValue = false;
}
CloseHandle(hFile);
}
return retValue;
}
bool PeDump::getOverlayData(const WCHAR * filepath, DWORD_PTR * overlayFileOffset, DWORD * overlaySize)
{
LONGLONG fileSize = 0;
DWORD dwSize = 0;
DWORD bufferSize = 1000;
BYTE *buffer = 0;
bool returnValue = 0;
PIMAGE_DOS_HEADER pDOSh = 0;
PIMAGE_NT_HEADERS pNTh = 0;
PIMAGE_SECTION_HEADER pSech = 0;
int counter = 0;
DWORD calcSize = 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"getOverlayData :: INVALID_HANDLE_VALUE %u", GetLastError());
#endif
returnValue = false;
}
else
{
fileSize = ProcessAccessHelp::getFileSize(hFile);
if (fileSize > 0)
{
if (fileSize > bufferSize)
{
dwSize = bufferSize;
}
else
{
dwSize = (DWORD)(fileSize - 1);
}
buffer = new BYTE[dwSize];
if (ProcessAccessHelp::readMemoryFromFile(hFile, 0, dwSize, buffer))
{
pDOSh = (PIMAGE_DOS_HEADER)buffer;
pNTh = (PIMAGE_NT_HEADERS)((DWORD_PTR)buffer + pDOSh->e_lfanew);
//first section
pSech = IMAGE_FIRST_SECTION(pNTh);
counter = 1;
//get last section
while(counter < pNTh->FileHeader.NumberOfSections)
{
counter++;
pSech++;
}
//printf("PointerToRawData %X\nSizeOfRawData %X\nfile size %X\n",pSech->PointerToRawData,pSech->SizeOfRawData,pSech->PointerToRawData+pSech->SizeOfRawData);
calcSize = pSech->PointerToRawData + pSech->SizeOfRawData;
if (calcSize < fileSize)
{
//overlay found
*overlayFileOffset = calcSize;
*overlaySize = (DWORD)(fileSize - calcSize);
}
else
{
*overlayFileOffset = 0;
*overlaySize = 0;
}
returnValue = true;
}
else
{
returnValue = false;
}
delete [] buffer;
}
else
{
returnValue = false;
}
CloseHandle(hFile);
}
return returnValue;
}
\ No newline at end of file
diff --git a/Scylla/PickDllGui.cpp b/Scylla/PickDllGui.cpp
index 75616c3..81a41b2 100644
--- a/Scylla/PickDllGui.cpp
+++ b/Scylla/PickDllGui.cpp
@@ -1,144 +1,144 @@
#include "PickDllGui.h"
-#include "definitions.h"
+#include "Architecture.h"
PickDllGui::PickDllGui(std::vector<ModuleInfo> &moduleList) : moduleList(moduleList)
{
selectedModule = 0;
prevColumn = -1;
ascending = true;
}
BOOL PickDllGui::OnInitDialog(CWindow wndFocus, LPARAM lInitParam)
{
DoDataExchange(); // attach controls
DlgResize_Init(true, true);
addColumnsToModuleList(ListDLLSelect);
displayModuleList(ListDLLSelect);
CenterWindow();
return TRUE;
}
LRESULT PickDllGui::OnListDllColumnClicked(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
ListDLLSelect.SortItems(&listviewCompareFunc, MAKEWORD(column, ascending));
return 0;
}
LRESULT PickDllGui::OnListDllDoubleClick(NMHDR* pnmh)
{
NMITEMACTIVATE* ia = (NMITEMACTIVATE*)pnmh;
LVHITTESTINFO hti;
hti.pt = ia->ptAction;
int clicked = ListDLLSelect.HitTest(&hti);
if(clicked != -1)
{
selectedModule = (ModuleInfo *)ListDLLSelect.GetItemData(clicked);
EndDialog(1);
}
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());
- swprintf_s(temp, TEXT(PRINTF_DWORD_PTR_FULL), iter->modBaseAddr);
+ swprintf_s(temp, PRINTF_DWORD_PTR_FULL, iter->modBaseAddr);
list.SetItemText(count, COL_IMAGEBASE, temp);
swprintf_s(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/ProcessAccessHelp.cpp b/Scylla/ProcessAccessHelp.cpp
index 00ca738..7ba0070 100644
--- a/Scylla/ProcessAccessHelp.cpp
+++ b/Scylla/ProcessAccessHelp.cpp
@@ -1,729 +1,803 @@
#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)
+{
+ SIZE_T lpNumberOfBytesRead = 0;
+ 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 (!ReadProcessMemory(hProcess, (LPVOID)address, dataBuffer, size, &lpNumberOfBytesRead))
+ {
+ 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 (!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);
+ 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;
}
diff --git a/Scylla/ProcessAccessHelp.h b/Scylla/ProcessAccessHelp.h
index 5b49e29..c5fc3c0 100644
--- a/Scylla/ProcessAccessHelp.h
+++ b/Scylla/ProcessAccessHelp.h
@@ -1,212 +1,217 @@
#pragma once
#include <windows.h>
#include <tlhelp32.h>
#include <vector>
/************************************************************************/
/* distorm */
/************************************************************************/
#include <distorm.h>
// The number of the array of instructions the decoder function will use to return the disassembled instructions.
// Play with this value for performance...
#define MAX_INSTRUCTIONS (200)
/************************************************************************/
class ApiInfo;
class ModuleInfo
{
public:
WCHAR fullPath[MAX_PATH];
DWORD_PTR modBaseAddr;
DWORD modBaseSize;
bool isAlreadyParsed;
bool parsing;
/*
for iat rebuilding with duplicate entries:
ntdll = low priority
kernelbase = low priority
SHLWAPI = low priority
kernel32 = high priority
priority = 1 -> normal/high priority
priority = 0 -> low priority
*/
int priority;
std::vector<ApiInfo *> apiList;
ModuleInfo()
{
modBaseAddr = 0;
modBaseSize = 0;
priority = 1;
isAlreadyParsed = false;
parsing = false;
}
const WCHAR * getFilename() const
{
const WCHAR* slash = wcsrchr(fullPath, L'\\');
if(slash)
{
return slash+1;
}
return fullPath;
}
};
class ApiInfo
{
public:
char name[MAX_PATH];
WORD hint;
DWORD_PTR va;
DWORD_PTR rva;
WORD ordinal;
bool isForwarded;
ModuleInfo * module;
};
class ProcessAccessHelp
{
public:
static HANDLE hProcess; //OpenProcess handle to target process
static DWORD_PTR targetImageBase;
static DWORD_PTR targetSizeOfImage;
static DWORD_PTR maxValidAddress;
static ModuleInfo * selectedModule;
static std::vector<ModuleInfo> moduleList; //target process module list
static std::vector<ModuleInfo> ownModuleList; //own module list
static const size_t PE_HEADER_BYTES_COUNT = 2000;
static BYTE fileHeaderFromDisk[PE_HEADER_BYTES_COUNT];
//for decomposer
static _DInst decomposerResult[MAX_INSTRUCTIONS];
static unsigned int decomposerInstructionsCount;
static _CodeInfo decomposerCi;
//distorm :: Decoded instruction information.
static _DecodedInst decodedInstructions[MAX_INSTRUCTIONS];
static unsigned int decodedInstructionsCount;
#ifdef _WIN64
static const _DecodeType dt = Decode64Bits;
#else
static const _DecodeType dt = Decode32Bits;
#endif
/*
* Open a new process handle
*/
static bool openProcessHandle(DWORD dwPID);
static HANDLE NativeOpenProcess(DWORD dwDesiredAccess, DWORD dwProcessId);
static void closeProcessHandle();
/*
* Get all modules from a process
*/
static bool getProcessModules(DWORD dwPID, std::vector<ModuleInfo> &moduleList);
/*
* file mapping view with different access level
*/
static LPVOID createFileMappingViewRead(const WCHAR * filePath);
static LPVOID createFileMappingViewFull(const WCHAR * filePath);
/*
* Create a file mapping view of a file
*/
static LPVOID createFileMappingView(const WCHAR * filePath, DWORD accessFile, DWORD flProtect, DWORD accessMap);
/*
* Read memory from target process
*/
static bool readMemoryFromProcess(DWORD_PTR address, SIZE_T size, LPVOID dataBuffer);
+ /*
+ * Read memory from target process and ignore no data pages
+ */
+ static bool readMemoryPartlyFromProcess(DWORD_PTR address, SIZE_T size, LPVOID dataBuffer);
+
/*
* Read memory from file
*/
static bool readMemoryFromFile(HANDLE hFile, LONG offset, DWORD size, LPVOID dataBuffer);
/*
* Write memory to file
*/
static bool writeMemoryToFile(HANDLE hFile, LONG offset, DWORD size, LPCVOID dataBuffer);
/*
* Write memory to new file
*/
static bool writeMemoryToNewFile(const WCHAR * file,DWORD size, LPCVOID dataBuffer);
/*
* Write memory to file end
*/
static bool writeMemoryToFileEnd(HANDLE hFile, DWORD size, LPCVOID dataBuffer);
/*
* Disassemble Memory
*/
static bool disassembleMemory(BYTE * dataBuffer, SIZE_T bufferSize, DWORD_PTR startOffset);
static bool decomposeMemory(BYTE * dataBuffer, SIZE_T bufferSize, DWORD_PTR startAddress);
/*
* Search for pattern
*/
static DWORD_PTR findPattern(DWORD_PTR startOffset, DWORD size, BYTE * pattern, const char * mask);
/*
* Get process ID by process name
*/
static DWORD getProcessByName(const WCHAR * processName);
/*
* Get memory region from address
*/
static bool getMemoryRegionFromAddress(DWORD_PTR address, DWORD_PTR * memoryRegionBase, SIZE_T * memoryRegionSize);
/*
* Read PE Header from file
*/
static bool readHeaderFromFile(BYTE * buffer, DWORD bufferSize, const WCHAR * filePath);
static bool readHeaderFromCurrentFile(const WCHAR * filePath);
/*
* Get real sizeOfImage value
*/
static SIZE_T getSizeOfImageProcess(HANDLE processHandle, DWORD_PTR moduleBase);
/*
* Get real sizeOfImage value current process
*/
static bool getSizeOfImageCurrentProcess();
static LONGLONG getFileSize(HANDLE hFile);
static LONGLONG getFileSize(const WCHAR * filePath);
static DWORD getEntryPointFromFile(const WCHAR * filePath);
static bool createBackupFile(const WCHAR * filePath);
};
diff --git a/Scylla/ProcessLister.cpp b/Scylla/ProcessLister.cpp
index c793ae1..1bb5c13 100644
--- a/Scylla/ProcessLister.cpp
+++ b/Scylla/ProcessLister.cpp
@@ -1,372 +1,331 @@
#include "ProcessLister.h"
#include "SystemInformation.h"
#include "Logger.h"
#include "ProcessAccessHelp.h"
#include <algorithm>
//#define DEBUG_COMMENTS
def_IsWow64Process ProcessLister::_IsWow64Process = 0;
std::vector<Process>& ProcessLister::getProcessList()
{
return processList;
}
bool ProcessLister::isWindows64()
{
#ifdef _WIN64
//compiled 64bit application
return true;
#else
//32bit exe, check wow64
BOOL bIsWow64 = FALSE;
//not available in all windows operating systems
//Minimum supported client: Windows Vista, Windows XP with SP2
//Minimum supported server: Windows Server 2008, Windows Server 2003 with SP1
if (_IsWow64Process)
{
_IsWow64Process(GetCurrentProcess(), &bIsWow64);
if (bIsWow64 == TRUE)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
#endif
}
-
-void ProcessLister::initDeviceNameList()
-{
- TCHAR shortName[3] = {0};
- TCHAR longName[MAX_PATH] = {0};
- HardDisk hardDisk;
-
- shortName[1] = L':';
-
- for ( WCHAR shortD = L'a'; shortD < L'z'; shortD++ )
- {
- shortName[0] = shortD;
- if (QueryDosDeviceW( shortName, longName, MAX_PATH ) > 0)
- {
- hardDisk.shortName[0] = towupper(shortD);
- hardDisk.shortName[1] = L':';
- hardDisk.shortName[2] = 0;
-
- hardDisk.longNameLength = wcslen(longName);
-
- wcscpy_s(hardDisk.longName, longName);
- deviceNameList.push_back(hardDisk);
- }
- }
-}
-
//only needed in windows xp
DWORD ProcessLister::setDebugPrivileges()
{
DWORD err = 0;
HANDLE hToken = 0;
TOKEN_PRIVILEGES Debug_Privileges = {0};
if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Debug_Privileges.Privileges[0].Luid))
{
return GetLastError();
}
if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
{
err = GetLastError();
if(hToken) CloseHandle(hToken);
return err;
}
Debug_Privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
Debug_Privileges.PrivilegeCount = 1;
AdjustTokenPrivileges(hToken, false, &Debug_Privileges, 0, NULL, NULL);
CloseHandle(hToken);
return GetLastError();
}
/************************************************************************/
/* Check if a process is 32 or 64bit */
/************************************************************************/
ProcessType ProcessLister::checkIsProcess64(DWORD dwPID)
{
HANDLE hProcess;
BOOL bIsWow64 = FALSE;
if (dwPID == 0)
{
//unknown
return PROCESS_UNKNOWN;
}
//hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, NULL, dwPID);
hProcess = ProcessAccessHelp::NativeOpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, dwPID);
if(!hProcess)
{
//missing rights
return PROCESS_MISSING_RIGHTS;
}
if (!isWindows64())
{
//32bit win can only run 32bit process
CloseHandle(hProcess);
return PROCESS_32;
}
_IsWow64Process(hProcess, &bIsWow64);
CloseHandle(hProcess);
if (bIsWow64 == FALSE)
{
//process not running under wow
return PROCESS_64;
}
else
{
//process running under wow -> 32bit
return PROCESS_32;
}
}
bool ProcessLister::getAbsoluteFilePath(Process * process)
{
WCHAR processPath[MAX_PATH];
HANDLE hProcess;
//hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, NULL, process->PID);
hProcess = ProcessAccessHelp::NativeOpenProcess(PROCESS_QUERY_INFORMATION, process->PID);
if(!hProcess)
{
//missing rights
return false;
}
if (GetProcessImageFileName(hProcess, processPath, _countof(processPath)) > 0)
{
CloseHandle(hProcess);
- if (!resolveDeviceLongNameToShort(processPath, process->fullPath))
+ if (!deviceNameResolver->resolveDeviceLongNameToShort(processPath, process->fullPath))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"getAbsoluteFilePath :: resolveDeviceLongNameToShort failed with path %s", processPath);
#endif
}
return true;
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"getAbsoluteFilePath :: GetProcessImageFileName failed %u", GetLastError());
#endif
CloseHandle(hProcess);
return false;
}
}
std::vector<Process>& ProcessLister::getProcessListSnapshot()
{
HANDLE hProcessSnap;
ProcessType processType;
PROCESSENTRY32 pe32;
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
MODULEENTRY32 me32 = {0};
Process process;
if (!processList.empty())
{
//clear elements, but keep reversed memory
processList.clear();
}
else
{
//first time, reserve memory
processList.reserve(34);
}
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hProcessSnap == INVALID_HANDLE_VALUE)
{
return processList;
}
pe32.dwSize = sizeof(PROCESSENTRY32);
if(!Process32First(hProcessSnap, &pe32))
{
CloseHandle(hProcessSnap);
return processList;
}
do
{
//filter process list
if (pe32.th32ProcessID > 4)
{
processType = checkIsProcess64(pe32.th32ProcessID);
if (processType != PROCESS_MISSING_RIGHTS)
{
#ifdef _WIN64
if (processType == PROCESS_64)
#else
if (processType == PROCESS_32)
#endif
{
process.PID = pe32.th32ProcessID;
hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, process.PID);
if(hModuleSnap != INVALID_HANDLE_VALUE)
{
me32.dwSize = sizeof(MODULEENTRY32);
Module32First(hModuleSnap, &me32);
process.imageBase = (DWORD_PTR)me32.hModule;
process.imageSize = me32.modBaseSize;
CloseHandle(hModuleSnap);
}
wcscpy_s(process.filename, pe32.szExeFile);
getAbsoluteFilePath(&process);
processList.push_back(process);
}
}
}
} while(Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
//reverse process list
std::reverse(processList.begin(), processList.end());
return processList;
}
void ProcessLister::getAllModuleInformation()
{
/*for (std::size_t i = 0; i < processList.size(); i++)
{
getModuleInformationByProcess(&processList[i]);
}*/
}
void ProcessLister::getModuleInformationByProcess(Process *process)
{
/* MODULEENTRY32 me32 = {0};
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
char temp[111];
if (process->PID == 0)
{
MessageBox(0, "PID == NULL","ProcessLister::getModuleInformationByProcess", MB_OK|MB_ICONWARNING);
return;
}
#ifdef _WIN64
if (!process->is64BitProcess)
{
//MessageBox(hWndDlg, "I'm a x64 process and you're trying to access a 32-bit process!","displayModuleList", MB_OK);
return;
}
#else
if (process->is64BitProcess)
{
//MessageBox(hWndDlg, "I'm a 32-bit process and you're trying to access a x64 process!","displayModuleList", MB_OK);
return;
}
#endif
hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, process->PID);
if(hModuleSnap == INVALID_HANDLE_VALUE)
{
sprintf_s(temp, "GetLastError %d",GetLastError());
MessageBox(0, temp,"ProcessLister::getModuleInformationByProcess", MB_OK|MB_ICONWARNING);
return;
}
me32.dwSize = sizeof(MODULEENTRY32);
if(!Module32First(hModuleSnap, &me32))
{
MessageBox(0, "Module32First error","ProcessLister::getModuleInformationByProcess", MB_OK|MB_ICONWARNING);
CloseHandle(hModuleSnap);
return;
}
do {
ModuleInfo moduleInfo;
if (!_strnicmp(me32.szExePath,"\\Systemroot",11))
{
char * path = (char *)malloc(MAX_PATH);
sprintf_s(path"%s\\%s",getenv("SystemRoot"),(me32.szExePath + 12));
strcpy_s(moduleInfo.fullPath,MAX_PATH, path);
free(path);
}
else if(!_strnicmp(me32.szExePath,"\\??\\",4))
{
strcpy_s(moduleInfo.fullPath,MAX_PATH, (me32.szExePath + 4));
}
else
{
strcpy_s(moduleInfo.fullPath,MAX_PATH,me32.szExePath);
}
moduleInfo.hModule = (DWORD_PTR)me32.hModule;
moduleInfo.modBaseSize = me32.modBaseSize;
moduleInfo.modBaseAddr = (DWORD_PTR)me32.modBaseAddr;
process->moduleList[moduleInfo.hModule] = moduleInfo;
} while(Module32Next(hModuleSnap, &me32));
CloseHandle(hModuleSnap);*/
}
-
-bool ProcessLister::resolveDeviceLongNameToShort( WCHAR * sourcePath, WCHAR * targetPath )
-{
- for (unsigned int i = 0; i < deviceNameList.size(); i++)
- {
- if (!_wcsnicmp(deviceNameList[i].longName, sourcePath, deviceNameList[i].longNameLength))
- {
- wcscpy_s(targetPath, MAX_PATH,deviceNameList[i].shortName);
- wcscat_s(targetPath, MAX_PATH, sourcePath + deviceNameList[i].longNameLength);
- return true;
- }
- }
-
- return false;
-}
diff --git a/Scylla/ProcessLister.h b/Scylla/ProcessLister.h
index a93630e..1664084 100644
--- a/Scylla/ProcessLister.h
+++ b/Scylla/ProcessLister.h
@@ -1,70 +1,65 @@
#pragma once
#include <windows.h>
#include <tlhelp32.h>
#include <vector>
#include <psapi.h>
+#include "DeviceNameResolver.h"
+
typedef BOOL (WINAPI *def_IsWow64Process)(HANDLE hProcess,PBOOL Wow64Process);
class Process {
public:
DWORD PID;
DWORD_PTR imageBase;
DWORD entryPoint; //without imagebase
DWORD imageSize;
WCHAR filename[MAX_PATH];
WCHAR fullPath[MAX_PATH];
Process()
{
PID = 0;
}
};
-class HardDisk {
-public:
- WCHAR shortName[3];
- WCHAR longName[MAX_PATH];
- size_t longNameLength;
-};
-
enum ProcessType {
PROCESS_UNKNOWN,
PROCESS_MISSING_RIGHTS,
PROCESS_32,
PROCESS_64
};
class ProcessLister {
public:
static def_IsWow64Process _IsWow64Process;
ProcessLister()
{
- initDeviceNameList();
+ deviceNameResolver = new DeviceNameResolver();
_IsWow64Process = (def_IsWow64Process)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "IsWow64Process");
}
+ ~ProcessLister()
+ {
+ delete deviceNameResolver;
+ }
std::vector<Process>& getProcessList();
static bool isWindows64();
static DWORD setDebugPrivileges();
std::vector<Process>& ProcessLister::getProcessListSnapshot();
private:
std::vector<Process> processList;
- std::vector<HardDisk> deviceNameList;
+ DeviceNameResolver * deviceNameResolver;
ProcessType checkIsProcess64(DWORD dwPID);
- void initDeviceNameList();
-
-
bool getAbsoluteFilePath(Process * process);
void getAllModuleInformation();
void getModuleInformationByProcess(Process *process);
- bool resolveDeviceLongNameToShort( WCHAR * sourcePath, WCHAR * targetPath );
};
\ No newline at end of file
diff --git a/Scylla/Scylla.h b/Scylla/Scylla.h
index bf02bc6..aff4d13 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 Beta"
+#define APPVERSION_S "v0.6 Beta 2"
#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[];
};
diff --git a/Scylla/Scylla.vcxproj b/Scylla/Scylla.vcxproj
index 8b449d0..7238499 100644
--- a/Scylla/Scylla.vcxproj
+++ b/Scylla/Scylla.vcxproj
@@ -1,236 +1,248 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{710434C9-FC4B-4F1D-B318-E10ADC78499F}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>Scylla</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v90</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v100</PlatformToolset>
+ <PlatformToolset>v90</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
+ <IncludePath>$(SolutionDir)WTL81_9127_Include;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
+ <IncludePath>$(SolutionDir)WTL81_9127_Include;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
+ <IncludePath>$(SolutionDir)WTL81_9127_Include;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
+ <IncludePath>$(SolutionDir)WTL81_9127_Include;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>$(SolutionDir)diStorm\include;$(SolutionDir)tinyxml;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(SolutionDir)tinyxml;$(SolutionDir)diStorm\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
- <AdditionalDependencies>$(SolutionDir)$(Platform)\$(Configuration)\diStorm.lib;$(SolutionDir)$(Platform)\$(Configuration)\tinyxml.lib;psapi.lib;imagehlp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>$(SolutionDir)$(Platform)\$(Configuration)\diStorm.lib;$(SolutionDir)$(Platform)\$(Configuration)\tinyxml.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalManifestDependencies>type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' </AdditionalManifestDependencies>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(TargetDir)$(TargetName).map</MapFileName>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>$(SolutionDir)diStorm\include;$(SolutionDir)tinyxml;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(SolutionDir)tinyxml;$(SolutionDir)diStorm\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
- <AdditionalDependencies>$(SolutionDir)$(Platform)\$(Configuration)\diStorm.lib;$(SolutionDir)$(Platform)\$(Configuration)\tinyxml.lib;psapi.lib;imagehlp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>$(SolutionDir)$(Platform)\$(Configuration)\diStorm.lib;$(SolutionDir)$(Platform)\$(Configuration)\tinyxml.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalManifestDependencies>type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' </AdditionalManifestDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
- <AdditionalIncludeDirectories>$(SolutionDir)diStorm\include;$(SolutionDir)tinyxml;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(SolutionDir)tinyxml;$(SolutionDir)diStorm\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MinimalRebuild>true</MinimalRebuild>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
- <AdditionalDependencies>$(SolutionDir)$(Platform)\$(Configuration)\diStorm.lib;$(SolutionDir)$(Platform)\$(Configuration)\tinyxml.lib;psapi.lib;imagehlp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>$(SolutionDir)$(Platform)\$(Configuration)\diStorm.lib;$(SolutionDir)$(Platform)\$(Configuration)\tinyxml.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalManifestDependencies>type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' </AdditionalManifestDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
- <AdditionalIncludeDirectories>$(SolutionDir)diStorm\include;$(SolutionDir)tinyxml;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(SolutionDir)tinyxml;$(SolutionDir)diStorm\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MinimalRebuild>true</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
- <AdditionalDependencies>$(SolutionDir)$(Platform)\$(Configuration)\diStorm.lib;$(SolutionDir)$(Platform)\$(Configuration)\tinyxml.lib;psapi.lib;imagehlp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>$(SolutionDir)$(Platform)\$(Configuration)\diStorm.lib;$(SolutionDir)$(Platform)\$(Configuration)\tinyxml.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalManifestDependencies>type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' </AdditionalManifestDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="AboutGui.cpp" />
<ClCompile Include="ApiReader.cpp" />
<ClCompile Include="Architecture.cpp" />
<ClCompile Include="Configuration.cpp" />
<ClCompile Include="ConfigurationHolder.cpp" />
+ <ClCompile Include="DeviceNameResolver.cpp" />
<ClCompile Include="DisassemblerGui.cpp" />
<ClCompile Include="DllInjection.cpp" />
<ClCompile Include="DllInjectionPlugin.cpp" />
+ <ClCompile Include="DumpMemoryGui.cpp" />
<ClCompile Include="IATSearch.cpp" />
<ClCompile Include="ImportRebuild.cpp" />
<ClCompile Include="ImportsHandling.cpp" />
<ClCompile Include="Logger.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="MainGui.cpp" />
<ClCompile Include="NativeWinApi.cpp" />
<ClCompile Include="OptionsGui.cpp" />
<ClCompile Include="PeDump.cpp" />
<ClCompile Include="PeRebuild.cpp" />
<ClCompile Include="PickApiGui.cpp" />
<ClCompile Include="PickDllGui.cpp" />
<ClCompile Include="PluginLoader.cpp" />
<ClCompile Include="ProcessAccessHelp.cpp" />
<ClCompile Include="ProcessLister.cpp" />
<ClCompile Include="Scylla.cpp" />
<ClCompile Include="StringConversion.cpp" />
<ClCompile Include="SystemInformation.cpp" />
<ClCompile Include="TreeImportExport.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="AboutGui.h" />
<ClInclude Include="ApiReader.h" />
<ClInclude Include="Architecture.h" />
<ClInclude Include="Configuration.h" />
<ClInclude Include="ConfigurationHolder.h" />
+ <ClInclude Include="DeviceNameResolver.h" />
<ClInclude Include="DisassemblerGui.h" />
<ClInclude Include="DllInjection.h" />
<ClInclude Include="DllInjectionPlugin.h" />
+ <ClInclude Include="DumpMemoryGui.h" />
<ClInclude Include="hexedit.h" />
<ClInclude Include="IATSearch.h" />
<ClInclude Include="ImportRebuild.h" />
<ClInclude Include="ImportsHandling.h" />
<ClInclude Include="Logger.h" />
<ClInclude Include="MainGui.h" />
<ClInclude Include="multitree.h" />
<ClInclude Include="NativeWinApi.h" />
<ClInclude Include="OptionsGui.h" />
<ClInclude Include="PeDump.h" />
<ClInclude Include="PeRebuild.h" />
<ClInclude Include="PickApiGui.h" />
<ClInclude Include="PickDllGui.h" />
<ClInclude Include="PluginLoader.h" />
<ClInclude Include="ProcessAccessHelp.h" />
<ClInclude Include="ProcessLister.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="Scylla.h" />
<ClInclude Include="StringConversion.h" />
<ClInclude Include="SystemInformation.h" />
<ClInclude Include="Thunks.h" />
<ClInclude Include="TreeImportExport.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="MainGui.rc" />
</ItemGroup>
<ItemGroup>
<None Include="check.ico" />
<None Include="error.ico" />
<None Include="scylla.ico" />
<None Include="warning.ico" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<ProjectExtensions>
<VisualStudio>
<UserProperties RESOURCE_FILE="MainGui.rc" />
</VisualStudio>
</ProjectExtensions>
</Project>
\ No newline at end of file
diff --git a/Scylla/resource.h b/Scylla/resource.h
index 2420cac..aeddc30 100644
Binary files a/Scylla/resource.h and b/Scylla/resource.h differ

File Metadata

Mime Type
text/x-diff
Expires
Mon, Apr 14, 10:41 AM (5 h, 43 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
24/ee/236584efce5fdc953025c68e08d5

Event Timeline