1
0
Fork 0

CPUDisassembly : Removed some code that was repeated from DisassembleAt function

Added a warning when user tries to assemble an instruction thats points to Non-executable memory and DEP is enabled
This commit is contained in:
Herzeh 2015-12-10 02:12:01 +01:00
parent 87fc0de91c
commit 9b8bcc70ec
9 changed files with 109 additions and 19 deletions

View File

@ -1250,6 +1250,11 @@ BRIDGE_IMPEXP void GuiDumpAtN(duint va, int index)
_gui_sendmessage(GUI_DUMP_AT_N, (void*)va, (void*)index);
}
BRIDGE_IMPEXP void GuiDisplayWarning(const char *title, const char *text)
{
_gui_sendmessage(GUI_DISPLAY_WARNING, (void*)title, (void*)text);
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
hInst = hinstDLL;

View File

@ -787,6 +787,7 @@ typedef enum
GUI_SET_DEBUGGEE_NOTES, // param1=const char* text, param2=unused
GUI_GET_DEBUGGEE_NOTES, // param1=char** text, param2=unused
GUI_DUMP_AT_N, // param1=int index, param2=duint va
GUI_DISPLAY_WARNING // param1=const char *text, param2=unused
} GUIMSG;
//GUI Typedefs
@ -886,6 +887,7 @@ BRIDGE_IMPEXP void GuiGetGlobalNotes(char** text);
BRIDGE_IMPEXP void GuiSetDebuggeeNotes(const char* text);
BRIDGE_IMPEXP void GuiGetDebuggeeNotes(char** text);
BRIDGE_IMPEXP void GuiDumpAtN(duint va, int index);
BRIDGE_IMPEXP void GuiDisplayWarning(const char *title, const char *text);
#ifdef __cplusplus
}

View File

@ -1,7 +1,7 @@
#ifndef _GLOBAL_H
#define _GLOBAL_H
#define _WIN32_WINNT 0x0501
#define _WIN32_WINNT 0x0601
#define WINVER 0x0501
#define _WIN32_IE 0x0500

View File

@ -9,6 +9,7 @@
#include "XEDParse\XEDParse.h"
#include "value.h"
#include "disasm_helper.h"
#include "debugger.h"
static bool cbUnknown(const char* text, ULONGLONG* value)
{
@ -67,6 +68,10 @@ bool assembleat(duint addr, const char* instruction, int* size, char* error, boo
if(size)
*size = destSize;
// Check if the instruction doesn't set IP to non-executable memory
if (!isInstructionPointingToExMemory(addr, dest))
GuiDisplayWarning("Non-executable memory region", "Assembled instruction points to non-executable memory region !");
bool ret = MemPatch(addr, dest, destSize);
if (ret)
@ -91,3 +96,81 @@ bool assembleat(duint addr, const char* instruction, int* size, char* error, boo
return ret;
}
bool isInstructionPointingToExMemory(duint addr, const unsigned char* dest)
{
MEMMAP wMemMapStruct;
DISASM_ARG arg;
DISASM_INSTR wDisasInstrStruct;
MEMORY_BASIC_INFORMATION *wMbiStruct = NULL;
duint instrArgCount;
dsint instrMemValues[3] = {0};
duint instrMemValuesIndex = 0;
dsint mbiBaseAddr, mbiEndAddr;
disasmget((unsigned char*)dest, 0, &wDisasInstrStruct);
instrArgCount = wDisasInstrStruct.argcount;
if (instrArgCount)
{
// Loop through all arguements
for (int i = 0; i < wDisasInstrStruct.argcount; i++)
{
arg = wDisasInstrStruct.arg[i];
// Check if any of the arguments is a memory
if (arg.type == arg_memory)
{
instrMemValues[instrMemValuesIndex] = addr + arg.memvalue; // add current instruction VA for rip-relative addressing
instrMemValuesIndex++;
}
else if (wDisasInstrStruct.type == instr_branch)
{
instrMemValues[instrMemValuesIndex] = addr + arg.value;
instrMemValuesIndex++;
}
}
}
// No memory pointer in the instruction, no need to go further
if (!instrMemValuesIndex)
return false;
// Get memory map to locate the sections to which the instr memory address belongs to
DbgMemMap(&wMemMapStruct);
// For each memPointerValue
for (auto & memValue : instrMemValues)
{
// Loop through the memMaps
for (int i = 0; i < wMemMapStruct.count; i++)
{
wMbiStruct = &(wMemMapStruct.page)[i].mbi;
mbiBaseAddr = (dsint)wMbiStruct->BaseAddress;
mbiEndAddr = (dsint)wMbiStruct->BaseAddress + (dsint)wMbiStruct->RegionSize;
if (memValue >= mbiBaseAddr && memValue < mbiEndAddr)
{
if (wMbiStruct->Protect == PAGE_EXECUTE ||
wMbiStruct->Protect == PAGE_EXECUTE_READ ||
wMbiStruct->Protect == PAGE_EXECUTE_READWRITE ||
wMbiStruct->Protect == PAGE_EXECUTE_WRITECOPY)
{
// Memory region is marked as executable
#ifndef _WIN64
DWORD lpFlagsDep;
BOOL bPermanentDep;
// DEP is disabled if lpFlagsDep == 0
if (GetProcessDEPPolicy(fdProcessInfo->hProcess, &lpFlagsDep, &bPermanentDep) && lpFlagsDep != 0)
return true;
#else
// DEP enabled on x64
return true;
#endif
}
}
}
}
return false;
}

View File

@ -5,5 +5,6 @@
bool assemble(duint addr, unsigned char* dest, int* size, const char* instruction, char* error);
bool assembleat(duint addr, const char* instruction, int* size, char* error, bool fillnop);
bool isInstructionPointingToExMemory(duint addr, const unsigned char* dest);
#endif // _ASSEMBLE_H

View File

@ -528,6 +528,14 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
emit dumpAtN((duint)param1, (int)param2);
}
break;
case GUI_DISPLAY_WARNING:
{
QString title = QString((const char*)param1);
QString text = QString((const char*)param2);
emit displayWarning(title, text);
}
break;
}
return nullptr;
}

View File

@ -115,6 +115,7 @@ signals:
void setDebuggeeNotes(const QString text);
void getDebuggeeNotes(void* text);
void dumpAtN(duint va, int index);
void displayWarning(QString title, QString text);
private:
QMutex* mBridgeMutex;

View File

@ -24,6 +24,7 @@ CPUDisassembly::CPUDisassembly(CPUWidget* parent) : Disassembly(parent)
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(debugStateChangedSlot(DBGSTATE)));
connect(Bridge::getBridge(), SIGNAL(selectionDisasmGet(SELECTIONDATA*)), this, SLOT(selectionGetSlot(SELECTIONDATA*)));
connect(Bridge::getBridge(), SIGNAL(selectionDisasmSet(const SELECTIONDATA*)), this, SLOT(selectionSetSlot(const SELECTIONDATA*)));
connect(Bridge::getBridge(), SIGNAL(displayWarning(QString, QString)), this, SLOT(displayWarningSlot(QString, QString)));
Initialize();
}
@ -704,24 +705,7 @@ void CPUDisassembly::assembleSlot()
duint wVA = rvaToVa(wRVA);
QString addr_text = QString("%1").arg(wVA, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
QByteArray wBuffer;
dsint wMaxByteCountToRead = 16 * 2;
//TODO: fix size problems
dsint size = getSize();
if(!size)
size = wRVA;
// Bounding
wMaxByteCountToRead = wMaxByteCountToRead > (size - wRVA) ? (size - wRVA) : wMaxByteCountToRead;
wBuffer.resize(wMaxByteCountToRead);
mMemPage->read(reinterpret_cast<byte_t*>(wBuffer.data()), wRVA, wMaxByteCountToRead);
QBeaEngine disasm(-1);
Instruction_t instr = disasm.DisassembleAt(reinterpret_cast<byte_t*>(wBuffer.data()), wMaxByteCountToRead, 0, 0, wVA);
Instruction_t instr = this->DisassembleAt(wRVA);
QString actual_inst = instr.instStr;
@ -1250,6 +1234,11 @@ void CPUDisassembly::decompileFunctionSlot()
}
}
void CPUDisassembly::displayWarningSlot(QString title, QString text)
{
QMessageBox::QMessageBox(QMessageBox::Information, title, text, QMessageBox::Ok).exec();
}
void CPUDisassembly::paintEvent(QPaintEvent* event)
{
// Hook/hack to update the sidebar at the same time as this widget.

View File

@ -83,6 +83,7 @@ public slots:
void openSourceSlot();
void decompileSelectionSlot();
void decompileFunctionSlot();
void displayWarningSlot(QString title, QString text);
protected:
void paintEvent(QPaintEvent* event);