1
0
Fork 0

DBG+GUI+BRIDGE: various fixes with regards to the disassembly view

This commit is contained in:
mrexodia 2016-06-23 01:43:54 +02:00
parent 89017073a6
commit 72888177b3
No known key found for this signature in database
GPG Key ID: D72F9A4FAA0073B4
15 changed files with 55 additions and 52 deletions

View File

@ -253,6 +253,7 @@ BRIDGE_IMPEXP bool DbgMemRead(duint va, unsigned char* dest, duint size)
if(IsBadWritePtr(dest, size))
{
GuiAddLogMessage("DbgMemRead with invalid boundaries!\n");
__debugbreak();
return false;
}
#endif //_DEBUG
@ -273,6 +274,7 @@ BRIDGE_IMPEXP bool DbgMemWrite(duint va, const unsigned char* src, duint size)
if(IsBadReadPtr(src, size))
{
GuiAddLogMessage("DbgMemWrite with invalid boundaries!\n");
__debugbreak();
return false;
}
#endif //_DEBUG

@ -1 +1 @@
Subproject commit cc82f1970cf6062ca0b50cd8f31202a410688082
Subproject commit 9dec3d7e8b8f3c3fa9ceeb09fef7e6f03b141603

View File

@ -300,6 +300,9 @@ void TraceRecordManager::saveToDb(JSON root)
}
if(json_array_size(jsonTraceRecords))
json_object_set_new(root, "tracerecord", jsonTraceRecords);
// Notify garbage collector
json_decref(jsonTraceRecords);
}
void TraceRecordManager::loadFromDb(JSON root)

View File

@ -1095,7 +1095,7 @@ extern "C" DLL_EXPORT duint _dbg_sendmessage(DBGMSG type, void* param1, void* pa
case DBG_GET_STRING_AT:
{
auto addr = duint(param1);
if(!MemIsValidReadPtr(addr, true))
if(!MemIsValidReadPtrUnsafe(addr, true))
return false;
auto dest = (char*)param2;
@ -1103,7 +1103,7 @@ extern "C" DLL_EXPORT duint _dbg_sendmessage(DBGMSG type, void* param1, void* pa
char string[MAX_STRING_SIZE];
duint addrPtr;
STRING_TYPE strtype;
if(MemReadUnsafe(addr, &addrPtr, sizeof(addr)) && MemIsValidReadPtr(addrPtr, true))
if(MemReadUnsafe(addr, &addrPtr, sizeof(addr)) && MemIsValidReadPtrUnsafe(addrPtr, true))
{
if(disasmgetstringat(addrPtr, &strtype, string, string, MAX_STRING_SIZE - 3))
{

View File

@ -1260,8 +1260,6 @@ CMDRESULT cbDebugDisasm(int argc, char* argv[])
{
addr = GetContextDataEx(hActiveThread, UE_CIP);
}
if(!MemIsValidReadPtr(addr))
return STATUS_CONTINUE;
DebugUpdateGui(addr, false);
return STATUS_CONTINUE;
}

View File

@ -303,7 +303,7 @@ bool disasmgetstringat(duint addr, STRING_TYPE* type, char* ascii, char* unicode
{
if(type)
*type = str_none;
if(!MemIsValidReadPtr(addr, true) || !disasmispossiblestring(addr))
if(!MemIsValidReadPtrUnsafe(addr, true) || !disasmispossiblestring(addr))
return false;
Memory<unsigned char*> data((maxlen + 1) * 2, "disasmgetstringat:data");
if(!MemReadUnsafe(addr, data(), (maxlen + 1) * 2)) //TODO: use safe version?

View File

@ -423,6 +423,14 @@ bool MemPatch(duint BaseAddress, const void* Buffer, duint Size, duint* NumberOf
}
bool MemIsValidReadPtr(duint Address, bool cache)
{
if(cache)
return MemFindBaseAddr(Address, nullptr) != 0;
unsigned char ch;
return MemRead(Address, &ch, sizeof(ch));
}
bool MemIsValidReadPtrUnsafe(duint Address, bool cache)
{
if(cache)
return MemFindBaseAddr(Address, nullptr) != 0;

View File

@ -29,6 +29,7 @@ bool MemReadUnsafe(duint BaseAddress, void* Buffer, duint Size, duint* NumberOfB
bool MemWrite(duint BaseAddress, const void* Buffer, duint Size, duint* NumberOfBytesWritten = nullptr);
bool MemPatch(duint BaseAddress, const void* Buffer, duint Size, duint* NumberOfBytesWritten = nullptr);
bool MemIsValidReadPtr(duint Address, bool cache = false);
bool MemIsValidReadPtrUnsafe(duint Address, bool cache = false);
bool MemIsCanonicalAddress(duint Address);
bool MemIsCodePage(duint Address, bool Refresh);
duint MemAllocRemote(duint Address, duint Size, DWORD Type = MEM_RESERVE | MEM_COMMIT, DWORD Protect = PAGE_EXECUTE_READWRITE);

View File

@ -14,7 +14,8 @@ std::unordered_map<duint, PATCHINFO> patches;
bool PatchSet(duint Address, unsigned char OldByte, unsigned char NewByte)
{
ASSERT_DEBUGGING("Export call");
if(!DbgIsDebugging())
return false;
// Address must be valid
if(!MemIsValidReadPtr(Address))
@ -62,7 +63,8 @@ bool PatchSet(duint Address, unsigned char OldByte, unsigned char NewByte)
bool PatchGet(duint Address, PATCHINFO* Patch)
{
ASSERT_DEBUGGING("Export call");
if(!DbgIsDebugging())
return false;
SHARED_ACQUIRE(LockPatches);
// Find this specific address in the list
@ -84,7 +86,8 @@ bool PatchGet(duint Address, PATCHINFO* Patch)
bool PatchDelete(duint Address, bool Restore)
{
ASSERT_DEBUGGING("Export call");
if(!DbgIsDebugging())
return false;
EXCLUSIVE_ACQUIRE(LockPatches);
// Do a list lookup with hash
@ -104,7 +107,8 @@ bool PatchDelete(duint Address, bool Restore)
void PatchDelRange(duint Start, duint End, bool Restore)
{
ASSERT_DEBUGGING("Export call");
if(!DbgIsDebugging())
return;
// Are all bookmarks going to be deleted?
// 0x00000000 - 0xFFFFFFFF

View File

@ -575,7 +575,6 @@ QString Disassembly::paintContent(QPainter* painter, dsint rowBase, int rowOffse
return "";
}
/************************************************************************************
Mouse Management
************************************************************************************/
@ -633,7 +632,6 @@ void Disassembly::mouseMoveEvent(QMouseEvent* event)
AbstractTableView::mouseMoveEvent(event);
}
/**
* @brief This method has been reimplemented. It manages the following actions:
* - Multi-rows selection
@ -714,7 +712,6 @@ void Disassembly::mousePressEvent(QMouseEvent* event)
AbstractTableView::mousePressEvent(event);
}
/**
* @brief This method has been reimplemented. It manages the following actions:
* - Multi-rows selection
@ -743,7 +740,6 @@ void Disassembly::mouseReleaseEvent(QMouseEvent* event)
AbstractTableView::mouseReleaseEvent(event);
}
/************************************************************************************
Keyboard Management
************************************************************************************/
@ -1160,7 +1156,6 @@ int Disassembly::paintFunctionGraphic(QPainter* painter, int x, int y, Function_
return x_add + line_width + end_add;
}
/************************************************************************************
Instructions Management
***********************************************************************************/
@ -1194,16 +1189,15 @@ dsint Disassembly::getPreviousInstructionRVA(dsint rva, duint count)
wMaxByteCountToRead = wVirtualRVA + 1 + 16;
wBuffer.resize(wMaxByteCountToRead);
mMemPage->read(reinterpret_cast<byte_t*>(wBuffer.data()), wBottomByteRealRVA, wMaxByteCountToRead);
mMemPage->read(wBuffer.data(), wBottomByteRealRVA, wBuffer.size());
dsint addr = mDisasm->DisassembleBack(reinterpret_cast<byte_t*>(wBuffer.data()), rvaToVa(wBottomByteRealRVA), wMaxByteCountToRead, wVirtualRVA , count, mTmpCodeCount, mTmpCodeList);
dsint addr = mDisasm->DisassembleBack((byte_t*)wBuffer.data(), rvaToVa(wBottomByteRealRVA), wBuffer.size(), wVirtualRVA , count, mTmpCodeCount, mTmpCodeList);
addr += rva - wVirtualRVA;
return addr;
}
/**
* @brief Returns the RVA of count-th instructions after the given instruction RVA.
*
@ -1229,16 +1223,15 @@ dsint Disassembly::getNextInstructionRVA(dsint rva, duint count)
wMaxByteCountToRead = wRemainingBytes > wMaxByteCountToRead ? wMaxByteCountToRead : wRemainingBytes;
wBuffer.resize(wMaxByteCountToRead);
mMemPage->read(reinterpret_cast<byte_t*>(wBuffer.data()), rva, wMaxByteCountToRead);
mMemPage->read(wBuffer.data(), rva, wBuffer.size());
wNewRVA = mDisasm->DisassembleNext(reinterpret_cast<byte_t*>(wBuffer.data()), rvaToVa(rva), wMaxByteCountToRead, 0, count, mTmpCodeCount, mTmpCodeList);
wNewRVA = mDisasm->DisassembleNext((byte_t*)wBuffer.data(), rvaToVa(rva), wBuffer.size(), 0, count, mTmpCodeCount, mTmpCodeList);
wNewRVA += rva;
return wNewRVA;
}
/**
* @brief Returns the RVA of count-th instructions before/after (depending on the sign) the given instruction RVA.
*
@ -1267,7 +1260,6 @@ dsint Disassembly::getInstructionRVA(dsint index, dsint count)
return wAddr;
}
/**
* @brief Disassembles the instruction at the given RVA.
*
@ -1278,29 +1270,25 @@ dsint Disassembly::getInstructionRVA(dsint index, dsint count)
Instruction_t Disassembly::DisassembleAt(dsint rva)
{
QByteArray wBuffer;
dsint base = mMemPage->getBase();
dsint wMaxByteCountToRead = 16 * 2;
duint base = mMemPage->getBase();
duint wMaxByteCountToRead = 16 * 2;
// Bounding
//TODO: fix problems with negative sizes
dsint size = getSize();
auto size = getSize();
if(!size)
size = rva;
size = rva + wMaxByteCountToRead * 2;
wMaxByteCountToRead = wMaxByteCountToRead > (size - rva) ? (size - rva) : wMaxByteCountToRead;
if(mCodeFoldingManager)
wMaxByteCountToRead += mCodeFoldingManager->getFoldedSize(rvaToVa(rva), rvaToVa(rva + wMaxByteCountToRead));
wMaxByteCountToRead = wMaxByteCountToRead > (size - rva) ? (size - rva) : wMaxByteCountToRead;
wBuffer.resize(wMaxByteCountToRead);
if(!wMaxByteCountToRead)
wMaxByteCountToRead = 1;
mMemPage->read(wBuffer.data(), rva, wBuffer.size());
mMemPage->read(reinterpret_cast<byte_t*>(wBuffer.data()), rva, wMaxByteCountToRead);
return mDisasm->DisassembleAt(reinterpret_cast<byte_t*>(wBuffer.data()), wMaxByteCountToRead, 0, base, rva, mTmpCodeCount, mTmpCodeList);
return mDisasm->DisassembleAt((byte_t*)wBuffer.data(), wBuffer.size(), base, rva, mTmpCodeCount, mTmpCodeList);
}
/**
* @brief Disassembles the instruction count instruction afterc the instruction at the given RVA.
* Count can be positive or negative.
@ -1316,7 +1304,6 @@ Instruction_t Disassembly::DisassembleAt(dsint rva, dsint count)
return DisassembleAt(rva);
}
/************************************************************************************
Selection Management
************************************************************************************/
@ -1528,9 +1515,7 @@ void Disassembly::prepareData()
wAddr = getNextInstructionRVA(wAddr, 1);
if(wAddr == wAddrPrev)
{
break;
}
wCount++;
}
@ -1557,8 +1542,8 @@ duint Disassembly::rvaToVa(dsint rva)
void Disassembly::disassembleAt(dsint parVA, dsint parCIP, bool history, dsint newTableOffset)
{
dsint wBase = DbgMemFindBaseAddr(parVA, 0);
dsint wSize = DbgMemGetPageSize(wBase);
duint wSize;
auto wBase = DbgMemFindBaseAddr(parVA, &wSize);
if(!wBase || !wSize)
return;
@ -1595,7 +1580,6 @@ void Disassembly::disassembleAt(dsint parVA, dsint parCIP, bool history, dsint n
bool cipChanged = rvaToVa(mCipRva) != parCIP;
if(mRvaDisplayEnabled && mMemPage->getBase() != mRvaDisplayPageBase)
mRvaDisplayEnabled = false;
@ -1696,7 +1680,6 @@ void Disassembly::disassembleAt(dsint parVA, dsint parCIP, bool history, dsint n
*/
emit disassembledAt(parVA, parCIP, history, newTableOffset);
reloadData();
}
QList<Instruction_t>* Disassembly::instructionsBuffer()

View File

@ -86,8 +86,8 @@ void HexDump::copySelectionSlot()
void HexDump::printDumpAt(dsint parVA, bool select, bool repaint, bool updateTableOffset)
{
dsint wBase = DbgMemFindBaseAddr(parVA, 0); //get memory base
dsint wSize = DbgMemGetPageSize(wBase); //get page size
duint wSize;
auto wBase = DbgMemFindBaseAddr(parVA, &wSize); //get memory base
if(!wBase || !wSize)
return;
dsint wRVA = parVA - wBase; //calculate rva

View File

@ -177,30 +177,28 @@ ulong QBeaEngine::DisassembleNext(byte_t* data, duint base, duint size, duint ip
*
* @param[in] data Pointer to memory data (Can be either a buffer or the original data memory)
* @param[in] size Size of the memory pointed by data (Can be the memory page size if data points to the original memory page base address)
* @param[in] instIndex Offset to reach the instruction data from the data pointer
* @param[in] origBase Original base address of the memory page (Required to disassemble destination addresses)
* @param[in] origInstRVA Original Instruction RVA of the instruction to disassemble
*
* @return Return the disassembled instruction
*/
Instruction_t QBeaEngine::DisassembleAt(byte_t* data, duint size, duint instIndex, duint origBase, duint origInstRVA, duint tmpcodecount, duint* tmpcodelist)
Instruction_t QBeaEngine::DisassembleAt(byte_t* data, duint size, duint origBase, duint origInstRVA, duint tmpcodecount, duint* tmpcodelist)
{
//tokenize
CapstoneTokenizer::InstructionToken cap;
_tokenizer.Tokenize(origBase + origInstRVA, data + instIndex, size, cap);
_tokenizer.Tokenize(origBase + origInstRVA, data, size, cap);
int len = _tokenizer.Size();
const auto & cp = _tokenizer.GetCapstone();
bool success = cp.Success();
ENCODETYPE type = enc_code;
type = mEncodeMap->getDataType(origBase + origInstRVA, cp.Success() ? len : 1, tmpcodecount, tmpcodelist);
if(type != enc_unknown && type != enc_code && type != enc_middle)
return DecodeDataAt(data, size, instIndex, origBase, origInstRVA, type);
return DecodeDataAt(data, size, origBase, origInstRVA, type);
auto branchType = Instruction_t::None;
if(success && (cp.InGroup(CS_GRP_JUMP) || cp.IsLoop()))
@ -218,7 +216,7 @@ Instruction_t QBeaEngine::DisassembleAt(byte_t* data, duint size, duint instInde
Instruction_t wInst;
wInst.instStr = QString(cp.InstructionText().c_str());
wInst.dump = QByteArray((const char*)data + instIndex, len);
wInst.dump = QByteArray((const char*)data, len);
wInst.rva = origInstRVA;
if(mCodeFoldingManager && mCodeFoldingManager->isFolded(origInstRVA))
wInst.length = mCodeFoldingManager->getFoldEnd(origInstRVA + origBase) - (origInstRVA + origBase) + 1;
@ -232,7 +230,7 @@ Instruction_t QBeaEngine::DisassembleAt(byte_t* data, duint size, duint instInde
}
Instruction_t QBeaEngine::DecodeDataAt(byte_t* data, duint size, duint instIndex, duint origBase, duint origInstRVA, ENCODETYPE type, duint tmpcodecount, duint* tmpcodelist)
Instruction_t QBeaEngine::DecodeDataAt(byte_t* data, duint size, duint origBase, duint origInstRVA, ENCODETYPE type, duint tmpcodecount, duint* tmpcodelist)
{
//tokenize
CapstoneTokenizer::InstructionToken cap;

View File

@ -41,8 +41,8 @@ public:
~QBeaEngine();
ulong DisassembleBack(byte_t* data, duint base, duint size, duint ip, int n, duint tmpcodecount = 0, duint* tmpcodelist = nullptr);
ulong DisassembleNext(byte_t* data, duint base, duint size, duint ip, int n, duint tmpcodecount = 0, duint* tmpcodelist = nullptr);
Instruction_t DisassembleAt(byte_t* data, duint size, duint instIndex, duint origBase, duint origInstRVA, duint tmpcodecount = 0, duint* tmpcodelist = nullptr);
Instruction_t DecodeDataAt(byte_t* data, duint size, duint instIndex, duint origBase, duint origInstRVA, ENCODETYPE type, duint tmpcodecount = 0, duint* tmpcodelist = nullptr);
Instruction_t DisassembleAt(byte_t* data, duint size, duint origBase, duint origInstRVA, duint tmpcodecount = 0, duint* tmpcodelist = nullptr);
Instruction_t DecodeDataAt(byte_t* data, duint size, duint origBase, duint origInstRVA, ENCODETYPE type, duint tmpcodecount = 0, duint* tmpcodelist = nullptr);
void setCodeFoldingManager(CodeFoldingHelper* CodeFoldingManager);
void UpdateConfig();
EncodeMap* getEncodeMap() { return mEncodeMap; }

View File

@ -48,3 +48,8 @@ void MemoryPage::setAttributes(duint base, duint size)
mBase = base;
mSize = size;
}
bool MemoryPage::inRange(duint va) const
{
return va >= mBase && va < mBase + mSize;
}

View File

@ -18,6 +18,7 @@ public:
duint getBase() const;
duint va(dsint rva) const;
void setAttributes(duint base, duint size);
bool inRange(duint va) const;
private:
duint mBase;