Page MenuHomedesp's stash

No OneTemporary

diff --git a/Scylla/DumpMemoryGui.cpp b/Scylla/DumpMemoryGui.cpp
index 8e492cd..11c9cf3 100644
--- a/Scylla/DumpMemoryGui.cpp
+++ b/Scylla/DumpMemoryGui.cpp
@@ -1,605 +1,571 @@
#include "DumpMemoryGui.h"
#include "Architecture.h"
#include "ProcessAccessHelp.h"
#include <Psapi.h>
+#include "PeParser.h"
WCHAR DumpMemoryGui::protectionString[100];
const WCHAR DumpMemoryGui::MemoryUndefined[] = L"UNDEF";
const WCHAR DumpMemoryGui::MemoryUnknown[] = L"UNKNOWN";
const WCHAR * DumpMemoryGui::MemoryStateValues[] = {L"COMMIT",L"FREE",L"RESERVE"};
const WCHAR * DumpMemoryGui::MemoryTypeValues[] = {L"IMAGE",L"MAPPED",L"PRIVATE"};
const WCHAR * DumpMemoryGui::MemoryProtectionValues[] = {L"EXECUTE",L"EXECUTE_READ",L"EXECUTE_READWRITE",L"EXECUTE_WRITECOPY",L"NOACCESS",L"READONLY",L"READWRITE",L"WRITECOPY",L"GUARD",L"NOCACHE",L"WRITECOMBINE"};
DumpMemoryGui::DumpMemoryGui()
{
dumpedMemory = 0;
dumpedMemorySize = 0;
deviceNameResolver = new DeviceNameResolver();
}
DumpMemoryGui::~DumpMemoryGui()
{
if (dumpedMemory)
{
delete [] dumpedMemory;
}
if (deviceNameResolver)
{
delete deviceNameResolver;
}
}
BOOL DumpMemoryGui::OnInitDialog(CWindow wndFocus, LPARAM lInitParam)
{
DoDataExchange(); // attach controls
DlgResize_Init(true, true);
addColumnsToMemoryList(ListMemorySelect);
displayMemoryList(ListMemorySelect);
forceDump = false;
DoDataExchange(DDX_LOAD);
EditMemoryAddress.SetValue(ProcessAccessHelp::targetImageBase);
EditMemorySize.SetValue((DWORD)ProcessAccessHelp::targetSizeOfImage);
CenterWindow();
return TRUE;
}
void DumpMemoryGui::addColumnsToMemoryList(CListViewCtrl& list)
{
list.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
list.InsertColumn(COL_ADDRESS, L"Address", LVCFMT_CENTER);
list.InsertColumn(COL_SIZE, L"Size", LVCFMT_CENTER);
list.InsertColumn(COL_FILENAME, L"File", LVCFMT_LEFT);
list.InsertColumn(COL_PESECTION, L"PE Section", LVCFMT_LEFT);
list.InsertColumn(COL_TYPE, L"Type", LVCFMT_CENTER);
list.InsertColumn(COL_PROTECTION, L"Protection", LVCFMT_CENTER);
list.InsertColumn(COL_STATE, L"State", LVCFMT_CENTER);
list.InsertColumn(COL_MAPPED_FILE, L"Mapped File", LVCFMT_LEFT);
}
void DumpMemoryGui::displayMemoryList(CListViewCtrl& list)
{
int count = 0;
WCHAR temp[20];
list.DeleteAllItems();
getMemoryList();
std::vector<Memory>::const_iterator iter;
for( iter = memoryList.begin(); iter != memoryList.end(); iter++ , count++)
{
swprintf_s(temp, PRINTF_DWORD_PTR_FULL, iter->address);
list.InsertItem(count,temp);
swprintf_s(temp, L"%08X", iter->size);
list.SetItemText(count, COL_SIZE, temp);
list.SetItemText(count, COL_FILENAME, iter->filename);
list.SetItemText(count, COL_PESECTION, iter->peSection);
if (iter->state == MEM_FREE)
{
list.SetItemText(count, COL_TYPE, MemoryUndefined);
}
else
{
list.SetItemText(count, COL_TYPE, getMemoryTypeString(iter->type));
}
if ( (iter->state == MEM_RESERVE) || (iter->state == MEM_FREE) )
{
list.SetItemText(count, COL_PROTECTION, MemoryUndefined);
}
else
{
list.SetItemText(count, COL_PROTECTION, getMemoryProtectionString(iter->protect));
}
list.SetItemText(count, COL_STATE, getMemoryStateString(iter->state));
list.SetItemText(count, COL_MAPPED_FILE, iter->mappedFilename);
list.SetItemData(count, (DWORD_PTR)&(*iter));
}
list.SetColumnWidth(COL_ADDRESS, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_SIZE, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_FILENAME, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_PESECTION, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_TYPE, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_PROTECTION, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_STATE, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_MAPPED_FILE, LVSCW_AUTOSIZE_USEHEADER);
}
const WCHAR * DumpMemoryGui::getMemoryTypeString(DWORD value)
{
switch(value)
{
case MEM_IMAGE:
return MemoryTypeValues[TYPE_IMAGE];
case MEM_MAPPED:
return MemoryTypeValues[TYPE_MAPPED];
case MEM_PRIVATE:
return MemoryTypeValues[TYPE_PRIVATE];
default:
return MemoryUnknown;
}
}
const WCHAR * DumpMemoryGui::getMemoryStateString(DWORD value)
{
switch(value)
{
case MEM_COMMIT:
return MemoryStateValues[STATE_COMMIT];
case MEM_FREE:
return MemoryStateValues[STATE_FREE];
case MEM_RESERVE:
return MemoryStateValues[STATE_RESERVE];
default:
return MemoryUnknown;
}
}
WCHAR * DumpMemoryGui::getMemoryProtectionString(DWORD value)
{
protectionString[0] = 0;
if (value & PAGE_GUARD)
{
wcscpy_s(protectionString, MemoryProtectionValues[PROT_GUARD]);
wcscat_s(protectionString, L" | ");
value ^= PAGE_GUARD;
}
if (value & PAGE_NOCACHE)
{
wcscpy_s(protectionString, MemoryProtectionValues[PROT_NOCACHE]);
wcscat_s(protectionString, L" | ");
value ^= PAGE_NOCACHE;
}
if (value & PAGE_WRITECOMBINE)
{
wcscpy_s(protectionString, MemoryProtectionValues[PROT_WRITECOMBINE]);
wcscat_s(protectionString, L" | ");
value ^= PAGE_WRITECOMBINE;
}
switch(value)
{
case PAGE_EXECUTE:
{
wcscat_s(protectionString, MemoryProtectionValues[PROT_EXECUTE]);
break;
}
case PAGE_EXECUTE_READ:
{
wcscat_s(protectionString, MemoryProtectionValues[PROT_EXECUTE_READ]);
break;
}
case PAGE_EXECUTE_READWRITE:
{
wcscat_s(protectionString, MemoryProtectionValues[PROT_EXECUTE_READWRITE]);
break;
}
case PAGE_EXECUTE_WRITECOPY:
{
wcscat_s(protectionString, MemoryProtectionValues[PROT_EXECUTE_WRITECOPY]);
break;
}
case PAGE_NOACCESS:
{
wcscat_s(protectionString, MemoryProtectionValues[PROT_NOACCESS]);
break;
}
case PAGE_READONLY:
{
wcscat_s(protectionString, MemoryProtectionValues[PROT_READONLY]);
break;
}
case PAGE_READWRITE:
{
wcscat_s(protectionString, MemoryProtectionValues[PROT_READWRITE]);
break;
}
case PAGE_WRITECOPY:
{
wcscat_s(protectionString, MemoryProtectionValues[PROT_WRITECOPY]);
break;
}
default:
{
wcscat_s(protectionString, MemoryUnknown);
}
}
return protectionString;
}
LRESULT DumpMemoryGui::OnListMemoryColumnClicked(NMHDR* pnmh)
{
NMLISTVIEW* list = (NMLISTVIEW*)pnmh;
int column = list->iSubItem;
if(column == prevColumn)
{
ascending = !ascending;
}
else
{
prevColumn = column;
ascending = true;
}
// lo-byte: column, hi-byte: sort-order
ListMemorySelect.SortItems(&listviewCompareFunc, MAKEWORD(column, ascending));
return 0;
}
LRESULT DumpMemoryGui::OnListMemoryClick(NMHDR* pnmh)
{
int index = ListMemorySelect.GetSelectionMark();
if (index != -1)
{
selectedMemory = (Memory *)ListMemorySelect.GetItemData(index);
if (selectedMemory)
{
updateAddressAndSize(selectedMemory);
}
}
return 0;
}
void DumpMemoryGui::OnOK(UINT uNotifyCode, int nID, CWindow wndCtl)
{
DoDataExchange(DDX_SAVE);
if (EditMemoryAddress.GetValue() == 0 || EditMemorySize.GetValue() == 0)
{
wndCtl.MessageBoxW(L"Textbox is empty!",L"Error",MB_ICONERROR);
}
else
{
if (dumpMemory())
{
EndDialog(1);
}
else
{
wndCtl.MessageBoxW(L"Reading memory from process failed",L"Error",MB_ICONERROR);
}
}
}
void DumpMemoryGui::OnCancel(UINT uNotifyCode, int nID, CWindow wndCtl)
{
EndDialog(0);
}
void DumpMemoryGui::updateAddressAndSize( Memory * selectedMemory )
{
EditMemoryAddress.SetValue(selectedMemory->address);
EditMemorySize.SetValue(selectedMemory->size);
}
int DumpMemoryGui::listviewCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
const Memory * module1 = (Memory *)lParam1;
const Memory * module2 = (Memory *)lParam2;
int column = LOBYTE(lParamSort);
bool ascending = (HIBYTE(lParamSort) == TRUE);
int diff = 0;
switch(column)
{
case COL_ADDRESS:
diff = module1->address < module2->address ? -1 : 1;
break;
case COL_SIZE:
diff = module1->size < module2->size ? -1 : 1;
break;
case COL_FILENAME:
diff = _wcsicmp(module1->filename, module2->filename);
break;
case COL_PESECTION:
diff = _wcsicmp(module1->peSection, module2->peSection);
break;
case COL_TYPE:
diff = module1->type < module2->type ? -1 : 1;
break;
case COL_PROTECTION:
diff = module1->protect < module2->protect ? -1 : 1;
break;
case COL_STATE:
diff = _wcsicmp(getMemoryStateString(module1->state), getMemoryStateString(module2->state));
//diff = module1->state < module2->state ? -1 : 1;
break;
case COL_MAPPED_FILE:
diff = _wcsicmp(module1->mappedFilename, module2->mappedFilename);
break;
}
return ascending ? diff : -diff;
}
void DumpMemoryGui::getMemoryList()
{
DWORD count = 0;
DWORD_PTR address = 0;
MEMORY_BASIC_INFORMATION memBasic = {0};
Memory memory;
HMODULE * hMods = 0;
DWORD cbNeeded = 0;
bool notEnough = true;
WCHAR target[MAX_PATH];
count = 100;
hMods = new HMODULE[count];
if (memoryList.empty())
{
memoryList.reserve(20);
}
else
{
memoryList.clear();
}
memory.filename[0] = 0;
memory.peSection[0] = 0;
memory.mappedFilename[0] = 0;
while(VirtualQueryEx(ProcessAccessHelp::hProcess,(LPCVOID)address,&memBasic,sizeof(memBasic)))
{
memory.address = (DWORD_PTR)memBasic.BaseAddress;
memory.type = memBasic.Type;
memory.state = memBasic.State;
memory.size = (DWORD)memBasic.RegionSize;
memory.protect = memBasic.Protect;
if (memory.type == MEM_MAPPED)
{
if (!getMappedFilename(&memory))
{
memory.mappedFilename[0] = 0;
}
}
memoryList.push_back(memory);
memory.mappedFilename[0] = 0;
address += memBasic.RegionSize;
}
do
{
if (!EnumProcessModules(ProcessAccessHelp::hProcess, hMods, count * sizeof(HMODULE), &cbNeeded))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"getMemoryList :: EnumProcessModules failed count %d", count);
#endif
delete [] hMods;
return;
}
if ( (count * sizeof(HMODULE)) < cbNeeded )
{
delete [] hMods;
count += 100;
hMods = new HMODULE[count];
}
else
{
notEnough = false;
}
} while (notEnough);
for (DWORD i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
{
if (GetModuleFileNameExW(ProcessAccessHelp::hProcess, hMods[i], target, _countof(target)))
{
setModuleName((DWORD_PTR)hMods[i],target);
setAllSectionNames((DWORD_PTR)hMods[i],target);
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"getMemoryList :: GetModuleFileNameExW failed 0x%X", GetLastError());
#endif
}
}
delete [] hMods;
}
void DumpMemoryGui::setSectionName(DWORD_PTR sectionAddress, DWORD sectionSize, const WCHAR * sectionName)
{
bool found = false;
std::vector<Memory>::const_iterator iter;
for( iter = memoryList.begin(); iter != memoryList.end(); iter++)
{
if (!found)
{
if ( (iter->address <= sectionAddress) && (sectionAddress < (iter->address + iter->size)) )
{
if (wcslen(iter->peSection) == 0)
{
wcscpy_s((WCHAR *)iter->peSection, IMAGE_SIZEOF_SHORT_NAME * 4, sectionName);
}
else
{
wcscat_s((WCHAR *)iter->peSection, IMAGE_SIZEOF_SHORT_NAME * 4, L"|");
wcscat_s((WCHAR *)iter->peSection, IMAGE_SIZEOF_SHORT_NAME * 4, sectionName);
}
found = true;
}
}
else
{
if ((sectionSize+sectionAddress) < iter->address)
{
break;
}
if (wcslen(iter->peSection) == 0)
{
wcscpy_s((WCHAR *)iter->peSection, IMAGE_SIZEOF_SHORT_NAME * 4, sectionName);
}
else
{
wcscat_s((WCHAR *)iter->peSection, IMAGE_SIZEOF_SHORT_NAME * 4, L"|");
wcscat_s((WCHAR *)iter->peSection, IMAGE_SIZEOF_SHORT_NAME * 4, sectionName);
}
}
}
}
void DumpMemoryGui::setModuleName(DWORD_PTR moduleBase, const WCHAR * moduleName)
{
bool found = false;
std::vector<Memory>::const_iterator iter;
//get filename
const WCHAR* slash = wcsrchr(moduleName, L'\\');
if(slash)
{
moduleName = slash+1;
}
for( iter = memoryList.begin(); iter != memoryList.end(); iter++)
{
if (iter->address == moduleBase)
{
found = true;
}
if (found)
{
if (iter->type == MEM_IMAGE)
{
wcscpy_s((WCHAR *)iter->filename, MAX_PATH, moduleName);
}
else
{
break;
}
}
}
}
void DumpMemoryGui::setAllSectionNames( DWORD_PTR moduleBase, WCHAR * moduleName )
{
- WORD numSections = 0;
- PIMAGE_DOS_HEADER pDos = 0;
- PIMAGE_NT_HEADERS pNT = 0;
- PIMAGE_SECTION_HEADER pSec = 0;
- DWORD size = sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS) + 200;
- DWORD correctSize = 0;
WCHAR sectionNameW[IMAGE_SIZEOF_SHORT_NAME + 1] = {0};
- CHAR sectionNameA[IMAGE_SIZEOF_SHORT_NAME + 1] = {0};
- BYTE * buffer = new BYTE[size];
+ PeParser peFile(moduleName);
- if (ProcessAccessHelp::readMemoryFromProcess(moduleBase,size,buffer))
+ if (peFile.isValidPeFile())
{
- pDos = (PIMAGE_DOS_HEADER)buffer;
+ std::vector<IMAGE_SECTION_HEADER> & listSectionHeader = peFile.getSectionHeaderList();
- if (pDos->e_magic == IMAGE_DOS_SIGNATURE)
+ for (WORD i = 0; i < peFile.getNumberOfSections(); i++)
{
- pNT = (PIMAGE_NT_HEADERS)((DWORD_PTR)pDos + pDos->e_lfanew);
- if (pNT->Signature == IMAGE_NT_SIGNATURE)
- {
- numSections = pNT->FileHeader.NumberOfSections;
- correctSize = (numSections*sizeof(IMAGE_SECTION_HEADER)) + sizeof(IMAGE_NT_HEADERS) + pDos->e_lfanew;
-
- if (size < correctSize)
- {
- size = correctSize;
- delete [] buffer;
- buffer = new BYTE[size];
- if (!ProcessAccessHelp::readMemoryFromProcess(moduleBase,size,buffer))
- {
- delete [] buffer;
- return;
- }
-
- pDos = (PIMAGE_DOS_HEADER)buffer;
- pNT = (PIMAGE_NT_HEADERS)((DWORD_PTR)pDos + pDos->e_lfanew);
- }
-
- pSec = IMAGE_FIRST_SECTION(pNT);
-
- for (WORD i = 0; i < numSections; i++)
- {
- ZeroMemory(sectionNameA, sizeof(sectionNameA));
- memcpy(sectionNameA,pSec->Name,8);
- swprintf_s(sectionNameW,L"%S",sectionNameA);
+ peFile.getSectionNameUnicode(i, sectionNameW, _countof(sectionNameW));
- setSectionName(moduleBase + pSec->VirtualAddress, pSec->Misc.VirtualSize,sectionNameW);
- pSec++;
- }
-
- }
+ setSectionName(moduleBase + listSectionHeader[i].VirtualAddress, listSectionHeader[i].Misc.VirtualSize, sectionNameW);
}
}
+ else
+ {
+ MessageBox(moduleName,L"Not a valid PE -> This should never happen",MB_ICONERROR);
+ }
- delete [] buffer;
}
bool DumpMemoryGui::dumpMemory()
{
DWORD_PTR address = EditMemoryAddress.GetValue();
dumpedMemorySize = EditMemorySize.GetValue();
swprintf_s(dumpFilename,TEXT("MEM_")TEXT(PRINTF_DWORD_PTR_FULL_S)TEXT("_")TEXT("%08X"),address,dumpedMemorySize);
dumpedMemory = new BYTE[dumpedMemorySize];
if (dumpedMemory)
{
if (forceDump)
{
return ProcessAccessHelp::readMemoryPartlyFromProcess(address,dumpedMemorySize,dumpedMemory);
}
else
{
return ProcessAccessHelp::readMemoryFromProcess(address,dumpedMemorySize,dumpedMemory);
}
}
else
{
return false;
}
}
bool DumpMemoryGui::getMappedFilename( Memory* memory )
{
WCHAR filename[MAX_PATH] = {0};
//TODO replace with Nt direct syscall
if (GetMappedFileNameW(ProcessAccessHelp::hProcess, (LPVOID)memory->address, filename, _countof(filename)) > 0)
{
return deviceNameResolver->resolveDeviceLongNameToShort(filename, memory->mappedFilename);
}
return false;
}
diff --git a/Scylla/DumpSectionGui.cpp b/Scylla/DumpSectionGui.cpp
index a985ce1..6a044b2 100644
--- a/Scylla/DumpSectionGui.cpp
+++ b/Scylla/DumpSectionGui.cpp
@@ -1,391 +1,355 @@
#include "DumpSectionGui.h"
#include "Architecture.h"
#include "ProcessAccessHelp.h"
+#include "PeParser.h"
bool PeSection::highlightVirtualSize()
{
//highlight big virtual sizes -> anti-dump protection
- if (virtualSize > 0x2000000)
- {
- return true;
- }
- else
- {
- return false;
- }
+ return (virtualSize > 0x2000000);
}
std::vector<PeSection> & DumpSectionGui::getSectionList()
{
return sectionList;
}
BOOL DumpSectionGui::OnInitDialog(CWindow wndFocus, LPARAM lInitParam)
{
DoDataExchange(); // attach controls
DlgResize_Init(true, true);
addColumnsToSectionList(ListSectionSelect);
displaySectionList(ListSectionSelect);
selectOrDeselectAll();
isEditing = false;
selectedSection = 0;
CenterWindow();
return TRUE;
}
LRESULT DumpSectionGui::OnListSectionColumnClicked(NMHDR* pnmh)
{
NMLISTVIEW* list = (NMLISTVIEW*)pnmh;
int column = list->iSubItem;
if(column == prevColumn)
{
ascending = !ascending;
}
else
{
prevColumn = column;
ascending = true;
}
// lo-byte: column, hi-byte: sort-order
ListSectionSelect.SortItems(&listviewCompareFunc, MAKEWORD(column, ascending));
return 0;
}
LRESULT DumpSectionGui::OnListSectionClick(NMHDR* pnmh)
{
//int index = ListSectionSelect.GetSelectionMark();
//if (index != -1)
//{
//}
return 0;
}
LRESULT DumpSectionGui::OnListDoubleClick(NMHDR* pnmh)
{
RECT rect;
RECT rect1,rect2;
NMITEMACTIVATE* ia = (NMITEMACTIVATE*)pnmh;
if (ia->iSubItem != COL_VSize)
{
return 0;
}
LVHITTESTINFO hti;
hti.pt = ia->ptAction;
int clicked = ListSectionSelect.HitTest(&hti);
if(clicked != -1)
{
selectedSection = (PeSection *)ListSectionSelect.GetItemData(clicked);
}
ListSectionSelect.GetSubItemRect(ia->iItem,ia->iSubItem,LVIR_BOUNDS,&rect);
//Get the Rectange of the listControl
ListSectionSelect.GetWindowRect(&rect1);
//Get the Rectange of the Dialog
GetWindowRect(&rect2);
int x = rect1.left - rect2.left;
int y = rect1.top - rect2.top;
isEditing = true;
EditListControl.SetWindowPos(HWND_TOP,rect.left + 7, rect.top + 7, rect.right - rect.left, rect.bottom - rect.top, NULL);
EditListControl.ShowWindow(SW_SHOW);
EditListControl.SetFocus();
//Draw a Rectangle around the SubItem
//Rectangle(ListSectionSelect.GetDC(),rect.left,rect.top-1,rect.right,rect.bottom);
//Set the listItem text in the EditBox
EditListControl.SetValue(selectedSection->virtualSize);
return 0;
}
void DumpSectionGui::OnSectionSelectAll(UINT uNotifyCode, int nID, CWindow wndCtl)
{
selectOrDeselectAll();
}
void DumpSectionGui::OnEditList(UINT uNotifyCode, int nID, CWindow wndCtl)
{
switch (uNotifyCode)
{
case EN_KILLFOCUS:
{
isEditing = false;
updateEditedItem();
EditListControl.ShowWindow(SW_HIDE);
}
break;
}
}
void DumpSectionGui::OnOK(UINT uNotifyCode, int nID, CWindow wndCtl)
{
if (isEditing) //EN_KILLFOCUS not sent?
{
updateEditedItem();
}
updateCheckState();
EndDialog(1);
}
void DumpSectionGui::OnCancel(UINT uNotifyCode, int nID, CWindow wndCtl)
{
EndDialog(0);
}
int DumpSectionGui::listviewCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
const PeSection * module1 = (PeSection *)lParam1;
const PeSection * module2 = (PeSection *)lParam2;
int column = LOBYTE(lParamSort);
bool ascending = (HIBYTE(lParamSort) == TRUE);
int diff = 0;
switch(column)
{
case COL_NAME:
diff = _wcsicmp(module1->name, module2->name);
break;
case COL_VA:
diff = module1->virtualAddress < module2->virtualAddress ? -1 : 1;
break;
case COL_VSize:
diff = module1->virtualSize < module2->virtualSize ? -1 : 1;
break;
case COL_RVA:
diff = module1->rawAddress < module2->rawAddress ? -1 : 1;
break;
case COL_RSize:
diff = module1->rawSize < module2->rawSize ? -1 : 1;
break;
case COL_Characteristics:
diff = module1->characteristics < module2->characteristics ? -1 : 1;
break;
}
return ascending ? diff : -diff;
}
void DumpSectionGui::addColumnsToSectionList(CListViewCtrl& list)
{
list.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT|LVS_EX_CHECKBOXES|LVS_EX_GRIDLINES, LVS_EX_FULLROWSELECT|LVS_EX_CHECKBOXES|LVS_EX_GRIDLINES);
list.InsertColumn(COL_NAME, L"Name", LVCFMT_CENTER);
list.InsertColumn(COL_VA, L"Virtual Address", LVCFMT_CENTER);
list.InsertColumn(COL_VSize, L"Virtual Size", LVCFMT_CENTER);
list.InsertColumn(COL_RVA, L"Raw Address", LVCFMT_CENTER);
list.InsertColumn(COL_RSize, L"Raw Size", LVCFMT_CENTER);
list.InsertColumn(COL_Characteristics, L"Characteristics", LVCFMT_CENTER);
}
void DumpSectionGui::displaySectionList(CListViewCtrl& list)
{
int count = 0;
WCHAR temp[20];
list.DeleteAllItems();
if (sectionList.empty())
{
getAllSectionsFromFile();
}
std::vector<PeSection>::const_iterator iter;
for( iter = sectionList.begin(); iter != sectionList.end(); iter++ , count++)
{
list.InsertItem(count, iter->name);
swprintf_s(temp, PRINTF_DWORD_PTR_FULL, iter->virtualAddress);
list.SetItemText(count, COL_VA, temp);
swprintf_s(temp, L"%08X", iter->virtualSize);
list.SetItemText(count, COL_VSize, temp);
swprintf_s(temp, L"%08X", iter->rawAddress);
list.SetItemText(count, COL_RVA, temp);
swprintf_s(temp, L"%08X", iter->rawSize);
list.SetItemText(count, COL_RSize, temp);
swprintf_s(temp, L"%08X", iter->characteristics);
list.SetItemText(count, COL_Characteristics, temp);
list.SetItemData(count, (DWORD_PTR)&(*iter));
}
list.SetColumnWidth(COL_NAME, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_VA, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_VSize, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_RVA, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_RSize, LVSCW_AUTOSIZE_USEHEADER);
list.SetColumnWidth(COL_Characteristics, LVSCW_AUTOSIZE_USEHEADER);
}
LRESULT DumpSectionGui::OnNMCustomdraw(NMHDR* pnmh)
{
LRESULT pResult = 0;
unsigned int vectorIndex = 0;
LPNMLVCUSTOMDRAW lpLVCustomDraw = (LPNMLVCUSTOMDRAW)(pnmh);
switch(lpLVCustomDraw->nmcd.dwDrawStage)
{
case CDDS_ITEMPREPAINT:
case CDDS_ITEMPREPAINT | CDDS_SUBITEM:
{
vectorIndex = (unsigned int)lpLVCustomDraw->nmcd.dwItemSpec;
if (lpLVCustomDraw->iSubItem == COL_VSize)
{
if (sectionList[vectorIndex].highlightVirtualSize())
{
lpLVCustomDraw->clrText = RGB(255,255,255); // white text
lpLVCustomDraw->clrTextBk = RGB(255,0,0); // red background
}
}
else
{
lpLVCustomDraw->clrText = CLR_DEFAULT;
lpLVCustomDraw->clrTextBk = CLR_DEFAULT;
}
}
break;
default:
break;
}
pResult |= CDRF_NOTIFYPOSTPAINT;
pResult |= CDRF_NOTIFYITEMDRAW;
pResult |= CDRF_NOTIFYSUBITEMDRAW;
return pResult;
}
void DumpSectionGui::getAllSectionsFromFile()
{
- PIMAGE_DOS_HEADER pDos = 0;
- PIMAGE_SECTION_HEADER pSec = 0;
- PIMAGE_NT_HEADERS pNT = 0;
- DWORD size = sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS) + 200;
- DWORD correctSize = 0;
- CHAR sectionNameA[IMAGE_SIZEOF_SHORT_NAME + 1] = {0};
PeSection peSection;
if (sectionList.empty())
{
sectionList.reserve(3);
}
else
{
sectionList.clear();
}
- BYTE * buffer = new BYTE[size];
+ PeParser peFile(fullpath);
- if (ProcessAccessHelp::readHeaderFromFile(buffer,size,fullpath))
+ if (peFile.isValidPeFile())
{
- pDos = (PIMAGE_DOS_HEADER)buffer;
+ std::vector<IMAGE_SECTION_HEADER> & listSectionHeader = peFile.getSectionHeaderList();
- if (pDos->e_magic == IMAGE_DOS_SIGNATURE)
+ for (WORD i = 0; i < peFile.getNumberOfSections(); i++)
{
- pNT = (PIMAGE_NT_HEADERS)((DWORD_PTR)pDos + pDos->e_lfanew);
- if (pNT->Signature == IMAGE_NT_SIGNATURE)
- {
- correctSize = (pNT->FileHeader.NumberOfSections*sizeof(IMAGE_SECTION_HEADER)) + sizeof(IMAGE_NT_HEADERS) + pDos->e_lfanew + 50;
-
- if (size < correctSize)
- {
- size = correctSize;
- delete [] buffer;
- buffer = new BYTE[size];
- if (!ProcessAccessHelp::readHeaderFromFile(buffer,size,fullpath))
- {
- delete [] buffer;
- return;
- }
-
- pDos = (PIMAGE_DOS_HEADER)buffer;
- pNT = (PIMAGE_NT_HEADERS)((DWORD_PTR)pDos + pDos->e_lfanew);
- }
-
- pSec = IMAGE_FIRST_SECTION(pNT);
-
- for (WORD i = 0; i < pNT->FileHeader.NumberOfSections; i++)
- {
- ZeroMemory(sectionNameA, sizeof(sectionNameA));
- memcpy(sectionNameA,pSec->Name,8);
- swprintf_s(peSection.name,L"%S",sectionNameA);
-
-
- peSection.virtualAddress = imageBase + pSec->VirtualAddress;
- peSection.virtualSize = pSec->Misc.VirtualSize;
- peSection.rawAddress = pSec->PointerToRawData;
- peSection.rawSize = pSec->SizeOfRawData;
- peSection.characteristics = pSec->Characteristics;
- peSection.isDumped = true;
+ peFile.getSectionNameUnicode(i, peSection.name, _countof(peSection.name));
- sectionList.push_back(peSection);
+ peSection.virtualAddress = imageBase + listSectionHeader[i].VirtualAddress;
+ peSection.virtualSize = listSectionHeader[i].Misc.VirtualSize;
+ peSection.rawAddress = listSectionHeader[i].PointerToRawData;
+ peSection.rawSize = listSectionHeader[i].SizeOfRawData;
+ peSection.characteristics = listSectionHeader[i].Characteristics;
+ peSection.isDumped = true;
- pSec++;
- }
-
- }
+ sectionList.push_back(peSection);
}
}
+ else
+ {
+ MessageBox(fullpath, L"Not a valid PE -> This should never happen", MB_ICONERROR);
+ }
- delete [] buffer;
}
void DumpSectionGui::updateEditedItem()
{
if (selectedSection)
{
- selectedSection->virtualSize = EditListControl.GetValue();
+ DWORD newValue = EditListControl.GetValue();
- displaySectionList(ListSectionSelect);
+ if (selectedSection->virtualSize != newValue)
+ {
+ selectedSection->virtualSize = newValue;
+ displaySectionList(ListSectionSelect);
+ selectOrDeselectAll();
+ }
}
}
void DumpSectionGui::updateCheckState()
{
PeSection * pesection;
for (size_t i = 0; i < sectionList.size(); i++)
{
pesection = (PeSection *)ListSectionSelect.GetItemData((int)i);
pesection->isDumped = ListSectionSelect.GetCheckState((int)i) == TRUE;
}
}
void DumpSectionGui::selectOrDeselectAll()
{
BOOL checkState = ListSectionSelect.GetCheckState((int)0) ? FALSE : TRUE;
for (size_t i = 0; i < sectionList.size(); i++)
{
ListSectionSelect.SetCheckState((int)i, checkState);
}
}
diff --git a/Scylla/PeDump.cpp b/Scylla/PeDump.cpp
index 86d9fb7..41fca1f 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))
+ if (!ProcessAccessHelp::readMemoryPartlyFromProcess(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::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/PeParser.cpp b/Scylla/PeParser.cpp
new file mode 100644
index 0000000..180d542
--- /dev/null
+++ b/Scylla/PeParser.cpp
@@ -0,0 +1,298 @@
+
+#include "PeParser.h"
+
+
+PeParser::PeParser(const WCHAR * file, bool readSectionHeaders)
+{
+ fileMemory = 0;
+ headerMemory = 0;
+ pDosHeader = 0;
+ pNTHeader32 = 0;
+ pNTHeader64 = 0;
+
+ filename = file;
+
+ if (wcslen(filename) > 3)
+ {
+ readPeHeader(readSectionHeaders);
+
+ if (readSectionHeaders)
+ {
+ if (isValidPeFile())
+ {
+ getSectionHeaders();
+ }
+ }
+ }
+}
+
+PeParser::~PeParser()
+{
+ if (headerMemory)
+ {
+ delete [] headerMemory;
+ }
+ if (fileMemory)
+ {
+ delete [] fileMemory;
+ }
+
+ listSectionHeaders.clear();
+}
+
+bool PeParser::isPE64()
+{
+ if (isValidPeFile())
+ {
+ return (pNTHeader32->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC);
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool PeParser::isPE32()
+{
+ if (isValidPeFile())
+ {
+ return (pNTHeader32->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC);
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool PeParser::isTargetFileSamePeFormat()
+{
+#ifdef _WIN64
+ return isPE64();
+#else
+ return isPE32();
+#endif
+}
+
+bool PeParser::isValidPeFile()
+{
+ bool retValue = false;
+
+ if (pDosHeader)
+ {
+ if (pDosHeader->e_magic == IMAGE_DOS_SIGNATURE)
+ {
+ if (pNTHeader32)
+ {
+ if (pNTHeader32->Signature == IMAGE_NT_SIGNATURE)
+ {
+ retValue = true;
+ }
+ }
+ }
+ }
+
+ return retValue;
+}
+
+bool PeParser::hasDirectory(const int directoryIndex)
+{
+ if (isPE32())
+ {
+ return (pNTHeader32->OptionalHeader.DataDirectory[directoryIndex].VirtualAddress != 0);
+ }
+ else if (isPE64())
+ {
+ return (pNTHeader64->OptionalHeader.DataDirectory[directoryIndex].VirtualAddress != 0);
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool PeParser::hasExportDirectory()
+{
+ return hasDirectory(IMAGE_DIRECTORY_ENTRY_EXPORT);
+}
+
+bool PeParser::hasTLSDirectory()
+{
+ return hasDirectory(IMAGE_DIRECTORY_ENTRY_TLS);
+}
+
+bool PeParser::hasRelocationDirectory()
+{
+ return hasDirectory(IMAGE_DIRECTORY_ENTRY_BASERELOC);
+}
+
+DWORD PeParser::getEntryPoint()
+{
+ if (isPE32())
+ {
+ return pNTHeader32->OptionalHeader.AddressOfEntryPoint;
+ }
+ else if (isPE64())
+ {
+ return pNTHeader64->OptionalHeader.AddressOfEntryPoint;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+bool PeParser::readPeHeader(bool readSectionHeaders)
+{
+ bool retValue = false;
+ DWORD readSize = sizeof(IMAGE_DOS_HEADER) + 200 + sizeof(IMAGE_NT_HEADERS64);
+ DWORD correctSize = 0;
+ DWORD numberOfBytesRead = 0;
+
+ if (readSectionHeaders)
+ {
+ readSize += (10 * sizeof(IMAGE_SECTION_HEADER));
+ }
+
+ headerMemory = new BYTE[readSize];
+
+ HANDLE hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
+
+ if (hFile != INVALID_HANDLE_VALUE)
+ {
+ if (ReadFile(hFile, headerMemory, readSize, &numberOfBytesRead, 0))
+ {
+ retValue = true;
+ pDosHeader = (PIMAGE_DOS_HEADER)headerMemory;
+
+ if (pDosHeader->e_lfanew > 0 && pDosHeader->e_lfanew < (LONG)readSize) //malformed PE
+ {
+ pNTHeader32 = (PIMAGE_NT_HEADERS32)((DWORD_PTR)pDosHeader + pDosHeader->e_lfanew);
+ pNTHeader64 = (PIMAGE_NT_HEADERS64)((DWORD_PTR)pDosHeader + pDosHeader->e_lfanew);
+ }
+
+ if (isValidPeFile())
+ {
+ correctSize = pDosHeader->e_lfanew + 50; //extra buffer
+
+ if (readSectionHeaders)
+ {
+ correctSize += getNumberOfSections() * sizeof(IMAGE_SECTION_HEADER);
+ }
+
+ if (isPE32())
+ {
+ correctSize += sizeof(IMAGE_NT_HEADERS32);
+ }
+ else if(isPE64())
+ {
+ correctSize += sizeof(IMAGE_NT_HEADERS64);
+ }
+ else
+ {
+ correctSize = 0; //not valid pe
+ }
+
+ if (readSize < correctSize)
+ {
+ readSize = correctSize;
+ delete [] headerMemory;
+ headerMemory = new BYTE[readSize];
+
+ SetFilePointer(hFile, 0, 0, FILE_BEGIN);
+
+ if (ReadFile(hFile,headerMemory,readSize,&numberOfBytesRead,0))
+ {
+ pDosHeader = (PIMAGE_DOS_HEADER)headerMemory;
+ if (pDosHeader->e_lfanew > 0 && pDosHeader->e_lfanew < (LONG)readSize) //malformed PE
+ {
+ pNTHeader32 = (PIMAGE_NT_HEADERS32)((DWORD_PTR)pDosHeader + pDosHeader->e_lfanew);
+ pNTHeader64 = (PIMAGE_NT_HEADERS64)((DWORD_PTR)pDosHeader + pDosHeader->e_lfanew);
+ }
+ }
+ }
+ }
+ }
+
+ CloseHandle(hFile);
+ }
+
+ return retValue;
+}
+
+bool PeParser::readFileToMemory()
+{
+ bool retValue = false;
+ DWORD numberOfBytesRead = 0;
+ LARGE_INTEGER largeInt = {0};
+ const DWORD MaxFileSize = 500 * 1024 * 1024; // GB * MB * KB * B -> 500 MB
+
+ HANDLE hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
+
+ if (hFile != INVALID_HANDLE_VALUE)
+ {
+ if (GetFileSizeEx(hFile, &largeInt))
+ {
+ if (largeInt.QuadPart > MaxFileSize)
+ {
+ //TODO handle big files
+ retValue = false;
+ }
+ else
+ {
+ fileMemory = new BYTE[largeInt.LowPart];
+
+ if (ReadFile(hFile,fileMemory,largeInt.LowPart,&numberOfBytesRead,0))
+ {
+ retValue = true;
+ }
+ else
+ {
+ delete [] fileMemory;
+ fileMemory = 0;
+ }
+ }
+ }
+
+ CloseHandle(hFile);
+ }
+
+ return retValue;
+}
+
+bool PeParser::getSectionHeaders()
+{
+ PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNTHeader32);
+
+ listSectionHeaders.clear();
+ listSectionHeaders.reserve(getNumberOfSections());
+
+ for (WORD i = 0; i < getNumberOfSections(); i++)
+ {
+ listSectionHeaders.push_back(*pSection);
+ pSection++;
+ }
+
+ return true;
+}
+
+bool PeParser::getSectionNameUnicode(const int sectionIndex, WCHAR * output, int outputLen)
+{
+ CHAR sectionNameA[IMAGE_SIZEOF_SHORT_NAME + 1] = {0};
+
+ output[0] = 0;
+
+ memcpy(sectionNameA, listSectionHeaders[sectionIndex].Name, IMAGE_SIZEOF_SHORT_NAME);
+
+ return (swprintf_s(output, outputLen, L"%S", sectionNameA) != -1);
+}
+
+WORD PeParser::getNumberOfSections()
+{
+ return pNTHeader32->FileHeader.NumberOfSections;
+}
+
+std::vector<IMAGE_SECTION_HEADER> & PeParser::getSectionHeaderList()
+{
+ return listSectionHeaders;
+}
+
diff --git a/Scylla/PeParser.h b/Scylla/PeParser.h
new file mode 100644
index 0000000..86b5c12
--- /dev/null
+++ b/Scylla/PeParser.h
@@ -0,0 +1,50 @@
+#pragma once
+
+#include <windows.h>
+#include <vector>
+
+class PeParser
+{
+public:
+ PeParser(const WCHAR * file, bool readSectionHeaders = true);
+ //PeParser(HANDLE hProcess, DWORD_PTR moduleBase, bool readSectionHeaders = true);
+
+ ~PeParser();
+
+ bool isValidPeFile();
+ bool isPE64();
+ bool isPE32();
+
+ bool isTargetFileSamePeFormat();
+
+ WORD getNumberOfSections();
+ std::vector<IMAGE_SECTION_HEADER> & getSectionHeaderList();
+
+ bool hasExportDirectory();
+ bool hasTLSDirectory();
+ bool hasRelocationDirectory();
+
+ DWORD getEntryPoint();
+
+ bool getSectionNameUnicode(const int sectionIndex, WCHAR * output, int outputLen);
+
+private:
+ const WCHAR * filename;
+
+ PIMAGE_DOS_HEADER pDosHeader;
+ PIMAGE_NT_HEADERS32 pNTHeader32;
+ PIMAGE_NT_HEADERS64 pNTHeader64;
+
+ std::vector<IMAGE_SECTION_HEADER> listSectionHeaders;
+
+ BYTE * fileMemory;
+ BYTE * headerMemory;
+
+ bool readPeHeader(bool readSectionHeaders);
+ bool readFileToMemory();
+
+ bool hasDirectory(const int directoryIndex);
+ bool getSectionHeaders();
+ bool readPeHeaderFromProcess( HANDLE hProcess, DWORD_PTR moduleBase );
+};
+
diff --git a/Scylla/PluginLoader.cpp b/Scylla/PluginLoader.cpp
index 4c8a168..ac0c3aa 100644
--- a/Scylla/PluginLoader.cpp
+++ b/Scylla/PluginLoader.cpp
@@ -1,353 +1,326 @@
#include "PluginLoader.h"
#include "Logger.h"
#include "ProcessAccessHelp.h"
#include "StringConversion.h"
#include <shlwapi.h>
+#include "PeParser.h"
+
const WCHAR PluginLoader::PLUGIN_DIR[] = L"Plugins\\";
const WCHAR PluginLoader::PLUGIN_SEARCH_STRING[] = L"*.dll";
const WCHAR PluginLoader::PLUGIN_IMPREC_DIR[] = L"ImpRec_Plugins\\";
const WCHAR PluginLoader::PLUGIN_IMPREC_WRAPPER_DLL[] = L"Imprec_Wrapper_DLL.dll";
//#define DEBUG_COMMENTS
std::vector<Plugin> & PluginLoader::getScyllaPluginList()
{
return scyllaPluginList;
}
std::vector<Plugin> & PluginLoader::getImprecPluginList()
{
return imprecPluginList;
}
bool PluginLoader::findAllPlugins()
{
if (!scyllaPluginList.empty())
{
scyllaPluginList.clear();
}
if (!imprecPluginList.empty())
{
imprecPluginList.clear();
}
if (!buildSearchString())
{
return false;
}
if (!searchForPlugin(scyllaPluginList, dirSearchString, true))
{
return false;
}
#ifndef _WIN64
if (!buildSearchStringImprecPlugins())
{
return false;
}
if (!searchForPlugin(imprecPluginList, dirSearchString, false))
{
return false;
}
#endif
return true;
}
bool PluginLoader::searchForPlugin(std::vector<Plugin> & newPluginList, const WCHAR * searchPath, bool isScyllaPlugin)
{
WIN32_FIND_DATA ffd;
HANDLE hFind = 0;
DWORD dwError = 0;
Plugin pluginData;
hFind = FindFirstFile(searchPath, &ffd);
dwError = GetLastError();
if (dwError == ERROR_FILE_NOT_FOUND)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"findAllPlugins :: No files found");
#endif
return true;
}
if (hFind == INVALID_HANDLE_VALUE)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"findAllPlugins :: FindFirstFile failed %d", dwError);
#endif
return false;
}
do
{
if ( !(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
{
if ((ffd.nFileSizeHigh != 0) || (ffd.nFileSizeLow < 200))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"findAllPlugins :: Plugin invalid file size: %s", ffd.cFileName);
#endif
}
else
{
pluginData.fileSize = ffd.nFileSizeLow;
wcscpy_s(pluginData.fullpath, baseDirPath);
wcscat_s(pluginData.fullpath, ffd.cFileName);
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"findAllPlugins :: Plugin %s", pluginData.fullpath);
#endif
if (isValidDllFile(pluginData.fullpath))
{
if (isScyllaPlugin)
{
if (getScyllaPluginName(&pluginData))
{
//add valid plugin
newPluginList.push_back(pluginData);
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"Cannot get scylla plugin name %s", pluginData.fullpath);
#endif
}
}
else
{
if (isValidImprecPlugin(pluginData.fullpath))
{
wcscpy_s(pluginData.pluginName, ffd.cFileName);
newPluginList.push_back(pluginData);
}
}
}
}
}
}
while (FindNextFile(hFind, &ffd) != 0);
dwError = GetLastError();
FindClose(hFind);
if (dwError == ERROR_NO_MORE_FILES)
{
return true;
}
else
{
return false;
}
}
bool PluginLoader::getScyllaPluginName(Plugin * pluginData)
{
bool retValue = false;
char * pluginName = 0;
def_ScyllaPluginNameW ScyllaPluginNameW = 0;
def_ScyllaPluginNameA ScyllaPluginNameA = 0;
HMODULE hModule = LoadLibraryEx(pluginData->fullpath, 0, DONT_RESOLVE_DLL_REFERENCES); //do not call DllMain
if (hModule)
{
ScyllaPluginNameW = (def_ScyllaPluginNameW)GetProcAddress(hModule, "ScyllaPluginNameW");
if (ScyllaPluginNameW)
{
wcscpy_s(pluginData->pluginName, ScyllaPluginNameW());
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"getPluginName :: Plugin name %s", pluginData->pluginName);
#endif
retValue = true;
}
else
{
ScyllaPluginNameA = (def_ScyllaPluginNameA)GetProcAddress(hModule, "ScyllaPluginNameA");
if (ScyllaPluginNameA)
{
pluginName = ScyllaPluginNameA();
StringConversion::ToUTF16(pluginName, pluginData->pluginName, _countof(pluginData->pluginName));
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"getPluginName :: Plugin name mbstowcs_s %s", pluginData->pluginName);
#endif
if (wcslen(pluginData->pluginName) > 1)
{
retValue = true;
}
else
{
retValue = false;
}
}
else
{
retValue = false;
}
}
FreeLibrary(hModule);
return retValue;
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"getPluginName :: LoadLibraryEx failed %s", pluginData->fullpath);
#endif
return false;
}
}
bool PluginLoader::buildSearchString()
{
ZeroMemory(dirSearchString, sizeof(dirSearchString));
ZeroMemory(baseDirPath, sizeof(baseDirPath));
if (!GetModuleFileName(0, dirSearchString, _countof(dirSearchString)))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"buildSearchString :: GetModuleFileName failed %d", GetLastError());
#endif
return false;
}
//wprintf(L"dirSearchString 1 %s\n\n", dirSearchString);
PathRemoveFileSpec(dirSearchString);
//wprintf(L"dirSearchString 2 %s\n\n", dirSearchString);
PathAppend(dirSearchString, PLUGIN_DIR);
wcscpy_s(baseDirPath, dirSearchString);
wcscat_s(dirSearchString, PLUGIN_SEARCH_STRING);
//wprintf(L"dirSearchString 3 %s\n\n", dirSearchString);
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"dirSearchString final %s", dirSearchString);
#endif
return true;
}
bool PluginLoader::isValidDllFile( const WCHAR * fullpath )
{
- BYTE * data = 0;
- DWORD lpNumberOfBytesRead = 0;
- PIMAGE_DOS_HEADER pDos = 0;
- PIMAGE_NT_HEADERS pNT = 0;
- bool retValue = false;
-
- HANDLE hFile = CreateFile(fullpath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
+ PeParser peFile(fullpath,false);
- if (hFile != INVALID_HANDLE_VALUE)
+ if (peFile.isTargetFileSamePeFormat() && peFile.hasExportDirectory())
{
- data = new BYTE[sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS) + 0x100];
-
- if (ReadFile(hFile, data, sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS) + 0x100, &lpNumberOfBytesRead, 0))
- {
- pDos = (PIMAGE_DOS_HEADER)data;
-
- if (pDos->e_magic == IMAGE_DOS_SIGNATURE)
- {
- pNT = (PIMAGE_NT_HEADERS)((DWORD_PTR)pDos + pDos->e_lfanew);
-
- if (pNT->Signature == IMAGE_NT_SIGNATURE)
- {
-#ifdef _WIN64
- if (pNT->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
-#else
- if (pNT->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
-#endif
- {
- retValue = true;
- }
- }
- }
- }
-
- delete [] data;
- CloseHandle(hFile);
+ return true;
+ }
+ else
+ {
+ return false;
}
-
- return retValue;
}
bool PluginLoader::isValidImprecPlugin(const WCHAR * fullpath)
{
def_Imprec_Trace Imprec_Trace = 0;
bool retValue = false;
HMODULE hModule = LoadLibraryEx(fullpath, 0, DONT_RESOLVE_DLL_REFERENCES); //do not call DllMain
if (hModule)
{
Imprec_Trace = (def_Imprec_Trace)GetProcAddress(hModule, "Trace");
if (Imprec_Trace)
{
retValue = true;
}
else
{
retValue = false;
}
FreeLibrary(hModule);
return retValue;
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"isValidImprecPlugin :: LoadLibraryEx failed %s", pluginData->fullpath);
#endif
return false;
}
}
bool PluginLoader::buildSearchStringImprecPlugins()
{
wcscpy_s(dirSearchString, baseDirPath);
wcscat_s(dirSearchString, PLUGIN_IMPREC_DIR);
wcscpy_s(baseDirPath, dirSearchString);
//build imprec wrapper dll path
wcscpy_s(imprecWrapperDllPath, dirSearchString);
wcscat_s(imprecWrapperDllPath, PLUGIN_IMPREC_WRAPPER_DLL);
if (!fileExists(imprecWrapperDllPath))
{
return false;
}
wcscat_s(dirSearchString, PLUGIN_SEARCH_STRING);
return true;
}
bool PluginLoader::fileExists(const WCHAR * fileName)
{
return (GetFileAttributesW(fileName) != INVALID_FILE_ATTRIBUTES);
}
diff --git a/Scylla/ProcessAccessHelp.cpp b/Scylla/ProcessAccessHelp.cpp
index 86324b9..f7867f7 100644
--- a/Scylla/ProcessAccessHelp.cpp
+++ b/Scylla/ProcessAccessHelp.cpp
@@ -1,802 +1,786 @@
#include "ProcessAccessHelp.h"
#include "Scylla.h"
#include "NativeWinApi.h"
+#include "PeParser.h"
HANDLE ProcessAccessHelp::hProcess = 0;
ModuleInfo * ProcessAccessHelp::selectedModule;
DWORD_PTR ProcessAccessHelp::targetImageBase = 0;
DWORD_PTR ProcessAccessHelp::targetSizeOfImage = 0;
DWORD_PTR ProcessAccessHelp::maxValidAddress = 0;
std::vector<ModuleInfo> ProcessAccessHelp::moduleList; //target process module list
std::vector<ModuleInfo> ProcessAccessHelp::ownModuleList; //own module list
_DInst ProcessAccessHelp::decomposerResult[MAX_INSTRUCTIONS];
unsigned int ProcessAccessHelp::decomposerInstructionsCount = 0;
_CodeInfo ProcessAccessHelp::decomposerCi = {0};
_DecodedInst ProcessAccessHelp::decodedInstructions[MAX_INSTRUCTIONS];
unsigned int ProcessAccessHelp::decodedInstructionsCount = 0;
BYTE ProcessAccessHelp::fileHeaderFromDisk[PE_HEADER_BYTES_COUNT];
//#define DEBUG_COMMENTS
bool ProcessAccessHelp::openProcessHandle(DWORD dwPID)
{
if (dwPID > 0)
{
if (hProcess)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"openProcessHandle :: There is already a process handle, HANDLE %X", hProcess);
#endif
return false;
}
else
{
//hProcess = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_QUERY_INFORMATION|PROCESS_VM_READ|PROCESS_VM_WRITE, 0, dwPID);
//if (!NT_SUCCESS(NativeWinApi::NtOpenProcess(&hProcess,PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_QUERY_INFORMATION|PROCESS_VM_READ|PROCESS_VM_WRITE,&ObjectAttributes, &cid)))
hProcess = NativeOpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_QUERY_INFORMATION|PROCESS_VM_READ|PROCESS_VM_WRITE, dwPID);
if (hProcess)
{
return true;
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"openProcessHandle :: Failed to open handle, PID %X", dwPID);
#endif
return false;
}
}
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"openProcessHandle :: Wrong PID, PID %X", dwPID);
#endif
return false;
}
}
HANDLE ProcessAccessHelp::NativeOpenProcess(DWORD dwDesiredAccess, DWORD dwProcessId)
{
HANDLE hProcess = 0;
CLIENT_ID cid = {0};
OBJECT_ATTRIBUTES ObjectAttributes;
NTSTATUS ntStatus = 0;
InitializeObjectAttributes(&ObjectAttributes, 0, 0, 0, 0);
cid.UniqueProcess = (HANDLE)dwProcessId;
ntStatus = NativeWinApi::NtOpenProcess(&hProcess,dwDesiredAccess,&ObjectAttributes, &cid);
if (NT_SUCCESS(ntStatus))
{
return hProcess;
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"NativeOpenProcess :: Failed to open handle, PID %X Error 0x%X", dwProcessId, NativeWinApi::RtlNtStatusToDosError(ntStatus));
#endif
return 0;
}
}
void ProcessAccessHelp::closeProcessHandle()
{
CloseHandle(hProcess);
hProcess = 0;
moduleList.clear();
targetImageBase = 0;
selectedModule = 0;
}
bool ProcessAccessHelp::readMemoryPartlyFromProcess(DWORD_PTR address, SIZE_T size, LPVOID dataBuffer)
{
DWORD_PTR addressPart = 0;
DWORD_PTR readBytes = 0;
DWORD_PTR bytesToRead = 0;
MEMORY_BASIC_INFORMATION memBasic = {0};
bool returnValue = false;
if (!hProcess)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryPartlyFromProcess :: hProcess == NULL");
#endif
return returnValue;
}
if (!readMemoryFromProcess(address, size, dataBuffer))
{
addressPart = address;
do
{
if (!VirtualQueryEx(ProcessAccessHelp::hProcess,(LPCVOID)addressPart,&memBasic,sizeof(memBasic)))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryPartlyFromProcess :: Error VirtualQueryEx %X %X err: %u", addressPart,size, GetLastError());
#endif
break;
}
bytesToRead = memBasic.RegionSize;
if ( (readBytes+bytesToRead) > size)
{
bytesToRead = size - readBytes;
}
if (memBasic.State == MEM_COMMIT)
{
if (!readMemoryFromProcess(addressPart, bytesToRead, (LPVOID)((DWORD_PTR)dataBuffer + readBytes)))
{
break;
}
}
else
{
ZeroMemory((LPVOID)((DWORD_PTR)dataBuffer + readBytes),bytesToRead);
}
readBytes += bytesToRead;
addressPart += memBasic.RegionSize;
} while (readBytes < size);
if (readBytes == size)
{
returnValue = true;
}
}
else
{
returnValue = true;
}
return returnValue;
}
bool ProcessAccessHelp::readMemoryFromProcess(DWORD_PTR address, SIZE_T size, LPVOID dataBuffer)
{
SIZE_T lpNumberOfBytesRead = 0;
DWORD dwProtect = 0;
bool returnValue = false;
if (!hProcess)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryFromProcess :: hProcess == NULL");
#endif
return returnValue;
}
if (!ReadProcessMemory(hProcess, (LPVOID)address, dataBuffer, size, &lpNumberOfBytesRead))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryFromProcess :: Error ReadProcessMemory %X %X err: %u", address, size, GetLastError());
#endif
if (!VirtualProtectEx(hProcess, (LPVOID)address, size, PAGE_READWRITE, &dwProtect))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryFromProcess :: Error VirtualProtectEx %X %X err: %u", address,size, GetLastError());
#endif
returnValue = false;
}
else
{
if (!ReadProcessMemory(hProcess, (LPVOID)address, dataBuffer, size, &lpNumberOfBytesRead))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryFromProcess :: Error ReadProcessMemory %X %X err: %u", address, size, GetLastError());
#endif
returnValue = false;
}
else
{
returnValue = true;
}
VirtualProtectEx(hProcess, (LPVOID)address, size, dwProtect, &dwProtect);
}
}
else
{
returnValue = true;
}
if (returnValue)
{
if (size != lpNumberOfBytesRead)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryFromProcess :: Error ReadProcessMemory read %d bytes requested %d bytes", lpNumberOfBytesRead, size);
#endif
returnValue = false;
}
else
{
returnValue = true;
}
}
return returnValue;
}
bool ProcessAccessHelp::decomposeMemory(BYTE * dataBuffer, SIZE_T bufferSize, DWORD_PTR startAddress)
{
ZeroMemory(&decomposerCi, sizeof(_CodeInfo));
decomposerCi.code = dataBuffer;
decomposerCi.codeLen = (int)bufferSize;
decomposerCi.dt = dt;
decomposerCi.codeOffset = startAddress;
decomposerInstructionsCount = 0;
if (distorm_decompose(&decomposerCi, decomposerResult, sizeof(decomposerResult)/sizeof(decomposerResult[0]), &decomposerInstructionsCount) == DECRES_INPUTERR)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"decomposeMemory :: distorm_decompose == DECRES_INPUTERR");
#endif
return false;
}
else
{
return true;
}
}
bool ProcessAccessHelp::disassembleMemory(BYTE * dataBuffer, SIZE_T bufferSize, DWORD_PTR startOffset)
{
// Holds the result of the decoding.
_DecodeResult res;
// next is used for instruction's offset synchronization.
// decodedInstructionsCount holds the count of filled instructions' array by the decoder.
decodedInstructionsCount = 0;
_OffsetType offset = startOffset;
res = distorm_decode(offset, dataBuffer, (int)bufferSize, dt, decodedInstructions, MAX_INSTRUCTIONS, &decodedInstructionsCount);
/* for (unsigned int i = 0; i < decodedInstructionsCount; i++) {
#ifdef SUPPORT_64BIT_OFFSET
printf("%0*I64x (%02d) %-24s %s%s%s\n", dt != Decode64Bits ? 8 : 16, decodedInstructions[i].offset, decodedInstructions[i].size, (char*)decodedInstructions[i].instructionHex.p, (char*)decodedInstructions[i].mnemonic.p, decodedInstructions[i].operands.length != 0 ? " " : "", (char*)decodedInstructions[i].operands.p);
#else
printf("%08x (%02d) %-24s %s%s%s\n", decodedInstructions[i].offset, decodedInstructions[i].size, (char*)decodedInstructions[i].instructionHex.p, (char*)decodedInstructions[i].mnemonic.p, decodedInstructions[i].operands.length != 0 ? " " : "", (char*)decodedInstructions[i].operands.p);
#endif
}*/
if (res == DECRES_INPUTERR)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"disassembleMemory :: res == DECRES_INPUTERR");
#endif
return false;
}
else if (res == DECRES_SUCCESS)
{
//printf("disassembleMemory :: res == DECRES_SUCCESS\n");
return true;
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"disassembleMemory :: res == %d", res);
#endif
return false;
}
}
DWORD_PTR ProcessAccessHelp::findPattern(DWORD_PTR startOffset, DWORD size, BYTE * pattern, const char * mask)
{
DWORD pos = 0;
size_t searchLen = strlen(mask) - 1;
for(DWORD_PTR retAddress = startOffset; retAddress < startOffset + size; retAddress++)
{
if( *(BYTE*)retAddress == pattern[pos] || mask[pos] == '?' )
{
if(mask[pos+1] == 0x00)
{
return (retAddress - searchLen);
}
pos++;
} else {
pos = 0;
}
}
return 0;
}
bool ProcessAccessHelp::readHeaderFromCurrentFile(const WCHAR * filePath)
{
return readHeaderFromFile(fileHeaderFromDisk, sizeof(fileHeaderFromDisk), filePath);
}
LONGLONG ProcessAccessHelp::getFileSize(const WCHAR * filePath)
{
LONGLONG fileSize = 0;
HANDLE hFile = CreateFile(filePath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if (hFile != INVALID_HANDLE_VALUE)
{
fileSize = getFileSize(hFile);
CloseHandle(hFile);
hFile = 0;
}
return fileSize;
}
LONGLONG ProcessAccessHelp::getFileSize(HANDLE hFile)
{
LARGE_INTEGER lpFileSize = {0};
if ((hFile != INVALID_HANDLE_VALUE) && (hFile != 0))
{
if (!GetFileSizeEx(hFile, &lpFileSize))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"ProcessAccessHelp::getFileSize :: GetFileSizeEx failed %u", GetLastError());
#endif
return 0;
}
else
{
return lpFileSize.QuadPart;
}
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"ProcessAccessHelp::getFileSize hFile invalid");
#endif
return 0;
}
}
bool ProcessAccessHelp::readMemoryFromFile(HANDLE hFile, LONG offset, DWORD size, LPVOID dataBuffer)
{
DWORD lpNumberOfBytesRead = 0;
DWORD retValue = 0;
DWORD dwError = 0;
if ((hFile != INVALID_HANDLE_VALUE) && (hFile != 0))
{
retValue = SetFilePointer(hFile, offset, NULL, FILE_BEGIN);
dwError = GetLastError();
if ((retValue == INVALID_SET_FILE_POINTER) && (dwError != NO_ERROR))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryFromFile :: SetFilePointer failed error %u", dwError);
#endif
return false;
}
else
{
if (ReadFile(hFile, dataBuffer, size, &lpNumberOfBytesRead, 0))
{
return true;
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryFromFile :: ReadFile failed - size %d - error %u", size, GetLastError());
#endif
return false;
}
}
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryFromFile :: hFile invalid");
#endif
return false;
}
}
bool ProcessAccessHelp::writeMemoryToNewFile(const WCHAR * file,DWORD size, LPCVOID dataBuffer)
{
HANDLE hFile = CreateFile(file, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
if (hFile != INVALID_HANDLE_VALUE)
{
return writeMemoryToFile(hFile,0,size,dataBuffer);
}
else
{
return false;
}
}
bool ProcessAccessHelp::writeMemoryToFile(HANDLE hFile, LONG offset, DWORD size, LPCVOID dataBuffer)
{
DWORD lpNumberOfBytesWritten = 0;
DWORD retValue = 0;
DWORD dwError = 0;
if ((hFile != INVALID_HANDLE_VALUE) && (hFile != 0))
{
retValue = SetFilePointer(hFile, offset, NULL, FILE_BEGIN);
dwError = GetLastError();
if ((retValue == INVALID_SET_FILE_POINTER) && (dwError != NO_ERROR))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"writeMemoryToFile :: SetFilePointer failed error %u", dwError);
#endif
return false;
}
else
{
if (WriteFile(hFile, dataBuffer, size, &lpNumberOfBytesWritten, 0))
{
return true;
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"writeMemoryToFile :: WriteFile failed - size %d - error %u", size, GetLastError());
#endif
return false;
}
}
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"writeMemoryToFile :: hFile invalid");
#endif
return false;
}
}
bool ProcessAccessHelp::writeMemoryToFileEnd(HANDLE hFile, DWORD size, LPCVOID dataBuffer)
{
DWORD lpNumberOfBytesWritten = 0;
DWORD retValue = 0;
if ((hFile != INVALID_HANDLE_VALUE) && (hFile != 0))
{
SetFilePointer(hFile, 0, 0, FILE_END);
if (WriteFile(hFile, dataBuffer, size, &lpNumberOfBytesWritten, 0))
{
return true;
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"writeMemoryToFileEnd :: WriteFile failed - size %d - error %u", size, GetLastError());
#endif
return false;
}
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"writeMemoryToFileEnd :: hFile invalid");
#endif
return false;
}
}
bool ProcessAccessHelp::readHeaderFromFile(BYTE * buffer, DWORD bufferSize, const WCHAR * filePath)
{
DWORD lpNumberOfBytesRead = 0;
LONGLONG fileSize = 0;
DWORD dwSize = 0;
bool returnValue = 0;
HANDLE hFile = CreateFile(filePath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if( hFile == INVALID_HANDLE_VALUE )
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readHeaderFromFile :: INVALID_HANDLE_VALUE %u", GetLastError());
#endif
returnValue = false;
}
else
{
fileSize = getFileSize(hFile);
if (fileSize > 0)
{
if (fileSize > bufferSize)
{
dwSize = bufferSize;
}
else
{
dwSize = (DWORD)(fileSize - 1);
}
returnValue = readMemoryFromFile(hFile, 0, dwSize, buffer);
}
CloseHandle(hFile);
}
return returnValue;
}
LPVOID ProcessAccessHelp::createFileMappingViewRead(const WCHAR * filePath)
{
return createFileMappingView(filePath, GENERIC_READ, PAGE_READONLY | SEC_IMAGE, FILE_MAP_READ);
}
LPVOID ProcessAccessHelp::createFileMappingViewFull(const WCHAR * filePath)
{
return createFileMappingView(filePath, GENERIC_ALL, PAGE_EXECUTE_READWRITE, FILE_MAP_ALL_ACCESS);
}
LPVOID ProcessAccessHelp::createFileMappingView(const WCHAR * filePath, DWORD accessFile, DWORD flProtect, DWORD accessMap)
{
HANDLE hFile = CreateFile(filePath, accessFile, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if( hFile == INVALID_HANDLE_VALUE )
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"createFileMappingView :: INVALID_HANDLE_VALUE %u", GetLastError());
#endif
return NULL;
}
HANDLE hMappedFile = CreateFileMapping(hFile, NULL, flProtect, 0, 0, NULL);
CloseHandle(hFile);
if( hMappedFile == NULL )
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"createFileMappingView :: hMappedFile == NULL");
#endif
return NULL;
}
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"createFileMappingView :: GetLastError() == ERROR_ALREADY_EXISTS");
#endif
return NULL;
}
LPVOID addrMappedDll = MapViewOfFile(hMappedFile, accessMap, 0, 0, 0);
if( addrMappedDll == NULL )
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"createFileMappingView :: addrMappedDll == NULL");
#endif
CloseHandle(hMappedFile);
return NULL;
}
CloseHandle(hMappedFile);
return addrMappedDll;
}
DWORD ProcessAccessHelp::getProcessByName(const WCHAR * processName)
{
DWORD dwPID = 0;
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32W pe32;
pe32.dwSize = sizeof(PROCESSENTRY32W);
if( !Process32FirstW( hProcessSnap, &pe32 ) )
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"getProcessByName :: Error getting first Process");
#endif
CloseHandle( hProcessSnap );
return 0;
}
do
{
if(!_wcsicmp(pe32.szExeFile, processName))
{
dwPID = pe32.th32ProcessID;
break;
}
} while(Process32NextW(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
return dwPID;
}
bool ProcessAccessHelp::getProcessModules(DWORD dwPID, std::vector<ModuleInfo> &moduleList)
{
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
MODULEENTRY32 me32;
ModuleInfo module;
// Take a snapshot of all modules in the specified process.
hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwPID );
if( hModuleSnap == INVALID_HANDLE_VALUE )
{
return false;
}
// Set the size of the structure before using it.
me32.dwSize = sizeof( MODULEENTRY32 );
// Retrieve information about the first module,
// and exit if unsuccessful
if( !Module32First( hModuleSnap, &me32 ) )
{
CloseHandle( hModuleSnap );
return false;
}
// Now walk the module list of the process,
// and display information about each module
//the first is always the .exe
if (!Module32Next(hModuleSnap, &me32))
{
CloseHandle( hModuleSnap );
return false;
}
moduleList.reserve(20);
do
{
//printf(L"\n MODULE NAME: %s", me32.szModule);
module.modBaseAddr = (DWORD_PTR)me32.modBaseAddr;
module.modBaseSize = me32.modBaseSize;
module.isAlreadyParsed = false;
module.parsing = false;
wcscpy_s(module.fullPath, me32.szExePath);
moduleList.push_back(module);
} while(Module32Next(hModuleSnap, &me32));
CloseHandle( hModuleSnap );
return true;
}
bool ProcessAccessHelp::getMemoryRegionFromAddress(DWORD_PTR address, DWORD_PTR * memoryRegionBase, SIZE_T * memoryRegionSize)
{
MEMORY_BASIC_INFORMATION memBasic;
if (VirtualQueryEx(hProcess,(LPCVOID)address,&memBasic,sizeof(MEMORY_BASIC_INFORMATION)) != sizeof(MEMORY_BASIC_INFORMATION))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"getMemoryRegionFromAddress :: VirtualQueryEx error %u", GetLastError());
#endif
return false;
}
else
{
*memoryRegionBase = (DWORD_PTR)memBasic.BaseAddress;
*memoryRegionSize = memBasic.RegionSize;
return true;
}
}
bool ProcessAccessHelp::getSizeOfImageCurrentProcess()
{
DWORD_PTR newSizeOfImage = getSizeOfImageProcess(ProcessAccessHelp::hProcess, ProcessAccessHelp::targetImageBase);
if (newSizeOfImage != 0)
{
ProcessAccessHelp::targetSizeOfImage = newSizeOfImage;
return true;
}
else
{
return false;
}
}
SIZE_T ProcessAccessHelp::getSizeOfImageProcess(HANDLE processHandle, DWORD_PTR moduleBase)
{
SIZE_T sizeOfImage = 0;
MEMORY_BASIC_INFORMATION lpBuffer = {0};
SIZE_T dwLength = sizeof(MEMORY_BASIC_INFORMATION);
do
{
moduleBase = (DWORD_PTR)((SIZE_T)moduleBase + lpBuffer.RegionSize);
sizeOfImage += lpBuffer.RegionSize;
//printf("Query 0x"PRINTF_DWORD_PTR_FULL" size 0x%08X\n",moduleBase,sizeOfImage);
if (!VirtualQueryEx(processHandle, (LPCVOID)moduleBase, &lpBuffer, dwLength))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"getSizeOfImageProcess :: VirtualQuery failed %X", GetLastError());
#endif
lpBuffer.Type = 0;
sizeOfImage = 0;
}
/*else
{
printf("\nAllocationBase %X\n",lpBuffer.AllocationBase);
printf("AllocationProtect %X\n",lpBuffer.AllocationProtect);
printf("BaseAddress %X\n",lpBuffer.BaseAddress);
printf("Protect %X\n",lpBuffer.Protect);
printf("RegionSize %X\n",lpBuffer.RegionSize);
printf("State %X\n",lpBuffer.State);
printf("Type %X\n",lpBuffer.Type);
}*/
} while (lpBuffer.Type == MEM_IMAGE);
//printf("Real sizeOfImage %X\n",sizeOfImage);
return sizeOfImage;
}
DWORD ProcessAccessHelp::getEntryPointFromFile(const WCHAR * filePath)
{
- PIMAGE_NT_HEADERS pNtHeader = 0;
- PIMAGE_DOS_HEADER pDosHeader = 0;
+ PeParser peFile(filePath, false);
- 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;
+ return peFile.getEntryPoint();
}
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/Scylla.h b/Scylla/Scylla.h
index 8bb0893..6163ba5 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 3"
+#define APPVERSION_S "v0.6 Beta 4"
#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 c22bab0..8397a2f 100644
--- a/Scylla/Scylla.vcxproj
+++ b/Scylla/Scylla.vcxproj
@@ -1,252 +1,252 @@
<?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>
- <PlatformToolset>v90</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v90</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v90</PlatformToolset>
</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)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;dbghelp.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)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;dbghelp.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)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;dbghelp.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)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;dbghelp.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="DumpSectionGui.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="PeParser.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="DumpSectionGui.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="PeParser.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

File Metadata

Mime Type
text/x-diff
Expires
Sat, Jul 5, 6:37 PM (1 d, 2 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
44/0e/a99074d3e29bc272298490fedcbe

Event Timeline