Page MenuHomedesp's stash

No OneTemporary

diff --git a/Scylla/ImportsHandling.cpp b/Scylla/ImportsHandling.cpp
index 6275be1..0251fcf 100644
--- a/Scylla/ImportsHandling.cpp
+++ b/Scylla/ImportsHandling.cpp
@@ -1,822 +1,822 @@
#include "ImportsHandling.h"
#include "Thunks.h"
#include "Architecture.h"
#include <atlmisc.h>
#include <atlcrack.h>
#include "multitree.h" // CMultiSelectTreeViewCtrl
#include "resource.h"
//#define DEBUG_COMMENTS
void ImportThunk::invalidate()
{
ordinal = 0;
hint = 0;
valid = false;
suspect = false;
moduleName[0] = 0;
name[0] = 0;
}
bool ImportModuleThunk::isValid() const
{
std::map<DWORD_PTR, ImportThunk>::const_iterator iterator = thunkList.begin();
while (iterator != thunkList.end())
{
if (iterator->second.valid == false)
{
return false;
}
iterator++;
}
return true;
}
DWORD_PTR ImportModuleThunk::getFirstThunk() const
{
if (thunkList.size() > 0)
{
const std::map<DWORD_PTR, ImportThunk>::const_iterator iterator = thunkList.begin();
return iterator->first;
}
else
{
return 0;
}
}
ImportsHandling::ImportsHandling(CMultiSelectTreeViewCtrl& TreeImports) : TreeImports(TreeImports)
{
hIconCheck.LoadIcon(IDI_ICON_CHECK, 16, 16);
hIconWarning.LoadIcon(IDI_ICON_WARNING, 16, 16);
hIconError.LoadIcon(IDI_ICON_ERROR, 16, 16);
CDCHandle dc = CWindow(::GetDesktopWindow()).GetDC();
int bits = dc.GetDeviceCaps(BITSPIXEL);
const UINT FLAGS = bits > 16 ? ILC_COLOR32 : (ILC_COLOR24 | ILC_MASK);
TreeIcons.Create(16, 16, FLAGS, 3, 1);
TreeIcons.AddIcon(hIconCheck);
TreeIcons.AddIcon(hIconWarning);
TreeIcons.AddIcon(hIconError);
m_thunkCount = m_invalidThunkCount = m_suspectThunkCount = 0;
}
ImportsHandling::~ImportsHandling()
{
TreeIcons.Destroy();
}
bool ImportsHandling::isModule(CTreeItem item)
{
return (0 != getModuleThunk(item));
}
bool ImportsHandling::isImport(CTreeItem item)
{
return (0 != getImportThunk(item));
}
ImportModuleThunk * ImportsHandling::getModuleThunk(CTreeItem item)
{
stdext::hash_map<HTREEITEM, TreeItemData>::const_iterator it;
it = itemData.find(item);
if(it != itemData.end())
{
const TreeItemData * data = &it->second;
if(data->isModule)
{
return data->module;
}
}
return NULL;
}
ImportThunk * ImportsHandling::getImportThunk(CTreeItem item)
{
stdext::hash_map<HTREEITEM, TreeItemData>::const_iterator it;
TreeItemData * data = getItemData(item);
if(data && !data->isModule)
{
return data->import;
}
return NULL;
}
void ImportsHandling::setItemData(CTreeItem item, const TreeItemData * data)
{
itemData[item] = *data;
}
ImportsHandling::TreeItemData * ImportsHandling::getItemData(CTreeItem item)
{
stdext::hash_map<HTREEITEM, TreeItemData>::iterator it;
it = itemData.find(item);
if(it != itemData.end())
{
return &it->second;
}
return NULL;
}
void ImportsHandling::updateCounts()
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator it_module;
std::map<DWORD_PTR, ImportThunk>::iterator it_import;
m_thunkCount = m_invalidThunkCount = m_suspectThunkCount = 0;
it_module = moduleList.begin();
while (it_module != moduleList.end())
{
ImportModuleThunk &moduleThunk = it_module->second;
it_import = moduleThunk.thunkList.begin();
while (it_import != moduleThunk.thunkList.end())
{
ImportThunk &importThunk = it_import->second;
m_thunkCount++;
if(!importThunk.valid)
m_invalidThunkCount++;
else if(importThunk.suspect)
m_suspectThunkCount++;
it_import++;
}
it_module++;
}
}
/*bool ImportsHandling::addImport(const WCHAR * moduleName, const CHAR * name, DWORD_PTR va, DWORD_PTR rva, WORD ordinal, bool valid, bool suspect)
{
ImportThunk import;
ImportModuleThunk * module = 0;
std::map<DWORD_PTR, ImportModuleThunk>::iterator iterator1;
if (moduleList.size() > 1)
{
iterator1 = moduleList.begin();
while (iterator1 != moduleList.end())
{
if (rva >= iterator1->second.firstThunk)
{
iterator1++;
if (iterator1 == moduleList.end())
{
iterator1--;
module = &(iterator1->second);
break;
}
else if (rva < iterator1->second.firstThunk)
{
iterator1--;
module = &(iterator1->second);
break;
}
}
}
}
else
{
iterator1 = moduleList.begin();
module = &(iterator1->second);
}
if (!module)
{
Scylla::debugLog.log(L"ImportsHandling::addFunction module not found rva " PRINTF_DWORD_PTR_FULL, rva);
return false;
}
//TODO
import.suspect = true;
import.valid = false;
import.va = va;
import.rva = rva;
import.ordinal = ordinal;
wcscpy_s(import.moduleName, MAX_PATH, moduleName);
strcpy_s(import.name, MAX_PATH, name);
module->thunkList.insert(std::pair<DWORD_PTR,ImportThunk>(import.rva, import));
return true;
}
*/
/*
bool ImportsHandling::addModule(const WCHAR * moduleName, DWORD_PTR firstThunk)
{
ImportModuleThunk module;
module.firstThunk = firstThunk;
wcscpy_s(module.moduleName, MAX_PATH, moduleName);
moduleList.insert(std::pair<DWORD_PTR,ImportModuleThunk>(firstThunk,module));
return true;
}
*/
void ImportsHandling::displayAllImports()
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator it_module;
std::map<DWORD_PTR, ImportThunk>::iterator it_import;
TreeImports.DeleteAllItems();
itemData.clear();
TreeImports.SetImageList(TreeIcons);
it_module = moduleList.begin();
while (it_module != moduleList.end())
{
ImportModuleThunk &moduleThunk = it_module->second;
moduleThunk.key = moduleThunk.firstThunk; // This belongs elsewhere...
moduleThunk.hTreeItem = addDllToTreeView(TreeImports, &moduleThunk);
it_import = moduleThunk.thunkList.begin();
while (it_import != moduleThunk.thunkList.end())
{
ImportThunk &importThunk = it_import->second;
importThunk.key = importThunk.rva; // This belongs elsewhere...
importThunk.hTreeItem = addApiToTreeView(TreeImports, moduleThunk.hTreeItem, &importThunk);
it_import++;
}
it_module++;
}
updateCounts();
}
void ImportsHandling::clearAllImports()
{
TreeImports.DeleteAllItems();
itemData.clear();
moduleList.clear();
updateCounts();
}
CTreeItem ImportsHandling::addDllToTreeView(CMultiSelectTreeViewCtrl& idTreeView, ImportModuleThunk * moduleThunk)
{
CTreeItem item = idTreeView.InsertItem(L"", NULL, TVI_ROOT);
item.SetData(itemData.size());
TreeItemData data;
data.isModule = true;
data.module = moduleThunk;
setItemData(item, &data);
updateModuleInTreeView(moduleThunk, item);
return item;
}
CTreeItem ImportsHandling::addApiToTreeView(CMultiSelectTreeViewCtrl& idTreeView, CTreeItem parentDll, ImportThunk * importThunk)
{
CTreeItem item = idTreeView.InsertItem(L"", parentDll, TVI_LAST);
item.SetData(itemData.size());
TreeItemData data;
data.isModule = false;
data.import = importThunk;
setItemData(item, &data);
updateImportInTreeView(importThunk, item);
return item;
}
void ImportsHandling::selectImports(bool invalid, bool suspect)
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator it_module;
std::map<DWORD_PTR, ImportThunk>::iterator it_import;
TreeImports.SelectAllItems(FALSE); //remove selection
it_module = moduleList.begin();
while (it_module != moduleList.end())
{
ImportModuleThunk &moduleThunk = it_module->second;
it_import = moduleThunk.thunkList.begin();
while (it_import != moduleThunk.thunkList.end())
{
ImportThunk &importThunk = it_import->second;
if ((invalid && !importThunk.valid) || (suspect && importThunk.suspect))
{
TreeImports.SelectItem(importThunk.hTreeItem, TRUE);
importThunk.hTreeItem.EnsureVisible();
}
it_import++;
}
it_module++;
}
}
bool ImportsHandling::invalidateImport(CTreeItem item)
{
ImportThunk * import = getImportThunk(item);
if(import)
{
CTreeItem parent = item.GetParent();
if(!parent.IsNull())
{
const ImportModuleThunk * module = getModuleThunk(parent);
if(module)
{
import->invalidate();
updateImportInTreeView(import, import->hTreeItem);
updateModuleInTreeView(module, module->hTreeItem);
updateCounts();
return true;
}
}
}
return false;
}
bool ImportsHandling::invalidateModule(CTreeItem item)
{
ImportModuleThunk * module = getModuleThunk(item);
if(module)
{
std::map<DWORD_PTR, ImportThunk>::iterator it_import;
it_import = module->thunkList.begin();
while(it_import != module->thunkList.end())
{
ImportThunk * import = &it_import->second;
import->invalidate();
updateImportInTreeView(import, import->hTreeItem);
it_import++;
}
updateModuleInTreeView(module, module->hTreeItem);
updateCounts();
return true;
}
return false;
}
bool ImportsHandling::setImport(CTreeItem item, const WCHAR * moduleName, const CHAR * apiName, WORD ordinal, WORD hint, bool valid, bool suspect)
{
ImportThunk * import = getImportThunk(item);
if(import)
{
CTreeItem parent = item.GetParent();
if(!parent.IsNull())
{
ImportModuleThunk * module = getModuleThunk(parent);
if(module)
{
wcscpy_s(import->moduleName, moduleName);
strcpy_s(import->name, apiName);
import->ordinal = ordinal;
//import->apiAddressVA = api->va; //??
import->hint = hint;
import->valid = valid;
import->suspect = suspect;
- updateImportInTreeView(import, item);
-
- if (module->isValid() && module->moduleName[0] == L'?')
+ if (module->isValid())
{
- //update module name
- wcscpy_s(module->moduleName, module->thunkList.begin()->second.moduleName);
scanAndFixModuleList();
displayAllImports();
}
else
{
- //updateModuleInTreeView(module, module->hTreeItem);
-
+ updateImportInTreeView(import, item);
updateCounts();
}
-
-
return true;
}
}
}
return false;
}
void ImportsHandling::updateImportInTreeView(const ImportThunk * importThunk, CTreeItem item)
{
if (importThunk->valid)
{
WCHAR tempString[300];
if (importThunk->name[0] != 0x00)
{
swprintf_s(tempString, L"ord: %04X name: %S", importThunk->ordinal, importThunk->name);
}
else
{
swprintf_s(tempString, L"ord: %04X", importThunk->ordinal);
}
swprintf_s(stringBuffer, L" rva: " PRINTF_DWORD_PTR_HALF L" mod: %s %s", importThunk->rva, importThunk->moduleName, tempString);
}
else
{
swprintf_s(stringBuffer, L" rva: " PRINTF_DWORD_PTR_HALF L" ptr: " PRINTF_DWORD_PTR_FULL, importThunk->rva, importThunk->apiAddressVA);
}
item.SetText(stringBuffer);
Icon icon = getAppropiateIcon(importThunk);
item.SetImage(icon, icon);
}
void ImportsHandling::updateModuleInTreeView(const ImportModuleThunk * importThunk, CTreeItem item)
{
swprintf_s(stringBuffer, L"%s (%d) FThunk: " PRINTF_DWORD_PTR_HALF, importThunk->moduleName,importThunk->thunkList.size(), importThunk->firstThunk);
item.SetText(stringBuffer);
Icon icon = getAppropiateIcon(importThunk->isValid());
item.SetImage(icon, icon);
}
ImportsHandling::Icon ImportsHandling::getAppropiateIcon(const ImportThunk * importThunk)
{
if(importThunk->valid)
{
if(importThunk->suspect)
{
return iconWarning;
}
else
{
return iconCheck;
}
}
else
{
return iconError;
}
}
ImportsHandling::Icon ImportsHandling::getAppropiateIcon(bool valid)
{
if(valid)
{
return iconCheck;
}
else
{
return iconError;
}
}
bool ImportsHandling::cutImport(CTreeItem item)
{
ImportThunk * import = getImportThunk(item);
if(import)
{
CTreeItem parent = item.GetParent();
if(!parent.IsNull())
{
ImportModuleThunk * module = getModuleThunk(parent);
if(module)
{
itemData.erase(item);
import->hTreeItem.Delete();
module->thunkList.erase(import->key);
import = 0;
if (module->thunkList.empty())
{
itemData.erase(parent);
module->hTreeItem.Delete();
moduleList.erase(module->key);
module = 0;
}
else
{
if (module->isValid() && module->moduleName[0] == L'?')
{
//update module name
wcscpy_s(module->moduleName, module->thunkList.begin()->second.moduleName);
}
module->firstThunk = module->thunkList.begin()->second.rva;
updateModuleInTreeView(module, module->hTreeItem);
}
updateCounts();
return true;
}
}
}
return false;
}
bool ImportsHandling::cutModule(CTreeItem item)
{
ImportModuleThunk * module = getModuleThunk(item);
if(module)
{
CTreeItem child = item.GetChild();
while(!child.IsNull())
{
itemData.erase(child);
child = child.GetNextSibling();
}
itemData.erase(item);
module->hTreeItem.Delete();
moduleList.erase(module->key);
module = 0;
updateCounts();
return true;
}
return false;
}
DWORD_PTR ImportsHandling::getApiAddressByNode(CTreeItem item)
{
const ImportThunk * import = getImportThunk(item);
if(import)
{
return import->apiAddressVA;
}
return 0;
}
void ImportsHandling::scanAndFixModuleList()
{
+ WCHAR prevModuleName[MAX_PATH] = {0};
std::map<DWORD_PTR, ImportModuleThunk>::iterator it_module;
std::map<DWORD_PTR, ImportThunk>::iterator it_import;
it_module = moduleList.begin();
while (it_module != moduleList.end())
{
ImportModuleThunk &moduleThunk = it_module->second;
it_import = moduleThunk.thunkList.begin();
+
+ ImportThunk * importThunkPrev;
+ importThunkPrev = &it_import->second;
+
while (it_import != moduleThunk.thunkList.end())
{
ImportThunk &importThunk = it_import->second;
if (importThunk.moduleName[0] == 0 || importThunk.moduleName[0] == L'?')
{
addNotFoundApiToModuleList(&importThunk);
}
else
{
- if (isNewModule(importThunk.moduleName))
+
+ if (_wcsicmp(importThunk.moduleName, prevModuleName))
{
addModuleToModuleList(importThunk.moduleName, importThunk.rva);
}
addFunctionToModuleList(&importThunk);
}
+ wcscpy_s(prevModuleName, importThunk.moduleName);
it_import++;
}
moduleThunk.thunkList.clear();
it_module++;
}
moduleList = moduleListNew;
moduleListNew.clear();
}
bool ImportsHandling::findNewModules(std::map<DWORD_PTR, ImportThunk> & thunkList)
{
throw std::exception("The method or operation is not implemented.");
}
bool ImportsHandling::addModuleToModuleList(const WCHAR * moduleName, DWORD_PTR firstThunk)
{
ImportModuleThunk module;
module.firstThunk = firstThunk;
wcscpy_s(module.moduleName, moduleName);
module.key = module.firstThunk;
moduleListNew[module.key] = module;
return true;
}
bool ImportsHandling::isNewModule(const WCHAR * moduleName)
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator it_module;
it_module = moduleListNew.begin();
while (it_module != moduleListNew.end())
{
if (!_wcsicmp(it_module->second.moduleName, moduleName))
{
return false;
}
it_module++;
}
return true;
}
void ImportsHandling::addUnknownModuleToModuleList(DWORD_PTR firstThunk)
{
ImportModuleThunk module;
module.firstThunk = firstThunk;
wcscpy_s(module.moduleName, L"?");
module.key = module.firstThunk;
moduleListNew[module.key] = module;
}
bool ImportsHandling::addNotFoundApiToModuleList(const ImportThunk * apiNotFound)
{
ImportThunk import;
ImportModuleThunk * module = 0;
std::map<DWORD_PTR, ImportModuleThunk>::iterator it_module;
DWORD_PTR rva = apiNotFound->rva;
if (moduleListNew.size() > 0)
{
it_module = moduleListNew.begin();
while (it_module != moduleListNew.end())
{
if (rva >= it_module->second.firstThunk)
{
it_module++;
if (it_module == moduleListNew.end())
{
it_module--;
//new unknown module
if (it_module->second.moduleName[0] == L'?')
{
module = &(it_module->second);
}
else
{
addUnknownModuleToModuleList(apiNotFound->rva);
module = &(moduleListNew.find(rva)->second);
}
break;
}
else if (rva < it_module->second.firstThunk)
{
it_module--;
module = &(it_module->second);
break;
}
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"Error iterator1 != (*moduleThunkList).end()");
#endif
break;
}
}
}
else
{
//new unknown module
addUnknownModuleToModuleList(apiNotFound->rva);
module = &(moduleListNew.find(rva)->second);
}
if (!module)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"ImportsHandling::addFunction module not found rva " PRINTF_DWORD_PTR_FULL, rva);
#endif
return false;
}
import.suspect = true;
import.valid = false;
import.va = apiNotFound->va;
import.rva = apiNotFound->rva;
import.apiAddressVA = apiNotFound->apiAddressVA;
import.ordinal = 0;
wcscpy_s(import.moduleName, L"?");
strcpy_s(import.name, "?");
import.key = import.rva;
module->thunkList[import.key] = import;
return true;
}
bool ImportsHandling::addFunctionToModuleList(const ImportThunk * apiFound)
{
ImportThunk import;
ImportModuleThunk * module = 0;
std::map<DWORD_PTR, ImportModuleThunk>::iterator it_module;
if (moduleListNew.size() > 1)
{
it_module = moduleListNew.begin();
while (it_module != moduleListNew.end())
{
if (apiFound->rva >= it_module->second.firstThunk)
{
it_module++;
if (it_module == moduleListNew.end())
{
it_module--;
module = &(it_module->second);
break;
}
else if (apiFound->rva < it_module->second.firstThunk)
{
it_module--;
module = &(it_module->second);
break;
}
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"Error iterator1 != moduleListNew.end()");
#endif
break;
}
}
}
else
{
it_module = moduleListNew.begin();
module = &(it_module->second);
}
if (!module)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"ImportsHandling::addFunction module not found rva " PRINTF_DWORD_PTR_FULL, apiFound->rva);
#endif
return false;
}
import.suspect = apiFound->suspect;
import.valid = apiFound->valid;
import.va = apiFound->va;
import.rva = apiFound->rva;
import.apiAddressVA = apiFound->apiAddressVA;
import.ordinal = apiFound->ordinal;
import.hint = apiFound->hint;
wcscpy_s(import.moduleName, apiFound->moduleName);
strcpy_s(import.name, apiFound->name);
import.key = import.rva;
module->thunkList[import.key] = import;
return true;
}
void ImportsHandling::expandAllTreeNodes()
{
changeExpandStateOfTreeNodes(TVE_EXPAND);
}
void ImportsHandling::collapseAllTreeNodes()
{
changeExpandStateOfTreeNodes(TVE_COLLAPSE);
}
void ImportsHandling::changeExpandStateOfTreeNodes(UINT flag)
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator it_module;
it_module = moduleList.begin();
while (it_module != moduleList.end())
{
ImportModuleThunk &moduleThunk = it_module->second;
moduleThunk.hTreeItem.Expand(flag);
it_module++;
}
}
diff --git a/Scylla/MainGui.cpp b/Scylla/MainGui.cpp
index 07c44f3..aff604d 100644
--- a/Scylla/MainGui.cpp
+++ b/Scylla/MainGui.cpp
@@ -1,1716 +1,1717 @@
#include "MainGui.h"
#include "Architecture.h"
//#include "PluginLoader.h"
//#include "ConfigurationHolder.h"
#include "PeParser.h"
#include "DllInjectionPlugin.h"
#include "DisassemblerGui.h"
#include "PickApiGui.h"
//#include "NativeWinApi.h"
#include "ImportRebuilder.h"
#include "SystemInformation.h"
#include "Scylla.h"
#include "AboutGui.h"
#include "DonateGui.h"
#include "OptionsGui.h"
#include "TreeImportExport.h"
extern CAppModule _Module; // o_O
const WCHAR MainGui::filterExe[] = L"Executable (*.exe)\0*.exe\0All files\0*.*\0";
const WCHAR MainGui::filterDll[] = L"Dynamic Link Library (*.dll)\0*.dll\0All files\0*.*\0";
const WCHAR MainGui::filterExeDll[] = L"Executable (*.exe)\0*.exe\0Dynamic Link Library (*.dll)\0*.dll\0All files\0*.*\0";
const WCHAR MainGui::filterTxt[] = L"Text file (*.txt)\0*.txt\0All files\0*.*\0";
const WCHAR MainGui::filterXml[] = L"XML file (*.xml)\0*.xml\0All files\0*.*\0";
const WCHAR MainGui::filterMem[] = L"MEM file (*.mem)\0*.mem\0All files\0*.*\0";
MainGui::MainGui() : selectedProcess(0), isProcessSuspended(false), importsHandling(TreeImports), TreeImportsSubclass(this, IDC_TREE_IMPORTS)
{
/*
Logger::getDebugLogFilePath();
ConfigurationHolder::loadConfiguration();
PluginLoader::findAllPlugins();
NativeWinApi::initialize();
SystemInformation::getSystemInformation();
if(ConfigurationHolder::getConfigObject(DEBUG_PRIVILEGE)->isTrue())
{
processLister.setDebugPrivileges();
}
ProcessAccessHelp::getProcessModules(GetCurrentProcessId(), ProcessAccessHelp::ownModuleList);
*/
hIcon.LoadIcon(IDI_ICON_SCYLLA);
hMenuImports.LoadMenu(IDR_MENU_IMPORTS);
hMenuLog.LoadMenu(IDR_MENU_LOG);
accelerators.LoadAccelerators(IDR_ACCELERATOR_MAIN);
hIconCheck.LoadIcon(IDI_ICON_CHECK, 16, 16);
hIconWarning.LoadIcon(IDI_ICON_WARNING, 16, 16);
hIconError.LoadIcon(IDI_ICON_ERROR, 16, 16);
}
BOOL MainGui::PreTranslateMessage(MSG* pMsg)
{
if(accelerators.TranslateAccelerator(m_hWnd, pMsg))
{
return TRUE; // handled keyboard shortcuts
}
else if(IsDialogMessage(pMsg))
{
return TRUE; // handled dialog messages
}
return FALSE;
}
void MainGui::InitDllStartWithPreSelect( PGUI_DLL_PARAMETER guiParam )
{
ComboProcessList.ResetContent();
std::vector<Process>& processList = Scylla::processLister.getProcessListSnapshotNative();
int newSel = -1;
for (size_t i = 0; i < processList.size(); i++)
{
if (processList[i].PID == guiParam->dwProcessId)
newSel = (int)i;
swprintf_s(stringBuffer, L"%04d - %s - %s", processList[i].PID, processList[i].filename, processList[i].fullPath);
ComboProcessList.AddString(stringBuffer);
}
if (newSel != -1)
{
ComboProcessList.SetCurSel(newSel);
processSelectedActionHandler(newSel);
if (guiParam->mod) //init mod
{
//select DLL
size_t len = ProcessAccessHelp::moduleList.size();
newSel = -1;
for (size_t i = 0; i < len; i++)
{
if (ProcessAccessHelp::moduleList.at(i).modBaseAddr == (DWORD_PTR)guiParam->mod)
{
newSel = (int)i;
break;
}
}
if (newSel != -1)
{
//get selected module
ProcessAccessHelp::selectedModule = &ProcessAccessHelp::moduleList.at(newSel);
ProcessAccessHelp::targetImageBase = ProcessAccessHelp::selectedModule->modBaseAddr;
ProcessAccessHelp::targetSizeOfImage = ProcessAccessHelp::selectedModule->modBaseSize;
DWORD modEntryPoint = ProcessAccessHelp::getEntryPointFromFile(ProcessAccessHelp::selectedModule->fullPath);
EditOEPAddress.SetValue(modEntryPoint + ProcessAccessHelp::targetImageBase);
Scylla::windowLog.log(L"->>> Module %s selected.", ProcessAccessHelp::selectedModule->getFilename());
Scylla::windowLog.log(L"Imagebase: " PRINTF_DWORD_PTR_FULL L" Size: %08X EntryPoint: %08X", ProcessAccessHelp::selectedModule->modBaseAddr, ProcessAccessHelp::selectedModule->modBaseSize, modEntryPoint);
}
}
}
}
BOOL MainGui::OnInitDialog(CWindow wndFocus, LPARAM lInitParam)
{
if (SystemInformation::currenOS == UNKNOWN_OS)
{
if(IDCANCEL == MessageBox(L"Operating System is not supported\r\nContinue anyway?", L"Scylla", MB_ICONWARNING | MB_OKCANCEL))
{
SendMessage(WM_CLOSE);
return FALSE;
}
}
// register ourselves to receive PreTranslateMessage
CMessageLoop* pLoop = _Module.GetMessageLoop();
pLoop->AddMessageFilter(this);
setupStatusBar();
DoDataExchange(); // attach controls
DlgResize_Init(true, true); // init CDialogResize
Scylla::windowLog.setWindow(ListLog);
appendPluginListToMenu(hMenuImports.GetSubMenu(0));
appendPluginListToMenu(CMenuHandle(GetMenu()).GetSubMenu(MenuImportsOffsetTrace));
enableDialogControls(FALSE);
setIconAndDialogCaption();
if (lInitParam)
{
InitDllStartWithPreSelect((PGUI_DLL_PARAMETER)lInitParam);
}
return TRUE;
}
void MainGui::OnDestroy()
{
PostQuitMessage(0);
}
void MainGui::OnSize(UINT nType, CSize size)
{
StatusBar.SendMessage(WM_SIZE);
SetMsgHandled(FALSE);
}
void MainGui::OnContextMenu(CWindow wnd, CPoint point)
{
switch(wnd.GetDlgCtrlID())
{
case IDC_TREE_IMPORTS:
DisplayContextMenuImports(wnd, point);
return;
case IDC_LIST_LOG:
DisplayContextMenuLog(wnd, point);
return;
}
SetMsgHandled(FALSE);
}
void MainGui::OnCommand(UINT uNotifyCode, int nID, CWindow wndCtl)
{
// Handle plugin trace menu selection
if(uNotifyCode == 0 && !wndCtl.IsWindow()) // make sure it's a menu
{
if ((nID >= PLUGIN_MENU_BASE_ID) && (nID <= (int)(Scylla::plugins.getScyllaPluginList().size() + Scylla::plugins.getImprecPluginList().size() + PLUGIN_MENU_BASE_ID)))
{
pluginActionHandler(nID);
return;
}
}
SetMsgHandled(FALSE);
}
LRESULT MainGui::OnTreeImportsDoubleClick(const NMHDR* pnmh)
{
if(TreeImports.GetCount() < 1)
return 0;
// Get item under cursor
CTreeItem over = findTreeItem(CPoint(GetMessagePos()), true);
if(over && importsHandling.isImport(over))
{
pickApiActionHandler(over);
}
return 0;
}
LRESULT MainGui::OnTreeImportsKeyDown(const NMHDR* pnmh)
{
const NMTVKEYDOWN * tkd = (NMTVKEYDOWN *)pnmh;
switch(tkd->wVKey)
{
case VK_RETURN:
{
CTreeItem selected = TreeImports.GetFocusItem();
if(!selected.IsNull() && importsHandling.isImport(selected))
{
pickApiActionHandler(selected);
}
}
return 1;
case VK_DELETE:
deleteSelectedImportsActionHandler();
return 1;
}
SetMsgHandled(FALSE);
return 0;
}
UINT MainGui::OnTreeImportsSubclassGetDlgCode(const MSG * lpMsg)
{
if(lpMsg)
{
switch(lpMsg->wParam)
{
case VK_RETURN:
return DLGC_WANTMESSAGE;
}
}
SetMsgHandled(FALSE);
return 0;
}
void MainGui::OnTreeImportsSubclassChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
switch(nChar)
{
case VK_RETURN:
break;
default:
SetMsgHandled(FALSE);
break;
}
}
void MainGui::OnProcessListDrop(UINT uNotifyCode, int nID, CWindow wndCtl)
{
fillProcessListComboBox(ComboProcessList);
}
void MainGui::OnProcessListSelected(UINT uNotifyCode, int nID, CWindow wndCtl)
{
int index = ComboProcessList.GetCurSel();
if (index != CB_ERR)
{
processSelectedActionHandler(index);
}
}
void MainGui::OnPickDLL(UINT uNotifyCode, int nID, CWindow wndCtl)
{
pickDllActionHandler();
}
void MainGui::OnOptions(UINT uNotifyCode, int nID, CWindow wndCtl)
{
optionsActionHandler();
}
void MainGui::OnDump(UINT uNotifyCode, int nID, CWindow wndCtl)
{
dumpActionHandler();
}
void MainGui::OnDumpMemory(UINT uNotifyCode, int nID, CWindow wndCtl)
{
dumpMemoryActionHandler();
}
void MainGui::OnDumpSection(UINT uNotifyCode, int nID, CWindow wndCtl)
{
dumpSectionActionHandler();
}
void MainGui::OnFixDump(UINT uNotifyCode, int nID, CWindow wndCtl)
{
dumpFixActionHandler();
}
void MainGui::OnPERebuild(UINT uNotifyCode, int nID, CWindow wndCtl)
{
peRebuildActionHandler();
}
void MainGui::OnDLLInject(UINT uNotifyCode, int nID, CWindow wndCtl)
{
dllInjectActionHandler();
}
void MainGui::OnDisassembler(UINT uNotifyCode, int nID, CWindow wndCtl)
{
disassemblerActionHandler();
}
void MainGui::OnIATAutoSearch(UINT uNotifyCode, int nID, CWindow wndCtl)
{
iatAutosearchActionHandler();
}
void MainGui::OnGetImports(UINT uNotifyCode, int nID, CWindow wndCtl)
{
getImportsActionHandler();
}
void MainGui::OnInvalidImports(UINT uNotifyCode, int nID, CWindow wndCtl)
{
showInvalidImportsActionHandler();
}
void MainGui::OnSuspectImports(UINT uNotifyCode, int nID, CWindow wndCtl)
{
showSuspectImportsActionHandler();
}
void MainGui::OnClearImports(UINT uNotifyCode, int nID, CWindow wndCtl)
{
clearImportsActionHandler();
}
void MainGui::OnInvalidateSelected(UINT uNotifyCode, int nID, CWindow wndCtl)
{
invalidateSelectedImportsActionHandler();
}
void MainGui::OnCutSelected(UINT uNotifyCode, int nID, CWindow wndCtl)
{
deleteSelectedImportsActionHandler();
}
void MainGui::OnSaveTree(UINT uNotifyCode, int nID, CWindow wndCtl)
{
saveTreeActionHandler();
}
void MainGui::OnLoadTree(UINT uNotifyCode, int nID, CWindow wndCtl)
{
loadTreeActionHandler();
}
void MainGui::OnAutotrace(UINT uNotifyCode, int nID, CWindow wndCtl)
{
// TODO
}
void MainGui::OnExit(UINT uNotifyCode, int nID, CWindow wndCtl)
{
if (isProcessSuspended)
{
int msgboxID = MessageBox(L"Process is suspended. Do you want to terminate the process?\r\n\r\nYES = Terminate Process\r\nNO = Try to resume the process\r\nCancel = Do nothing", L"Information", MB_YESNOCANCEL|MB_ICONINFORMATION);
switch (msgboxID)
{
case IDYES:
ProcessAccessHelp::terminateProcess();
break;
case IDNO:
ProcessAccessHelp::resumeProcess();
break;
default:
break;
}
}
DestroyWindow();
}
void MainGui::OnAbout(UINT uNotifyCode, int nID, CWindow wndCtl)
{
showAboutDialog();
}
void MainGui::OnDonate(UINT uNotifyCode, int nID, CWindow wndCtl)
{
showDonateDialog();
}
void MainGui::setupStatusBar()
{
StatusBar.Create(m_hWnd, NULL, L"", WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_TOOLTIPS, NULL, IDC_STATUS_BAR);
CRect rcMain, rcStatus;
GetClientRect(&rcMain);
StatusBar.GetWindowRect(&rcStatus);
const int PARTS = 4;
int widths[PARTS];
widths[PART_COUNT] = rcMain.Width() / 5;
widths[PART_INVALID] = widths[PART_COUNT] + rcMain.Width() / 5;
widths[PART_IMAGEBASE] = widths[PART_INVALID] + rcMain.Width() / 3;
widths[PART_MODULE] = -1;
StatusBar.SetParts(PARTS, widths);
ResizeClient(rcMain.Width(), rcMain.Height() + rcStatus.Height(), FALSE);
}
void MainGui::updateStatusBar()
{
// Rewrite ImportsHandling so we get these easily
unsigned int totalImports = importsHandling.thunkCount();
unsigned int invalidImports = importsHandling.invalidThunkCount();
// \t = center, \t\t = right-align
swprintf_s(stringBuffer, L"\tImports: %u", totalImports);
StatusBar.SetText(PART_COUNT, stringBuffer);
if(invalidImports > 0)
{
StatusBar.SetIcon(PART_INVALID, hIconError);
}
else
{
StatusBar.SetIcon(PART_INVALID, hIconCheck);
}
swprintf_s(stringBuffer, L"\tInvalid: %u", invalidImports);
StatusBar.SetText(PART_INVALID, stringBuffer);
if(selectedProcess)
{
DWORD_PTR imageBase = 0;
const WCHAR * fileName = 0;
if(ProcessAccessHelp::selectedModule)
{
imageBase = ProcessAccessHelp::selectedModule->modBaseAddr;
fileName = ProcessAccessHelp::selectedModule->getFilename();
}
else
{
imageBase = selectedProcess->imageBase;
fileName = selectedProcess->filename;
}
swprintf_s(stringBuffer, L"\tImagebase: " PRINTF_DWORD_PTR_FULL, imageBase);
StatusBar.SetText(PART_IMAGEBASE, stringBuffer);
StatusBar.SetText(PART_MODULE, fileName);
StatusBar.SetTipText(PART_MODULE, fileName);
}
else
{
StatusBar.SetText(PART_IMAGEBASE, L"");
StatusBar.SetText(PART_MODULE, L"");
}
}
bool MainGui::showFileDialog(WCHAR * selectedFile, bool save, const WCHAR * defFileName, const WCHAR * filter, const WCHAR * defExtension, const WCHAR * directory)
{
OPENFILENAME ofn = {0};
// WTL doesn't support new explorer styles on Vista and up
// This is because it uses a custom hook, we could remove it or derive
// from CFileDialog but this solution is easier and allows more control anyway (e.g. initial dir)
if(defFileName)
{
wcscpy_s(selectedFile, MAX_PATH, defFileName);
}
else
{
selectedFile[0] = L'\0';
}
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = m_hWnd;
ofn.lpstrFilter = filter;
ofn.lpstrDefExt = defExtension; // only first 3 chars are used, no dots!
ofn.lpstrFile = selectedFile;
ofn.lpstrInitialDir = directory;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
/*
*OFN_EXPLORER is automatically used, it only has to be specified
*if using a custom hook
*OFN_LONGNAMES is automatically used by explorer-style dialogs
*/
if(save)
ofn.Flags |= OFN_OVERWRITEPROMPT;
else
ofn.Flags |= OFN_FILEMUSTEXIST;
if(save)
return 0 != GetSaveFileName(&ofn);
else
return 0 != GetOpenFileName(&ofn);
}
void MainGui::setIconAndDialogCaption()
{
SetIcon(hIcon, TRUE);
SetIcon(hIcon, FALSE);
SetWindowText(APPNAME L" " ARCHITECTURE L" " APPVERSION);
}
void MainGui::pickDllActionHandler()
{
if(!selectedProcess)
return;
PickDllGui dlgPickDll(ProcessAccessHelp::moduleList);
if(dlgPickDll.DoModal())
{
//get selected module
ProcessAccessHelp::selectedModule = dlgPickDll.getSelectedModule();
ProcessAccessHelp::targetImageBase = ProcessAccessHelp::selectedModule->modBaseAddr;
ProcessAccessHelp::targetSizeOfImage = ProcessAccessHelp::selectedModule->modBaseSize;
DWORD modEntryPoint = ProcessAccessHelp::getEntryPointFromFile(ProcessAccessHelp::selectedModule->fullPath);
EditOEPAddress.SetValue(modEntryPoint + ProcessAccessHelp::targetImageBase);
Scylla::windowLog.log(L"->>> Module %s selected.", ProcessAccessHelp::selectedModule->getFilename());
Scylla::windowLog.log(L"Imagebase: " PRINTF_DWORD_PTR_FULL L" Size: %08X EntryPoint: %08X", ProcessAccessHelp::selectedModule->modBaseAddr, ProcessAccessHelp::selectedModule->modBaseSize, modEntryPoint);
}
else
{
ProcessAccessHelp::selectedModule = 0;
}
updateStatusBar();
}
void MainGui::pickApiActionHandler(CTreeItem item)
{
if(!importsHandling.isImport(item))
return;
// TODO: new node when user picked an API from another DLL?
PickApiGui dlgPickApi(ProcessAccessHelp::moduleList);
if(dlgPickApi.DoModal())
{
const ApiInfo* api = dlgPickApi.getSelectedApi();
if(api && api->module)
{
importsHandling.setImport(item, api->module->getFilename(), api->name, api->ordinal, api->hint, true, api->isForwarded);
}
}
updateStatusBar();
}
void MainGui::startDisassemblerGui(CTreeItem selectedTreeNode)
{
if(!selectedProcess)
return;
DWORD_PTR address = importsHandling.getApiAddressByNode(selectedTreeNode);
if (address)
{
BYTE test;
if(!ProcessAccessHelp::readMemoryFromProcess(address, sizeof(test), &test))
{
swprintf_s(stringBuffer, L"Can't read memory at " PRINTF_DWORD_PTR_FULL, address);
MessageBox(stringBuffer, L"Failure", MB_ICONERROR);
}
else
{
DisassemblerGui dlgDisassembler(address, &apiReader);
dlgDisassembler.DoModal();
}
}
}
void MainGui::processSelectedActionHandler(int index)
{
std::vector<Process>& processList = Scylla::processLister.getProcessList();
Process &process = processList.at(index);
selectedProcess = 0;
clearImportsActionHandler();
Scylla::windowLog.log(L"Analyzing %s", process.fullPath);
if (ProcessAccessHelp::hProcess != 0)
{
ProcessAccessHelp::closeProcessHandle();
apiReader.clearAll();
}
if (!ProcessAccessHelp::openProcessHandle(process.PID))
{
enableDialogControls(FALSE);
Scylla::windowLog.log(L"Error: Cannot open process handle.");
updateStatusBar();
return;
}
ProcessAccessHelp::getProcessModules(ProcessAccessHelp::hProcess, ProcessAccessHelp::moduleList);
apiReader.readApisFromModuleList();
Scylla::windowLog.log(L"Loading modules done.");
//TODO improve
ProcessAccessHelp::selectedModule = 0;
ProcessAccessHelp::targetImageBase = process.imageBase;
ProcessAccessHelp::targetSizeOfImage = process.imageSize;
process.imageSize = (DWORD)ProcessAccessHelp::targetSizeOfImage;
Scylla::windowLog.log(L"Imagebase: " PRINTF_DWORD_PTR_FULL L" Size: %08X", process.imageBase, process.imageSize);
process.entryPoint = ProcessAccessHelp::getEntryPointFromFile(process.fullPath);
EditOEPAddress.SetValue(process.entryPoint + process.imageBase);
selectedProcess = &process;
enableDialogControls(TRUE);
updateStatusBar();
}
void MainGui::fillProcessListComboBox(CComboBox& hCombo)
{
hCombo.ResetContent();
std::vector<Process>& processList = Scylla::processLister.getProcessListSnapshotNative();
for (size_t i = 0; i < processList.size(); i++)
{
swprintf_s(stringBuffer, L"%04d - %s - %s", processList[i].PID, processList[i].filename, processList[i].fullPath);
hCombo.AddString(stringBuffer);
}
}
/*
void MainGui::addTextToOutputLog(const WCHAR * text)
{
if (m_hWnd)
{
ListLog.SetCurSel(ListLog.AddString(text));
}
}
*/
void MainGui::clearOutputLog()
{
if (m_hWnd)
{
ListLog.ResetContent();
}
}
bool MainGui::saveLogToFile(const WCHAR * file)
{
const BYTE BOM[] = {0xFF, 0xFE}; // UTF-16 little-endian
const WCHAR newLine[] = L"\r\n";
bool success = true;
HANDLE hFile = CreateFile(file, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if(hFile != INVALID_HANDLE_VALUE)
{
ProcessAccessHelp::writeMemoryToFileEnd(hFile, sizeof(BOM), BOM);
WCHAR * buffer = 0;
size_t bufsize = 0;
for(int i = 0; i < ListLog.GetCount(); i++)
{
size_t size = ListLog.GetTextLen(i);
size += _countof(newLine)-1;
if(size+1 > bufsize)
{
bufsize = size+1;
delete[] buffer;
try
{
buffer = new WCHAR[bufsize];
}
catch(std::bad_alloc&)
{
buffer = 0;
success = false;
break;
}
}
ListLog.GetText(i, buffer);
wcscat_s(buffer, bufsize, newLine);
ProcessAccessHelp::writeMemoryToFileEnd(hFile, (DWORD)(size * sizeof(WCHAR)), buffer);
}
delete[] buffer;
CloseHandle(hFile);
}
return success;
}
void MainGui::showInvalidImportsActionHandler()
{
importsHandling.selectImports(true, false);
GotoDlgCtrl(TreeImports);
}
void MainGui::showSuspectImportsActionHandler()
{
importsHandling.selectImports(false, true);
GotoDlgCtrl(TreeImports);
}
void MainGui::deleteSelectedImportsActionHandler()
{
CTreeItem selected = TreeImports.GetFirstSelectedItem();
while(!selected.IsNull())
{
if(importsHandling.isModule(selected))
{
importsHandling.cutModule(selected);
}
else
{
importsHandling.cutImport(selected);
}
selected = TreeImports.GetNextSelectedItem(selected);
}
updateStatusBar();
}
void MainGui::invalidateSelectedImportsActionHandler()
{
CTreeItem selected = TreeImports.GetFirstSelectedItem();
while(!selected.IsNull())
{
if(importsHandling.isImport(selected))
{
importsHandling.invalidateImport(selected);
}
selected = TreeImports.GetNextSelectedItem(selected);
}
updateStatusBar();
}
void MainGui::loadTreeActionHandler()
{
if(!selectedProcess)
return;
WCHAR selectedFilePath[MAX_PATH];
getCurrentModulePath(stringBuffer, _countof(stringBuffer));
if(showFileDialog(selectedFilePath, false, NULL, filterXml, NULL, stringBuffer))
{
TreeImportExport treeIO(selectedFilePath);
DWORD_PTR addrOEP = 0;
DWORD_PTR addrIAT = 0;
DWORD sizeIAT = 0;
if(!treeIO.importTreeList(importsHandling.moduleList, &addrOEP, &addrIAT, &sizeIAT))
{
Scylla::windowLog.log(L"Loading tree file failed %s", selectedFilePath);
MessageBox(L"Loading tree file failed.", L"Failure", MB_ICONERROR);
}
else
{
EditOEPAddress.SetValue(addrOEP);
EditIATAddress.SetValue(addrIAT);
EditIATSize.SetValue(sizeIAT);
importsHandling.displayAllImports();
updateStatusBar();
Scylla::windowLog.log(L"Loaded tree file %s", selectedFilePath);
Scylla::windowLog.log(L"-> OEP: " PRINTF_DWORD_PTR_FULL, addrOEP);
Scylla::windowLog.log(L"-> IAT: " PRINTF_DWORD_PTR_FULL L" Size: " PRINTF_DWORD_PTR, addrIAT, sizeIAT);
}
}
}
void MainGui::saveTreeActionHandler()
{
if(!selectedProcess)
return;
WCHAR selectedFilePath[MAX_PATH];
getCurrentModulePath(stringBuffer, _countof(stringBuffer));
if(showFileDialog(selectedFilePath, true, NULL, filterXml, L"xml", stringBuffer))
{
TreeImportExport treeIO(selectedFilePath);
DWORD_PTR addrOEP = EditOEPAddress.GetValue();
DWORD_PTR addrIAT = EditIATAddress.GetValue();
DWORD sizeIAT = EditIATSize.GetValue();
if(!treeIO.exportTreeList(importsHandling.moduleList, selectedProcess, addrOEP, addrIAT, sizeIAT))
{
Scylla::windowLog.log(L"Saving tree file failed %s", selectedFilePath);
MessageBox(L"Saving tree file failed.", L"Failure", MB_ICONERROR);
}
else
{
Scylla::windowLog.log(L"Saved tree file %s", selectedFilePath);
}
}
}
void MainGui::iatAutosearchActionHandler()
{
DWORD_PTR searchAddress = 0;
DWORD_PTR addressIAT = 0, addressIATAdv = 0;
DWORD sizeIAT = 0, sizeIATAdv = 0;
IATSearch iatSearch;
if(!selectedProcess)
return;
if(EditOEPAddress.GetWindowTextLength() > 0)
{
searchAddress = EditOEPAddress.GetValue();
if (searchAddress)
{
if (Scylla::config[USE_ADVANCED_IAT_SEARCH].isTrue())
{
if (iatSearch.searchImportAddressTableInProcess(searchAddress, &addressIATAdv, &sizeIATAdv, true))
{
Scylla::windowLog.log(L"IAT Search Adv: IAT VA " PRINTF_DWORD_PTR_FULL L" RVA " PRINTF_DWORD_PTR_FULL L" Size 0x%04X (%d)", addressIATAdv, addressIATAdv - ProcessAccessHelp::targetImageBase, sizeIATAdv, sizeIATAdv);
}
else
{
Scylla::windowLog.log(L"IAT Search Adv: IAT not found at OEP " PRINTF_DWORD_PTR_FULL L"!", searchAddress);
}
}
if (iatSearch.searchImportAddressTableInProcess(searchAddress, &addressIAT, &sizeIAT, false))
{
Scylla::windowLog.log(L"IAT Search Nor: IAT VA " PRINTF_DWORD_PTR_FULL L" RVA " PRINTF_DWORD_PTR_FULL L" Size 0x%04X (%d)", addressIAT, addressIAT - ProcessAccessHelp::targetImageBase, sizeIAT, sizeIAT);
}
else
{
Scylla::windowLog.log(L"IAT Search Nor: IAT not found at OEP " PRINTF_DWORD_PTR_FULL L"!", searchAddress);
}
if (addressIAT != 0 && addressIATAdv == 0)
{
setDialogIATAddressAndSize(addressIAT, sizeIAT);
}
else if (addressIAT == 0 && addressIATAdv != 0)
{
setDialogIATAddressAndSize(addressIATAdv, sizeIATAdv);
}
else if (addressIAT != 0 && addressIATAdv != 0)
{
if (addressIATAdv != addressIAT || sizeIAT != sizeIATAdv)
{
int msgboxID = MessageBox(L"Result of advanced and normal search is different. Do you want to use the IAT Search Advanced result?", L"Information", MB_YESNO|MB_ICONINFORMATION);
if (msgboxID == IDYES)
{
setDialogIATAddressAndSize(addressIATAdv, sizeIATAdv);
}
else
{
setDialogIATAddressAndSize(addressIAT, sizeIAT);
}
}
else
{
setDialogIATAddressAndSize(addressIAT, sizeIAT);
}
}
}
}
}
void MainGui::getImportsActionHandler()
{
if(!selectedProcess)
return;
DWORD_PTR addressIAT = EditIATAddress.GetValue();
DWORD sizeIAT = EditIATSize.GetValue();
if (addressIAT && sizeIAT)
{
apiReader.readAndParseIAT(addressIAT, sizeIAT, importsHandling.moduleList);
+ importsHandling.scanAndFixModuleList();
importsHandling.displayAllImports();
updateStatusBar();
if (Scylla::config[SCAN_DIRECT_IMPORTS].isTrue())
{
iatReferenceScan.ScanForDirectImports = true;
iatReferenceScan.ScanForNormalImports = false;
iatReferenceScan.apiReader = &apiReader;
iatReferenceScan.startScan(ProcessAccessHelp::targetImageBase, (DWORD)ProcessAccessHelp::targetSizeOfImage, addressIAT, sizeIAT);
Scylla::windowLog.log(L"DIRECT IMPORTS - Found %d possible direct imports with %d unique APIs!", iatReferenceScan.numberOfFoundDirectImports(), iatReferenceScan.numberOfFoundUniqueDirectImports());
if (iatReferenceScan.numberOfFoundDirectImports() > 0)
{
if (iatReferenceScan.numberOfDirectImportApisNotInIat() > 0)
{
Scylla::windowLog.log(L"DIRECT IMPORTS - Found %d additional api addresses!", iatReferenceScan.numberOfDirectImportApisNotInIat());
DWORD sizeIatNew = iatReferenceScan.addAdditionalApisToList();
Scylla::windowLog.log(L"DIRECT IMPORTS - Old IAT size 0x%08X new IAT size 0x%08X!", sizeIAT, sizeIatNew);
EditIATSize.SetValue(sizeIatNew);
importsHandling.scanAndFixModuleList();
importsHandling.displayAllImports();
}
iatReferenceScan.printDirectImportLog();
if (Scylla::config[FIX_DIRECT_IMPORTS_NORMAL].isTrue() && (Scylla::config[FIX_DIRECT_IMPORTS_UNIVERSAL].isTrue() == false))
{
int msgboxID = MessageBox(L"Direct Imports found. I can patch only direct imports by JMP/CALL (use universal method if you don't like this) but where is the junk byte?\r\n\r\nYES = After Instruction\r\nNO = Before the Instruction\r\nCancel = Do nothing", L"Information", MB_YESNOCANCEL|MB_ICONINFORMATION);
if (msgboxID != IDCANCEL)
{
bool isAfter;
if (msgboxID == IDYES)
{
isAfter = true;
}
else
{
isAfter = false;
}
iatReferenceScan.patchDirectImportsMemory(isAfter);
Scylla::windowLog.log(L"DIRECT IMPORTS - Patched! Please dump target.");
}
}
}
}
if (isIATOutsidePeImage(addressIAT))
{
Scylla::windowLog.log(L"WARNING! IAT is not inside the PE image, requires rebasing!");
}
}
}
void MainGui::SetupImportsMenuItems(CTreeItem item)
{
bool isItem, isImport = false;
isItem = !item.IsNull();
if(isItem)
{
isImport = importsHandling.isImport(item);
}
CMenuHandle hSub = hMenuImports.GetSubMenu(0);
UINT itemOnly = isItem ? MF_ENABLED : MF_GRAYED;
UINT importOnly = isImport ? MF_ENABLED : MF_GRAYED;
hSub.EnableMenuItem(ID__INVALIDATE, itemOnly);
hSub.EnableMenuItem(ID__DISASSEMBLE, importOnly);
hSub.EnableMenuItem(ID__CUTTHUNK, importOnly);
hSub.EnableMenuItem(ID__DELETETREENODE, itemOnly);
}
void MainGui::DisplayContextMenuImports(CWindow hwnd, CPoint pt)
{
if(TreeImports.GetCount() < 1)
return;
CTreeItem over, parent;
if(pt.x == -1 && pt.y == -1) // invoked by keyboard
{
CRect pos;
over = TreeImports.GetFocusItem();
if(over)
{
over.EnsureVisible();
over.GetRect(&pos, TRUE);
TreeImports.ClientToScreen(&pos);
}
else
{
TreeImports.GetWindowRect(&pos);
}
pt = pos.TopLeft();
}
else
{
// Get item under cursor
over = findTreeItem(pt, true);
}
SetupImportsMenuItems(over);
CMenuHandle hSub = hMenuImports.GetSubMenu(0);
BOOL menuItem = hSub.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, hwnd);
if (menuItem)
{
if ((menuItem >= PLUGIN_MENU_BASE_ID) && (menuItem <= (int)(Scylla::plugins.getScyllaPluginList().size() + Scylla::plugins.getImprecPluginList().size() + PLUGIN_MENU_BASE_ID)))
{
//wsprintf(stringBuffer, L"%d %s\n",menuItem,pluginList[menuItem - PLUGIN_MENU_BASE_ID].pluginName);
//MessageBox(stringBuffer, L"plugin selection");
pluginActionHandler(menuItem);
return;
}
switch (menuItem)
{
case ID__INVALIDATE:
if(importsHandling.isModule(over))
importsHandling.invalidateModule(over);
else
importsHandling.invalidateImport(over);
break;
case ID__DISASSEMBLE:
startDisassemblerGui(over);
break;
case ID__EXPANDALLNODES:
importsHandling.expandAllTreeNodes();
break;
case ID__COLLAPSEALLNODES:
importsHandling.collapseAllTreeNodes();
break;
case ID__CUTTHUNK:
importsHandling.cutImport(over);
break;
case ID__DELETETREENODE:
importsHandling.cutModule(importsHandling.isImport(over) ? over.GetParent() : over);
break;
}
}
updateStatusBar();
}
void MainGui::DisplayContextMenuLog(CWindow hwnd, CPoint pt)
{
if(pt.x == -1 && pt.y == -1) // invoked by keyboard
{
CRect pos;
ListLog.GetWindowRect(&pos);
pt = pos.TopLeft();
}
CMenuHandle hSub = hMenuLog.GetSubMenu(0);
BOOL menuItem = hSub.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, hwnd);
if (menuItem)
{
switch (menuItem)
{
case ID__SAVE:
WCHAR selectedFilePath[MAX_PATH];
getCurrentModulePath(stringBuffer, _countof(stringBuffer));
if(showFileDialog(selectedFilePath, true, NULL, filterTxt, L"txt", stringBuffer))
{
saveLogToFile(selectedFilePath);
}
break;
case ID__CLEAR:
clearOutputLog();
break;
}
}
}
void MainGui::appendPluginListToMenu(CMenuHandle hMenu)
{
std::vector<Plugin> &scyllaPluginList = Scylla::plugins.getScyllaPluginList();
std::vector<Plugin> &imprecPluginList = Scylla::plugins.getImprecPluginList();
if (scyllaPluginList.size() > 0)
{
CMenuHandle newMenu;
newMenu.CreatePopupMenu();
for (size_t i = 0; i < scyllaPluginList.size(); i++)
{
newMenu.AppendMenu(MF_STRING, i + PLUGIN_MENU_BASE_ID, scyllaPluginList[i].pluginName);
}
hMenu.AppendMenu(MF_MENUBARBREAK);
hMenu.AppendMenu(MF_POPUP, newMenu, L"Scylla Plugins");
}
if (imprecPluginList.size() > 0)
{
CMenuHandle newMenu;
newMenu.CreatePopupMenu();
for (size_t i = 0; i < imprecPluginList.size(); i++)
{
newMenu.AppendMenu(MF_STRING, scyllaPluginList.size() + i + PLUGIN_MENU_BASE_ID, imprecPluginList[i].pluginName);
}
hMenu.AppendMenu(MF_MENUBARBREAK);
hMenu.AppendMenu(MF_POPUP, newMenu, L"ImpREC Plugins");
}
}
void MainGui::dumpMemoryActionHandler()
{
WCHAR selectedFilePath[MAX_PATH];
DumpMemoryGui dlgDumpMemory;
if(dlgDumpMemory.DoModal())
{
getCurrentModulePath(stringBuffer, _countof(stringBuffer));
if(showFileDialog(selectedFilePath, true, dlgDumpMemory.dumpFilename, filterMem, L"mem", stringBuffer))
{
if (ProcessAccessHelp::writeMemoryToNewFile(selectedFilePath,dlgDumpMemory.dumpedMemorySize,dlgDumpMemory.dumpedMemory))
{
Scylla::windowLog.log(L"Memory dump saved %s", selectedFilePath);
}
else
{
Scylla::windowLog.log(L"Error! Cannot write memory dump to disk");
}
}
}
}
void MainGui::dumpSectionActionHandler()
{
WCHAR selectedFilePath[MAX_PATH] = {0};
WCHAR defaultFilename[MAX_PATH] = {0};
DumpSectionGui dlgDumpSection;
const WCHAR * fileFilter;
const WCHAR * defExtension;
PeParser * peFile = 0;
dlgDumpSection.entryPoint = EditOEPAddress.GetValue();
if (ProcessAccessHelp::selectedModule)
{
//dump DLL
fileFilter = filterDll;
defExtension = L"dll";
dlgDumpSection.imageBase = ProcessAccessHelp::selectedModule->modBaseAddr;
//get it from gui
wcscpy_s(dlgDumpSection.fullpath, ProcessAccessHelp::selectedModule->fullPath);
}
else
{
fileFilter = filterExe;
defExtension = L"exe";
dlgDumpSection.imageBase = ProcessAccessHelp::targetImageBase;
//get it from gui
wcscpy_s(dlgDumpSection.fullpath, selectedProcess->fullPath);
}
if(dlgDumpSection.DoModal())
{
getCurrentDefaultDumpFilename(defaultFilename, _countof(defaultFilename));
getCurrentModulePath(stringBuffer, _countof(stringBuffer));
if(showFileDialog(selectedFilePath, true, defaultFilename, fileFilter, defExtension, stringBuffer))
{
checkSuspendProcess();
if (Scylla::config[USE_PE_HEADER_FROM_DISK].isTrue())
{
peFile = new PeParser(dlgDumpSection.fullpath, true);
}
else
{
peFile = new PeParser(dlgDumpSection.imageBase, true);
}
std::vector<PeSection> & sectionList = dlgDumpSection.getSectionList();
if (peFile->dumpProcess(dlgDumpSection.imageBase, dlgDumpSection.entryPoint, selectedFilePath, sectionList))
{
Scylla::windowLog.log(L"Dump success %s", selectedFilePath);
}
else
{
Scylla::windowLog.log(L"Error: Cannot dump image.");
MessageBox(L"Cannot dump image.", L"Failure", MB_ICONERROR);
}
delete peFile;
}
}
}
void MainGui::dumpActionHandler()
{
if(!selectedProcess)
return;
WCHAR selectedFilePath[MAX_PATH] = {0};
WCHAR defaultFilename[MAX_PATH] = {0};
const WCHAR * fileFilter;
const WCHAR * defExtension;
DWORD_PTR modBase = 0;
DWORD_PTR entrypoint = 0;
WCHAR * filename = 0;
PeParser * peFile = 0;
if (ProcessAccessHelp::selectedModule)
{
fileFilter = filterDll;
defExtension = L"dll";
}
else
{
fileFilter = filterExe;
defExtension = L"exe";
}
getCurrentModulePath(stringBuffer, _countof(stringBuffer));
getCurrentDefaultDumpFilename(defaultFilename, _countof(defaultFilename));
if(showFileDialog(selectedFilePath, true, defaultFilename, fileFilter, defExtension, stringBuffer))
{
entrypoint = EditOEPAddress.GetValue();
checkSuspendProcess();
if (ProcessAccessHelp::selectedModule)
{
//dump DLL
modBase = ProcessAccessHelp::selectedModule->modBaseAddr;
filename = ProcessAccessHelp::selectedModule->fullPath;
}
else
{
//dump exe
modBase = ProcessAccessHelp::targetImageBase;
filename = selectedProcess->fullPath;
}
if (Scylla::config[USE_PE_HEADER_FROM_DISK].isTrue())
{
peFile = new PeParser(filename, true);
}
else
{
peFile = new PeParser(modBase, true);
}
if (peFile->isValidPeFile())
{
if (peFile->dumpProcess(modBase, entrypoint, selectedFilePath))
{
Scylla::windowLog.log(L"Dump success %s", selectedFilePath);
}
else
{
Scylla::windowLog.log(L"Error: Cannot dump image.");
MessageBox(L"Cannot dump image.", L"Failure", MB_ICONERROR);
}
}
else
{
Scylla::windowLog.log(L"Error: Invalid PE file or invalid PE header. Try reading PE header from disk/process.");
}
delete peFile;
}
}
void MainGui::peRebuildActionHandler()
{
DWORD newSize = 0;
WCHAR selectedFilePath[MAX_PATH];
getCurrentModulePath(stringBuffer, _countof(stringBuffer));
if(showFileDialog(selectedFilePath, false, NULL, filterExeDll, NULL, stringBuffer))
{
if (Scylla::config[CREATE_BACKUP].isTrue())
{
if (!ProcessAccessHelp::createBackupFile(selectedFilePath))
{
Scylla::windowLog.log(L"Creating backup file failed %s", selectedFilePath);
}
}
DWORD fileSize = (DWORD)ProcessAccessHelp::getFileSize(selectedFilePath);
PeParser peFile(selectedFilePath, true);
if (!peFile.isValidPeFile())
{
Scylla::windowLog.log(L"This is not a valid PE file %s", selectedFilePath);
MessageBox(L"Not a valid PE file.", L"Failure", MB_ICONERROR);
return;
}
if (peFile.readPeSectionsFromFile())
{
peFile.setDefaultFileAlignment();
if (Scylla::config[REMOVE_DOS_HEADER_STUB].isTrue())
{
peFile.removeDosStub();
}
peFile.alignAllSectionHeaders();
peFile.fixPeHeader();
if (peFile.savePeFileToDisk(selectedFilePath))
{
newSize = (DWORD)ProcessAccessHelp::getFileSize(selectedFilePath);
if (Scylla::config[UPDATE_HEADER_CHECKSUM].isTrue())
{
Scylla::windowLog.log(L"Generating PE header checksum");
if (!PeParser::updatePeHeaderChecksum(selectedFilePath, newSize))
{
Scylla::windowLog.log(L"Generating PE header checksum FAILED!");
}
}
Scylla::windowLog.log(L"Rebuild success %s", selectedFilePath);
Scylla::windowLog.log(L"-> Old file size 0x%08X new file size 0x%08X (%d %%)", fileSize, newSize, ((newSize * 100) / fileSize) );
}
else
{
Scylla::windowLog.log(L"Rebuild failed, cannot save file %s", selectedFilePath);
MessageBox(L"Rebuild failed. Cannot save file.", L"Failure", MB_ICONERROR);
}
}
else
{
Scylla::windowLog.log(L"Rebuild failed, cannot read file %s", selectedFilePath);
MessageBox(L"Rebuild failed. Cannot read file.", L"Failure", MB_ICONERROR);
}
}
}
void MainGui::dumpFixActionHandler()
{
if(!selectedProcess)
return;
if (TreeImports.GetCount() < 2)
{
Scylla::windowLog.log(L"Nothing to rebuild");
return;
}
WCHAR newFilePath[MAX_PATH];
WCHAR selectedFilePath[MAX_PATH];
const WCHAR * fileFilter;
DWORD_PTR modBase = 0;
DWORD_PTR entrypoint = EditOEPAddress.GetValue();
if (ProcessAccessHelp::selectedModule)
{
modBase = ProcessAccessHelp::selectedModule->modBaseAddr;
fileFilter = filterDll;
}
else
{
modBase = ProcessAccessHelp::targetImageBase;
fileFilter = filterExe;
}
getCurrentModulePath(stringBuffer, _countof(stringBuffer));
if (showFileDialog(selectedFilePath, false, NULL, fileFilter, NULL, stringBuffer))
{
wcscpy_s(newFilePath, selectedFilePath);
const WCHAR * extension = 0;
WCHAR* dot = wcsrchr(newFilePath, L'.');
if (dot)
{
*dot = L'\0';
extension = selectedFilePath + (dot - newFilePath); //wcsrchr(selectedFilePath, L'.');
}
wcscat_s(newFilePath, L"_SCY");
if(extension)
{
wcscat_s(newFilePath, extension);
}
ImportRebuilder importRebuild(selectedFilePath);
if (Scylla::config[IAT_FIX_AND_OEP_FIX].isTrue())
{
importRebuild.setEntryPointRva((DWORD)(entrypoint - modBase));
}
if (Scylla::config[OriginalFirstThunk_SUPPORT].isTrue())
{
importRebuild.enableOFTSupport();
}
if (Scylla::config[SCAN_DIRECT_IMPORTS].isTrue() && Scylla::config[FIX_DIRECT_IMPORTS_UNIVERSAL].isTrue())
{
if (iatReferenceScan.numberOfFoundDirectImports() > 0)
{
importRebuild.iatReferenceScan = &iatReferenceScan;
importRebuild.BuildDirectImportsJumpTable = true;
}
}
if (Scylla::config[CREATE_NEW_IAT_IN_SECTION].isTrue())
{
importRebuild.iatReferenceScan = &iatReferenceScan;
DWORD_PTR addressIAT = EditIATAddress.GetValue();
DWORD sizeIAT = EditIATSize.GetValue();
importRebuild.enableNewIatInSection(addressIAT, sizeIAT);
}
if (importRebuild.rebuildImportTable(newFilePath, importsHandling.moduleList))
{
Scylla::windowLog.log(L"Import Rebuild success %s", newFilePath);
}
else
{
Scylla::windowLog.log(L"Import Rebuild failed %s", selectedFilePath);
MessageBox(L"Import Rebuild failed", L"Failure", MB_ICONERROR);
}
}
}
void MainGui::enableDialogControls(BOOL value)
{
BOOL valButton = value ? TRUE : FALSE;
GetDlgItem(IDC_BTN_PICKDLL).EnableWindow(valButton);
GetDlgItem(IDC_BTN_DUMP).EnableWindow(valButton);
GetDlgItem(IDC_BTN_FIXDUMP).EnableWindow(valButton);
GetDlgItem(IDC_BTN_IATAUTOSEARCH).EnableWindow(valButton);
GetDlgItem(IDC_BTN_GETIMPORTS).EnableWindow(valButton);
GetDlgItem(IDC_BTN_SUSPECTIMPORTS).EnableWindow(valButton);
GetDlgItem(IDC_BTN_INVALIDIMPORTS).EnableWindow(valButton);
GetDlgItem(IDC_BTN_CLEARIMPORTS).EnableWindow(valButton);
CMenuHandle menu = GetMenu();
UINT valMenu = value ? MF_ENABLED : MF_GRAYED;
menu.EnableMenuItem(ID_FILE_DUMP, valMenu);
menu.EnableMenuItem(ID_FILE_DUMPMEMORY, valMenu);
menu.EnableMenuItem(ID_FILE_DUMPSECTION, valMenu);
menu.EnableMenuItem(ID_FILE_FIXDUMP, valMenu);
menu.EnableMenuItem(ID_IMPORTS_INVALIDATESELECTED, valMenu);
menu.EnableMenuItem(ID_IMPORTS_CUTSELECTED, valMenu);
menu.EnableMenuItem(ID_IMPORTS_SAVETREE, valMenu);
menu.EnableMenuItem(ID_IMPORTS_LOADTREE, valMenu);
menu.EnableMenuItem(ID_MISC_DLLINJECTION, valMenu);
menu.EnableMenuItem(ID_MISC_DISASSEMBLER, valMenu);
menu.GetSubMenu(MenuImportsOffsetTrace).EnableMenuItem(MenuImportsTraceOffsetScylla, MF_BYPOSITION | valMenu);
menu.GetSubMenu(MenuImportsOffsetTrace).EnableMenuItem(MenuImportsTraceOffsetImpRec, MF_BYPOSITION | valMenu);
//not yet implemented
GetDlgItem(IDC_BTN_AUTOTRACE).EnableWindow(FALSE);
menu.EnableMenuItem(ID_TRACE_AUTOTRACE, MF_GRAYED);
}
CTreeItem MainGui::findTreeItem(CPoint pt, bool screenCoordinates)
{
if(screenCoordinates)
{
TreeImports.ScreenToClient(&pt);
}
UINT flags;
CTreeItem over = TreeImports.HitTest(pt, &flags);
if(over)
{
if(!(flags & TVHT_ONITEM))
{
over.m_hTreeItem = NULL;
}
}
return over;
}
void MainGui::showAboutDialog()
{
AboutGui dlgAbout;
dlgAbout.DoModal();
}
void MainGui::showDonateDialog()
{
DonateGui dlgDonate;
dlgDonate.DoModal();
}
void MainGui::dllInjectActionHandler()
{
if(!selectedProcess)
return;
WCHAR selectedFilePath[MAX_PATH];
HMODULE hMod = 0;
DllInjection dllInjection;
getCurrentModulePath(stringBuffer, _countof(stringBuffer));
if (showFileDialog(selectedFilePath, false, NULL, filterDll, NULL, stringBuffer))
{
hMod = dllInjection.dllInjection(ProcessAccessHelp::hProcess, selectedFilePath);
if (hMod && Scylla::config[DLL_INJECTION_AUTO_UNLOAD].isTrue())
{
if (!dllInjection.unloadDllInProcess(ProcessAccessHelp::hProcess, hMod))
{
Scylla::windowLog.log(L"DLL unloading failed, target %s", selectedFilePath);
}
}
if (hMod)
{
Scylla::windowLog.log(L"DLL Injection was successful, target %s", selectedFilePath);
}
else
{
Scylla::windowLog.log(L"DLL Injection failed, target %s", selectedFilePath);
}
}
}
void MainGui::disassemblerActionHandler()
{
DWORD_PTR oep = EditOEPAddress.GetValue();
DisassemblerGui disGuiDlg(oep, &apiReader);
disGuiDlg.DoModal();
}
void MainGui::optionsActionHandler()
{
OptionsGui dlgOptions;
dlgOptions.DoModal();
}
void MainGui::clearImportsActionHandler()
{
importsHandling.clearAllImports();
updateStatusBar();
}
void MainGui::pluginActionHandler( int menuItem )
{
if(!selectedProcess)
return;
DllInjectionPlugin dllInjectionPlugin;
std::vector<Plugin> &scyllaPluginList = Scylla::plugins.getScyllaPluginList();
std::vector<Plugin> &imprecPluginList = Scylla::plugins.getImprecPluginList();
menuItem -= PLUGIN_MENU_BASE_ID;
dllInjectionPlugin.hProcess = ProcessAccessHelp::hProcess;
dllInjectionPlugin.apiReader = &apiReader;
if (menuItem < (int)scyllaPluginList.size())
{
//scylla plugin
dllInjectionPlugin.injectPlugin(scyllaPluginList[menuItem], importsHandling.moduleList,selectedProcess->imageBase, selectedProcess->imageSize);
}
else
{
#ifndef _WIN64
menuItem -= (int)scyllaPluginList.size();
//imprec plugin
dllInjectionPlugin.injectImprecPlugin(imprecPluginList[menuItem], importsHandling.moduleList,selectedProcess->imageBase, selectedProcess->imageSize);
#endif
}
importsHandling.scanAndFixModuleList();
importsHandling.displayAllImports();
updateStatusBar();
}
bool MainGui::getCurrentModulePath(WCHAR * buffer, size_t bufferSize)
{
if(!selectedProcess)
return false;
if(ProcessAccessHelp::selectedModule)
{
wcscpy_s(buffer, bufferSize, ProcessAccessHelp::selectedModule->fullPath);
}
else
{
wcscpy_s(buffer, bufferSize, selectedProcess->fullPath);
}
WCHAR * slash = wcsrchr(buffer, L'\\');
if(slash)
{
*(slash+1) = L'\0';
}
return true;
}
void MainGui::checkSuspendProcess()
{
if (Scylla::config[SUSPEND_PROCESS_FOR_DUMPING].isTrue())
{
if (!ProcessAccessHelp::suspendProcess())
{
Scylla::windowLog.log(L"Error: Cannot suspend process.");
}
else
{
isProcessSuspended = true;
Scylla::windowLog.log(L"Suspending process successful, please resume manually.");
}
}
}
void MainGui::setDialogIATAddressAndSize( DWORD_PTR addressIAT, DWORD sizeIAT )
{
EditIATAddress.SetValue(addressIAT);
EditIATSize.SetValue(sizeIAT);
swprintf_s(stringBuffer, L"IAT found:\r\n\r\nStart: " PRINTF_DWORD_PTR_FULL L"\r\nSize: 0x%04X (%d) ", addressIAT, sizeIAT, sizeIAT);
MessageBox(stringBuffer, L"IAT found", MB_ICONINFORMATION);
}
bool MainGui::isIATOutsidePeImage( DWORD_PTR addressIAT )
{
DWORD_PTR minAdd = 0, maxAdd = 0;
if(ProcessAccessHelp::selectedModule)
{
minAdd = ProcessAccessHelp::selectedModule->modBaseAddr;
maxAdd = minAdd + ProcessAccessHelp::selectedModule->modBaseSize;
}
else
{
minAdd = selectedProcess->imageBase;
maxAdd = minAdd + selectedProcess->imageSize;
}
if (addressIAT > minAdd && addressIAT < maxAdd)
{
return false; //inside pe image
}
else
{
return true; //outside pe image, requires rebasing iat
}
}
bool MainGui::getCurrentDefaultDumpFilename( WCHAR * buffer, size_t bufferSize )
{
if(!selectedProcess)
return false;
WCHAR * fullPath;
if(ProcessAccessHelp::selectedModule)
{
fullPath = ProcessAccessHelp::selectedModule->fullPath;
}
else
{
fullPath = selectedProcess->fullPath;
}
WCHAR * temp = wcsrchr(fullPath, L'\\');
if(temp)
{
temp++;
wcscpy_s(buffer, bufferSize, temp);
temp = wcsrchr(buffer, L'.');
if (temp)
{
*temp = 0;
if(ProcessAccessHelp::selectedModule)
{
wcscat_s(buffer, bufferSize, L"_dump.dll");
}
else
{
wcscat_s(buffer, bufferSize, L"_dump.exe");
}
}
return true;
}
return false;
}
diff --git a/Scylla/Scylla.h b/Scylla/Scylla.h
index 4a00c09..72e7571 100644
--- a/Scylla/Scylla.h
+++ b/Scylla/Scylla.h
@@ -1,35 +1,35 @@
#pragma once
#include "ConfigurationHolder.h"
#include "PluginLoader.h"
#include "ProcessLister.h"
#include "Logger.h"
#define APPNAME_S "Scylla"
-#define APPVERSION_S "v0.9.6b"
-#define APPVERSIONDWORD 0x00009600
+#define APPVERSION_S "v0.9.7b"
+#define APPVERSIONDWORD 0x00009700
#define DONATE_BTC_ADDRESS "1GmVrhWwUhwLohaCLP4SKV5kkz8rd16N8h"
#define APPNAME TEXT(APPNAME_S)
#define APPVERSION TEXT(APPVERSION_S)
class Scylla
{
public:
static void initAsGuiApp();
static void initAsDll();
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/main.cpp b/Scylla/main.cpp
index 7a32029..6121181 100644
--- a/Scylla/main.cpp
+++ b/Scylla/main.cpp
@@ -1,156 +1,172 @@
//#include <vld.h> // Visual Leak Detector
#include <atlbase.h> // base ATL classes
#include <atlapp.h> // base WTL classes
#include "Architecture.h"
CAppModule _Module;
#include "MainGui.h"
#include "Scylla.h"
MainGui* pMainGui = NULL; // for Logger
HINSTANCE hDllModule = 0;
bool IsDllMode = false;
LONG WINAPI HandleUnknownException(struct _EXCEPTION_POINTERS *ExceptionInfo);
void AddExceptionHandler();
void RemoveExceptionHandler();
int InitializeGui(HINSTANCE hInstance, LPARAM param);
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
AddExceptionHandler();
return InitializeGui(hInstance, (LPARAM)0);
}
int InitializeGui(HINSTANCE hInstance, LPARAM param)
{
CoInitialize(NULL);
AtlInitCommonControls(ICC_LISTVIEW_CLASSES | ICC_TREEVIEW_CLASSES);
Scylla::initAsGuiApp();
IsDllMode = false;
HRESULT hRes = _Module.Init(NULL, hInstance);
ATLASSERT(SUCCEEDED(hRes));
int nRet = 0;
// BLOCK: Run application
{
MainGui dlgMain;
pMainGui = &dlgMain; // o_O
CMessageLoop loop;
_Module.AddMessageLoop(&loop);
dlgMain.Create(GetDesktopWindow(), param);
dlgMain.ShowWindow(SW_SHOW);
loop.Run();
}
_Module.Term();
CoUninitialize();
return nRet;
}
void InitializeDll(HINSTANCE hinstDLL)
{
hDllModule = hinstDLL;
IsDllMode = true;
Scylla::initAsDll();
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
// Perform actions based on the reason for calling.
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Return FALSE to fail DLL load.
AddExceptionHandler();
InitializeDll(hinstDLL);
break;
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;
case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;
case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
RemoveExceptionHandler();
break;
}
return TRUE; // Successful DLL_PROCESS_ATTACH.
}
LPTOP_LEVEL_EXCEPTION_FILTER oldFilter;
void AddExceptionHandler()
{
oldFilter = SetUnhandledExceptionFilter(HandleUnknownException);
}
void RemoveExceptionHandler()
{
SetUnhandledExceptionFilter(oldFilter);
}
LONG WINAPI HandleUnknownException(struct _EXCEPTION_POINTERS *ExceptionInfo)
{
WCHAR registerInfo[220];
- WCHAR message[159 + _countof(registerInfo)];
+ WCHAR filepath[MAX_PATH] = {0};
+ WCHAR file[MAX_PATH] = {0};
+ WCHAR message[MAX_PATH + 159 + _countof(registerInfo)];
+ DWORD_PTR baseAddress = 0;
DWORD_PTR address = (DWORD_PTR)ExceptionInfo->ExceptionRecord->ExceptionAddress;
+
+ wcscpy_s(filepath, L"unknown");
+ wcscpy_s(file, L"unknown");
+
+ if (GetMappedFileNameW(GetCurrentProcess(), (LPVOID)address, filepath, _countof(filepath)) > 0)
+ {
+ WCHAR *temp = wcsrchr(filepath, '\\');
+ if (temp)
+ {
+ temp++;
+ wcscpy_s(file, temp);
+ }
+ }
- swprintf_s(message, _countof(message), TEXT("ExceptionCode %08X\r\nExceptionFlags %08X\r\nNumberParameters %08X\r\nExceptionAddress VA ")TEXT(PRINTF_DWORD_PTR_FULL_S)TEXT("\r\nExceptionAddress RVA ")TEXT(PRINTF_DWORD_PTR_FULL_S)TEXT("\r\n\r\n"),
+ swprintf_s(message, _countof(message), TEXT("ExceptionCode %08X\r\nExceptionFlags %08X\r\nNumberParameters %08X\r\nExceptionAddress VA ")TEXT(PRINTF_DWORD_PTR_FULL_S)TEXT("\r\nExceptionAddress module %s\r\n\r\n"),
ExceptionInfo->ExceptionRecord->ExceptionCode,
ExceptionInfo->ExceptionRecord->ExceptionFlags,
ExceptionInfo->ExceptionRecord->NumberParameters,
address,
- address - (DWORD_PTR)GetModuleHandle(NULL));
+ file);
#ifdef _WIN64
swprintf_s(registerInfo, _countof(registerInfo),TEXT("rax=0x%p, rbx=0x%p, rdx=0x%p, rcx=0x%p, rsi=0x%p, rdi=0x%p, rbp=0x%p, rsp=0x%p, rip=0x%p"),
ExceptionInfo->ContextRecord->Rax,
ExceptionInfo->ContextRecord->Rbx,
ExceptionInfo->ContextRecord->Rdx,
ExceptionInfo->ContextRecord->Rcx,
ExceptionInfo->ContextRecord->Rsi,
ExceptionInfo->ContextRecord->Rdi,
ExceptionInfo->ContextRecord->Rbp,
ExceptionInfo->ContextRecord->Rsp,
ExceptionInfo->ContextRecord->Rip
);
#else
swprintf_s(registerInfo, _countof(registerInfo),TEXT("eax=0x%p, ebx=0x%p, edx=0x%p, ecx=0x%p, esi=0x%p, edi=0x%p, ebp=0x%p, esp=0x%p, eip=0x%p"),
ExceptionInfo->ContextRecord->Eax,
ExceptionInfo->ContextRecord->Ebx,
ExceptionInfo->ContextRecord->Edx,
ExceptionInfo->ContextRecord->Ecx,
ExceptionInfo->ContextRecord->Esi,
ExceptionInfo->ContextRecord->Edi,
ExceptionInfo->ContextRecord->Ebp,
ExceptionInfo->ContextRecord->Esp,
ExceptionInfo->ContextRecord->Eip
);
#endif
wcscat_s(message, _countof(message), registerInfo);
MessageBox(0, message, TEXT("Exception! Please report it!"), MB_ICONERROR);
return EXCEPTION_EXECUTE_HANDLER;
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Jan 7, 12:40 AM (2 h, 25 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
6f/9a/ac82b7c6e010f719f3491a7d82c3

Event Timeline