1
0
Fork 0

Merge pull request #3192 from x64dbg/cross-platform-preparations

Cross platform preparations
This commit is contained in:
Duncan Ogilvie 2023-09-20 02:30:40 +02:00 committed by GitHub
commit 7f2566b6ed
Signed by: GitHub
GPG Key ID: 4AEE18F83AFDEB23
191 changed files with 71127 additions and 4315 deletions

6
.gitmodules vendored
View File

@ -1,6 +1,3 @@
[submodule "src/gui/Translations"]
path = src/gui/Translations
url = ../Translations.git
[submodule "src/dbg/btparser"] [submodule "src/dbg/btparser"]
path = src/dbg/btparser path = src/dbg/btparser
url = ../btparser url = ../btparser
@ -8,6 +5,3 @@
path = deps path = deps
url = ../deps url = ../deps
shallow = true shallow = true
[submodule "src/zydis_wrapper/zydis"]
path = src/zydis_wrapper/zydis
url = ../zydis.git

View File

@ -176,7 +176,10 @@ extern "C"
#define MAX_SECTION_SIZE 10 #define MAX_SECTION_SIZE 10
#define MAX_COMMAND_LINE_SIZE 256 #define MAX_COMMAND_LINE_SIZE 256
#define MAX_MNEMONIC_SIZE 64 #define MAX_MNEMONIC_SIZE 64
#ifndef PAGE_SIZE
#define PAGE_SIZE 0x1000 #define PAGE_SIZE 0x1000
#endif // PAGE_SIZE
//Debugger enums //Debugger enums
typedef enum typedef enum

View File

@ -205,14 +205,14 @@ void TraceRecordManager::TraceExecute(duint address, duint size)
//See https://www.felixcloutier.com/x86/FXSAVE.html, max 512 bytes //See https://www.felixcloutier.com/x86/FXSAVE.html, max 512 bytes
#define memoryContentSize 512 #define memoryContentSize 512
static void HandleZydisOperand(const Zydis & cp, int opindex, DISASM_ARGTYPE* argType, duint* value, unsigned char memoryContent[memoryContentSize], unsigned char* memorySize) static void HandleZydisOperand(const Zydis & zydis, int opindex, DISASM_ARGTYPE* argType, duint* value, unsigned char memoryContent[memoryContentSize], unsigned char* memorySize)
{ {
*value = cp.ResolveOpValue(opindex, [&cp](ZydisRegister reg) *value = (duint)zydis.ResolveOpValue(opindex, [&zydis](ZydisRegister reg) -> uint64_t
{ {
auto regName = cp.RegName(reg); auto regName = zydis.RegName(reg);
return regName ? getregister(nullptr, regName) : 0; //TODO: temporary needs enums + caching return regName ? getregister(nullptr, regName) : 0; //TODO: temporary needs enums + caching
}); });
const auto & op = cp[opindex]; const auto & op = zydis[opindex];
switch(op.type) switch(op.type)
{ {
case ZYDIS_OPERAND_TYPE_REGISTER: case ZYDIS_OPERAND_TYPE_REGISTER:
@ -269,7 +269,7 @@ void TraceRecordManager::TraceExecuteRecord(const Zydis & newInstruction)
if(newInstruction.Success() && !newInstruction.IsNop() && newInstruction.GetId() != ZYDIS_MNEMONIC_LEA) if(newInstruction.Success() && !newInstruction.IsNop() && newInstruction.GetId() != ZYDIS_MNEMONIC_LEA)
{ {
// This can happen when trace execute instruction is used, we need to fix that or something would go wrong with the GUI. // This can happen when trace execute instruction is used, we need to fix that or something would go wrong with the GUI.
newContext.registers.regcontext.cip = newInstruction.Address(); newContext.registers.regcontext.cip = (duint)newInstruction.Address();
DISASM_ARGTYPE argType; DISASM_ARGTYPE argType;
duint value; duint value;
unsigned char memoryContent[memoryContentSize]; unsigned char memoryContent[memoryContentSize];
@ -553,13 +553,13 @@ bool TraceRecordManager::enableTraceRecording(bool enabled, const char* fileName
for(size_t i = 0; i < _countof(rtOldContextChanged); i++) for(size_t i = 0; i < _countof(rtOldContextChanged); i++)
rtOldContextChanged[i] = true; rtOldContextChanged[i] = true;
dprintf(QT_TRANSLATE_NOOP("DBG", "Started trace recording to file: %s\r\n"), fileName); dprintf(QT_TRANSLATE_NOOP("DBG", "Started trace recording to file: %s\r\n"), fileName);
Zydis cp; Zydis zydis;
unsigned char instr[MAX_DISASM_BUFFER]; unsigned char instr[MAX_DISASM_BUFFER];
auto cip = GetContextDataEx(hActiveThread, UE_CIP); auto cip = GetContextDataEx(hActiveThread, UE_CIP);
if(MemRead(cip, instr, MAX_DISASM_BUFFER)) if(MemRead(cip, instr, MAX_DISASM_BUFFER))
{ {
cp.DisassembleSafe(cip, instr, MAX_DISASM_BUFFER); zydis.DisassembleSafe(cip, instr, MAX_DISASM_BUFFER);
TraceExecuteRecord(cp); TraceExecuteRecord(zydis);
} }
GuiOpenTraceFile(fileName); GuiOpenTraceFile(fileName);
return true; return true;

View File

@ -102,8 +102,8 @@ extern "C" DLL_EXPORT bool _dbg_isjumpgoingtoexecute(duint addr)
unsigned char data[16]; unsigned char data[16];
if(MemRead(addr, data, sizeof(data), nullptr, true)) if(MemRead(addr, data, sizeof(data), nullptr, true))
{ {
Zydis cp; Zydis zydis;
if(cp.Disassemble(addr, data)) if(zydis.Disassemble(addr, data))
{ {
CONTEXT ctx; CONTEXT ctx;
memset(&ctx, 0, sizeof(ctx)); memset(&ctx, 0, sizeof(ctx));
@ -116,7 +116,7 @@ extern "C" DLL_EXPORT bool _dbg_isjumpgoingtoexecute(duint addr)
auto cflags = ctx.EFlags; auto cflags = ctx.EFlags;
auto ccx = ctx.Ecx; auto ccx = ctx.Ecx;
#endif //_WIN64 #endif //_WIN64
return cp.IsBranchGoingToExecute(cflags, ccx); return zydis.IsBranchGoingToExecute(cflags, ccx);
} }
} }
return false; return false;
@ -329,11 +329,11 @@ static bool getAutoComment(duint addr, String & comment)
BRIDGE_ADDRINFO newinfo; BRIDGE_ADDRINFO newinfo;
char string_text[MAX_STRING_SIZE] = ""; char string_text[MAX_STRING_SIZE] = "";
Zydis cp; Zydis zydis;
auto getregs = !bOnlyCipAutoComments || addr == lastContext.cip; auto getregs = !bOnlyCipAutoComments || addr == lastContext.cip;
disasmget(cp, addr, &instr, getregs); disasmget(zydis, addr, &instr, getregs);
// Some nop variants have 'operands' that should be ignored // Some nop variants have 'operands' that should be ignored
if(cp.Success() && !cp.IsNop()) if(zydis.Success() && !zydis.IsNop())
{ {
//Ignore register values when not on CIP and OnlyCipAutoComments is enabled: https://github.com/x64dbg/x64dbg/issues/1383 //Ignore register values when not on CIP and OnlyCipAutoComments is enabled: https://github.com/x64dbg/x64dbg/issues/1383
if(!getregs) if(!getregs)
@ -342,7 +342,7 @@ static bool getAutoComment(duint addr, String & comment)
instr.arg[i].value = instr.arg[i].constant; instr.arg[i].value = instr.arg[i].constant;
} }
if(addr == lastContext.cip && (cp.GetId() == ZYDIS_MNEMONIC_SYSCALL || (cp.GetId() == ZYDIS_MNEMONIC_INT && cp[0].imm.value.u == 0x2e))) if(addr == lastContext.cip && (zydis.GetId() == ZYDIS_MNEMONIC_SYSCALL || (zydis.GetId() == ZYDIS_MNEMONIC_INT && zydis[0].imm.value.u == 0x2e)))
{ {
auto syscallName = SyscallToName((unsigned int)lastContext.cax); auto syscallName = SyscallToName((unsigned int)lastContext.cax);
if(!syscallName.empty()) if(!syscallName.empty())
@ -367,9 +367,9 @@ static bool getAutoComment(duint addr, String & comment)
if(instr.arg[i].constant == instr.arg[i].value) //avoid: call <module.label> ; addr:label if(instr.arg[i].constant == instr.arg[i].value) //avoid: call <module.label> ; addr:label
{ {
auto constant = instr.arg[i].constant; auto constant = instr.arg[i].constant;
if(instr.arg[i].type == arg_normal && instr.arg[i].value == addr + instr.instr_size && cp.IsCall()) if(instr.arg[i].type == arg_normal && instr.arg[i].value == addr + instr.instr_size && zydis.IsCall())
temp_string.assign("call $0"); temp_string.assign("call $0");
else if(instr.arg[i].type == arg_normal && instr.arg[i].value == addr + instr.instr_size && cp.IsJump()) else if(instr.arg[i].type == arg_normal && instr.arg[i].value == addr + instr.instr_size && zydis.IsJump())
temp_string.assign("jmp $0"); temp_string.assign("jmp $0");
else if(instr.type == instr_branch) else if(instr.type == instr_branch)
continue; continue;
@ -881,12 +881,12 @@ extern "C" DLL_EXPORT duint _dbg_getbranchdestination(duint addr)
unsigned char data[MAX_DISASM_BUFFER]; unsigned char data[MAX_DISASM_BUFFER];
if(!MemIsValidReadPtr(addr, true) || !MemRead(addr, data, sizeof(data))) if(!MemIsValidReadPtr(addr, true) || !MemRead(addr, data, sizeof(data)))
return 0; return 0;
Zydis cp; Zydis zydis;
if(!cp.Disassemble(addr, data)) if(!zydis.Disassemble(addr, data))
return 0; return 0;
if(cp.IsBranchType(Zydis::BTJmp | Zydis::BTCall | Zydis::BTLoop | Zydis::BTXbegin)) if(zydis.IsBranchType(Zydis::BTJmp | Zydis::BTCall | Zydis::BTLoop | Zydis::BTXbegin))
{ {
auto opValue = cp.ResolveOpValue(0, [](ZydisRegister reg) -> size_t auto opValue = (duint)zydis.ResolveOpValue(0, [](ZydisRegister reg) -> uint64_t
{ {
switch(reg) switch(reg)
{ {
@ -949,10 +949,10 @@ extern "C" DLL_EXPORT duint _dbg_getbranchdestination(duint addr)
return 0; return 0;
} }
}); });
if(cp.OpCount() && cp[0].type == ZYDIS_OPERAND_TYPE_MEMORY) if(zydis.OpCount() && zydis[0].type == ZYDIS_OPERAND_TYPE_MEMORY)
{ {
auto const tebseg = ArchValue(ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS); auto const tebseg = ArchValue(ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS);
if(cp[0].mem.segment == tebseg) if(zydis[0].mem.segment == tebseg)
opValue += duint(GetTEBLocation(hActiveThread)); opValue += duint(GetTEBLocation(hActiveThread));
if(MemRead(opValue, &opValue, sizeof(opValue))) if(MemRead(opValue, &opValue, sizeof(opValue)))
return opValue; return opValue;
@ -960,7 +960,7 @@ extern "C" DLL_EXPORT duint _dbg_getbranchdestination(duint addr)
else else
return opValue; return opValue;
} }
if(cp.IsRet()) if(zydis.IsRet())
{ {
auto csp = lastContext.csp; auto csp = lastContext.csp;
duint dest = 0; duint dest = 0;

View File

@ -31,9 +31,9 @@ bool CodeFollowPass::Analyse()
return false; return false;
} }
duint CodeFollowPass::GetReferenceOperand(const ZydisDecodedInstruction & Context) duint CodeFollowPass::GetReferenceOperand(const ZydisDisassembledInstruction & Context)
{ {
for(int i = 0; i < Context.operandCount; i++) for(int i = 0; i < Context.info.operand_count; i++)
{ {
auto operand = Context.operands[i]; auto operand = Context.operands[i];
@ -50,9 +50,9 @@ duint CodeFollowPass::GetReferenceOperand(const ZydisDecodedInstruction & Contex
return 0; return 0;
} }
duint CodeFollowPass::GetMemoryOperand(Zydis & Disasm, const ZydisDecodedInstruction & Context, bool* Indirect) duint CodeFollowPass::GetMemoryOperand(Zydis & Disasm, const ZydisDisassembledInstruction & Context, bool* Indirect)
{ {
if(Context.operandCount <= 0) if(Context.info.operand_count <= 0)
return 0; return 0;
// Only the first operand matters // Only the first operand matters

View File

@ -14,6 +14,6 @@ public:
virtual bool Analyse() override; virtual bool Analyse() override;
private: private:
duint GetReferenceOperand(const ZydisDecodedInstruction & Context); duint GetReferenceOperand(const ZydisDisassembledInstruction & Context);
duint GetMemoryOperand(Zydis & Disasm, const ZydisDecodedInstruction & Context, bool* Indirect); duint GetMemoryOperand(Zydis & Disasm, const ZydisDisassembledInstruction & Context, bool* Indirect);
}; };

View File

@ -94,7 +94,7 @@ void AdvancedAnalysis::analyzeFunction(duint entryPoint, bool writedata)
while(true) while(true)
{ {
node.icount++; node.icount++;
if(!mCp.Disassemble(node.end, translateAddr(node.end))) if(!mZydis.Disassemble(node.end, translateAddr(node.end)))
{ {
if(writedata) if(writedata)
mEncMap[node.end - mBase] = (byte)enc_byte; mEncMap[node.end - mBase] = (byte)enc_byte;
@ -109,7 +109,7 @@ void AdvancedAnalysis::analyzeFunction(duint entryPoint, bool writedata)
} }
// If the memory range doesn't fit the entire instruction // If the memory range doesn't fit the entire instruction
// mark it as bytes and finish this node // mark it as bytes and finish this node
if(!inRange(node.end + mCp.Size() - 1)) if(!inRange(node.end + mZydis.Size() - 1))
{ {
duint remainingSize = mBase + mSize - node.end; duint remainingSize = mBase + mSize - node.end;
memset(&mEncMap[node.end - mBase], (byte)enc_byte, remainingSize); memset(&mEncMap[node.end - mBase], (byte)enc_byte, remainingSize);
@ -119,15 +119,15 @@ void AdvancedAnalysis::analyzeFunction(duint entryPoint, bool writedata)
if(writedata) if(writedata)
{ {
mEncMap[node.end - mBase] = (byte)enc_code; mEncMap[node.end - mBase] = (byte)enc_code;
for(int i = 1; i < mCp.Size(); i++) for(size_t i = 1; i < mZydis.Size(); i++)
mEncMap[node.end - mBase + i] = (byte)enc_middle; mEncMap[node.end - mBase + i] = (byte)enc_middle;
} }
if(mCp.IsJump() || mCp.IsLoop()) //jump if(mZydis.IsJump() || mZydis.IsLoop()) //jump
{ {
//set the branch destinations //set the branch destinations
node.brtrue = mCp.BranchDestination(); node.brtrue = (duint)mZydis.BranchDestination();
if(mCp.GetId() != ZYDIS_MNEMONIC_JMP) //unconditional jumps dont have a brfalse if(mZydis.GetId() != ZYDIS_MNEMONIC_JMP) //unconditional jumps dont have a brfalse
node.brfalse = node.end + mCp.Size(); node.brfalse = node.end + mZydis.Size();
//add node to the function graph //add node to the function graph
graph.AddNode(node); graph.AddNode(node);
@ -140,26 +140,26 @@ void AdvancedAnalysis::analyzeFunction(duint entryPoint, bool writedata)
break; break;
} }
if(mCp.IsCall()) //call if(mZydis.IsCall()) //call
{ {
//TODO: handle no return //TODO: handle no return
duint target = mCp.BranchDestination(); auto target = (duint)mZydis.BranchDestination();
if(inRange(target) && mEntryPoints.find(target) == mEntryPoints.end()) if(inRange(target) && mEntryPoints.find(target) == mEntryPoints.end())
mCandidateEPs.insert(target); mCandidateEPs.insert(target);
} }
if(mCp.IsRet()) //return if(mZydis.IsRet()) //return
{ {
node.terminal = true; node.terminal = true;
graph.AddNode(node); graph.AddNode(node);
break; break;
} }
// If this instruction finishes the memory range, end the loop for this entry point // If this instruction finishes the memory range, end the loop for this entry point
if(!inRange(node.end + mCp.Size())) if(!inRange(node.end + mZydis.Size()))
{ {
graph.AddNode(node); graph.AddNode(node);
break; break;
} }
node.end += mCp.Size(); node.end += mZydis.Size();
} }
} }
mFunctions.push_back(graph); mFunctions.push_back(graph);
@ -173,20 +173,20 @@ void AdvancedAnalysis::linearXrefPass()
for(auto addr = mBase; addr < mBase + mSize;) for(auto addr = mBase; addr < mBase + mSize;)
{ {
if(!mCp.Disassemble(addr, translateAddr(addr))) if(!mZydis.Disassemble(addr, translateAddr(addr)))
{ {
addr++; addr++;
continue; continue;
} }
addr += mCp.Size(); addr += mZydis.Size();
XREF xref; XREF xref;
xref.valid = true; xref.valid = true;
xref.addr = 0; xref.addr = 0;
xref.from = mCp.Address(); xref.from = (duint)mZydis.Address();
for(auto i = 0; i < mCp.OpCount(); i++) for(auto i = 0; i < mZydis.OpCount(); i++)
{ {
duint dest = mCp.ResolveOpValue(i, [](ZydisRegister)->size_t auto dest = (duint)mZydis.ResolveOpValue(i, [](ZydisRegister) -> uint64_t
{ {
return 0; return 0;
}); });
@ -198,9 +198,9 @@ void AdvancedAnalysis::linearXrefPass()
} }
if(xref.addr) if(xref.addr)
{ {
if(mCp.IsCall()) if(mZydis.IsCall())
xref.type = XREF_CALL; xref.type = XREF_CALL;
else if(mCp.IsJump()) else if(mZydis.IsJump())
xref.type = XREF_JMP; xref.type = XREF_JMP;
else else
xref.type = XREF_DATA; xref.type = XREF_DATA;
@ -270,16 +270,16 @@ void AdvancedAnalysis::writeDataXrefs()
{ {
if(xref.type == XREF_DATA && xref.valid) if(xref.type == XREF_DATA && xref.valid)
{ {
if(!mCp.Disassemble(xref.from, translateAddr(xref.from))) if(!mZydis.Disassemble(xref.from, translateAddr(xref.from)))
{ {
xref.valid = false; xref.valid = false;
continue; continue;
} }
auto opcode = mCp.GetId(); auto opcode = mZydis.GetId();
bool isfloat = isFloatInstruction(opcode); bool isfloat = isFloatInstruction(opcode);
for(auto i = 0; i < mCp.OpCount(); i++) for(auto i = 0; i < mZydis.OpCount(); i++)
{ {
auto & op = mCp[i]; auto & op = mZydis[i];
ENCODETYPE type = enc_unknown; ENCODETYPE type = enc_unknown;
//Todo: Analyze op type and set correct type //Todo: Analyze op type and set correct type

View File

@ -17,7 +17,7 @@ protected:
duint mBase; duint mBase;
duint mSize; duint mSize;
unsigned char* mData; unsigned char* mData;
Zydis mCp; Zydis mZydis;
bool inRange(duint addr) const bool inRange(duint addr) const
{ {

View File

@ -140,26 +140,26 @@ void ControlFlowAnalysis::BasicBlockStarts()
for(duint i = 0; i < mSize;) for(duint i = 0; i < mSize;)
{ {
auto addr = mBase + i; auto addr = mBase + i;
if(mCp.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER)) if(mZydis.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER))
{ {
if(bSkipFilling) //handle filling skip mode if(bSkipFilling) //handle filling skip mode
{ {
if(!mCp.IsFilling()) //do nothing until the filling stopped if(!mZydis.IsFilling()) //do nothing until the filling stopped
{ {
bSkipFilling = false; bSkipFilling = false;
mBlockStarts.insert(addr); mBlockStarts.insert(addr);
} }
} }
else if(mCp.IsRet()) //RET breaks control flow else if(mZydis.IsRet()) //RET breaks control flow
{ {
bSkipFilling = true; //skip INT3/NOP/whatever filling bytes (those are not part of the control flow) bSkipFilling = true; //skip INT3/NOP/whatever filling bytes (those are not part of the control flow)
} }
else if(mCp.IsJump() || mCp.IsLoop()) //branches else if(mZydis.IsJump() || mZydis.IsLoop()) //branches
{ {
auto dest1 = getReferenceOperand(); auto dest1 = getReferenceOperand();
duint dest2 = 0; duint dest2 = 0;
if(mCp.GetId() != ZYDIS_MNEMONIC_JMP) //conditional jump if(mZydis.GetId() != ZYDIS_MNEMONIC_JMP) //conditional jump
dest2 = addr + mCp.Size(); dest2 = addr + mZydis.Size();
if(!dest1 && !dest2) //TODO: better code for this (make sure absolutely no filling is inserted) if(!dest1 && !dest2) //TODO: better code for this (make sure absolutely no filling is inserted)
bSkipFilling = true; bSkipFilling = true;
@ -168,7 +168,7 @@ void ControlFlowAnalysis::BasicBlockStarts()
if(dest2) if(dest2)
mBlockStarts.insert(dest2); mBlockStarts.insert(dest2);
} }
else if(mCp.IsCall()) else if(mZydis.IsCall())
{ {
auto dest1 = getReferenceOperand(); auto dest1 = getReferenceOperand();
if(dest1) if(dest1)
@ -183,7 +183,7 @@ void ControlFlowAnalysis::BasicBlockStarts()
if(dest1) if(dest1)
mBlockStarts.insert(dest1); mBlockStarts.insert(dest1);
} }
i += mCp.Size(); i += mZydis.Size();
} }
else else
i++; i++;
@ -204,23 +204,23 @@ void ControlFlowAnalysis::BasicBlocks()
for(duint addr = start, prevaddr; addr < mBase + mSize;) for(duint addr = start, prevaddr; addr < mBase + mSize;)
{ {
prevaddr = addr; prevaddr = addr;
if(mCp.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER)) if(mZydis.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER))
{ {
if(mCp.IsRet()) if(mZydis.IsRet())
{ {
insertBlock(BasicBlock(start, addr, 0, 0)); //leaf block insertBlock(BasicBlock(start, addr, 0, 0)); //leaf block
break; break;
} }
else if(mCp.IsJump() || mCp.IsLoop()) else if(mZydis.IsJump() || mZydis.IsLoop())
{ {
auto dest1 = getReferenceOperand(); auto dest1 = getReferenceOperand();
auto dest2 = mCp.GetId() != ZYDIS_MNEMONIC_JMP ? addr + mCp.Size() : 0; auto dest2 = mZydis.GetId() != ZYDIS_MNEMONIC_JMP ? addr + mZydis.Size() : 0;
insertBlock(BasicBlock(start, addr, dest1, dest2)); insertBlock(BasicBlock(start, addr, dest1, dest2));
insertParent(dest1, start); insertParent(dest1, start);
insertParent(dest2, start); insertParent(dest2, start);
break; break;
} }
addr += mCp.Size(); addr += mZydis.Size();
} }
else else
addr++; addr++;
@ -413,9 +413,9 @@ String ControlFlowAnalysis::blockToString(const BasicBlock* block)
duint ControlFlowAnalysis::getReferenceOperand() const duint ControlFlowAnalysis::getReferenceOperand() const
{ {
for(auto i = 0; i < mCp.OpCount(); i++) for(auto i = 0; i < mZydis.OpCount(); i++)
{ {
const auto & op = mCp[i]; const auto & op = mZydis[i];
if(op.type == ZYDIS_OPERAND_TYPE_IMMEDIATE) if(op.type == ZYDIS_OPERAND_TYPE_IMMEDIATE)
{ {
auto dest = duint(op.imm.value.u); auto dest = duint(op.imm.value.u);
@ -426,7 +426,7 @@ duint ControlFlowAnalysis::getReferenceOperand() const
{ {
auto dest = duint(op.mem.disp.value); auto dest = duint(op.mem.disp.value);
if(op.mem.base == ZYDIS_REGISTER_RIP) //rip-relative if(op.mem.base == ZYDIS_REGISTER_RIP) //rip-relative
dest += mCp.Address() + mCp.Size(); dest += (duint)mZydis.Address() + mZydis.Size();
if(inRange(dest)) if(inRange(dest))
return dest; return dest;
} }

View File

@ -45,12 +45,12 @@ void LinearAnalysis::populateReferences()
for(duint i = 0; i < mSize;) for(duint i = 0; i < mSize;)
{ {
auto addr = mBase + i; auto addr = mBase + i;
if(mCp.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER)) if(mZydis.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER))
{ {
auto ref = getReferenceOperand(); auto ref = getReferenceOperand();
if(ref) if(ref)
mFunctions.push_back({ ref, 0 }); mFunctions.push_back({ ref, 0 });
i += mCp.Size(); i += mZydis.Size();
} }
else else
i++; i++;
@ -72,8 +72,8 @@ void LinearAnalysis::analyseFunctions()
auto end = findFunctionEnd(function.start, maxaddr); auto end = findFunctionEnd(function.start, maxaddr);
if(end) if(end)
{ {
if(mCp.Disassemble(end, translateAddr(end), MAX_DISASM_BUFFER)) if(mZydis.Disassemble(end, translateAddr(end), MAX_DISASM_BUFFER))
function.end = end + mCp.Size() - 1; function.end = end + mZydis.Size() - 1;
else else
function.end = end; function.end = end;
} }
@ -83,10 +83,10 @@ void LinearAnalysis::analyseFunctions()
duint LinearAnalysis::findFunctionEnd(duint start, duint maxaddr) duint LinearAnalysis::findFunctionEnd(duint start, duint maxaddr)
{ {
//disassemble first instruction for some heuristics //disassemble first instruction for some heuristics
if(mCp.Disassemble(start, translateAddr(start), MAX_DISASM_BUFFER)) if(mZydis.Disassemble(start, translateAddr(start), MAX_DISASM_BUFFER))
{ {
//JMP [123456] ; import //JMP [123456] ; import
if(mCp.IsJump() && mCp.OpCount() && mCp[0].type == ZYDIS_OPERAND_TYPE_MEMORY) if(mZydis.IsJump() && mZydis.OpCount() && mZydis[0].type == ZYDIS_OPERAND_TYPE_MEMORY)
return 0; return 0;
} }
@ -95,14 +95,14 @@ duint LinearAnalysis::findFunctionEnd(duint start, duint maxaddr)
duint jumpback = 0; duint jumpback = 0;
for(duint addr = start, fardest = 0; addr < maxaddr;) for(duint addr = start, fardest = 0; addr < maxaddr;)
{ {
if(mCp.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER)) if(mZydis.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER))
{ {
if(addr + mCp.Size() > maxaddr) //we went past the maximum allowed address if(addr + mZydis.Size() > maxaddr) //we went past the maximum allowed address
break; break;
if((mCp.IsJump() || mCp.IsLoop()) && mCp.OpCount() && mCp[0].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) //jump if((mZydis.IsJump() || mZydis.IsLoop()) && mZydis.OpCount() && mZydis[0].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) //jump
{ {
auto dest = duint(mCp[0].imm.value.u); auto dest = duint(mZydis[0].imm.value.u);
if(dest >= maxaddr) //jump across function boundaries if(dest >= maxaddr) //jump across function boundaries
{ {
@ -112,19 +112,19 @@ duint LinearAnalysis::findFunctionEnd(duint start, duint maxaddr)
{ {
fardest = dest; fardest = dest;
} }
else if(end && dest < end && (mCp.GetId() == ZYDIS_MNEMONIC_JMP || mCp.GetId() == ZYDIS_MNEMONIC_LOOP)) //save the last JMP backwards else if(end && dest < end && (mZydis.GetId() == ZYDIS_MNEMONIC_JMP || mZydis.GetId() == ZYDIS_MNEMONIC_LOOP)) //save the last JMP backwards
{ {
jumpback = addr; jumpback = addr;
} }
} }
else if(mCp.IsRet()) //possible function end? else if(mZydis.IsRet()) //possible function end?
{ {
end = addr; end = addr;
if(fardest < addr) //we stop if the farthest JXX destination forward is before this RET if(fardest < addr) //we stop if the farthest JXX destination forward is before this RET
break; break;
} }
addr += mCp.Size(); addr += mZydis.Size();
} }
else else
addr++; addr++;
@ -134,10 +134,10 @@ duint LinearAnalysis::findFunctionEnd(duint start, duint maxaddr)
duint LinearAnalysis::getReferenceOperand() const duint LinearAnalysis::getReferenceOperand() const
{ {
for(auto i = 0; i < mCp.OpCount(); i++) for(auto i = 0; i < mZydis.OpCount(); i++)
{ {
const auto & op = mCp[i]; const auto & op = mZydis[i];
if(mCp.IsJump() || mCp.IsLoop()) //skip jumps/loops if(mZydis.IsJump() || mZydis.IsLoop()) //skip jumps/loops
continue; continue;
if(op.type == ZYDIS_OPERAND_TYPE_IMMEDIATE) //we are looking for immediate references if(op.type == ZYDIS_OPERAND_TYPE_IMMEDIATE) //we are looking for immediate references
{ {

View File

@ -59,11 +59,11 @@ void RecursiveAnalysis::SetMarkers()
duint rangeStart = 0, rangeEnd = 0, rangeInstructionCount = 0; duint rangeStart = 0, rangeEnd = 0, rangeInstructionCount = 0;
for(auto rangeItr = blockRanges.begin(); rangeItr != blockRanges.end(); ++rangeItr) for(auto rangeItr = blockRanges.begin(); rangeItr != blockRanges.end(); ++rangeItr)
{ {
auto disasmLen = [this](duint addr) auto disasmLen = [this](duint addr) -> size_t
{ {
if(!mCp.Disassemble(addr, translateAddr(addr))) if(!mZydis.Disassemble(addr, translateAddr(addr)))
return 1; return 1;
return mCp.Size(); return mZydis.Size();
}; };
const auto & node = *rangeItr->second; const auto & node = *rangeItr->second;
if(!rangeStart) if(!rangeStart)
@ -171,14 +171,14 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
{ {
if(!inRange(node.end)) if(!inRange(node.end))
{ {
node.end = mCp.Address(); node.end = (duint)mZydis.Address();
node.terminal = true; node.terminal = true;
graph.AddNode(node); graph.AddNode(node);
break; break;
} }
node.icount++; node.icount++;
if(!mCp.Disassemble(node.end, translateAddr(node.end))) if(!mZydis.Disassemble(node.end, translateAddr(node.end)))
{ {
node.end++; node.end++;
continue; continue;
@ -187,10 +187,10 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
//do xref analysis on the instruction //do xref analysis on the instruction
XREF xref; XREF xref;
xref.addr = 0; xref.addr = 0;
xref.from = mCp.Address(); xref.from = (duint)mZydis.Address();
for(auto i = 0; i < mCp.OpCount(); i++) for(auto i = 0; i < mZydis.OpCount(); i++)
{ {
duint dest = mCp.ResolveOpValue(i, [](ZydisRegister)->size_t auto dest = (duint)mZydis.ResolveOpValue(i, [](ZydisRegister) -> uint64_t
{ {
return 0; return 0;
}); });
@ -203,23 +203,23 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
if(xref.addr) if(xref.addr)
mXrefs.push_back(xref); mXrefs.push_back(xref);
if(!mCp.IsNop() && (mCp.IsJump() || mCp.IsLoop())) //non-nop jump if(!mZydis.IsNop() && (mZydis.IsJump() || mZydis.IsLoop())) //non-nop jump
{ {
//set the branch destinations //set the branch destinations
node.brtrue = mCp.BranchDestination(); node.brtrue = (duint)mZydis.BranchDestination();
if(mCp.GetId() != ZYDIS_MNEMONIC_JMP) //unconditional jumps dont have a brfalse if(mZydis.GetId() != ZYDIS_MNEMONIC_JMP) //unconditional jumps dont have a brfalse
node.brfalse = node.end + mCp.Size(); node.brfalse = node.end + mZydis.Size();
//consider register/memory branches as terminal nodes //consider register/memory branches as terminal nodes
if(mCp.OpCount() && mCp[0].type != ZYDIS_OPERAND_TYPE_IMMEDIATE) if(mZydis.OpCount() && mZydis[0].type != ZYDIS_OPERAND_TYPE_IMMEDIATE)
{ {
//jmp ptr [index * sizeof(duint) + switchTable] //jmp ptr [index * sizeof(duint) + switchTable]
if(mCp[0].type == ZYDIS_OPERAND_TYPE_MEMORY && mCp[0].mem.base == ZYDIS_REGISTER_NONE && mCp[0].mem.index != ZYDIS_REGISTER_NONE if(mZydis[0].type == ZYDIS_OPERAND_TYPE_MEMORY && mZydis[0].mem.base == ZYDIS_REGISTER_NONE && mZydis[0].mem.index != ZYDIS_REGISTER_NONE
&& mCp[0].mem.scale == sizeof(duint) && MemIsValidReadPtr(duint(mCp[0].mem.disp.value))) && mZydis[0].mem.scale == sizeof(duint) && MemIsValidReadPtr(duint(mZydis[0].mem.disp.value)))
{ {
Memory<duint*> switchTable(512 * sizeof(duint)); Memory<duint*> switchTable(512 * sizeof(duint));
duint actualSize, index; duint actualSize, index;
MemRead(duint(mCp[0].mem.disp.value), switchTable(), 512 * sizeof(duint), &actualSize); MemRead(duint(mZydis[0].mem.disp.value), switchTable(), 512 * sizeof(duint), &actualSize);
actualSize /= sizeof(duint); actualSize /= sizeof(duint);
for(index = 0; index < actualSize; index++) for(index = 0; index < actualSize; index++)
if(MemIsCodePage(switchTable()[index], false) == false) if(MemIsCodePage(switchTable()[index], false) == false)
@ -257,17 +257,17 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
break; break;
} }
if(mCp.IsCall()) if(mZydis.IsCall())
{ {
//TODO: add this to a queue to be analyzed later //TODO: add this to a queue to be analyzed later
} }
if(mCp.IsRet()) if(mZydis.IsRet())
{ {
node.terminal = true; node.terminal = true;
graph.AddNode(node); graph.AddNode(node);
break; break;
} }
node.end += mCp.Size(); node.end += mZydis.Size();
} }
} }
//second pass: split overlapping blocks introduced by backedges //second pass: split overlapping blocks introduced by backedges
@ -279,7 +279,7 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
while(addr < node.end) while(addr < node.end)
{ {
icount++; icount++;
auto size = mCp.Disassemble(addr, translateAddr(addr)) ? mCp.Size() : 1; auto size = mZydis.Disassemble(addr, translateAddr(addr)) ? mZydis.Size() : 1;
if(graph.nodes.count(addr + size)) if(graph.nodes.count(addr + size))
{ {
node.end = addr; node.end = addr;
@ -312,10 +312,10 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
auto addr = node.start; auto addr = node.start;
while(addr <= node.end) //disassemble all instructions while(addr <= node.end) //disassemble all instructions
{ {
auto size = mCp.Disassemble(addr, translateAddr(addr)) ? mCp.Size() : 1; auto size = mZydis.Disassemble(addr, translateAddr(addr)) ? mZydis.Size() : 1;
if(mCp.IsCall() && mCp.OpCount()) //call reg / call [reg+X] if(mZydis.IsCall() && mZydis.OpCount()) //call reg / call [reg+X]
{ {
auto & op = mCp[0]; auto & op = mZydis[0];
switch(op.type) switch(op.type)
{ {
case ZYDIS_OPERAND_TYPE_REGISTER: case ZYDIS_OPERAND_TYPE_REGISTER:

View File

@ -17,19 +17,19 @@ void XrefsAnalysis::Analyse()
for(auto addr = mBase; addr < mBase + mSize;) for(auto addr = mBase; addr < mBase + mSize;)
{ {
if(!mCp.Disassemble(addr, translateAddr(addr))) if(!mZydis.Disassemble(addr, translateAddr(addr)))
{ {
addr++; addr++;
continue; continue;
} }
addr += mCp.Size(); addr += mZydis.Size();
XREF xref; XREF xref;
xref.addr = 0; xref.addr = 0;
xref.from = mCp.Address(); xref.from = (duint)mZydis.Address();
for(auto i = 0; i < mCp.OpCount(); i++) for(auto i = 0; i < mZydis.OpCount(); i++)
{ {
duint dest = mCp.ResolveOpValue(i, [](ZydisRegister)->size_t auto dest = (duint)mZydis.ResolveOpValue(i, [](ZydisRegister) -> uint64_t
{ {
return 0; return 0;
}); });

View File

@ -504,7 +504,7 @@ static bool IsRepeated(const Zydis & zydis)
case ZYDIS_MNEMONIC_SCASW: case ZYDIS_MNEMONIC_SCASW:
case ZYDIS_MNEMONIC_SCASD: case ZYDIS_MNEMONIC_SCASD:
case ZYDIS_MNEMONIC_SCASQ: case ZYDIS_MNEMONIC_SCASQ:
return (zydis.GetInstr()->attributes & (ZYDIS_ATTRIB_HAS_REP | ZYDIS_ATTRIB_HAS_REPZ | ZYDIS_ATTRIB_HAS_REPNZ)) != 0; return (zydis.GetInstr()->info.attributes & (ZYDIS_ATTRIB_HAS_REP | ZYDIS_ATTRIB_HAS_REPZ | ZYDIS_ATTRIB_HAS_REPNZ)) != 0;
} }
return false; return false;
} }

View File

@ -710,9 +710,9 @@ static bool cbModCallFind(Zydis* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFI
duint foundaddr = 0; duint foundaddr = 0;
char label[MAX_LABEL_SIZE] = ""; char label[MAX_LABEL_SIZE] = "";
char module[MAX_MODULE_SIZE] = ""; char module[MAX_MODULE_SIZE] = "";
duint base = ModBaseFromAddr(disasm->Address()), size = 0; duint base = ModBaseFromAddr((duint)disasm->Address()), size = 0;
if(!base) if(!base)
base = MemFindBaseAddr(disasm->Address(), &size); base = MemFindBaseAddr((duint)disasm->Address(), &size);
else else
size = ModSizeFromAddr(base); size = ModSizeFromAddr(base);
if(!base || !size) if(!base || !size)

View File

@ -243,23 +243,26 @@ bool cbInstrZydis(int argc, char* argv[])
if(!valfromstring(argv[2], &addr, false)) if(!valfromstring(argv[2], &addr, false))
return false; return false;
Zydis cp; Zydis zydis;
if(!cp.Disassemble(addr, data)) if(!zydis.Disassemble(addr, data))
{ {
dputs_untranslated("Failed to disassemble!\n"); dputs_untranslated("Failed to disassemble!\n");
return false; return false;
} }
auto instr = cp.GetInstr(); auto instr = zydis.GetInstr();
int argcount = instr->operandCount; int argcount = zydis.OpCount();
dputs_untranslated(cp.InstructionText(true).c_str()); dputs_untranslated(zydis.InstructionText(true).c_str());
dprintf_untranslated("prefix size: %d\n", instr->raw.prefixes.count); dprintf_untranslated("prefix size: %d\n", instr->info.raw.prefix_count);
if(instr->attributes & ZYDIS_ATTRIB_HAS_REX) if(instr->info.attributes & ZYDIS_ATTRIB_HAS_REX)
dprintf_untranslated("rex.W: %d, rex.R: %d, rex.X: %d, rex.B: %d, rex.data: %02x\n", instr->raw.rex.W, instr->raw.rex.R, instr->raw.rex.X, instr->raw.rex.B, instr->raw.rex.data[0]); {
dprintf_untranslated("disp.offset: %d, disp.size: %d\n", instr->raw.disp.offset, instr->raw.disp.size); auto rexdata = data[instr->info.raw.rex.offset];
dprintf_untranslated("imm[0].offset: %d, imm[0].size: %d\n", instr->raw.imm[0].offset, instr->raw.imm[0].size); dprintf_untranslated("rex.W: %d, rex.R: %d, rex.X: %d, rex.B: %d, rex.data: %02x\n", instr->info.raw.rex.W, instr->info.raw.rex.R, instr->info.raw.rex.X, instr->info.raw.rex.B, rexdata);
dprintf_untranslated("imm[1].offset: %d, imm[1].size: %d\n", instr->raw.imm[1].offset, instr->raw.imm[1].size); }
dprintf_untranslated("size: %d, id: %d, opcount: %d\n", cp.Size(), cp.GetId(), instr->operandCount); dprintf_untranslated("disp.offset: %d, disp.size: %d\n", instr->info.raw.disp.offset, instr->info.raw.disp.size);
dprintf_untranslated("imm[0].offset: %d, imm[0].size: %d\n", instr->info.raw.imm[0].offset, instr->info.raw.imm[0].size);
dprintf_untranslated("imm[1].offset: %d, imm[1].size: %d\n", instr->info.raw.imm[1].offset, instr->info.raw.imm[1].size);
dprintf_untranslated("size: %d, id: %d, opcount: %d\n", zydis.Size(), zydis.GetId(), instr->info.operand_count);
auto rwstr = [](uint8_t action) auto rwstr = [](uint8_t action)
{ {
switch(action) switch(action)
@ -297,11 +300,11 @@ bool cbInstrZydis(int argc, char* argv[])
for(int i = 0; i < argcount; i++) for(int i = 0; i < argcount; i++)
{ {
const auto & op = instr->operands[i]; const auto & op = instr->operands[i];
dprintf("operand %d (size: %d, access: %s, visibility: %s) \"%s\", ", i + 1, op.size, rwstr(op.action), vis(op.visibility), cp.OperandText(i).c_str()); dprintf("operand %d (size: %d, access: %s, visibility: %s) \"%s\", ", i + 1, op.size, rwstr(op.actions), vis(op.visibility), zydis.OperandText(i).c_str());
switch(op.type) switch(op.type)
{ {
case ZYDIS_OPERAND_TYPE_REGISTER: case ZYDIS_OPERAND_TYPE_REGISTER:
dprintf_untranslated("register: %s\n", cp.RegName(op.reg.value)); dprintf_untranslated("register: %s\n", zydis.RegName(op.reg.value));
break; break;
case ZYDIS_OPERAND_TYPE_IMMEDIATE: case ZYDIS_OPERAND_TYPE_IMMEDIATE:
dprintf_untranslated("immediate: 0x%p\n", op.imm.value.u); dprintf_untranslated("immediate: 0x%p\n", op.imm.value.u);
@ -311,9 +314,9 @@ bool cbInstrZydis(int argc, char* argv[])
//[base + index * scale +/- disp] //[base + index * scale +/- disp]
const auto & mem = op.mem; const auto & mem = op.mem;
dprintf_untranslated("memory segment: %s, base: %s, index: %s, scale: %d, displacement: 0x%p\n", dprintf_untranslated("memory segment: %s, base: %s, index: %s, scale: %d, displacement: 0x%p\n",
cp.RegName(mem.segment), zydis.RegName(mem.segment),
cp.RegName(mem.base), zydis.RegName(mem.base),
cp.RegName(mem.index), zydis.RegName(mem.index),
mem.scale, mem.scale,
mem.disp.value); mem.disp.value);
} }
@ -348,7 +351,7 @@ bool cbInstrVisualize(int argc, char* argv[])
//DisassemblyBreakpointColor = #000000 //DisassemblyBreakpointColor = #000000
{ {
//initialize //initialize
Zydis _cp; Zydis zydis;
duint _base = start; duint _base = start;
duint _size = maxaddr - start; duint _size = maxaddr - start;
Memory<unsigned char*> _data(_size); Memory<unsigned char*> _data(_size);
@ -376,14 +379,14 @@ bool cbInstrVisualize(int argc, char* argv[])
//continue algorithm //continue algorithm
const unsigned char* curData = (addr >= _base && addr < _base + _size) ? _data() + (addr - _base) : nullptr; const unsigned char* curData = (addr >= _base && addr < _base + _size) ? _data() + (addr - _base) : nullptr;
if(_cp.Disassemble(addr, curData, MAX_DISASM_BUFFER)) if(zydis.Disassemble(addr, curData, MAX_DISASM_BUFFER))
{ {
if(addr + _cp.Size() > maxaddr) //we went past the maximum allowed address if(addr + zydis.Size() > maxaddr) //we went past the maximum allowed address
break; break;
if((_cp.IsJump() || _cp.IsLoop()) && _cp.OpCount() && _cp[0].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) //jump if((zydis.IsJump() || zydis.IsLoop()) && zydis.OpCount() && zydis[0].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) //jump
{ {
duint dest = (duint)_cp[0].imm.value.u; duint dest = (duint)zydis[0].imm.value.u;
if(dest >= maxaddr) //jump across function boundaries if(dest >= maxaddr) //jump across function boundaries
{ {
@ -393,19 +396,19 @@ bool cbInstrVisualize(int argc, char* argv[])
{ {
fardest = dest; fardest = dest;
} }
else if(end && dest < end && _cp.GetId() == ZYDIS_MNEMONIC_JMP) //save the last JMP backwards else if(end && dest < end && zydis.GetId() == ZYDIS_MNEMONIC_JMP) //save the last JMP backwards
{ {
jumpback = addr; jumpback = addr;
} }
} }
else if(_cp.IsRet()) //possible function end? else if(zydis.IsRet()) //possible function end?
{ {
end = addr; end = addr;
if(fardest < addr) //we stop if the farthest JXX destination forward is before this RET if(fardest < addr) //we stop if the farthest JXX destination forward is before this RET
break; break;
} }
addr += _cp.Size(); addr += zydis.Size();
} }
else else
addr++; addr++;
@ -471,22 +474,22 @@ bool cbInstrBriefcheck(int argc, char* argv[])
return false; return false;
Memory<unsigned char*> buffer(size + 16); Memory<unsigned char*> buffer(size + 16);
DbgMemRead(base, buffer(), size); DbgMemRead(base, buffer(), size);
Zydis cp; Zydis zydis;
std::unordered_set<String> reported; std::unordered_set<String> reported;
for(duint i = 0; i < size;) for(duint i = 0; i < size;)
{ {
if(!cp.Disassemble(base + i, buffer() + i, 16)) if(!zydis.Disassemble(base + i, buffer() + i, 16))
{ {
i++; i++;
continue; continue;
} }
i += cp.Size(); i += zydis.Size();
auto mnem = StringUtils::ToLower(cp.Mnemonic()); auto mnem = StringUtils::ToLower(zydis.Mnemonic());
auto brief = MnemonicHelp::getBriefDescription(mnem.c_str()); auto brief = MnemonicHelp::getBriefDescription(mnem.c_str());
if(brief.length() || reported.count(mnem)) if(brief.length() || reported.count(mnem))
continue; continue;
reported.insert(mnem); reported.insert(mnem);
dprintf_untranslated("%p: %s\n", cp.Address(), mnem.c_str()); dprintf_untranslated("%p: %s\n", zydis.Address(), mnem.c_str());
} }
return true; return true;
} }

View File

@ -1263,8 +1263,8 @@ void cbRtrStep()
#endif //_WIN64 #endif //_WIN64
) )
{ {
Zydis cp; Zydis zydis;
if(cp.Disassemble(cip, data) && cp.IsRet()) if(zydis.Disassemble(cip, data) && zydis.IsRet())
reachedReturn = true; reachedReturn = true;
} }
} }

View File

@ -83,17 +83,17 @@ bool disasmfast(const unsigned char* data, duint addr, BASIC_INSTRUCTION_INFO* b
{ {
if(!data || !basicinfo) if(!data || !basicinfo)
return false; return false;
Zydis cp; Zydis zydis;
cp.Disassemble(addr, data, MAX_DISASM_BUFFER); zydis.Disassemble(addr, data, MAX_DISASM_BUFFER);
if(trydisasmfast(data, addr, basicinfo, cp.Success() ? cp.Size() : 1)) if(trydisasmfast(data, addr, basicinfo, zydis.Success() ? zydis.Size() : 1))
return true; return true;
if(!cp.Success()) if(!zydis.Success())
{ {
strcpy_s(basicinfo->instruction, "???"); strcpy_s(basicinfo->instruction, "???");
basicinfo->size = 1; basicinfo->size = 1;
return false; return false;
} }
fillbasicinfo(&cp, basicinfo); fillbasicinfo(&zydis, basicinfo);
return true; return true;
} }

View File

@ -22,7 +22,7 @@ duint disasmback(unsigned char* data, duint base, duint size, duint ip, int n)
unsigned char* pdata; unsigned char* pdata;
// Reset Disasm Structure // Reset Disasm Structure
Zydis cp; Zydis zydis;
// Check if the pointer is not null // Check if the pointer is not null
if(data == NULL) if(data == NULL)
@ -58,10 +58,10 @@ duint disasmback(unsigned char* data, duint base, duint size, duint ip, int n)
{ {
abuf[i % 128] = addr; abuf[i % 128] = addr;
if(!cp.Disassemble(0, pdata, (int)size)) if(!zydis.Disassemble(0, pdata, (int)size))
cmdsize = 1; cmdsize = 1;
else else
cmdsize = cp.Size(); cmdsize = zydis.Size();
pdata += cmdsize; pdata += cmdsize;
addr += cmdsize; addr += cmdsize;
@ -82,7 +82,7 @@ duint disasmnext(unsigned char* data, duint base, duint size, duint ip, int n)
unsigned char* pdata; unsigned char* pdata;
// Reset Disasm Structure // Reset Disasm Structure
Zydis cp; Zydis zydis;
if(data == NULL) if(data == NULL)
return 0; return 0;
@ -98,10 +98,10 @@ duint disasmnext(unsigned char* data, duint base, duint size, duint ip, int n)
for(i = 0; i < n && size > 0; i++) for(i = 0; i < n && size > 0; i++)
{ {
if(!cp.Disassemble(0, pdata, (int)size)) if(!zydis.Disassemble(0, pdata, (int)size))
cmdsize = 1; cmdsize = 1;
else else
cmdsize = cp.Size(); cmdsize = zydis.Size();
pdata += cmdsize; pdata += cmdsize;
ip += cmdsize; ip += cmdsize;
@ -111,16 +111,16 @@ duint disasmnext(unsigned char* data, duint base, duint size, duint ip, int n)
return ip; return ip;
} }
static void HandleZydisOperand(Zydis & cp, int opindex, DISASM_ARG* arg, bool getregs) static void HandleZydisOperand(Zydis & zydis, int opindex, DISASM_ARG* arg, bool getregs)
{ {
auto value = cp.ResolveOpValue(opindex, [&cp, getregs](ZydisRegister reg) auto value = (duint)zydis.ResolveOpValue(opindex, [&zydis, getregs](ZydisRegister reg)
{ {
auto regName = getregs ? cp.RegName(reg) : nullptr; auto regName = getregs ? zydis.RegName(reg) : nullptr;
return regName ? getregister(nullptr, regName) : 0; //TODO: temporary needs enums + caching return regName ? getregister(nullptr, regName) : 0; //TODO: temporary needs enums + caching
}); });
const auto & op = cp[opindex]; const auto & op = zydis[opindex];
arg->segment = SEG_DEFAULT; arg->segment = SEG_DEFAULT;
auto opText = cp.OperandText(opindex); auto opText = zydis.OperandText(opindex);
StringUtils::ReplaceAll(opText, "0x", ""); StringUtils::ReplaceAll(opText, "0x", "");
strcpy_s(arg->mnemonic, opText.c_str()); strcpy_s(arg->mnemonic, opText.c_str());
switch(op.type) switch(op.type)
@ -144,7 +144,7 @@ static void HandleZydisOperand(Zydis & cp, int opindex, DISASM_ARG* arg, bool ge
arg->type = arg_memory; arg->type = arg_memory;
const auto & mem = op.mem; const auto & mem = op.mem;
if(mem.base == ZYDIS_REGISTER_RIP) //rip-relative if(mem.base == ZYDIS_REGISTER_RIP) //rip-relative
arg->constant = cp.Address() + duint(mem.disp.value) + cp.Size(); arg->constant = (duint)zydis.Address() + duint(mem.disp.value) + zydis.Size();
else else
arg->constant = duint(mem.disp.value); arg->constant = duint(mem.disp.value);
if(mem.segment == ArchValue(ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS)) if(mem.segment == ArchValue(ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS))
@ -216,13 +216,13 @@ static void HandleZydisOperand(Zydis & cp, int opindex, DISASM_ARG* arg, bool ge
} }
} }
void disasmget(Zydis & cp, unsigned char* buffer, duint addr, DISASM_INSTR* instr, bool getregs) void disasmget(Zydis & zydis, unsigned char* buffer, duint addr, DISASM_INSTR* instr, bool getregs)
{ {
memset(instr, 0, sizeof(DISASM_INSTR)); memset(instr, 0, sizeof(DISASM_INSTR));
cp.Disassemble(addr, buffer, MAX_DISASM_BUFFER); zydis.Disassemble(addr, buffer, MAX_DISASM_BUFFER);
if(trydisasm(buffer, addr, instr, cp.Success() ? cp.Size() : 1)) if(trydisasm(buffer, addr, instr, zydis.Success() ? zydis.Size() : 1))
return; return;
if(!cp.Success()) if(!zydis.Success())
{ {
strcpy_s(instr->instruction, "???"); strcpy_s(instr->instruction, "???");
instr->instr_size = 1; instr->instr_size = 1;
@ -230,21 +230,21 @@ void disasmget(Zydis & cp, unsigned char* buffer, duint addr, DISASM_INSTR* inst
instr->argcount = 0; instr->argcount = 0;
return; return;
} }
auto cpInstr = cp.GetInstr(); auto zyInstr = zydis.GetInstr();
strncpy_s(instr->instruction, cp.InstructionText().c_str(), _TRUNCATE); strncpy_s(instr->instruction, zydis.InstructionText().c_str(), _TRUNCATE);
instr->instr_size = cpInstr->length; instr->instr_size = zyInstr->info.length;
if(cp.IsBranchType(Zydis::BTJmp | Zydis::BTLoop | Zydis::BTRet | Zydis::BTCall)) if(zydis.IsBranchType(Zydis::BTJmp | Zydis::BTLoop | Zydis::BTRet | Zydis::BTCall))
instr->type = instr_branch; instr->type = instr_branch;
else if(strstr(instr->instruction, "sp") || strstr(instr->instruction, "bp")) else if(strstr(instr->instruction, "sp") || strstr(instr->instruction, "bp"))
instr->type = instr_stack; instr->type = instr_stack;
else else
instr->type = instr_normal; instr->type = instr_normal;
instr->argcount = cp.OpCount() <= 3 ? cp.OpCount() : 3; instr->argcount = zydis.OpCount() <= 3 ? zydis.OpCount() : 3;
for(int i = 0; i < instr->argcount; i++) for(int i = 0; i < instr->argcount; i++)
HandleZydisOperand(cp, i, &instr->arg[i], getregs); HandleZydisOperand(zydis, i, &instr->arg[i], getregs);
} }
void disasmget(Zydis & cp, duint addr, DISASM_INSTR* instr, bool getregs) void disasmget(Zydis & zydis, duint addr, DISASM_INSTR* instr, bool getregs)
{ {
if(!DbgIsDebugging()) if(!DbgIsDebugging())
{ {
@ -254,15 +254,15 @@ void disasmget(Zydis & cp, duint addr, DISASM_INSTR* instr, bool getregs)
} }
unsigned char buffer[MAX_DISASM_BUFFER] = ""; unsigned char buffer[MAX_DISASM_BUFFER] = "";
if(MemRead(addr, buffer, sizeof(buffer))) if(MemRead(addr, buffer, sizeof(buffer)))
disasmget(cp, buffer, addr, instr, getregs); disasmget(zydis, buffer, addr, instr, getregs);
else else
memset(instr, 0, sizeof(DISASM_INSTR)); // Buffer overflow memset(instr, 0, sizeof(DISASM_INSTR)); // Buffer overflow
} }
void disasmget(unsigned char* buffer, duint addr, DISASM_INSTR* instr, bool getregs) void disasmget(unsigned char* buffer, duint addr, DISASM_INSTR* instr, bool getregs)
{ {
Zydis cp; Zydis zydis;
disasmget(cp, buffer, addr, instr, getregs); disasmget(zydis, buffer, addr, instr, getregs);
} }
void disasmget(duint addr, DISASM_INSTR* instr, bool getregs) void disasmget(duint addr, DISASM_INSTR* instr, bool getregs)
@ -532,10 +532,10 @@ bool disasmgetstringatwrapper(duint addr, char* dest, bool cache)
int disasmgetsize(duint addr, unsigned char* data) int disasmgetsize(duint addr, unsigned char* data)
{ {
Zydis cp; Zydis zydis;
if(!cp.Disassemble(addr, data, MAX_DISASM_BUFFER)) if(!zydis.Disassemble(addr, data, MAX_DISASM_BUFFER))
return 1; return 1;
return int(EncodeMapGetSize(addr, cp.Size())); return int(EncodeMapGetSize(addr, zydis.Size()));
} }
int disasmgetsize(duint addr) int disasmgetsize(duint addr)

View File

@ -7,8 +7,8 @@
//functions //functions
duint disasmback(unsigned char* data, duint base, duint size, duint ip, int n); duint disasmback(unsigned char* data, duint base, duint size, duint ip, int n);
duint disasmnext(unsigned char* data, duint base, duint size, duint ip, int n); duint disasmnext(unsigned char* data, duint base, duint size, duint ip, int n);
void disasmget(Zydis & cp, unsigned char* buffer, duint addr, DISASM_INSTR* instr, bool getregs = true); void disasmget(Zydis & zydis, unsigned char* buffer, duint addr, DISASM_INSTR* instr, bool getregs = true);
void disasmget(Zydis & cp, duint addr, DISASM_INSTR* instr, bool getregs = true); void disasmget(Zydis & zydis, duint addr, DISASM_INSTR* instr, bool getregs = true);
void disasmget(unsigned char* buffer, duint addr, DISASM_INSTR* instr, bool getregs = true); void disasmget(unsigned char* buffer, duint addr, DISASM_INSTR* instr, bool getregs = true);
void disasmget(duint addr, DISASM_INSTR* instr, bool getregs = true); void disasmget(duint addr, DISASM_INSTR* instr, bool getregs = true);
bool disasmispossiblestring(duint addr, STRING_TYPE* type = nullptr); bool disasmispossiblestring(duint addr, STRING_TYPE* type = nullptr);

View File

@ -287,7 +287,7 @@ bool EncodeMapSetType(duint addr, duint size, ENCODETYPE type, bool* created)
memset(map.data + offset, (byte)enc_middle, size); memset(map.data + offset, (byte)enc_middle, size);
if(IsCodeType(type) && size > 1) if(IsCodeType(type) && size > 1)
{ {
Zydis cp; Zydis zydis;
Memory<unsigned char*> buffer(size); Memory<unsigned char*> buffer(size);
if(!MemRead(addr, buffer(), size)) if(!MemRead(addr, buffer(), size))
return false; return false;
@ -296,8 +296,8 @@ bool EncodeMapSetType(duint addr, duint size, ENCODETYPE type, bool* created)
for(auto i = offset; i < offset + size;) for(auto i = offset; i < offset + size;)
{ {
map.data[i] = (byte)type; map.data[i] = (byte)type;
cp.Disassemble(base + i, buffer() + bufferoffset, int(buffersize - bufferoffset)); zydis.Disassemble(base + i, buffer() + bufferoffset, int(buffersize - bufferoffset));
cmdsize = cp.Success() ? cp.Size() : 1; cmdsize = zydis.Success() ? zydis.Size() : 1;
i += cmdsize; i += cmdsize;
bufferoffset += cmdsize; bufferoffset += cmdsize;
buffersize -= cmdsize; buffersize -= cmdsize;

View File

@ -282,9 +282,9 @@ namespace Exprfunc
unsigned char data[16]; unsigned char data[16];
if(MemRead(addr, data, sizeof(data), nullptr, true)) if(MemRead(addr, data, sizeof(data), nullptr, true))
{ {
Zydis cp; Zydis zydis;
if(cp.Disassemble(addr, data)) if(zydis.Disassemble(addr, data))
return cp.IsNop(); return zydis.IsNop();
} }
return false; return false;
} }
@ -294,9 +294,9 @@ namespace Exprfunc
unsigned char data[16]; unsigned char data[16];
if(MemRead(addr, data, sizeof(data), nullptr, true)) if(MemRead(addr, data, sizeof(data), nullptr, true))
{ {
Zydis cp; Zydis zydis;
if(cp.Disassemble(addr, data)) if(zydis.Disassemble(addr, data))
return cp.IsUnusual(); return zydis.IsUnusual();
} }
return false; return false;
} }
@ -455,7 +455,7 @@ namespace Exprfunc
duint rdtsc() duint rdtsc()
{ {
return __rdtsc(); return (duint)__rdtsc();
} }
static duint readMem(duint addr, duint size) static duint readMem(duint addr, duint size)

View File

@ -63,14 +63,14 @@ int RefFind(duint Address, duint Size, CBREF Callback, void* UserData, bool Sile
sprintf_s(fullName, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "%s (Region %p)")), Name, scanStart); sprintf_s(fullName, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "%s (Region %p)")), Name, scanStart);
// Initialize disassembler // Initialize disassembler
Zydis cp; Zydis zydis;
// Allow an "initialization" notice // Allow an "initialization" notice
refInfo.refcount = 0; refInfo.refcount = 0;
refInfo.userinfo = UserData; refInfo.userinfo = UserData;
refInfo.name = fullName; refInfo.name = fullName;
RefFindInRange(scanStart, scanSize, Callback, UserData, Silent, refInfo, cp, true, [](int percent) RefFindInRange(scanStart, scanSize, Callback, UserData, Silent, refInfo, zydis, true, [](int percent)
{ {
GuiReferenceSetCurrentTaskProgress(percent, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Region Search"))); GuiReferenceSetCurrentTaskProgress(percent, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Region Search")));
GuiReferenceSetProgress(percent); GuiReferenceSetProgress(percent);
@ -104,14 +104,14 @@ int RefFind(duint Address, duint Size, CBREF Callback, void* UserData, bool Sile
sprintf_s(fullName, "%s (%p)", Name, scanStart); sprintf_s(fullName, "%s (%p)", Name, scanStart);
// Initialize disassembler // Initialize disassembler
Zydis cp; Zydis zydis;
// Allow an "initialization" notice // Allow an "initialization" notice
refInfo.refcount = 0; refInfo.refcount = 0;
refInfo.userinfo = UserData; refInfo.userinfo = UserData;
refInfo.name = fullName; refInfo.name = fullName;
RefFindInRange(scanStart, scanSize, Callback, UserData, Silent, refInfo, cp, true, [](int percent) RefFindInRange(scanStart, scanSize, Callback, UserData, Silent, refInfo, zydis, true, [](int percent)
{ {
GuiReferenceSetCurrentTaskProgress(percent, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Module Search"))); GuiReferenceSetCurrentTaskProgress(percent, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Module Search")));
GuiReferenceSetProgress(percent); GuiReferenceSetProgress(percent);
@ -147,7 +147,7 @@ int RefFind(duint Address, duint Size, CBREF Callback, void* UserData, bool Sile
} }
// Initialize disassembler // Initialize disassembler
Zydis cp; Zydis zydis;
// Determine the full module // Determine the full module
sprintf_s(fullName, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "User Modules (%s)")), Name); sprintf_s(fullName, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "User Modules (%s)")), Name);
@ -165,7 +165,7 @@ int RefFind(duint Address, duint Size, CBREF Callback, void* UserData, bool Sile
scanStart = modList[i].base; scanStart = modList[i].base;
scanSize = modList[i].size; scanSize = modList[i].size;
RefFindInRange(scanStart, scanSize, Callback, UserData, Silent, refInfo, cp, initCallBack, [&i, &modList](int percent) RefFindInRange(scanStart, scanSize, Callback, UserData, Silent, refInfo, zydis, initCallBack, [&i, &modList](int percent)
{ {
float fPercent = (float)percent / 100.f; float fPercent = (float)percent / 100.f;
float fTotalPercent = ((float)i + fPercent) / (float)modList.size(); float fTotalPercent = ((float)i + fPercent) / (float)modList.size();
@ -209,7 +209,7 @@ int RefFind(duint Address, duint Size, CBREF Callback, void* UserData, bool Sile
} }
// Initialize disassembler // Initialize disassembler
Zydis cp; Zydis zydis;
// Determine the full module // Determine the full module
sprintf_s(fullName, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "System Modules (%s)")), Name); sprintf_s(fullName, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "System Modules (%s)")), Name);
@ -228,7 +228,7 @@ int RefFind(duint Address, duint Size, CBREF Callback, void* UserData, bool Sile
scanSize = modList[i].size; scanSize = modList[i].size;
RefFindInRange(scanStart, scanSize, Callback, UserData, Silent, refInfo, cp, initCallBack, [&i, &modList](int percent) RefFindInRange(scanStart, scanSize, Callback, UserData, Silent, refInfo, zydis, initCallBack, [&i, &modList](int percent)
{ {
float fPercent = (float)percent / 100.f; float fPercent = (float)percent / 100.f;
float fTotalPercent = ((float)i + fPercent) / (float)modList.size(); float fTotalPercent = ((float)i + fPercent) / (float)modList.size();
@ -271,7 +271,7 @@ int RefFind(duint Address, duint Size, CBREF Callback, void* UserData, bool Sile
} }
// Initialize disassembler // Initialize disassembler
Zydis cp; Zydis zydis;
// Determine the full module // Determine the full module
sprintf_s(fullName, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "All Modules (%s)")), Name); sprintf_s(fullName, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "All Modules (%s)")), Name);
@ -289,7 +289,7 @@ int RefFind(duint Address, duint Size, CBREF Callback, void* UserData, bool Sile
if(i != 0) if(i != 0)
initCallBack = false; initCallBack = false;
RefFindInRange(scanStart, scanSize, Callback, UserData, Silent, refInfo, cp, initCallBack, [&i, &modList](int percent) RefFindInRange(scanStart, scanSize, Callback, UserData, Silent, refInfo, zydis, initCallBack, [&i, &modList](int percent)
{ {
float fPercent = (float)percent / 100.f; float fPercent = (float)percent / 100.f;
float fTotalPercent = ((float)i + fPercent) / (float)modList.size(); float fTotalPercent = ((float)i + fPercent) / (float)modList.size();
@ -309,7 +309,7 @@ int RefFind(duint Address, duint Size, CBREF Callback, void* UserData, bool Sile
return refInfo.refcount; return refInfo.refcount;
} }
int RefFindInRange(duint scanStart, duint scanSize, CBREF Callback, void* UserData, bool Silent, REFINFO & refInfo, Zydis & cp, bool initCallBack, const CBPROGRESS & cbUpdateProgress, bool disasmText) int RefFindInRange(duint scanStart, duint scanSize, CBREF Callback, void* UserData, bool Silent, REFINFO & refInfo, Zydis & zydis, bool initCallBack, const CBPROGRESS & cbUpdateProgress, bool disasmText)
{ {
// Allocate and read a buffer from the remote process // Allocate and read a buffer from the remote process
Memory<unsigned char*> data(scanSize, "reffind:data"); Memory<unsigned char*> data(scanSize, "reffind:data");
@ -339,15 +339,15 @@ int RefFindInRange(duint scanStart, duint scanSize, CBREF Callback, void* UserDa
int disasmMaxSize = min(MAX_DISASM_BUFFER, (int)(scanSize - i)); // Prevent going past the boundary int disasmMaxSize = min(MAX_DISASM_BUFFER, (int)(scanSize - i)); // Prevent going past the boundary
int disasmLen = 1; int disasmLen = 1;
if(cp.Disassemble(scanStart, data() + i, disasmMaxSize)) if(zydis.Disassemble(scanStart, data() + i, disasmMaxSize))
{ {
BASIC_INSTRUCTION_INFO basicinfo; BASIC_INSTRUCTION_INFO basicinfo;
fillbasicinfo(&cp, &basicinfo, disasmText); fillbasicinfo(&zydis, &basicinfo, disasmText);
if(Callback(&cp, &basicinfo, &refInfo)) if(Callback(&zydis, &basicinfo, &refInfo))
refInfo.refcount++; refInfo.refcount++;
disasmLen = cp.Size(); disasmLen = zydis.Size();
} }
else else
{ {

View File

@ -26,6 +26,6 @@ typedef bool (*CBREF)(Zydis* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO*
typedef std::function<void(int)> CBPROGRESS; typedef std::function<void(int)> CBPROGRESS;
int RefFind(duint Address, duint Size, CBREF Callback, void* UserData, bool Silent, const char* Name, REFFINDTYPE type, bool disasmText); int RefFind(duint Address, duint Size, CBREF Callback, void* UserData, bool Silent, const char* Name, REFFINDTYPE type, bool disasmText);
int RefFindInRange(duint scanStart, duint scanSize, CBREF Callback, void* UserData, bool Silent, REFINFO & refInfo, Zydis & cp, bool initCallBack, const CBPROGRESS & cbUpdateProgress, bool disasmText); int RefFindInRange(duint scanStart, duint scanSize, CBREF Callback, void* UserData, bool Silent, REFINFO & refInfo, Zydis & zydis, bool initCallBack, const CBPROGRESS & cbUpdateProgress, bool disasmText);
#endif // _REFERENCE_H #endif // _REFERENCE_H

View File

@ -699,8 +699,6 @@ extern "C" DLL_EXPORT const char* _dbg_dbginit()
dputs(QT_TRANSLATE_NOOP("DBG", "Setting JSON memory management functions...")); dputs(QT_TRANSLATE_NOOP("DBG", "Setting JSON memory management functions..."));
json_set_alloc_funcs(json_malloc, json_free); json_set_alloc_funcs(json_malloc, json_free);
//#endif //ENABLE_MEM_TRACE //#endif //ENABLE_MEM_TRACE
dputs(QT_TRANSLATE_NOOP("DBG", "Initializing Zydis..."));
Zydis::GlobalInitialize();
dputs(QT_TRANSLATE_NOOP("DBG", "Getting directory information...")); dputs(QT_TRANSLATE_NOOP("DBG", "Getting directory information..."));
strcpy_s(scriptDllDir, szUserDir); strcpy_s(scriptDllDir, szUserDir);
@ -833,7 +831,6 @@ extern "C" DLL_EXPORT void _dbg_dbgexitsignal()
dputs(QT_TRANSLATE_NOOP("DBG", "Cleaning up allocated data...")); dputs(QT_TRANSLATE_NOOP("DBG", "Cleaning up allocated data..."));
cmdfree(); cmdfree();
varfree(); varfree();
Zydis::GlobalFinalize();
dputs(QT_TRANSLATE_NOOP("DBG", "Cleaning up wait objects...")); dputs(QT_TRANSLATE_NOOP("DBG", "Cleaning up wait objects..."));
waitdeinitialize(); waitdeinitialize();
SafeDbghelpDeinitialize(); SafeDbghelpDeinitialize();

View File

@ -19,11 +19,11 @@ public:
virtual void unlock() = 0; virtual void unlock() = 0;
virtual AbstractStdTable* list() const = 0; virtual AbstractStdTable* list() const = 0;
virtual AbstractStdTable* searchList() const = 0; virtual AbstractStdTable* searchList() const = 0;
virtual void filter(const QString & filter, FilterType type, int startColumn) = 0; virtual void filter(const QString & filter, FilterType type, duint startColumn) = 0;
bool rowMatchesFilter(const QString & filter, FilterType type, int row, int startColumn) const bool rowMatchesFilter(const QString & filter, FilterType type, duint row, duint startColumn) const
{ {
int count = list()->getColumnCount(); auto count = list()->getColumnCount();
if(startColumn + 1 > count) if(startColumn + 1 > count)
return false; return false;
auto cs = Qt::CaseInsensitive; auto cs = Qt::CaseInsensitive;
@ -32,21 +32,21 @@ public:
case FilterStartsWithTextCaseSensitive: case FilterStartsWithTextCaseSensitive:
cs = Qt::CaseSensitive; cs = Qt::CaseSensitive;
case FilterStartsWithTextCaseInsensitive: case FilterStartsWithTextCaseInsensitive:
for(int i = startColumn; i < count; i++) for(duint i = startColumn; i < count; i++)
if(list()->getCellContent(row, i).startsWith(filter, cs)) if(list()->getCellContent(row, i).startsWith(filter, cs))
return true; return true;
break; break;
case FilterContainsTextCaseSensitive: case FilterContainsTextCaseSensitive:
cs = Qt::CaseSensitive; cs = Qt::CaseSensitive;
case FilterContainsTextCaseInsensitive: case FilterContainsTextCaseInsensitive:
for(int i = startColumn; i < count; i++) for(duint i = startColumn; i < count; i++)
if(list()->getCellContent(row, i).contains(filter, cs)) if(list()->getCellContent(row, i).contains(filter, cs))
return true; return true;
break; break;
case FilterRegexCaseSensitive: case FilterRegexCaseSensitive:
cs = Qt::CaseSensitive; cs = Qt::CaseSensitive;
case FilterRegexCaseInsensitive: case FilterRegexCaseInsensitive:
for(int i = startColumn; i < count; i++) for(duint i = startColumn; i < count; i++)
if(list()->getCellContent(row, i).contains(QRegExp(filter, cs))) if(list()->getCellContent(row, i).contains(QRegExp(filter, cs)))
return true; return true;
break; break;

View File

@ -8,7 +8,7 @@ AbstractStdTable::AbstractStdTable(QWidget* parent) : AbstractTableView(parent)
connect(Bridge::getBridge(), SIGNAL(repaintTableView()), this, SLOT(reloadData())); connect(Bridge::getBridge(), SIGNAL(repaintTableView()), this, SLOT(reloadData()));
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequestedSlot(QPoint))); connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequestedSlot(QPoint)));
connect(this, SIGNAL(headerButtonPressed(int)), this, SLOT(headerButtonPressedSlot(int))); connect(this, SIGNAL(headerButtonPressed(duint)), this, SLOT(headerButtonPressedSlot(duint)));
Initialize(); Initialize();
@ -22,27 +22,27 @@ AbstractStdTable::AbstractStdTable(QWidget* parent) : AbstractTableView(parent)
mExportTableCSV = makeShortcutAction(DIcon("database-export"), tr("&Export Table"), SLOT(exportTableSlot()), "ActionExport"); mExportTableCSV = makeShortcutAction(DIcon("database-export"), tr("&Export Table"), SLOT(exportTableSlot()), "ActionExport");
} }
QString AbstractStdTable::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) QString AbstractStdTable::paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h)
{ {
bool isaddr = DbgIsDebugging() && getRowCount() > 0 && col == mAddressColumn; bool isaddr = DbgIsDebugging() && getRowCount() > 0 && col == mAddressColumn;
bool wIsSelected = isSelected(rowBase, rowOffset); bool rowSelected = isSelected(row);
QString text = getCellContent(rowBase + rowOffset, col); QString text = getCellContent(row, col);
duint wVA = isaddr ? duint(text.toULongLong(&isaddr, 16)) : 0; duint va = isaddr ? duint(text.toULongLong(&isaddr, 16)) : 0;
auto wIsTraced = isaddr && DbgFunctions()->GetTraceRecordHitCount(wVA) != 0; auto rowTraced = isaddr && DbgFunctions()->GetTraceRecordHitCount(va) != 0;
QColor lineBackgroundColor; QColor lineBackgroundColor;
bool isBackgroundColorSet; bool isBackgroundColorSet;
if(wIsSelected && wIsTraced) if(rowSelected && rowTraced)
{ {
lineBackgroundColor = mTracedSelectedAddressBackgroundColor; lineBackgroundColor = mTracedSelectedAddressBackgroundColor;
isBackgroundColorSet = true; isBackgroundColorSet = true;
} }
else if(wIsSelected) else if(rowSelected)
{ {
lineBackgroundColor = mSelectionColor; lineBackgroundColor = mSelectionColor;
isBackgroundColorSet = true; isBackgroundColorSet = true;
} }
else if(wIsTraced) else if(rowTraced)
{ {
lineBackgroundColor = mTracedBackgroundColor; lineBackgroundColor = mTracedBackgroundColor;
isBackgroundColorSet = true; isBackgroundColorSet = true;
@ -57,16 +57,16 @@ QString AbstractStdTable::paintContent(QPainter* painter, dsint rowBase, int row
if(col == mAddressColumn && isaddr) if(col == mAddressColumn && isaddr)
{ {
char label[MAX_LABEL_SIZE] = ""; char label[MAX_LABEL_SIZE] = "";
if(bAddressLabel && DbgGetLabelAt(wVA, SEG_DEFAULT, label)) //has label if(bAddressLabel && DbgGetLabelAt(va, SEG_DEFAULT, label)) //has label
{ {
char module[MAX_MODULE_SIZE] = ""; char module[MAX_MODULE_SIZE] = "";
if(DbgGetModuleAt(wVA, module) && !QString(label).startsWith("JMP.&")) if(DbgGetModuleAt(va, module) && !QString(label).startsWith("JMP.&"))
text += " <" + QString(module) + "." + QString(label) + ">"; text += " <" + QString(module) + "." + QString(label) + ">";
else else
text += " <" + QString(label) + ">"; text += " <" + QString(label) + ">";
} }
BPXTYPE bpxtype = DbgGetBpxTypeAt(wVA); BPXTYPE bpxtype = DbgGetBpxTypeAt(va);
bool isbookmark = DbgGetBookmarkAt(wVA); bool isbookmark = DbgGetBookmarkAt(va);
duint cip = Bridge::getBridge()->mLastCip; duint cip = Bridge::getBridge()->mLastCip;
if(bCipBase) if(bCipBase)
@ -76,7 +76,7 @@ QString AbstractStdTable::paintContent(QPainter* painter, dsint rowBase, int row
cip = base; cip = base;
} }
if(DbgIsDebugging() && wVA == cip) //debugging + cip if(DbgIsDebugging() && va == cip) //debugging + cip
{ {
painter->fillRect(QRect(x, y, w, h), QBrush(mCipBackgroundColor)); painter->fillRect(QRect(x, y, w, h), QBrush(mCipBackgroundColor));
if(!isbookmark) //no bookmark if(!isbookmark) //no bookmark
@ -149,7 +149,7 @@ QString AbstractStdTable::paintContent(QPainter* painter, dsint rowBase, int row
if(bpxtype == bp_none) //no label, no breakpoint if(bpxtype == bp_none) //no label, no breakpoint
{ {
QColor background; QColor background;
if(wIsSelected) if(rowSelected)
{ {
background = mSelectedAddressBackgroundColor; background = mSelectedAddressBackgroundColor;
painter->setPen(mSelectedAddressColor); //black address (DisassemblySelectedAddressColor) painter->setPen(mSelectedAddressColor); //black address (DisassemblySelectedAddressColor)
@ -177,7 +177,7 @@ QString AbstractStdTable::paintContent(QPainter* painter, dsint rowBase, int row
else //other cases (memory breakpoint in disassembly) -> do as normal else //other cases (memory breakpoint in disassembly) -> do as normal
{ {
QColor background; QColor background;
if(wIsSelected) if(rowSelected)
{ {
background = mSelectedAddressBackgroundColor; background = mSelectedAddressBackgroundColor;
painter->setPen(mSelectedAddressColor); //black address (DisassemblySelectedAddressColor) painter->setPen(mSelectedAddressColor); //black address (DisassemblySelectedAddressColor)
@ -265,12 +265,12 @@ QString AbstractStdTable::paintContent(QPainter* painter, dsint rowBase, int row
} }
} }
while(index != -1); while(index != -1);
QStringList split = text.split(QChar('\1'), QString::SkipEmptyParts, Qt::CaseInsensitive); QStringList split = text.split(QChar('\1'), Qt::SkipEmptyParts, Qt::CaseInsensitive);
//create rich text list //create rich text list
RichTextPainter::CustomRichText_t curRichText; RichTextPainter::CustomRichText_t curRichText;
curRichText.flags = RichTextPainter::FlagColor; curRichText.flags = RichTextPainter::FlagColor;
QColor textColor = getCellColor(rowBase + rowOffset, col); QColor textColor = getCellColor(row, col);
QColor textBackgroundColor = Qt::transparent; QColor textBackgroundColor = Qt::transparent;
QColor highlightColor = ConfigColor("SearchListViewHighlightColor"); QColor highlightColor = ConfigColor("SearchListViewHighlightColor");
QColor highlightBackgroundColor = ConfigColor("SearchListViewHighlightBackgroundColor"); QColor highlightBackgroundColor = ConfigColor("SearchListViewHighlightBackgroundColor");
@ -326,7 +326,7 @@ void AbstractStdTable::updateColors()
void AbstractStdTable::mouseMoveEvent(QMouseEvent* event) void AbstractStdTable::mouseMoveEvent(QMouseEvent* event)
{ {
bool wAccept = true; bool accept = true;
int y = transY(event->y()); int y = transY(event->y());
if(mGuiState == AbstractStdTable::MultiRowsSelectionState) if(mGuiState == AbstractStdTable::MultiRowsSelectionState)
@ -335,18 +335,19 @@ void AbstractStdTable::mouseMoveEvent(QMouseEvent* event)
if(y >= 0 && y <= this->getTableHeight()) if(y >= 0 && y <= this->getTableHeight())
{ {
int wRowIndex = getTableOffset() + getIndexOffsetFromY(y); auto rowIndex = getTableOffset() + getIndexOffsetFromY(y);
if(wRowIndex < getRowCount()) if(rowIndex < getRowCount())
{ {
if(mIsMultiSelectionAllowed) if(mIsMultiSelectionAllowed)
expandSelectionUpTo(wRowIndex); expandSelectionUpTo(rowIndex);
else else
setSingleSelection(wRowIndex); setSingleSelection(rowIndex);
// TODO: only update if the selection actually changed
updateViewport(); updateViewport();
wAccept = false; accept = false;
} }
} }
else if(y < 0) else if(y < 0)
@ -359,13 +360,13 @@ void AbstractStdTable::mouseMoveEvent(QMouseEvent* event)
} }
} }
if(wAccept) if(accept)
AbstractTableView::mouseMoveEvent(event); AbstractTableView::mouseMoveEvent(event);
} }
void AbstractStdTable::mousePressEvent(QMouseEvent* event) void AbstractStdTable::mousePressEvent(QMouseEvent* event)
{ {
bool wAccept = false; bool accept = false;
if(((event->buttons() & Qt::LeftButton) != 0) && ((event->buttons() & Qt::RightButton) == 0)) if(((event->buttons() & Qt::LeftButton) != 0) && ((event->buttons() & Qt::RightButton) == 0))
{ {
@ -373,26 +374,27 @@ void AbstractStdTable::mousePressEvent(QMouseEvent* event)
{ {
if(event->y() > getHeaderHeight()) if(event->y() > getHeaderHeight())
{ {
int wRowIndex = getTableOffset() + getIndexOffsetFromY(transY(event->y())); auto rowIndex = getTableOffset() + getIndexOffsetFromY(transY(event->y()));
if(wRowIndex < getRowCount()) if(rowIndex < getRowCount())
{ {
if(mIsMultiSelectionAllowed && (event->modifiers() & Qt::ShiftModifier)) if(mIsMultiSelectionAllowed && (event->modifiers() & Qt::ShiftModifier))
expandSelectionUpTo(wRowIndex); expandSelectionUpTo(rowIndex);
else else
setSingleSelection(wRowIndex); setSingleSelection(rowIndex);
mGuiState = AbstractStdTable::MultiRowsSelectionState; mGuiState = AbstractStdTable::MultiRowsSelectionState;
// TODO: only update if the selection actually changed
updateViewport(); updateViewport();
wAccept = true; accept = true;
} }
} }
} }
} }
if(!wAccept) if(!accept)
AbstractTableView::mousePressEvent(event); AbstractTableView::mousePressEvent(event);
} }
@ -405,7 +407,7 @@ void AbstractStdTable::mouseDoubleClickEvent(QMouseEvent* event)
void AbstractStdTable::mouseReleaseEvent(QMouseEvent* event) void AbstractStdTable::mouseReleaseEvent(QMouseEvent* event)
{ {
bool wAccept = true; bool accept = true;
if((event->buttons() & Qt::LeftButton) == 0) if((event->buttons() & Qt::LeftButton) == 0)
{ {
@ -413,13 +415,11 @@ void AbstractStdTable::mouseReleaseEvent(QMouseEvent* event)
{ {
mGuiState = AbstractStdTable::NoState; mGuiState = AbstractStdTable::NoState;
updateViewport(); accept = false;
wAccept = false;
} }
} }
if(wAccept) if(accept)
AbstractTableView::mouseReleaseEvent(event); AbstractTableView::mouseReleaseEvent(event);
} }
@ -436,8 +436,8 @@ void AbstractStdTable::keyPressEvent(QKeyEvent* event)
key == Qt::Key_A || key == Qt::Key_A ||
key == Qt::Key_C) key == Qt::Key_C)
{ {
dsint wBotIndex = getTableOffset(); auto botIndex = getTableOffset();
dsint wTopIndex = wBotIndex + getNbrOfLineToPrint() - 1; auto topIndex = botIndex + getNbrOfLineToPrint() - 1;
switch(key) switch(key)
{ {
@ -500,15 +500,16 @@ void AbstractStdTable::keyPressEvent(QKeyEvent* event)
break; break;
} }
if(getInitialSelection() < wBotIndex) if(getInitialSelection() < botIndex)
{ {
setTableOffset(getInitialSelection()); setTableOffset(getInitialSelection());
} }
else if(getInitialSelection() >= wTopIndex) else if(getInitialSelection() >= topIndex)
{ {
setTableOffset(getInitialSelection() - getNbrOfLineToPrint() + 2); setTableOffset(getInitialSelection() - getNbrOfLineToPrint() + 2);
} }
// TODO: only update if the selection actually changed
updateViewport(); updateViewport();
} }
else else
@ -530,19 +531,19 @@ void AbstractStdTable::enableColumnSorting(bool enabled)
/************************************************************************************ /************************************************************************************
Selection Management Selection Management
************************************************************************************/ ************************************************************************************/
void AbstractStdTable::expandSelectionUpTo(int to) void AbstractStdTable::expandSelectionUpTo(duint to)
{ {
if(to < mSelection.firstSelectedIndex) if(to < mSelection.firstSelectedIndex)
{ {
mSelection.fromIndex = to; mSelection.fromIndex = to;
mSelection.toIndex = mSelection.firstSelectedIndex; mSelection.toIndex = mSelection.firstSelectedIndex;
emit selectionChangedSignal(to); emit selectionChanged(to);
} }
else if(to > mSelection.firstSelectedIndex) else if(to > mSelection.firstSelectedIndex)
{ {
mSelection.fromIndex = mSelection.firstSelectedIndex; mSelection.fromIndex = mSelection.firstSelectedIndex;
mSelection.toIndex = to; mSelection.toIndex = to;
emit selectionChangedSignal(to); emit selectionChanged(to);
} }
else if(to == mSelection.firstSelectedIndex) else if(to == mSelection.firstSelectedIndex)
{ {
@ -552,46 +553,46 @@ void AbstractStdTable::expandSelectionUpTo(int to)
void AbstractStdTable::expandUp() void AbstractStdTable::expandUp()
{ {
int wRowIndex = mSelection.firstSelectedIndex - 1; auto rowIndex = mSelection.firstSelectedIndex - 1;
if(wRowIndex >= 0) if(rowIndex >= 0)
{ {
if(wRowIndex < mSelection.fromIndex) if(rowIndex < mSelection.fromIndex)
{ {
mSelection.fromIndex = wRowIndex; mSelection.fromIndex = rowIndex;
mSelection.firstSelectedIndex = wRowIndex; mSelection.firstSelectedIndex = rowIndex;
} }
else else
{ {
mSelection.firstSelectedIndex = wRowIndex; mSelection.firstSelectedIndex = rowIndex;
mSelection.toIndex = wRowIndex; mSelection.toIndex = rowIndex;
} }
emit selectionChangedSignal(wRowIndex); emit selectionChanged(rowIndex);
} }
} }
void AbstractStdTable::expandDown() void AbstractStdTable::expandDown()
{ {
int wRowIndex = mSelection.firstSelectedIndex + 1; auto rowIndex = mSelection.firstSelectedIndex + 1;
int endIndex = getRowCount() - 1; auto endIndex = getRowCount() - 1;
if(wRowIndex <= endIndex) if(rowIndex <= endIndex)
{ {
if(wRowIndex > mSelection.toIndex) if(rowIndex > mSelection.toIndex)
{ {
mSelection.firstSelectedIndex = wRowIndex; mSelection.firstSelectedIndex = rowIndex;
mSelection.toIndex = wRowIndex; mSelection.toIndex = rowIndex;
} }
else else
{ {
mSelection.fromIndex = wRowIndex; mSelection.fromIndex = rowIndex;
mSelection.firstSelectedIndex = wRowIndex; mSelection.firstSelectedIndex = rowIndex;
} }
emit selectionChangedSignal(wRowIndex); emit selectionChanged(rowIndex);
} }
} }
@ -605,31 +606,31 @@ void AbstractStdTable::expandTop()
void AbstractStdTable::expandBottom() void AbstractStdTable::expandBottom()
{ {
int endIndex = getRowCount() - 1; auto rowCount = getRowCount();
if(endIndex >= 0) if(rowCount > 0)
{ {
expandSelectionUpTo(endIndex); expandSelectionUpTo(rowCount - 1);
} }
} }
void AbstractStdTable::setSingleSelection(int index) void AbstractStdTable::setSingleSelection(duint index)
{ {
mSelection.firstSelectedIndex = index; mSelection.firstSelectedIndex = index;
mSelection.fromIndex = index; mSelection.fromIndex = index;
mSelection.toIndex = index; mSelection.toIndex = index;
emit selectionChangedSignal(index); emit selectionChanged(index);
} }
int AbstractStdTable::getInitialSelection() const duint AbstractStdTable::getInitialSelection() const
{ {
return mSelection.firstSelectedIndex; return mSelection.firstSelectedIndex;
} }
QList<int> AbstractStdTable::getSelection() const QList<duint> AbstractStdTable::getSelection() const
{ {
QList<int> selection; QList<duint> selection;
selection.reserve(mSelection.toIndex - mSelection.fromIndex); selection.reserve(mSelection.toIndex - mSelection.fromIndex);
for(int i = mSelection.fromIndex; i <= mSelection.toIndex; i++) for(duint i = mSelection.fromIndex; i <= mSelection.toIndex; i++)
{ {
selection.append(i); selection.append(i);
} }
@ -646,7 +647,7 @@ void AbstractStdTable::selectStart()
void AbstractStdTable::selectEnd() void AbstractStdTable::selectEnd()
{ {
int endIndex = getRowCount() - 1; auto endIndex = getRowCount() - 1;
if(endIndex >= 0) if(endIndex >= 0)
{ {
setSingleSelection(endIndex); setSingleSelection(endIndex);
@ -655,60 +656,56 @@ void AbstractStdTable::selectEnd()
void AbstractStdTable::selectNext() void AbstractStdTable::selectNext()
{ {
int wNext = getInitialSelection() + 1; // TODO: fix the signed/unsigned
duint next = getInitialSelection() + 1;
// Bounding // Bounding
wNext = wNext > getRowCount() - 1 ? getRowCount() - 1 : wNext; next = next > getRowCount() - 1 ? getRowCount() - 1 : next;
wNext = wNext < 0 ? 0 : wNext; next = next < 0 ? 0 : next;
setSingleSelection(wNext); setSingleSelection(next);
} }
void AbstractStdTable::selectPrevious() void AbstractStdTable::selectPrevious()
{ {
int wNext = getInitialSelection() - 1; duint next = getInitialSelection() - 1;
// Bounding // Bounding
wNext = wNext > getRowCount() - 1 ? getRowCount() - 1 : wNext; next = next > getRowCount() - 1 ? getRowCount() - 1 : next;
wNext = wNext < 0 ? 0 : wNext; next = next < 0 ? 0 : next;
setSingleSelection(wNext); setSingleSelection(next);
} }
void AbstractStdTable::selectAll() void AbstractStdTable::selectAll()
{ {
int index = 0; duint index = 0;
int indexEnd = getRowCount() - 1; duint indexEnd = getRowCount() - 1;
mSelection.firstSelectedIndex = index; mSelection.firstSelectedIndex = index;
mSelection.fromIndex = index; mSelection.fromIndex = index;
mSelection.toIndex = indexEnd; mSelection.toIndex = indexEnd;
emit selectionChangedSignal(index); emit selectionChanged(index);
} }
bool AbstractStdTable::isSelected(int base, int offset) const bool AbstractStdTable::isSelected(duint row) const
{ {
int wIndex = base + offset; return row >= mSelection.fromIndex && row <= mSelection.toIndex;
if(wIndex >= mSelection.fromIndex && wIndex <= mSelection.toIndex)
return true;
else
return false;
} }
bool AbstractStdTable::scrollSelect(int offset) bool AbstractStdTable::scrollSelect(duint row)
{ {
if(!isValidIndex(offset, 0)) if(!isValidIndex(row, 0))
return false; return false;
int rangefrom = getTableOffset(); auto rangefrom = getTableOffset();
int rangeto = rangefrom + getViewableRowsCount() - 1; auto rangeto = rangefrom + getViewableRowsCount() - 1;
if(offset < rangefrom) //offset lays before the current view if(row < rangefrom) //offset lays before the current view
setTableOffset(offset); setTableOffset(row);
else if(offset > (rangeto - 1)) //offset lays after the current view else if(row > (rangeto - 1)) //offset lays after the current view
setTableOffset(offset - getViewableRowsCount() + 2); setTableOffset(row - getViewableRowsCount() + 2);
setSingleSelection(offset); setSingleSelection(row);
return true; return true;
} }
@ -735,15 +732,15 @@ void AbstractStdTable::deleteAllColumns()
void AbstractStdTable::copyLineSlot() void AbstractStdTable::copyLineSlot()
{ {
int colCount = getColumnCount(); auto colCount = getColumnCount();
QString finalText = ""; QString finalText = "";
if(colCount == 1) if(colCount == 1)
finalText = getCellContent(getInitialSelection(), 0); finalText = getCellContent(getInitialSelection(), 0);
else else
{ {
for(int selected : getSelection()) for(auto selected : getSelection())
{ {
for(int i = 0; i < colCount; i++) for(duint i = 0; i < colCount; i++)
{ {
QString cellContent = getCellContent(selected, i); QString cellContent = getCellContent(selected, i);
if(!cellContent.length()) //skip empty cells if(!cellContent.length()) //skip empty cells
@ -761,14 +758,14 @@ void AbstractStdTable::copyLineSlot()
void AbstractStdTable::copyLineToLogSlot() void AbstractStdTable::copyLineToLogSlot()
{ {
int colCount = getColumnCount(); auto colCount = getColumnCount();
int selected = getInitialSelection(); auto selected = getInitialSelection();
QString finalText = ""; QString finalText = "";
if(colCount == 1) if(colCount == 1)
finalText = getCellContent(selected, 0); finalText = getCellContent(selected, 0);
else else
{ {
for(int i = 0; i < colCount; i++) for(duint i = 0; i < colCount; i++)
{ {
QString cellContent = getCellContent(selected, i); QString cellContent = getCellContent(selected, i);
if(!cellContent.length()) //skip empty cells if(!cellContent.length()) //skip empty cells
@ -785,12 +782,12 @@ void AbstractStdTable::copyLineToLogSlot()
QString AbstractStdTable::copyTable(const std::vector<int> & colWidths) QString AbstractStdTable::copyTable(const std::vector<int> & colWidths)
{ {
int colCount = getColumnCount(); auto colCount = getColumnCount();
int rowCount = getRowCount(); auto rowCount = getRowCount();
QString finalText = ""; QString finalText = "";
if(colCount == 1) if(colCount == 1)
{ {
for(int i = 0; i < rowCount; i++) for(duint i = 0; i < rowCount; i++)
{ {
QString cellContent = getCellContent(i, 0); QString cellContent = getCellContent(i, 0);
if(!cellContent.length()) //skip empty cells if(!cellContent.length()) //skip empty cells
@ -803,7 +800,7 @@ QString AbstractStdTable::copyTable(const std::vector<int> & colWidths)
//std::vector<int> colWidths; //std::vector<int> colWidths;
//for(int i = 0; i < colCount; i++) //for(int i = 0; i < colCount; i++)
// colWidths.push_back(getMaxColumnLength(i)); // colWidths.push_back(getMaxColumnLength(i));
for(int i = 0; i < colCount; i++) for(duint i = 0; i < colCount; i++)
{ {
if(i) if(i)
finalText += " "; finalText += " ";
@ -814,10 +811,10 @@ QString AbstractStdTable::copyTable(const std::vector<int> & colWidths)
finalText += getColTitle(i); finalText += getColTitle(i);
} }
finalText += "\r\n"; finalText += "\r\n";
for(int i = 0; i < rowCount; i++) for(duint i = 0; i < rowCount; i++)
{ {
QString finalRowText = ""; QString finalRowText = "";
for(int j = 0; j < colCount; j++) for(duint j = 0; j < colCount; j++)
{ {
if(j) if(j)
finalRowText += " "; finalRowText += " ";
@ -855,12 +852,12 @@ void AbstractStdTable::copyTableToLogSlot()
void AbstractStdTable::copyTableResizeSlot() void AbstractStdTable::copyTableResizeSlot()
{ {
std::vector<int> colWidths; std::vector<int> colWidths;
int rowCount = getRowCount(); auto rowCount = getRowCount();
int colCount = getColumnCount(); auto colCount = getColumnCount();
for(int i = 0; i < colCount; i++) for(duint i = 0; i < colCount; i++)
{ {
int max = getCellContent(0, i).length(); auto max = getCellContent(0, i).length();
for(int j = 1; j < rowCount; j++) for(duint j = 1; j < rowCount; j++)
max = std::max(getCellContent(j, i).length(), max); max = std::max(getCellContent(j, i).length(), max);
colWidths.push_back(max); colWidths.push_back(max);
} }
@ -874,7 +871,7 @@ void AbstractStdTable::copyTableResizeToLogSlot()
int colCount = getColumnCount(); int colCount = getColumnCount();
for(int i = 0; i < colCount; i++) for(int i = 0; i < colCount; i++)
{ {
int max = getCellContent(0, i).length(); auto max = getCellContent(0, i).length();
for(int j = 1; j < rowCount; j++) for(int j = 1; j < rowCount; j++)
max = std::max(getCellContent(j, i).length(), max); max = std::max(getCellContent(j, i).length(), max);
colWidths.push_back(max); colWidths.push_back(max);
@ -897,7 +894,7 @@ void AbstractStdTable::exportTableSlot()
{ {
std::vector<QString> headers; std::vector<QString> headers;
headers.reserve(getColumnCount()); headers.reserve(getColumnCount());
for(int i = 0; i < getColumnCount(); i++) for(duint i = 0; i < getColumnCount(); i++)
headers.push_back(getColTitle(i)); headers.push_back(getColTitle(i));
ExportCSV(getRowCount(), getColumnCount(), headers, [this](duint row, duint column) ExportCSV(getRowCount(), getColumnCount(), headers, [this](duint row, duint column)
{ {
@ -934,7 +931,7 @@ void AbstractStdTable::setupCopyMenu(QMenu* copyMenu)
void AbstractStdTable::setupCopyColumnMenu(QMenu* copyMenu) void AbstractStdTable::setupCopyColumnMenu(QMenu* copyMenu)
{ {
for(int i = 0; i < getColumnCount(); i++) for(duint i = 0; i < getColumnCount(); i++)
{ {
if(!getCellContent(getInitialSelection(), i).length()) //skip empty cells if(!getCellContent(getInitialSelection(), i).length()) //skip empty cells
continue; continue;
@ -978,7 +975,7 @@ void AbstractStdTable::setupCopyColumnMenu(MenuBuilder* copyMenu)
{ {
copyMenu->addBuilder(new MenuBuilder(this, [this](QMenu * menu) copyMenu->addBuilder(new MenuBuilder(this, [this](QMenu * menu)
{ {
for(int i = 0; i < getColumnCount(); i++) for(duint i = 0; i < getColumnCount(); i++)
{ {
if(!getCellContent(getInitialSelection(), i).length()) //skip empty cells if(!getCellContent(getInitialSelection(), i).length()) //skip empty cells
continue; continue;
@ -1002,6 +999,8 @@ void AbstractStdTable::setCopyMenuOnly(bool bSet, bool bDebugOnly)
void AbstractStdTable::contextMenuRequestedSlot(const QPoint & pos) void AbstractStdTable::contextMenuRequestedSlot(const QPoint & pos)
{ {
if(pos.y() < getHeaderHeight())
return;
if(!mCopyMenuOnly) if(!mCopyMenuOnly)
{ {
emit contextMenuSignal(pos); emit contextMenuSignal(pos);
@ -1009,18 +1008,18 @@ void AbstractStdTable::contextMenuRequestedSlot(const QPoint & pos)
} }
if(mCopyMenuDebugOnly && !DbgIsDebugging()) if(mCopyMenuDebugOnly && !DbgIsDebugging())
return; return;
QMenu wMenu(this); auto menu = new QMenu(this);
QMenu wCopyMenu(tr("&Copy"), this); auto copyMenu = new QMenu(tr("&Copy"), this);
setupCopyMenu(&wCopyMenu); setupCopyMenu(copyMenu);
if(wCopyMenu.actions().length()) if(copyMenu->actions().length())
{ {
wMenu.addSeparator(); menu->addSeparator();
wMenu.addMenu(&wCopyMenu); menu->addMenu(copyMenu);
wMenu.exec(mapToGlobal(pos)); menu->popup(mapToGlobal(pos));
} }
} }
void AbstractStdTable::headerButtonPressedSlot(int col) void AbstractStdTable::headerButtonPressedSlot(duint col)
{ {
if(!mIsColumnSortingAllowed) if(!mIsColumnSortingAllowed)
return; return;
@ -1044,22 +1043,16 @@ void AbstractStdTable::reloadData()
AbstractTableView::reloadData(); AbstractTableView::reloadData();
} }
duint AbstractStdTable::getDisassemblyPopupAddress(int mousex, int mousey) duint AbstractStdTable::getAddressForPosition(int x, int y)
{ {
if(!bDisassemblyPopupEnabled) //No disassembly popup is meaningful for this table auto c = getColumnIndexFromX(x);
return 0; auto r = getTableOffset() + getIndexOffsetFromY(transY(y));
int c = getColumnIndexFromX(mousex);
int r = getTableOffset() + getIndexOffsetFromY(transY(mousey));
if(r < getRowCount()) if(r < getRowCount())
{ {
QString cell = getCellContent(r, c); QString cell = getCellContent(r, c);
duint addr; duint addr;
bool ok = false; bool ok = false;
#ifdef _WIN64
addr = cell.toULongLong(&ok, 16); addr = cell.toULongLong(&ok, 16);
#else //x86
addr = cell.toULong(&ok, 16);
#endif //_WIN64
if(!ok) if(!ok)
return 0; return 0;
else else

View File

@ -6,8 +6,8 @@ class AbstractStdTable : public AbstractTableView
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit AbstractStdTable(QWidget* parent = 0); explicit AbstractStdTable(QWidget* parent = nullptr);
QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) override; QString paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h) override;
void updateColors() override; void updateColors() override;
void reloadData() override; void reloadData() override;
@ -21,30 +21,29 @@ public:
void enableColumnSorting(bool enabled); void enableColumnSorting(bool enabled);
// Selection Management // Selection Management
void expandSelectionUpTo(int to); void expandSelectionUpTo(duint to);
void expandUp(); void expandUp();
void expandDown(); void expandDown();
void expandTop(); void expandTop();
void expandBottom(); void expandBottom();
void setSingleSelection(int index); void setSingleSelection(duint index);
int getInitialSelection() const; duint getInitialSelection() const;
QList<int> getSelection() const; QList<duint> getSelection() const;
void selectStart(); void selectStart();
void selectEnd(); void selectEnd();
void selectNext(); void selectNext();
void selectPrevious(); void selectPrevious();
void selectAll(); void selectAll();
bool isSelected(int base, int offset) const; bool isSelected(duint row) const;
bool scrollSelect(int offset); bool scrollSelect(duint row);
// Data Management // Data Management
void addColumnAt(int width, QString title, bool isClickable, QString copyTitle = ""); void addColumnAt(int width, QString title, bool isClickable, QString copyTitle = "");
void deleteAllColumns() override; void deleteAllColumns() override;
virtual QString getCellContent(int r, int c) = 0; virtual QString getCellContent(duint row, duint column) = 0;
virtual bool isValidIndex(int r, int c) = 0; virtual bool isValidIndex(duint row, duint column) = 0;
virtual void sortRows(int column, bool ascending) = 0; virtual void sortRows(duint column, bool ascending) = 0;
duint getDisassemblyPopupAddress(int mousex, int mousey) override;
//context menu helpers //context menu helpers
void setupCopyMenu(QMenu* copyMenu); void setupCopyMenu(QMenu* copyMenu);
@ -54,13 +53,13 @@ public:
void setCopyMenuOnly(bool bSet, bool bDebugOnly = true); void setCopyMenuOnly(bool bSet, bool bDebugOnly = true);
//draw helpers //draw helpers
void setHighlightText(QString highlightText, int minCol = 0) void setHighlightText(QString highlightText, duint minCol = 0)
{ {
mHighlightText = highlightText; mHighlightText = highlightText;
mMinimumHighlightColumn = minCol; mMinimumHighlightColumn = minCol;
} }
void setAddressColumn(int col, bool cipBase = false) void setAddressColumn(duint col, bool cipBase = false)
{ {
mAddressColumn = col; mAddressColumn = col;
bCipBase = cipBase; bCipBase = cipBase;
@ -71,13 +70,8 @@ public:
bAddressLabel = addressLabel; bAddressLabel = addressLabel;
} }
bool setDisassemblyPopupEnabled(bool enabled)
{
return bDisassemblyPopupEnabled = enabled;
}
signals: signals:
void selectionChangedSignal(int index); void selectionChanged(duint index);
void keyPressedSignal(QKeyEvent* event); void keyPressedSignal(QKeyEvent* event);
void doubleClickedSignal(); void doubleClickedSignal();
void contextMenuSignal(const QPoint & pos); void contextMenuSignal(const QPoint & pos);
@ -92,21 +86,22 @@ public slots:
void copyEntrySlot(); void copyEntrySlot();
void exportTableSlot(); void exportTableSlot();
void contextMenuRequestedSlot(const QPoint & pos); void contextMenuRequestedSlot(const QPoint & pos);
void headerButtonPressedSlot(int col); void headerButtonPressedSlot(duint col);
protected: protected:
QString copyTable(const std::vector<int> & colWidths); QString copyTable(const std::vector<int> & colWidths);
duint getAddressForPosition(int x, int y) override;
struct SelectionData struct SelectionData
{ {
int firstSelectedIndex = 0; duint firstSelectedIndex = 0;
int fromIndex = 0; duint fromIndex = 0;
int toIndex = 0; duint toIndex = 0;
}; };
SelectionData mSelection; SelectionData mSelection;
enum enum GuiState
{ {
NoState, NoState,
MultiRowsSelectionState MultiRowsSelectionState
@ -121,7 +116,7 @@ protected:
struct SortData struct SortData
{ {
int column = -1; duint column = -1;
bool ascending = true; bool ascending = true;
} mSort; } mSort;
@ -146,7 +141,6 @@ protected:
int mMinimumHighlightColumn = 0; int mMinimumHighlightColumn = 0;
int mAddressColumn = -1; int mAddressColumn = -1;
bool bAddressLabel = true; bool bAddressLabel = true;
bool bDisassemblyPopupEnabled = true;
QAction* mCopyLine; QAction* mCopyLine;
QAction* mCopyTable; QAction* mCopyTable;

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@
#include "ActionHelpers.h" #include "ActionHelpers.h"
class CachedFontMetrics; class CachedFontMetrics;
class DisassemblyPopup; class ColumnReorderDialog;
//Hacky class that fixes a really annoying cursor problem //Hacky class that fixes a really annoying cursor problem
class AbstractTableScrollBar : public QScrollBar class AbstractTableScrollBar : public QScrollBar
@ -22,8 +22,7 @@ class AbstractTableScrollBar : public QScrollBar
Q_OBJECT Q_OBJECT
public: public:
explicit AbstractTableScrollBar(QScrollBar* scrollbar); explicit AbstractTableScrollBar(QScrollBar* scrollbar);
void enterEvent(QEvent* event) override; bool event(QEvent* event) override;
void leaveEvent(QEvent* event) override;
}; };
class AbstractTableView; class AbstractTableView;
@ -32,17 +31,7 @@ class AbstractTableView : public QAbstractScrollArea, public ActionHelper<Abstra
Q_OBJECT Q_OBJECT
public: public:
enum GuiState explicit AbstractTableView(QWidget* parent = nullptr);
{
NoState,
ReadyToResize,
ResizeColumnState,
HeaderButtonPressed,
HeaderButtonReordering
};
// Constructor
explicit AbstractTableView(QWidget* parent = 0);
virtual ~AbstractTableView() = default; virtual ~AbstractTableView() = default;
// Configuration // Configuration
@ -51,8 +40,8 @@ public:
virtual void updateFonts(); virtual void updateFonts();
// Pure Virtual Methods // Pure Virtual Methods
virtual QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) = 0; virtual QString paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h) = 0;
virtual QColor getCellColor(int r, int c); virtual QColor getCellColor(duint row, duint col);
// Painting Stuff // Painting Stuff
void paintEvent(QPaintEvent* event) override; void paintEvent(QPaintEvent* event) override;
@ -65,53 +54,62 @@ public:
void wheelEvent(QWheelEvent* event) override; void wheelEvent(QWheelEvent* event) override;
void resizeEvent(QResizeEvent* event) override; void resizeEvent(QResizeEvent* event) override;
void keyPressEvent(QKeyEvent* event) override; void keyPressEvent(QKeyEvent* event) override;
void leaveEvent(QEvent* event) override;
void hideEvent(QHideEvent* event) override;
// ScrollBar Management // ScrollBar Management
virtual dsint sliderMovedHook(int type, dsint value, dsint delta); // can be made protected virtual duint sliderMovedHook(QScrollBar::SliderAction action, duint prevTableOffset, dsint delta); // can be made protected
int scaleFromUint64ToScrollBarRange(dsint value); // can be made private int scaleFromUint64ToScrollBarRange(duint value); // can be made private
dsint scaleFromScrollBarRangeToUint64(int value); // can be made private duint scaleFromScrollBarRangeToUint64(int value); // can be made private
void updateScrollBarRange(dsint range); // setRowCount+resizeEvent needs this, can be made private void updateScrollBarRange(duint range); // setRowCount+resizeEvent needs this, can be made private
// Coordinates Utils // Coordinates Utils
int getIndexOffsetFromY(int y) const; // can be made protected dsint getIndexOffsetFromY(int y) const; // can be made protected
int getColumnIndexFromX(int x) const; // can be made protected duint getColumnIndexFromX(int x) const; // can be made protected
int getColumnPosition(int index) const; // can be made protected int getColumnPosition(duint column) const; // can be made protected
int transY(int y) const; // can be made protected int transY(int y) const; // can be made protected
int getViewableRowsCount() const; // can be made protected
virtual int getLineToPrintcount() const; // TODO: this should probably be uint32_t?
duint getViewableRowsCount() const; // can be made protected
duint getMaxTableOffset() const;
// New Columns/New Size // New Columns/New Size
virtual void addColumnAt(int width, const QString & title, bool isClickable); virtual void addColumnAt(int width, const QString & title, bool isClickable);
virtual void setRowCount(dsint count); virtual void setRowCount(duint count);
virtual void deleteAllColumns(); // can be made protected, although it makes sense as a public API virtual void deleteAllColumns(); // can be made protected, although it makes sense as a public API
void setColTitle(int index, const QString & title); // can be deleted, although it makes sense as a public API void setColTitle(duint col, const QString & title); // can be deleted, although it makes sense as a public API
QString getColTitle(int index) const; // can be deleted, although it makes sense as a public API QString getColTitle(duint col) const; // can be deleted, although it makes sense as a public API
enum GuiState
{
NoState,
ReadyToResize,
ResizeColumnState,
HeaderButtonPressed,
HeaderButtonReordering
};
// Getter & Setter // Getter & Setter
dsint getRowCount() const; duint getRowCount() const;
int getColumnCount() const; duint getColumnCount() const;
int getRowHeight() const; int getRowHeight() const;
int getColumnWidth(int index) const; int getColumnWidth(duint col) const;
void setColumnWidth(int index, int width); void setColumnWidth(duint col, int width);
void setColumnOrder(int pos, int index); void setColumnOrder(duint col, duint colNew);
int getColumnOrder(int index) const; duint getColumnOrder(duint col) const;
int getHeaderHeight() const; // can be made protected int getHeaderHeight() const; // can be made protected
int getTableHeight() const; // can be made protected int getTableHeight() const; // can be made protected
int getGuiState() const; // can be made protected GuiState getGuiState() const; // can be made protected
int getNbrOfLineToPrint() const; duint getNbrOfLineToPrint() const; // TODO: should this be signed?
void setNbrOfLineToPrint(int parNbrOfLineToPrint); void setNbrOfLineToPrint(duint parNbrOfLineToPrint);
void setShowHeader(bool show); void setShowHeader(bool show);
int getCharWidth() const; int getCharWidth() const;
bool getColumnHidden(int col) const; int calculateColumnWidth(int characterCount) const;
void setColumnHidden(int col, bool hidden); bool getColumnHidden(duint col) const;
void setColumnHidden(duint col, bool hidden);
bool getDrawDebugOnly() const; bool getDrawDebugOnly() const;
void setDrawDebugOnly(bool value); void setDrawDebugOnly(bool value);
bool getAllowPainting() const; bool getAllowPainting() const;
void setAllowPainting(bool allow); void setAllowPainting(bool allow);
void setDisassemblyPopupEnabled(bool enable);
// UI customization // UI customization
void loadColumnFromConfig(const QString & viewName); void loadColumnFromConfig(const QString & viewName);
@ -119,20 +117,20 @@ public:
static void setupColumnConfigDefaultValue(QMap<QString, duint> & map, const QString & viewName, int columnCount); static void setupColumnConfigDefaultValue(QMap<QString, duint> & map, const QString & viewName, int columnCount);
// Table offset management // Table offset management
dsint getTableOffset() const; duint getTableOffset() const; // TODO: duint
void setTableOffset(dsint val); void setTableOffset(duint val); // TODO: duint
// Update/Reload/Refresh/Repaint // Update/Reload/Refresh/Repaint
virtual void prepareData(); virtual void prepareData();
virtual duint getDisassemblyPopupAddress(int mousex, int mousey); virtual duint getAddressForPosition(int x, int y);
signals: signals:
void enterPressedSignal(); void enterPressedSignal();
void headerButtonPressed(int col); void headerButtonPressed(duint col);
void headerButtonReleased(int col); void headerButtonReleased(duint col);
void tableOffsetChanged(dsint i); void tableOffsetChanged(duint i);
void viewableRowsChanged(int rows); void viewableRowsChanged(duint rowCount);
void repainted(); void repainted();
public slots: public slots:
@ -145,96 +143,96 @@ public slots:
void editColumnDialog(); void editColumnDialog();
protected slots:
void ShowDisassemblyPopup(duint addr, int x, int y); // this should probably be a slot, but doesn't need emit fixes (it's already used correctly)
void timerEvent(QTimerEvent* event);
private slots: private slots:
// Configuration // Configuration
void updateColorsSlot(); void updateColorsSlot();
void updateFontsSlot(); void updateFontsSlot();
void updateShortcutsSlot(); void updateShortcutsSlot();
void shutdownSlot(); void closeSlot();
private: private:
struct ColumnResizingData GuiState mGuiState = NoState;
struct ColumnResizeState
{ {
bool splitHandle; bool splitHandle = false;
int index; int index = -1;
int lastPosX; int lastPosX = -1;
}; } mColResizeData;
struct HeaderButton struct HeaderButton
{ {
bool isClickable; bool isClickable = false;
bool isPressed; bool isPressed = false;
bool isMouseOver; bool isMouseOver = false;
}; };
struct Column struct Column
{ {
int width; int width = 0;
bool hidden; int paintedWidth = -1;
bool hidden = false;
HeaderButton header; HeaderButton header;
QString title; QString title;
}; };
struct Header struct HeaderConfig
{ {
bool isVisible; bool isVisible = true;
int height; int height = 20;
int activeButtonIndex; int activeButtonIndex = -1;
}; } mHeader;
struct ScrollBar64
{
bool is64;
int rightShiftCount;
};
GuiState mGuiState;
Header mHeader;
QPushButton mHeaderButtonSytle;
int mMinColumnWidth = 5;
QList<Column> mColumnList; QList<Column> mColumnList;
ColumnResizingData mColResizeData; QList<duint> mColumnOrder;
int mReorderStartX = -1;
duint mHoveredColumnDisplayIndex = 0;
QList<int> mColumnOrder; duint mRowCount = 0;
int mReorderStartX; duint mTableOffset = 0;
int mHoveredColumnDisplayIndex; duint mPrevTableOffset = -1;
duint mNbrOfLineToPrint = 0;
dsint mRowCount; bool mShouldReload = true;
dsint mTableOffset; bool mDrawDebugOnly = false;
dsint mPrevTableOffset;
int mNbrOfLineToPrint;
bool mShouldReload; // State for accumulating scroll events
bool mDrawDebugOnly; enum ScrollDirection
bool mPopupEnabled; {
int mPopupTimer; ScrollUnknown,
ScrollVertical,
ScrollHorizontal,
} mPixelScrollDirection = ScrollUnknown;
QPoint mPixelScrollDelta;
QPoint mAngleScrollDelta;
static int mMouseWheelScrollDelta; struct ScrollBarAttributes
ScrollBar64 mScrollBarAttributes; {
bool is64 = false;
int rightShiftCount = 0;
} mScrollBarAttributes;
int getColumnDisplayIndexFromX(int x); duint getColumnDisplayIndexFromX(int x);
friend class ColumnReorderDialog; friend class ColumnReorderDialog;
protected: void updateLastColumnWidth();
// Configuration
QColor mBackgroundColor;
QColor mTextColor;
QColor mSeparatorColor;
QColor mHeaderTextColor;
QColor mSelectionColor;
QString mViewName;
bool mAllowPainting; protected:
bool mAllowPainting = true;
// Configuration
QColor mTextColor;
QColor mBackgroundColor;
QColor mHeaderTextColor;
QColor mHeaderBackgroundColor;
QColor mSeparatorColor;
QColor mSelectionColor;
QString mViewName; // TODO: this is needed during construction
// Font metrics // Font metrics
CachedFontMetrics* mFontMetrics; CachedFontMetrics* mFontMetrics = nullptr;
void invalidateCachedFont(); void invalidateCachedFont();
// Disassembly Popup ColumnReorderDialog* mReorderDialog = nullptr;
DisassemblyPopup* mDisassemblyPopup;
}; };

File diff suppressed because it is too large Load Diff

View File

@ -1,25 +1,28 @@
#pragma once #pragma once
#include "AbstractTableView.h" #include "AbstractTableView.h"
#include "QBeaEngine.h" #include "QZydis.h"
#include <QTextLayout> #include <QTextLayout>
#include "Architecture.h"
class CodeFoldingHelper; class CodeFoldingHelper;
class MemoryPage; class MemoryPage;
class DisassemblyPopup;
class Disassembly : public AbstractTableView class Disassembly : public AbstractTableView
{ {
Q_OBJECT Q_OBJECT
public: public:
Disassembly(QWidget* parent, bool isMain); Disassembly(Architecture* architecture, bool isMain, QWidget* parent = nullptr);
~Disassembly() override; ~Disassembly() override;
Architecture* getArchitecture() const;
// Configuration // Configuration
void updateColors() override; void updateColors() override;
void updateFonts() override; void updateFonts() override;
// Reimplemented Functions // Reimplemented Functions
QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) override; QString paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h) override;
// Mouse Management // Mouse Management
void mouseMoveEvent(QMouseEvent* event) override; void mouseMoveEvent(QMouseEvent* event) override;
@ -31,25 +34,25 @@ public:
void keyPressEvent(QKeyEvent* event) override; void keyPressEvent(QKeyEvent* event) override;
// ScrollBar Management // ScrollBar Management
dsint sliderMovedHook(int type, dsint value, dsint delta) override; duint sliderMovedHook(QScrollBar::SliderAction action, duint value, dsint delta) override;
// Instructions Management // Instructions Management
dsint getPreviousInstructionRVA(dsint rva, duint count); duint getPreviousInstructionRVA(duint rva, duint count);
dsint getNextInstructionRVA(dsint rva, duint count, bool isGlobal = false); duint getNextInstructionRVA(duint rva, duint count, bool isGlobal = false);
dsint getInstructionRVA(dsint index, dsint count); duint getInstructionRVA(duint index, dsint count);
Instruction_t DisassembleAt(dsint rva); Instruction_t DisassembleAt(duint rva);
Instruction_t DisassembleAt(dsint rva, dsint count); Instruction_t DisassembleAt(duint rva, dsint count);
// Selection Management // Selection Management
void expandSelectionUpTo(dsint to); void expandSelectionUpTo(duint to);
void setSingleSelection(dsint index); void setSingleSelection(duint index);
dsint getInitialSelection() const; duint getInitialSelection() const;
dsint getSelectionSize() const; duint getSelectionSize() const;
dsint getSelectionStart() const; duint getSelectionStart() const;
dsint getSelectionEnd() const; duint getSelectionEnd() const;
void selectNext(bool expand); void selectNext(bool expand);
void selectPrevious(bool expand); void selectPrevious(bool expand);
bool isSelected(dsint base, dsint offset); bool isSelected(duint base, dsint offset);
bool isSelected(QList<Instruction_t>* buffer, int index) const; bool isSelected(QList<Instruction_t>* buffer, int index) const;
duint getSelectedVa() const; duint getSelectedVa() const;
@ -60,7 +63,7 @@ public:
void paintEvent(QPaintEvent* event) override; void paintEvent(QPaintEvent* event) override;
// Public Methods // Public Methods
duint rvaToVa(dsint rva) const; duint rvaToVa(duint rva) const;
void disassembleClear(); void disassembleClear();
const duint getBase() const; const duint getBase() const;
duint getSize() const; duint getSize() const;
@ -75,32 +78,31 @@ public:
//disassemble //disassemble
void gotoAddress(duint addr); void gotoAddress(duint addr);
void disassembleAt(dsint parVA, bool history, dsint newTableOffset); void disassembleAt(duint va, bool history, duint newTableOffset);
QList<Instruction_t>* instructionsBuffer(); // ugly QList<Instruction_t>* instructionsBuffer(); // ugly
const dsint baseAddress() const; const duint baseAddress() const;
QString getAddrText(dsint cur_addr, char label[MAX_LABEL_SIZE], bool getLabel = true); QString getAddrText(duint cur_addr, QString & label, bool getLabel = true);
void prepareDataCount(const QList<dsint> & wRVAs, QList<Instruction_t>* instBuffer); void prepareDataCount(const QList<duint> & rvas, QList<Instruction_t>* instBuffer);
void prepareDataRange(dsint startRva, dsint endRva, const std::function<bool(int, const Instruction_t &)> & disassembled); void prepareDataRange(duint startRva, duint endRva, const std::function<bool(int, const Instruction_t &)> & disassembled);
RichTextPainter::List getRichBytes(const Instruction_t & instr, bool isSelected) const; RichTextPainter::List getRichBytes(const Instruction_t & instr, bool isSelected) const;
//misc //misc
void setCodeFoldingManager(CodeFoldingHelper* CodeFoldingManager); void setCodeFoldingManager(CodeFoldingHelper* CodeFoldingManager);
duint getDisassemblyPopupAddress(int mousex, int mousey) override; void unfold(duint rva);
void unfold(dsint rva);
bool hightlightToken(const ZydisTokenizer::SingleToken & token); bool hightlightToken(const ZydisTokenizer::SingleToken & token);
bool isHighlightMode() const; bool isHighlightMode() const;
signals: signals:
void selectionChanged(dsint parVA); void selectionChanged(duint va);
void selectionExpanded(); void selectionExpanded();
void updateWindowTitle(QString title); void updateWindowTitle(QString title);
public slots: public slots:
void disassembleAtSlot(dsint parVA, dsint parCIP); void disassembleAtSlot(duint va, duint cip);
void debugStateChangedSlot(DBGSTATE state); void debugStateChangedSlot(DBGSTATE state);
void selectionChangedSlot(dsint parVA); void selectionChangedSlot(duint va);
void tokenizerConfigUpdatedSlot(); void tokenizerConfigUpdatedSlot();
void updateConfigSlot(); void updateConfigSlot();
@ -127,30 +129,31 @@ private:
{ {
GJD_Nothing, GJD_Nothing,
GJD_Up, GJD_Up,
GJD_Down GJD_Down,
GJD_Out,
}; };
struct SelectionData struct SelectionData
{ {
dsint firstSelectedIndex; duint firstSelectedIndex = 0;
dsint fromIndex; duint fromIndex = 0;
dsint toIndex; duint toIndex = 0;
}; } mSelection;
SelectionData mSelection;
Architecture* mArchitecture = nullptr;
bool mIsLastInstDisplayed; bool mIsLastInstDisplayed;
GuiState mGuiState; GuiState mGuiState;
duint mCipVa = 0; duint mCipVa = 0;
Instruction_t mSelectedInstruction;
QList<Instruction_t> mInstBuffer; QList<Instruction_t> mInstBuffer;
struct HistoryData struct HistoryData
{ {
dsint va; duint va = 0;
dsint tableOffset; duint tableOffset = 0;
}; };
QList<HistoryData> mVaHistory; QList<HistoryData> mVaHistory;
@ -165,9 +168,11 @@ private:
ColMnemonicBrief, ColMnemonicBrief,
}; };
DisassemblyPopup* mDisassemblyPopup = nullptr;
protected: protected:
// Jumps Graphic // Jumps Graphic
int paintJumpsGraphic(QPainter* painter, int x, int y, dsint addr, bool isjmp); int paintJumpsGraphic(QPainter* painter, int x, int y, const Instruction_t & instruction);
// Function Graphic // Function Graphic
@ -182,6 +187,9 @@ protected:
}; };
int paintFunctionGraphic(QPainter* painter, int x, int y, Function_t funcType, bool loop); int paintFunctionGraphic(QPainter* painter, int x, int y, Function_t funcType, bool loop);
duint getAddressForPosition(int mousex, int mousey) override;
// Configuration // Configuration
QColor mInstructionHighlightColor; QColor mInstructionHighlightColor;
QColor mDisassemblyRelocationUnderlineColor; QColor mDisassemblyRelocationUnderlineColor;
@ -243,7 +251,7 @@ protected:
dsint mRvaDisplayPageBase; dsint mRvaDisplayPageBase;
bool mHighlightingMode; bool mHighlightingMode;
MemoryPage* mMemPage; MemoryPage* mMemPage;
QBeaEngine* mDisasm; QZydis* mDisasm;
bool mShowMnemonicBrief; bool mShowMnemonicBrief;
XREF_INFO mXrefInfo; XREF_INFO mXrefInfo;
CodeFoldingHelper* mCodeFoldingManager; CodeFoldingHelper* mCodeFoldingManager;

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,6 @@
#include "RichTextPainter.h" #include "RichTextPainter.h"
#include "MemoryPage.h" #include "MemoryPage.h"
#include "VaHistory.h" #include "VaHistory.h"
#include <QTextCodec>
class HexDump : public AbstractTableView class HexDump : public AbstractTableView
{ {
@ -74,12 +73,12 @@ public:
bool isData = true; bool isData = true;
int itemCount = 16; int itemCount = 16;
int separator = 0; int separator = 0;
QTextCodec* textCodec = nullptr; //name of the text codec (leave empty if you want to keep your sanity) QByteArray textEncoding; // name of the text codec (leave empty if you want to keep your sanity)
DataDescriptor data; DataDescriptor data;
std::function<void()> columnSwitch; std::function<void()> columnSwitch;
}; };
explicit HexDump(QWidget* parent = 0); HexDump(Architecture* architecture, QWidget* parent = nullptr);
~HexDump() override; ~HexDump() override;
// Configuration // Configuration
@ -87,41 +86,40 @@ public:
void updateFonts() override; void updateFonts() override;
void updateShortcuts() override; void updateShortcuts() override;
//QString getStringToPrint(int rowBase, int rowOffset, int col);
void mouseMoveEvent(QMouseEvent* event) override; void mouseMoveEvent(QMouseEvent* event) override;
void mousePressEvent(QMouseEvent* event) override; void mousePressEvent(QMouseEvent* event) override;
void mouseReleaseEvent(QMouseEvent* event) override; void mouseReleaseEvent(QMouseEvent* event) override;
void wheelEvent(QWheelEvent* event) override; void wheelEvent(QWheelEvent* event) override;
void keyPressEvent(QKeyEvent* event) override; void keyPressEvent(QKeyEvent* event) override;
QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) override; QString paintContent(QPainter* painter, duint row, duint column, int x, int y, int w, int h) override;
void paintGraphicDump(QPainter* painter, int x, int y, int addr); void paintGraphicDump(QPainter* painter, int x, int y, int addr);
void printSelected(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h); void printSelected(QPainter* painter, duint row, duint column, int x, int y, int w, int h);
// Selection Management // Selection Management
void expandSelectionUpTo(dsint rva); void expandSelectionUpTo(duint rva);
void setSingleSelection(dsint rva); void setSingleSelection(duint rva);
dsint getInitialSelection() const; duint getInitialSelection() const;
dsint getSelectionStart() const; duint getSelectionStart() const;
dsint getSelectionEnd() const; duint getSelectionEnd() const;
bool isSelected(dsint rva) const; bool isSelected(duint rva) const;
virtual void getColumnRichText(int col, dsint rva, RichTextPainter::List & richText); virtual void getColumnRichText(duint column, duint rva, RichTextPainter::List & richText);
static size_t getSizeOf(DataSize size); static size_t getSizeOf(DataSize size);
void toString(DataDescriptor desc, duint rva, byte_t* data, RichTextPainter::CustomRichText_t & richText); void toString(DataDescriptor desc, duint rva, uint8_t* data, RichTextPainter::CustomRichText_t & richText);
void byteToString(duint rva, byte_t byte, ByteViewMode mode, RichTextPainter::CustomRichText_t & richText); void byteToString(duint rva, uint8_t byte, ByteViewMode mode, RichTextPainter::CustomRichText_t & richText);
void wordToString(duint rva, uint16 word, WordViewMode mode, RichTextPainter::CustomRichText_t & richText); void wordToString(duint rva, uint16_t word, WordViewMode mode, RichTextPainter::CustomRichText_t & richText);
static void dwordToString(duint rva, uint32 dword, DwordViewMode mode, RichTextPainter::CustomRichText_t & richText); static void dwordToString(duint rva, uint32_t dword, DwordViewMode mode, RichTextPainter::CustomRichText_t & richText);
static void qwordToString(duint rva, uint64 qword, QwordViewMode mode, RichTextPainter::CustomRichText_t & richText); static void qwordToString(duint rva, uint64_t qword, QwordViewMode mode, RichTextPainter::CustomRichText_t & richText);
static void twordToString(duint rva, void* tword, TwordViewMode mode, RichTextPainter::CustomRichText_t & richText); static void twordToString(duint rva, void* tword, TwordViewMode mode, RichTextPainter::CustomRichText_t & richText);
int getItemIndexFromX(int x) const; int getItemIndexFromX(int x) const;
dsint getItemStartingAddress(int x, int y); duint getItemStartingAddress(int x, int y);
int getBytePerRowCount() const; size_t getBytePerRowCount() const;
int getItemPixelWidth(ColumnDescriptor desc) const; int getItemPixelWidth(ColumnDescriptor desc) const;
//descriptor management //descriptor management
@ -129,8 +127,8 @@ public:
void appendResetDescriptor(int width, QString title, bool clickable, ColumnDescriptor descriptor); void appendResetDescriptor(int width, QString title, bool clickable, ColumnDescriptor descriptor);
void clearDescriptors(); void clearDescriptors();
void printDumpAt(dsint parVA, bool select, bool repaint = true, bool updateTableOffset = true); void printDumpAt(duint parVA, bool select, bool repaint = true, bool updateTableOffset = true);
duint rvaToVa(dsint rva) const; duint rvaToVa(duint rva) const;
duint getTableOffsetRva() const; duint getTableOffsetRva() const;
QString makeAddrText(duint va) const; QString makeAddrText(duint va) const;
@ -144,7 +142,7 @@ signals:
void selectionUpdated(); void selectionUpdated();
public slots: public slots:
void printDumpAt(dsint parVA); void printDumpAt(duint parVA);
void debugStateChanged(DBGSTATE state); void debugStateChanged(DBGSTATE state);
void updateDumpSlot(); void updateDumpSlot();
void copySelectionSlot(); void copySelectionSlot();
@ -162,9 +160,9 @@ private:
struct SelectionData struct SelectionData
{ {
dsint firstSelectedIndex; duint firstSelectedIndex = 0;
dsint fromIndex; duint fromIndex = 0;
dsint toIndex; duint toIndex = 0;
}; };
SelectionData mSelection; SelectionData mSelection;
@ -209,13 +207,14 @@ private:
std::vector<uint8_t> mUpdateCacheTemp; std::vector<uint8_t> mUpdateCacheTemp;
protected: protected:
MemoryPage* mMemPage; Architecture* mArchitecture = nullptr;
int mByteOffset; MemoryPage* mMemPage = nullptr;
dsint mByteOffset = 0;
QList<ColumnDescriptor> mDescriptor; QList<ColumnDescriptor> mDescriptor;
int mForceColumn; int mForceColumn;
bool mRvaDisplayEnabled; bool mRvaDisplayEnabled;
duint mRvaDisplayBase; duint mRvaDisplayBase;
dsint mRvaDisplayPageBase; duint mRvaDisplayPageBase;
QString mSyncAddrExpression; QString mSyncAddrExpression;
QAction* mCopyAddress; QAction* mCopyAddress;
QAction* mCopyRva; QAction* mCopyRva;

View File

@ -67,7 +67,7 @@ QString HistoryLineEdit::addHistoryClear()
void HistoryLineEdit::keyPressEvent(QKeyEvent* event) void HistoryLineEdit::keyPressEvent(QKeyEvent* event)
{ {
int wKey = event->key(); int key = event->key();
//This fixes a very annoying bug on some systems //This fixes a very annoying bug on some systems
if(bSixPressed) if(bSixPressed)
@ -79,14 +79,14 @@ void HistoryLineEdit::keyPressEvent(QKeyEvent* event)
return; return;
} }
} }
if(wKey == Qt::Key_6) if(key == Qt::Key_6)
bSixPressed = true; bSixPressed = true;
if(wKey == Qt::Key_Up || wKey == Qt::Key_Down) if(key == Qt::Key_Up || key == Qt::Key_Down)
{ {
if(wKey == Qt::Key_Up) if(key == Qt::Key_Up)
mCmdIndex++; mCmdIndex++;
else if(wKey == Qt::Key_Down) else if(key == Qt::Key_Down)
mCmdIndex--; mCmdIndex--;
mCmdIndex = mCmdIndex < -1 ? -1 : mCmdIndex; mCmdIndex = mCmdIndex < -1 ? -1 : mCmdIndex;

View File

@ -7,7 +7,7 @@ class HistoryLineEdit : public QLineEdit
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit HistoryLineEdit(QWidget* parent = 0); explicit HistoryLineEdit(QWidget* parent = nullptr);
void keyPressEvent(QKeyEvent* event); void keyPressEvent(QKeyEvent* event);
void addLineToHistory(QString parLine); void addLineToHistory(QString parLine);
QString getLineFromHistory(); QString getLineFromHistory();

View File

@ -278,7 +278,7 @@ void LabeledSplitter::loadFromConfig(const QString & configName)
size_t sizeofState = strlen(state); size_t sizeofState = strlen(state);
if(sizeofState > 0) if(sizeofState > 0)
this->restoreState(QByteArray::fromBase64(QByteArray(state, int(sizeofState)))); this->restoreState(QByteArray::fromBase64(QByteArray(state, int(sizeofState))));
connect(Bridge::getBridge(), SIGNAL(shutdown()), this, SLOT(shutdownSlot())); connect(Bridge::getBridge(), SIGNAL(close()), this, SLOT(shutdownSlot()));
} }
} }

View File

@ -32,7 +32,7 @@ class LabeledSplitterDetachedWindow : public QMainWindow
Q_OBJECT Q_OBJECT
public: public:
LabeledSplitterDetachedWindow(QWidget* parent = 0, LabeledSplitter* splitterwidget = 0); LabeledSplitterDetachedWindow(QWidget* parent = nullptr, LabeledSplitter* splitterwidget = 0);
~LabeledSplitterDetachedWindow(); ~LabeledSplitterDetachedWindow();
int index; int index;

View File

@ -6,6 +6,7 @@
#include "Configuration.h" #include "Configuration.h"
#include "Bridge.h" #include "Bridge.h"
#include "MiscUtil.h" #include "MiscUtil.h"
#include "DisassemblyPopup.h"
ReferenceView::ReferenceView(bool sourceView, QWidget* parent) : StdSearchListView(parent, true, false), mParent(dynamic_cast<QTabWidget*>(parent)) ReferenceView::ReferenceView(bool sourceView, QWidget* parent) : StdSearchListView(parent, true, false), mParent(dynamic_cast<QTabWidget*>(parent))
{ {
@ -53,6 +54,10 @@ ReferenceView::ReferenceView(bool sourceView, QWidget* parent) : StdSearchListVi
connect(this, SIGNAL(enterPressedSignal()), this, SLOT(followGenericAddress())); connect(this, SIGNAL(enterPressedSignal()), this, SLOT(followGenericAddress()));
setupContextMenu(); setupContextMenu();
// Add disassembly popups
new DisassemblyPopup(stdList(), Bridge::getArchitecture());
new DisassemblyPopup(stdSearchList(), Bridge::getArchitecture());
} }
void ReferenceView::setupContextMenu() void ReferenceView::setupContextMenu()
@ -102,8 +107,8 @@ void ReferenceView::connectBridge()
connect(Bridge::getBridge(), SIGNAL(referenceSetProgress(int)), this, SLOT(referenceSetProgressSlot(int))); connect(Bridge::getBridge(), SIGNAL(referenceSetProgress(int)), this, SLOT(referenceSetProgressSlot(int)));
connect(Bridge::getBridge(), SIGNAL(referenceSetCurrentTaskProgress(int, QString)), this, SLOT(referenceSetCurrentTaskProgressSlot(int, QString))); connect(Bridge::getBridge(), SIGNAL(referenceSetCurrentTaskProgress(int, QString)), this, SLOT(referenceSetCurrentTaskProgressSlot(int, QString)));
connect(Bridge::getBridge(), SIGNAL(referenceAddCommand(QString, QString)), this, SLOT(addCommand(QString, QString))); connect(Bridge::getBridge(), SIGNAL(referenceAddCommand(QString, QString)), this, SLOT(addCommand(QString, QString)));
connect(stdSearchList(), SIGNAL(selectionChangedSignal(int)), this, SLOT(searchSelectionChanged(int))); connect(stdSearchList(), SIGNAL(selectionChanged(duint)), this, SLOT(searchSelectionChanged(int)));
connect(stdList(), SIGNAL(selectionChangedSignal(int)), this, SLOT(searchSelectionChanged(int))); connect(stdList(), SIGNAL(selectionChanged(duint)), this, SLOT(searchSelectionChanged(int)));
} }
void ReferenceView::disconnectBridge() void ReferenceView::disconnectBridge()
@ -113,8 +118,8 @@ void ReferenceView::disconnectBridge()
disconnect(Bridge::getBridge(), SIGNAL(referenceSetProgress(int)), this, SLOT(referenceSetProgressSlot(int))); disconnect(Bridge::getBridge(), SIGNAL(referenceSetProgress(int)), this, SLOT(referenceSetProgressSlot(int)));
disconnect(Bridge::getBridge(), SIGNAL(referenceSetCurrentTaskProgress(int, QString)), this, SLOT(referenceSetCurrentTaskProgressSlot(int, QString))); disconnect(Bridge::getBridge(), SIGNAL(referenceSetCurrentTaskProgress(int, QString)), this, SLOT(referenceSetCurrentTaskProgressSlot(int, QString)));
disconnect(Bridge::getBridge(), SIGNAL(referenceAddCommand(QString, QString)), this, SLOT(addCommand(QString, QString))); disconnect(Bridge::getBridge(), SIGNAL(referenceAddCommand(QString, QString)), this, SLOT(addCommand(QString, QString)));
disconnect(stdSearchList(), SIGNAL(selectionChangedSignal(int)), this, SLOT(searchSelectionChanged(int))); disconnect(stdSearchList(), SIGNAL(selectionChanged(int)), this, SLOT(searchSelectionChanged(int)));
disconnect(stdList(), SIGNAL(selectionChangedSignal(int)), this, SLOT(searchSelectionChanged(int))); disconnect(stdList(), SIGNAL(selectionChanged(int)), this, SLOT(searchSelectionChanged(int)));
} }
int ReferenceView::progress() const int ReferenceView::progress() const
@ -203,7 +208,7 @@ void ReferenceView::addCommand(QString title, QString command)
mCommands.append(command); mCommands.append(command);
} }
void ReferenceView::referenceContextMenu(QMenu* wMenu) void ReferenceView::referenceContextMenu(QMenu* menu)
{ {
if(!mCurList->getRowCount()) if(!mCurList->getRowCount())
return; return;
@ -213,39 +218,39 @@ void ReferenceView::referenceContextMenu(QMenu* wMenu)
return; return;
if(DbgMemIsValidReadPtr(addr)) if(DbgMemIsValidReadPtr(addr))
{ {
wMenu->addAction(mFollowAddress); menu->addAction(mFollowAddress);
wMenu->addAction(mFollowDumpAddress); menu->addAction(mFollowDumpAddress);
dsint apiaddr = apiAddressFromString(mCurList->getCellContent(mCurList->getInitialSelection(), 1)); dsint apiaddr = apiAddressFromString(mCurList->getCellContent(mCurList->getInitialSelection(), 1));
if(apiaddr) if(apiaddr)
wMenu->addAction(mFollowApiAddress); menu->addAction(mFollowApiAddress);
wMenu->addSeparator(); menu->addSeparator();
wMenu->addAction(mToggleBreakpoint); menu->addAction(mToggleBreakpoint);
wMenu->addAction(mSetBreakpointOnAllCommands); menu->addAction(mSetBreakpointOnAllCommands);
wMenu->addAction(mRemoveBreakpointOnAllCommands); menu->addAction(mRemoveBreakpointOnAllCommands);
if(apiaddr) if(apiaddr)
{ {
char label[MAX_LABEL_SIZE] = ""; char label[MAX_LABEL_SIZE] = "";
if(DbgGetLabelAt(apiaddr, SEG_DEFAULT, label)) if(DbgGetLabelAt(apiaddr, SEG_DEFAULT, label))
{ {
wMenu->addSeparator(); menu->addSeparator();
mSetBreakpointOnAllApiCalls->setText(tr("Set breakpoint on all calls to %1").arg(label)); mSetBreakpointOnAllApiCalls->setText(tr("Set breakpoint on all calls to %1").arg(label));
wMenu->addAction(mSetBreakpointOnAllApiCalls); menu->addAction(mSetBreakpointOnAllApiCalls);
mRemoveBreakpointOnAllApiCalls->setText(tr("Remove breakpoint on all calls to %1").arg(label)); mRemoveBreakpointOnAllApiCalls->setText(tr("Remove breakpoint on all calls to %1").arg(label));
wMenu->addAction(mRemoveBreakpointOnAllApiCalls); menu->addAction(mRemoveBreakpointOnAllApiCalls);
} }
} }
wMenu->addSeparator(); menu->addSeparator();
wMenu->addAction(mToggleBookmark); menu->addAction(mToggleBookmark);
} }
if(this->mCommands.size() > 0) if(this->mCommands.size() > 0)
{ {
wMenu->addSeparator(); menu->addSeparator();
for(auto i = 0; i < this->mCommandTitles.size(); i++) for(auto i = 0; i < this->mCommandTitles.size(); i++)
{ {
QAction* newCommandAction = new QAction(this->mCommandTitles.at(i), wMenu); QAction* newCommandAction = new QAction(this->mCommandTitles.at(i), menu);
newCommandAction->setData(QVariant(mCommands.at(i))); newCommandAction->setData(QVariant(mCommands.at(i)));
connect(newCommandAction, SIGNAL(triggered()), this, SLOT(referenceExecCommand())); connect(newCommandAction, SIGNAL(triggered()), this, SLOT(referenceExecCommand()));
wMenu->addAction(newCommandAction); menu->addAction(newCommandAction);
} }
} }
} }
@ -284,7 +289,7 @@ void ReferenceView::followGenericAddress()
} }
} }
void ReferenceView::setBreakpointAt(int row, BPSetAction action) void ReferenceView::setBreakpointAt(duint row, BPSetAction action)
{ {
if(!DbgIsDebugging()) if(!DbgIsDebugging())
return; return;
@ -292,30 +297,30 @@ void ReferenceView::setBreakpointAt(int row, BPSetAction action)
if(!mCurList->getRowCount()) if(!mCurList->getRowCount())
return; return;
QString addrText = mCurList->getCellContent(row, 0).toUtf8().constData(); QString addrText = mCurList->getCellContent(row, 0).toUtf8().constData();
duint wVA; duint va = 0;
if(!DbgFunctions()->ValFromString(addrText.toUtf8().constData(), &wVA)) if(!DbgFunctions()->ValFromString(addrText.toUtf8().constData(), &va))
return; return;
if(!DbgMemIsValidReadPtr(wVA)) if(!DbgMemIsValidReadPtr(va))
return; return;
BPXTYPE wBpType = DbgGetBpxTypeAt(wVA); BPXTYPE bpType = DbgGetBpxTypeAt(va);
QString wCmd; QString cmd;
if((wBpType & bp_normal) == bp_normal) if((bpType & bp_normal) == bp_normal)
{ {
if(action == Toggle || action == Remove) if(action == Toggle || action == Remove)
wCmd = "bc " + ToPtrString(wVA); cmd = "bc " + ToPtrString(va);
else if(action == Disable) else if(action == Disable)
wCmd = "bpd " + ToPtrString(wVA); cmd = "bpd " + ToPtrString(va);
else if(action == Enable) else if(action == Enable)
wCmd = "bpe " + ToPtrString(wVA); cmd = "bpe " + ToPtrString(va);
} }
else if(wBpType == bp_none && (action == Toggle || action == Enable)) else if(bpType == bp_none && (action == Toggle || action == Enable))
{ {
wCmd = "bp " + ToPtrString(wVA); cmd = "bp " + ToPtrString(va);
} }
DbgCmdExecDirect(wCmd); DbgCmdExecDirect(cmd);
} }
void ReferenceView::toggleBreakpoint() void ReferenceView::toggleBreakpoint()
@ -334,14 +339,14 @@ void ReferenceView::toggleBreakpoint()
void ReferenceView::setBreakpointOnAllCommands() void ReferenceView::setBreakpointOnAllCommands()
{ {
GuiDisableUpdateScope s; GuiDisableUpdateScope s;
for(int i = 0; i < mCurList->getRowCount(); i++) for(duint i = 0; i < mCurList->getRowCount(); i++)
setBreakpointAt(i, Enable); setBreakpointAt(i, Enable);
} }
void ReferenceView::removeBreakpointOnAllCommands() void ReferenceView::removeBreakpointOnAllCommands()
{ {
GuiDisableUpdateScope s; GuiDisableUpdateScope s;
for(int i = 0; i < mCurList->getRowCount(); i++) for(duint i = 0; i < mCurList->getRowCount(); i++)
setBreakpointAt(i, Remove); setBreakpointAt(i, Remove);
} }
@ -355,7 +360,7 @@ void ReferenceView::setBreakpointOnAllApiCalls()
QString apiText = mCurList->getCellContent(mCurList->getInitialSelection(), 1); QString apiText = mCurList->getCellContent(mCurList->getInitialSelection(), 1);
GuiDisableUpdateScope s; GuiDisableUpdateScope s;
for(int i = 0; i < mCurList->getRowCount(); i++) for(duint i = 0; i < mCurList->getRowCount(); i++)
if(mCurList->getCellContent(i, 1) == apiText) if(mCurList->getCellContent(i, 1) == apiText)
setBreakpointAt(i, Enable); setBreakpointAt(i, Enable);
} }
@ -371,7 +376,7 @@ void ReferenceView::removeBreakpointOnAllApiCalls()
QString apiText = mCurList->getCellContent(mCurList->getInitialSelection(), 1); QString apiText = mCurList->getCellContent(mCurList->getInitialSelection(), 1);
GuiDisableUpdateScope s; GuiDisableUpdateScope s;
for(int i = 0; i < mCurList->getRowCount(); i++) for(duint i = 0; i < mCurList->getRowCount(); i++)
if(mCurList->getCellContent(i, 1) == apiText) if(mCurList->getCellContent(i, 1) == apiText)
setBreakpointAt(i, Remove); setBreakpointAt(i, Remove);
} }
@ -384,17 +389,17 @@ void ReferenceView::toggleBookmark()
if(!mCurList->getRowCount()) if(!mCurList->getRowCount())
return; return;
QString addrText = mCurList->getCellContent(mCurList->getInitialSelection(), 0); QString addrText = mCurList->getCellContent(mCurList->getInitialSelection(), 0);
duint wVA; duint va = 0;
if(!DbgFunctions()->ValFromString(addrText.toUtf8().constData(), &wVA)) if(!DbgFunctions()->ValFromString(addrText.toUtf8().constData(), &va))
return; return;
if(!DbgMemIsValidReadPtr(wVA)) if(!DbgMemIsValidReadPtr(va))
return; return;
bool result; bool result;
if(DbgGetBookmarkAt(wVA)) if(DbgGetBookmarkAt(va))
result = DbgSetBookmarkAt(wVA, false); result = DbgSetBookmarkAt(va, false);
else else
result = DbgSetBookmarkAt(wVA, true); result = DbgSetBookmarkAt(va, true);
if(!result) if(!result)
SimpleErrorBox(this, tr("Error!"), tr("DbgSetBookmarkAt failed!")); SimpleErrorBox(this, tr("Error!"), tr("DbgSetBookmarkAt failed!"));
GuiUpdateAllViews(); GuiUpdateAllViews();
@ -423,7 +428,7 @@ void ReferenceView::referenceExecCommand()
for(int selected : mCurList->getSelection()) //to do: enable multi-selection for(int selected : mCurList->getSelection()) //to do: enable multi-selection
{ {
QString specializedCommand = command; QString specializedCommand = command;
for(int i = 0; i < mCurList->getColumnCount(); i++) for(duint i = 0; i < mCurList->getColumnCount(); i++)
{ {
QString token = "$" + QString::number(i); QString token = "$" + QString::number(i);
if(specializedCommand.contains(token)) if(specializedCommand.contains(token))

View File

@ -3,7 +3,6 @@
#include <QProgressBar> #include <QProgressBar>
#include <QLabel> #include <QLabel>
#include "StdSearchListView.h" #include "StdSearchListView.h"
class DisassemblyPopup;
class QTabWidget; class QTabWidget;
@ -26,7 +25,7 @@ public slots:
void setSingleSelection(int index, bool scroll); void setSingleSelection(int index, bool scroll);
void addCommand(QString title, QString command); void addCommand(QString title, QString command);
void referenceContextMenu(QMenu* wMenu); void referenceContextMenu(QMenu* menu);
void followAddress(); void followAddress();
void followDumpAddress(); void followDumpAddress();
void followApiAddress(); void followApiAddress();
@ -75,7 +74,7 @@ private:
Remove Remove
}; };
void setBreakpointAt(int row, BPSetAction action); void setBreakpointAt(duint row, BPSetAction action);
dsint apiAddressFromString(const QString & s); dsint apiAddressFromString(const QString & s);
void mouseReleaseEvent(QMouseEvent* event); void mouseReleaseEvent(QMouseEvent* event);

View File

@ -93,7 +93,6 @@ SearchListView::SearchListView(QWidget* parent, AbstractSearchList* abstractSear
// Set global variables // Set global variables
mCurList = abstractSearchList->list(); mCurList = abstractSearchList->list();
mSearchStartCol = 0;
// Install input event filter // Install input event filter
mSearchBox->installEventFilter(this); mSearchBox->installEventFilter(this);
@ -205,9 +204,9 @@ void SearchListView::filterEntries()
bool hasSetSingleSelection = false; bool hasSetSingleSelection = false;
if(!mLastFirstColValue.isEmpty()) if(!mLastFirstColValue.isEmpty())
{ {
int rows = mCurList->getRowCount(); auto rows = mCurList->getRowCount();
mCurList->setTableOffset(0); mCurList->setTableOffset(0);
for(int i = 0; i < rows; i++) for(duint i = 0; i < rows; i++)
{ {
if(mCurList->getCellContent(i, 0) == mLastFirstColValue) if(mCurList->getCellContent(i, 0) == mLastFirstColValue)
{ {
@ -297,16 +296,16 @@ void SearchListView::clearFilter()
void SearchListView::listContextMenu(const QPoint & pos) void SearchListView::listContextMenu(const QPoint & pos)
{ {
QMenu wMenu(this); QMenu menu(this);
emit listContextMenuSignal(&wMenu); emit listContextMenuSignal(&menu);
wMenu.addSeparator(); menu.addSeparator();
wMenu.addAction(mSearchAction); menu.addAction(mSearchAction);
QMenu wCopyMenu(tr("&Copy"), this); QMenu copyMenu(tr("&Copy"), this);
wCopyMenu.setIcon(DIcon("copy")); copyMenu.setIcon(DIcon("copy"));
mCurList->setupCopyMenu(&wCopyMenu); mCurList->setupCopyMenu(&copyMenu);
if(wCopyMenu.actions().length()) if(copyMenu.actions().length())
wMenu.addMenu(&wCopyMenu); menu.addMenu(&copyMenu);
wMenu.exec(mCurList->mapToGlobal(pos)); menu.exec(mCurList->mapToGlobal(pos));
} }
void SearchListView::doubleClickedSlot() void SearchListView::doubleClickedSlot()

View File

@ -12,10 +12,10 @@ class SearchListView : public QWidget, public ActionHelper<SearchListView>
Q_OBJECT Q_OBJECT
public: public:
explicit SearchListView(QWidget* parent, AbstractSearchList* abstractSearchList, bool enableRegex, bool enableLock); SearchListView(QWidget* parent, AbstractSearchList* abstractSearchList, bool enableRegex, bool enableLock);
AbstractStdTable* mCurList; AbstractStdTable* mCurList = nullptr;
int mSearchStartCol; duint mSearchStartCol = 0;
bool findTextInList(AbstractStdTable* list, QString text, int row, int startcol, bool startswith); bool findTextInList(AbstractStdTable* list, QString text, int row, int startcol, bool startswith);
void refreshSearchList(); void refreshSearchList();
@ -32,7 +32,7 @@ private slots:
signals: signals:
void enterPressedSignal(); void enterPressedSignal();
void listContextMenuSignal(QMenu* wMenu); void listContextMenuSignal(QMenu* menu);
void emptySearchResult(); void emptySearchResult();
protected: protected:

View File

@ -12,7 +12,7 @@ class ShortcutEdit : public QLineEdit
bool mError; bool mError;
public: public:
explicit ShortcutEdit(QWidget* parent = 0); explicit ShortcutEdit(QWidget* parent = nullptr);
const QKeySequence getKeysequence() const; const QKeySequence getKeysequence() const;
bool error() const; bool error() const;

View File

@ -24,20 +24,13 @@ int StdIconTable::getIconColumn() const
return mIconColumn; return mIconColumn;
} }
void StdIconTable::setRowCount(dsint count) void StdIconTable::setRowCount(duint count)
{ {
int wRowToAddOrRemove = count - int(mIcon.size()); mIcon.resize(count);
for(int i = 0; i < qAbs(wRowToAddOrRemove); i++)
{
if(wRowToAddOrRemove > 0)
mIcon.push_back(QIcon());
else
mIcon.pop_back();
}
StdTable::setRowCount(count); StdTable::setRowCount(count);
} }
void StdIconTable::sortRows(int column, bool ascending) void StdIconTable::sortRows(duint column, bool ascending)
{ {
auto sortFn = mColumnSortFunctions.at(column); auto sortFn = mColumnSortFunctions.at(column);
std::vector<size_t> index; std::vector<size_t> index;
@ -61,24 +54,24 @@ void StdIconTable::sortRows(int column, bool ascending)
} }
} }
QString StdIconTable::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) QString StdIconTable::paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h)
{ {
if(col == mIconColumn) if(col == mIconColumn)
{ {
// Draw the selection first, so that transparent icons are drawn properly // Draw the selection first, so that transparent icons are drawn properly
if(isSelected(rowBase, rowOffset)) if(isSelected(row))
painter->fillRect(QRect(x, y, w, h), QBrush(mSelectionColor)); painter->fillRect(QRect(x, y, w, h), QBrush(mSelectionColor));
mIcon.at(rowBase + rowOffset).paint(painter, x, y, h, h); mIcon.at(row).paint(painter, x, y, h, h);
QString wStr = StdTable::paintContent(painter, rowBase, rowOffset, col, x + h, y, w - h, h); QString str = StdTable::paintContent(painter, row, col, x + h, y, w - h, h);
if(wStr.length()) if(str.length())
{ {
painter->setPen(getCellColor(rowBase + rowOffset, col)); painter->setPen(getCellColor(row, col));
painter->drawText(QRect(x + 4 + h, y, w - 4 - h, h), Qt::AlignVCenter | Qt::AlignLeft, wStr); painter->drawText(QRect(x + 4 + h, y, w - 4 - h, h), Qt::AlignVCenter | Qt::AlignLeft, str);
} }
return QString(); return QString();
} }
else else
return StdTable::paintContent(painter, rowBase, rowOffset, col, x, y, w, h); return StdTable::paintContent(painter, row, col, x, y, w, h);
} }

View File

@ -7,17 +7,17 @@ class StdIconTable : public StdTable
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit StdIconTable(QWidget* parent = 0) : StdTable(parent), mIconColumn(0) {} explicit StdIconTable(QWidget* parent = nullptr) : StdTable(parent), mIconColumn(0) {}
// Data Management // Data Management
void setRowIcon(int r, const QIcon & icon); // set the icon for a row void setRowIcon(int r, const QIcon & icon); // set the icon for a row
QIcon getRowIcon(int r) const; QIcon getRowIcon(int r) const;
void setIconColumn(int c); // set in which column the icons appear void setIconColumn(int c); // set in which column the icons appear
int getIconColumn() const; int getIconColumn() const;
void setRowCount(dsint count) override; void setRowCount(duint count) override;
void sortRows(int column, bool ascending) override; void sortRows(duint column, bool ascending) override;
QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) override; QString paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h) override;
protected: protected:
std::vector<QIcon> mIcon; //listof(row) where row = (listof(col) where col = CellData) std::vector<QIcon> mIcon; //listof(row) where row = (listof(col) where col = CellData)

View File

@ -79,18 +79,12 @@ void StdSearchListView::reloadData()
}); });
} }
void StdSearchListView::setSearchStartCol(int col) void StdSearchListView::setSearchStartCol(duint col)
{ {
if(col < stdList()->getColumnCount()) if(col < stdList()->getColumnCount())
mSearchStartCol = col; mSearchStartCol = col;
} }
bool StdSearchListView::setDisassemblyPopupEnabled(bool enabled)
{
stdList()->setDisassemblyPopupEnabled(enabled);
return stdSearchList()->setDisassemblyPopupEnabled(enabled);
}
StdTable* StdSearchListView::stdList() StdTable* StdSearchListView::stdList()
{ {
return mSearchListData->mList; return mSearchListData->mList;

View File

@ -18,13 +18,12 @@ public:
void enableMultiSelection(bool enabled); void enableMultiSelection(bool enabled);
void setAddressColumn(int col, bool cipBase = false); void setAddressColumn(int col, bool cipBase = false);
void loadColumnFromConfig(const QString & viewName); void loadColumnFromConfig(const QString & viewName);
bool setDisassemblyPopupEnabled(bool enabled);
public slots: public slots:
virtual void setRowCount(dsint count); virtual void setRowCount(dsint count);
void setCellContent(int r, int c, QString s); void setCellContent(int r, int c, QString s);
void reloadData(); void reloadData();
void setSearchStartCol(int col); void setSearchStartCol(duint col);
private: private:
StdTableSearchList* mSearchListData; StdTableSearchList* mSearchListData;
@ -32,6 +31,8 @@ private:
protected: protected:
friend class SymbolView; friend class SymbolView;
friend class Bridge; friend class Bridge;
friend class HandlesView;
StdTable* stdList(); StdTable* stdList();
StdTable* stdSearchList(); StdTable* stdSearchList();
}; };

View File

@ -10,8 +10,7 @@ StdTable::StdTable(QWidget* parent) : AbstractStdTable(parent)
************************************************************************************/ ************************************************************************************/
bool StdTable::SortBy::AsText(const QString & a, const QString & b) bool StdTable::SortBy::AsText(const QString & a, const QString & b)
{ {
auto i = QString::compare(a, b); return QString::compare(a, b) < 0;
return i < 0;
} }
bool StdTable::SortBy::AsInt(const QString & a, const QString & b) bool StdTable::SortBy::AsInt(const QString & a, const QString & b)
@ -53,30 +52,36 @@ void StdTable::deleteAllColumns()
mColumnSortFunctions.clear(); mColumnSortFunctions.clear();
} }
void StdTable::setRowCount(dsint count) void StdTable::setRowCount(duint count)
{ {
int wRowToAddOrRemove = count - int(mData.size()); auto oldSize = mData.size();
for(int i = 0; i < qAbs(wRowToAddOrRemove); i++) mData.resize(count);
if(oldSize < count)
{ {
if(wRowToAddOrRemove > 0) for(duint i = oldSize; i < count; i++)
{ {
mData.push_back(std::vector<CellData>()); mData[i].resize(getColumnCount());
for(int j = 0; j < getColumnCount(); j++)
mData[mData.size() - 1].push_back(CellData());
} }
else
mData.pop_back();
} }
AbstractTableView::setRowCount(count); AbstractTableView::setRowCount(count);
} }
void StdTable::setCellContent(int r, int c, QString s) void StdTable::setCellContent(duint r, duint c, QString s)
{ {
if(isValidIndex(r, c)) if(isValidIndex(r, c))
mData[r][c].text = std::move(s); mData[r][c].text = std::move(s);
} }
QString StdTable::getCellContent(int r, int c) void StdTable::setCellContent(duint r, duint c, QString s, duint userdata)
{
if(isValidIndex(r, c))
{
mData[r][c].text = std::move(s);
mData[r][c].userdata = userdata;
}
}
QString StdTable::getCellContent(duint r, duint c)
{ {
if(isValidIndex(r, c)) if(isValidIndex(r, c))
return mData[r][c].text; return mData[r][c].text;
@ -84,25 +89,25 @@ QString StdTable::getCellContent(int r, int c)
return QString(""); return QString("");
} }
void StdTable::setCellUserdata(int r, int c, duint userdata) void StdTable::setCellUserdata(duint r, duint c, duint userdata)
{ {
if(isValidIndex(r, c)) if(isValidIndex(r, c))
mData[r][c].userdata = userdata; mData[r][c].userdata = userdata;
} }
duint StdTable::getCellUserdata(int r, int c) duint StdTable::getCellUserdata(duint r, duint c)
{ {
return isValidIndex(r, c) ? mData[r][c].userdata : 0; return isValidIndex(r, c) ? mData[r][c].userdata : 0;
} }
bool StdTable::isValidIndex(int r, int c) bool StdTable::isValidIndex(duint r, duint c)
{ {
if(r < 0 || c < 0 || r >= int(mData.size())) if(r < 0 || c < 0 || r >= int(mData.size()))
return false; return false;
return c < int(mData.at(r).size()); return c < int(mData.at(r).size());
} }
void StdTable::sortRows(int column, bool ascending) void StdTable::sortRows(duint column, bool ascending)
{ {
auto sortFn = mColumnSortFunctions.at(column); auto sortFn = mColumnSortFunctions.at(column);
std::stable_sort(mData.begin(), mData.end(), [column, ascending, &sortFn](const std::vector<CellData> & a, const std::vector<CellData> & b) std::stable_sort(mData.begin(), mData.end(), [column, ascending, &sortFn](const std::vector<CellData> & a, const std::vector<CellData> & b)

View File

@ -6,7 +6,7 @@ class StdTable : public AbstractStdTable
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit StdTable(QWidget* parent = 0); explicit StdTable(QWidget* parent = nullptr);
// Sorting // Sorting
struct SortBy struct SortBy
@ -20,13 +20,14 @@ public:
// Data Management // Data Management
void addColumnAt(int width, QString title, bool isClickable, QString copyTitle = "", SortBy::t sortFn = SortBy::AsText); void addColumnAt(int width, QString title, bool isClickable, QString copyTitle = "", SortBy::t sortFn = SortBy::AsText);
void deleteAllColumns() override; void deleteAllColumns() override;
void setRowCount(dsint count) override; void setRowCount(duint count) override;
void setCellContent(int r, int c, QString s); void setCellContent(duint r, duint c, QString s);
QString getCellContent(int r, int c) override; void setCellContent(duint r, duint c, QString s, duint userdata);
void setCellUserdata(int r, int c, duint userdata); QString getCellContent(duint r, duint c) override;
duint getCellUserdata(int r, int c); void setCellUserdata(duint r, duint c, duint userdata);
bool isValidIndex(int r, int c) override; duint getCellUserdata(duint r, duint c);
void sortRows(int column, bool ascending) override; bool isValidIndex(duint r, duint c) override;
void sortRows(duint column, bool ascending) override;
protected: protected:
struct CellData struct CellData

View File

@ -1,7 +1,7 @@
#include "StdTableSearchList.h" #include "StdTableSearchList.h"
#include "StdIconTable.h" #include "StdIconTable.h"
void StdTableSearchList::filter(const QString & filter, FilterType type, int startColumn) void StdTableSearchList::filter(const QString & filter, FilterType type, duint startColumn)
{ {
StdIconTable* mSearchIconList = qobject_cast<StdIconTable*>(mSearchList); StdIconTable* mSearchIconList = qobject_cast<StdIconTable*>(mSearchList);
StdIconTable* mIconList = qobject_cast<StdIconTable*>(mList); StdIconTable* mIconList = qobject_cast<StdIconTable*>(mList);

View File

@ -17,7 +17,7 @@ public:
AbstractStdTable* list() const override { return mList; } AbstractStdTable* list() const override { return mList; }
AbstractStdTable* searchList() const override { return mSearchList; } AbstractStdTable* searchList() const override { return mSearchList; }
void filter(const QString & filter, FilterType type, int startColumn) override; void filter(const QString & filter, FilterType type, duint startColumn) override;
private: private:
StdTable* mList; StdTable* mList;

View File

@ -1,6 +1,6 @@
#include "Bridge.h" #include "Bridge.h"
#include <QClipboard> #include <QClipboard>
#include "QBeaEngine.h" #include "QZydis.h"
#include "main.h" #include "main.h"
#include "Exports.h" #include "Exports.h"
@ -12,6 +12,19 @@
************************************************************************************/ ************************************************************************************/
static Bridge* mBridge; static Bridge* mBridge;
class BridgeArchitecture : public Architecture
{
bool disasm64() const override
{
return ArchValue(false, true);
}
bool addr64() const override
{
return ArchValue(false, true);
}
} mArch;
/************************************************************************************ /************************************************************************************
Class Members Class Members
************************************************************************************/ ************************************************************************************/
@ -72,6 +85,11 @@ void Bridge::initBridge()
mBridge = new Bridge(); mBridge = new Bridge();
} }
Architecture* Bridge::getArchitecture()
{
return &mArch;
}
/************************************************************************************ /************************************************************************************
Helper Functions Helper Functions
************************************************************************************/ ************************************************************************************/
@ -100,7 +118,7 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
{ {
case GUI_DISASSEMBLE_AT: case GUI_DISASSEMBLE_AT:
mLastCip = (duint)param2; mLastCip = (duint)param2;
emit disassembleAt((dsint)param1, (dsint)param2); emit disassembleAt((duint)param1, (duint)param2);
break; break;
case GUI_SET_DEBUG_STATE: case GUI_SET_DEBUG_STATE:
@ -317,7 +335,7 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
case GUI_REF_SETSEARCHSTARTCOL: case GUI_REF_SETSEARCHSTARTCOL:
if(referenceManager->currentReferenceView()) if(referenceManager->currentReferenceView())
referenceManager->currentReferenceView()->setSearchStartCol((int)param1); referenceManager->currentReferenceView()->setSearchStartCol((duint)param1);
break; break;
case GUI_REF_INITIALIZE: case GUI_REF_INITIALIZE:
@ -358,11 +376,11 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
char* text = (char*)param2; char* text = (char*)param2;
if(!text || !parVA || !DbgIsDebugging()) if(!text || !parVA || !DbgIsDebugging())
return 0; return 0;
byte_t wBuffer[16]; byte_t buffer[16];
if(!DbgMemRead(parVA, wBuffer, 16)) if(!DbgMemRead(parVA, buffer, 16))
return 0; return 0;
QBeaEngine disasm(int(ConfigUint("Disassembler", "MaxModuleSize"))); QZydis disasm(int(ConfigUint("Disassembler", "MaxModuleSize")), Bridge::getArchitecture());
Instruction_t instr = disasm.DisassembleAt(wBuffer, 16, 0, parVA); Instruction_t instr = disasm.DisassembleAt(buffer, 16, 0, parVA);
QString finalInstruction; QString finalInstruction;
for(const auto & curToken : instr.tokens.tokens) for(const auto & curToken : instr.tokens.tokens)
finalInstruction += curToken.text; finalInstruction += curToken.text;

View File

@ -7,6 +7,15 @@
#include <QMenu> #include <QMenu>
#include "Imports.h" #include "Imports.h"
#include "BridgeResult.h" #include "BridgeResult.h"
#include "Architecture.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
namespace Qt
{
static QString::SplitBehavior KeepEmptyParts = QString::KeepEmptyParts;
static QString::SplitBehavior SkipEmptyParts = QString::SkipEmptyParts;
}
#endif // QT_VERSION
class ReferenceManager; class ReferenceManager;
class SymbolView; class SymbolView;
@ -18,11 +27,12 @@ class Bridge : public QObject
friend class BridgeResult; friend class BridgeResult;
public: public:
explicit Bridge(QObject* parent = 0); explicit Bridge(QObject* parent = nullptr);
~Bridge(); ~Bridge();
static Bridge* getBridge(); static Bridge* getBridge();
static void initBridge(); static void initBridge();
static Architecture* getArchitecture();
// Message processing function // Message processing function
void* processMessage(GUIMSG type, void* param1, void* param2); void* processMessage(GUIMSG type, void* param1, void* param2);
@ -47,7 +57,7 @@ public:
bool loggingEnabled = true; bool loggingEnabled = true;
signals: signals:
void disassembleAt(dsint va, dsint eip); void disassembleAt(duint va, duint eip);
void updateDisassembly(); void updateDisassembly();
void dbgStateChanged(DBGSTATE state); void dbgStateChanged(DBGSTATE state);
void addMsgToLog(QByteArray msg); void addMsgToLog(QByteArray msg);
@ -57,11 +67,11 @@ signals:
void saveLogToFile(QString file); void saveLogToFile(QString file);
void redirectLogStop(); void redirectLogStop();
void redirectLogToFile(QString filename); void redirectLogToFile(QString filename);
void shutdown(); void close();
void updateRegisters(); void updateRegisters();
void updateBreakpoints(); void updateBreakpoints();
void updateWindowTitle(QString filename); void updateWindowTitle(QString filename);
void dumpAt(dsint va); void dumpAt(duint va);
void scriptAdd(int count, const char** lines); void scriptAdd(int count, const char** lines);
void scriptClear(); void scriptClear();
void scriptSetIp(int line); void scriptSetIp(int line);
@ -76,7 +86,7 @@ signals:
void clearSymbolLog(); void clearSymbolLog();
void setSymbolProgress(int progress); void setSymbolProgress(int progress);
void referenceAddColumnAt(int width, QString title); void referenceAddColumnAt(int width, QString title);
void referenceSetRowCount(dsint count); void referenceSetRowCount(duint count);
void referenceSetCellContent(int r, int c, QString s); void referenceSetCellContent(int r, int c, QString s);
void referenceAddCommand(QString title, QString command); void referenceAddCommand(QString title, QString command);
void referenceReloadData(); void referenceReloadData();

View File

@ -0,0 +1 @@
#include "Architecture.h"

View File

@ -0,0 +1,17 @@
#pragma once
/*
This should probably take some inspiration from Zydis:
- Address space min/max (64 vs 32 bit basically)
- Disassembly architecture (likely should return a reference to a disassembler)
*/
class Architecture
{
public:
virtual ~Architecture() = default;
// TODO: replace this with something about address space
virtual bool disasm64() const = 0;
virtual bool addr64() const = 0;
};

View File

@ -1,75 +0,0 @@
#pragma once
#include <QString>
#include <vector>
#include "ZydisTokenizer.h"
class EncodeMap;
class CodeFoldingHelper;
struct Instruction_t
{
enum BranchType
{
None,
Conditional,
Unconditional,
Call
};
Instruction_t()
: rva(0),
length(0),
branchDestination(0),
branchType(None)
{
}
QString instStr;
QByteArray dump;
uint8_t prefixSize, opcodeSize, group1Size, group2Size, group3Size;
duint rva;
int length;
duint branchDestination;
BranchType branchType;
ZydisTokenizer::InstructionToken tokens;
std::vector<std::pair<const char*, uint8_t>> regsReferenced;
uint8_t vectorElementType[4];
};
class QBeaEngine
{
public:
explicit QBeaEngine(int maxModuleSize);
~QBeaEngine();
ulong DisassembleBack(const byte_t* data, duint base, duint size, duint ip, int n);
ulong DisassembleNext(const byte_t* data, duint base, duint size, duint ip, int n);
Instruction_t DisassembleAt(const byte_t* data, duint size, duint origBase, duint origInstRVA, bool datainstr = true);
Instruction_t DecodeDataAt(const byte_t* data, duint size, duint origBase, duint origInstRVA, ENCODETYPE type);
void setCodeFoldingManager(CodeFoldingHelper* CodeFoldingManager);
void UpdateConfig();
EncodeMap* getEncodeMap()
{
return mEncodeMap;
}
private:
struct DataInstructionInfo
{
QString shortName;
QString longName;
QString cName;
};
void UpdateDataInstructionMap();
ZydisTokenizer _tokenizer;
QHash<ENCODETYPE, DataInstructionInfo> dataInstMap;
bool _bLongDataInst;
EncodeMap* mEncodeMap;
CodeFoldingHelper* mCodeFoldingManager;
uint8_t reginfo[ZYDIS_REGISTER_MAX_VALUE + 1];
uint8_t flaginfo[ZYDIS_CPUFLAG_MAX_VALUE + 1];
};
void formatOpcodeString(const Instruction_t & inst, RichTextPainter::List & list, std::vector<std::pair<size_t, bool>> & realBytes);

View File

@ -1,19 +1,24 @@
#include "QBeaEngine.h" #include "QZydis.h"
#include "StringUtil.h" #include "StringUtil.h"
#include "EncodeMap.h" #include "EncodeMap.h"
#include "CodeFolding.h" #include "CodeFolding.h"
#include "Bridge.h"
QBeaEngine::QBeaEngine(int maxModuleSize) #ifndef _countof
: _tokenizer(maxModuleSize), mCodeFoldingManager(nullptr), _bLongDataInst(false) #define _countof(array) (sizeof(array) / sizeof(array[0]))
#endif // _countof
QZydis::QZydis(int maxModuleSize, Architecture* architecture)
: mTokenizer(maxModuleSize, architecture), mArchitecture(architecture)
{ {
ZydisTokenizer::UpdateColors(); ZydisTokenizer::UpdateColors();
UpdateDataInstructionMap(); UpdateDataInstructionMap();
this->mEncodeMap = new EncodeMap(); mEncodeMap = new EncodeMap();
} }
QBeaEngine::~QBeaEngine() QZydis::~QZydis()
{ {
delete this->mEncodeMap; delete mEncodeMap;
} }
/** /**
@ -28,14 +33,14 @@ QBeaEngine::~QBeaEngine()
* *
* @return Return the RVA (Relative to the data pointer) of the nth instruction before the instruction pointed by ip * @return Return the RVA (Relative to the data pointer) of the nth instruction before the instruction pointed by ip
*/ */
ulong QBeaEngine::DisassembleBack(const byte_t* data, duint base, duint size, duint ip, int n) ulong QZydis::DisassembleBack(const uint8_t* data, duint base, duint size, duint ip, int n)
{ {
int i; int i;
uint abuf[128], addr, back, cmdsize; uint abuf[128], addr, back, cmdsize;
const unsigned char* pdata; const unsigned char* pdata;
// Reset Disasm Structure // Reset Disasm Structure
Zydis cp; Zydis zydis(mArchitecture->disasm64());
// Check if the pointer is not null // Check if the pointer is not null
if(data == NULL) if(data == NULL)
@ -89,10 +94,10 @@ ulong QBeaEngine::DisassembleBack(const byte_t* data, duint base, duint size, du
} }
else else
{ {
if(!cp.DisassembleSafe(addr + base, pdata, (int)size)) if(!zydis.DisassembleSafe(addr + base, pdata, (int)size))
cmdsize = 2; //heuristic for better output (FF FE or FE FF are usually part of an instruction) cmdsize = 2; //heuristic for better output (FF FE or FE FF are usually part of an instruction)
else else
cmdsize = cp.Size(); cmdsize = zydis.Size();
cmdsize = mEncodeMap->getDataSize(base + addr, cmdsize); cmdsize = mEncodeMap->getDataSize(base + addr, cmdsize);
@ -124,14 +129,14 @@ ulong QBeaEngine::DisassembleBack(const byte_t* data, duint base, duint size, du
* *
* @return Return the RVA (Relative to the data pointer) of the nth instruction after the instruction pointed by ip * @return Return the RVA (Relative to the data pointer) of the nth instruction after the instruction pointed by ip
*/ */
ulong QBeaEngine::DisassembleNext(const byte_t* data, duint base, duint size, duint ip, int n) ulong QZydis::DisassembleNext(const uint8_t* data, duint base, duint size, duint ip, int n)
{ {
int i; int i;
uint cmdsize; uint cmdsize;
const unsigned char* pdata; const unsigned char* pdata;
// Reset Disasm Structure // Reset Disasm Structure
Zydis cp; Zydis zydis(mArchitecture->disasm64());
if(data == NULL) if(data == NULL)
return 0; return 0;
@ -154,10 +159,10 @@ ulong QBeaEngine::DisassembleNext(const byte_t* data, duint base, duint size, du
} }
else else
{ {
if(!cp.DisassembleSafe(ip + base, pdata, (int)size)) if(!zydis.DisassembleSafe(ip + base, pdata, (int)size))
cmdsize = 1; cmdsize = 1;
else else
cmdsize = cp.Size(); cmdsize = zydis.Size();
cmdsize = mEncodeMap->getDataSize(base + ip, cmdsize); cmdsize = mEncodeMap->getDataSize(base + ip, cmdsize);
@ -181,7 +186,7 @@ ulong QBeaEngine::DisassembleNext(const byte_t* data, duint base, duint size, du
* *
* @return Return the disassembled instruction * @return Return the disassembled instruction
*/ */
Instruction_t QBeaEngine::DisassembleAt(const byte_t* data, duint size, duint origBase, duint origInstRVA, bool datainstr) Instruction_t QZydis::DisassembleAt(const uint8_t* data, duint size, duint origBase, duint origInstRVA, bool datainstr)
{ {
if(datainstr) if(datainstr)
{ {
@ -189,95 +194,87 @@ Instruction_t QBeaEngine::DisassembleAt(const byte_t* data, duint size, duint or
if(!mEncodeMap->isCode(type)) if(!mEncodeMap->isCode(type))
return DecodeDataAt(data, size, origBase, origInstRVA, type); return DecodeDataAt(data, size, origBase, origInstRVA, type);
} }
//tokenize //tokenize
ZydisTokenizer::InstructionToken cap; ZydisTokenizer::InstructionToken cap;
_tokenizer.Tokenize(origBase + origInstRVA, data, size, cap); mTokenizer.Tokenize(origBase + origInstRVA, data, size, cap);
int len = _tokenizer.Size(); int len = mTokenizer.Size();
const auto & cp = _tokenizer.GetZydis();
bool success = cp.Success();
const auto & zydis = mTokenizer.GetZydis();
bool success = zydis.Success();
auto branchType = Instruction_t::None; auto branchType = Instruction_t::None;
Instruction_t wInst; Instruction_t inst;
if(success && cp.IsBranchType(Zydis::BTJmp | Zydis::BTCall | Zydis::BTRet | Zydis::BTLoop | Zydis::BTXbegin)) if(success && zydis.IsBranchType(Zydis::BTJmp | Zydis::BTCall | Zydis::BTRet | Zydis::BTLoop | Zydis::BTXbegin))
{ {
wInst.branchDestination = DbgGetBranchDestination(origBase + origInstRVA); inst.branchDestination = DbgGetBranchDestination(origBase + origInstRVA);
if(cp.IsBranchType(Zydis::BTUncondJmp)) if(zydis.IsBranchType(Zydis::BTUncondJmp))
branchType = Instruction_t::Unconditional; branchType = Instruction_t::Unconditional;
else if(cp.IsBranchType(Zydis::BTCall)) else if(zydis.IsBranchType(Zydis::BTCall))
branchType = Instruction_t::Call; branchType = Instruction_t::Call;
else if(cp.IsBranchType(Zydis::BTCondJmp) || cp.IsBranchType(Zydis::BTLoop)) else if(zydis.IsBranchType(Zydis::BTCondJmp) || zydis.IsBranchType(Zydis::BTLoop))
branchType = Instruction_t::Conditional; branchType = Instruction_t::Conditional;
} }
else else
wInst.branchDestination = 0; inst.branchDestination = 0;
wInst.instStr = QString(cp.InstructionText().c_str()); inst.instStr = QString(zydis.InstructionText().c_str());
wInst.dump = QByteArray((const char*)data, len); inst.dump = QByteArray((const char*)data, len);
wInst.rva = origInstRVA; inst.rva = origInstRVA;
if(mCodeFoldingManager && mCodeFoldingManager->isFolded(origInstRVA)) if(mCodeFoldingManager && mCodeFoldingManager->isFolded(origInstRVA))
wInst.length = mCodeFoldingManager->getFoldEnd(origInstRVA + origBase) - (origInstRVA + origBase) + 1; inst.length = mCodeFoldingManager->getFoldEnd(origInstRVA + origBase) - (origInstRVA + origBase) + 1;
else else
wInst.length = len; inst.length = len;
wInst.branchType = branchType; inst.branchType = branchType;
wInst.tokens = cap; inst.tokens = cap;
cp.BytesGroup(&wInst.prefixSize, &wInst.opcodeSize, &wInst.group1Size, &wInst.group2Size, &wInst.group3Size); zydis.BytesGroup(&inst.prefixSize, &inst.opcodeSize, &inst.group1Size, &inst.group2Size, &inst.group3Size);
for(uint8_t i = 0; i < _countof(wInst.vectorElementType); ++i) for(uint8_t i = 0; i < _countof(inst.vectorElementType); ++i)
wInst.vectorElementType[i] = cp.getVectorElementType(i); inst.vectorElementType[i] = zydis.getVectorElementType(i);
if(!success) if(!success)
return wInst; return inst;
auto instr = cp.GetInstr(); uint8_t regInfo[ZYDIS_REGISTER_MAX_VALUE + 1];
cp.RegInfo(reginfo); uint8_t flagInfo[32];
zydis.RegInfo(regInfo);
zydis.FlagInfo(flagInfo);
for(size_t i = 0; i < _countof(instr->accessedFlags); ++i) regInfo[ZYDIS_REGISTER_RFLAGS] = Zydis::RAINone;
{ regInfo[ZYDIS_REGISTER_EFLAGS] = Zydis::RAINone;
auto flagAction = instr->accessedFlags[i].action; regInfo[ZYDIS_REGISTER_FLAGS] = Zydis::RAINone;
if(flagAction == ZYDIS_CPUFLAG_ACTION_NONE) regInfo[mArchitecture->disasm64() ? ZYDIS_REGISTER_RIP : ZYDIS_REGISTER_EIP] = Zydis::RAINone;
continue;
Zydis::RegAccessInfo rai; inst.regsReferenced.reserve(ZYDIS_REGISTER_MAX_VALUE + 21);
switch(flagAction)
{
case ZYDIS_CPUFLAG_ACTION_MODIFIED:
case ZYDIS_CPUFLAG_ACTION_SET_0:
case ZYDIS_CPUFLAG_ACTION_SET_1:
rai = Zydis::RAIWrite;
break;
case ZYDIS_CPUFLAG_ACTION_TESTED:
rai = Zydis::RAIRead;
break;
default:
rai = Zydis::RAINone;
break;
}
reginfo[ZYDIS_REGISTER_RFLAGS] = Zydis::RAINone;
reginfo[ZYDIS_REGISTER_EFLAGS] = Zydis::RAINone;
reginfo[ZYDIS_REGISTER_FLAGS] = Zydis::RAINone;
wInst.regsReferenced.emplace_back(cp.FlagName(ZydisCPUFlag(i)), rai);
}
wInst.regsReferenced.reserve(ZYDIS_REGISTER_MAX_VALUE);
reginfo[ArchValue(ZYDIS_REGISTER_EIP, ZYDIS_REGISTER_RIP)] = Zydis::RAINone;
for(int i = ZYDIS_REGISTER_NONE; i <= ZYDIS_REGISTER_MAX_VALUE; ++i) for(int i = ZYDIS_REGISTER_NONE; i <= ZYDIS_REGISTER_MAX_VALUE; ++i)
if(reginfo[i]) {
wInst.regsReferenced.emplace_back(cp.RegName(ZydisRegister(i)), reginfo[i]); if(regInfo[i] != Zydis::RAINone)
{
inst.regsReferenced.emplace_back(zydis.RegName(ZydisRegister(i)), regInfo[i]);
}
}
for(uint8_t i = 0; i < _countof(flagInfo); i++)
{
auto flag = 1u << i;
auto name = zydis.FlagName(flag);
auto rai = flagInfo[i];
if(name != nullptr && rai != Zydis::RAINone)
{
inst.regsReferenced.emplace_back(name, rai);
}
}
// Info about volatile and nonvolatile registers // Info about volatile and nonvolatile registers
if(cp.IsBranchType(Zydis::BranchType::BTCall)) if(zydis.IsBranchType(Zydis::BranchType::BTCall))
{ {
enum : uint8_t enum : uint8_t
{ {
Volatile = Zydis::RAIImplicit | Zydis::RAIWrite, Volatile = Zydis::RAIImplicit | Zydis::RAIWrite,
Parameter = Volatile | Zydis::RAIRead, Parameter = Volatile | Zydis::RAIRead,
}; };
#define info(reg, type) wInst.regsReferenced.emplace_back(#reg, type) #define info(reg, type) inst.regsReferenced.emplace_back(#reg, type)
#ifdef _WIN64 if(mArchitecture->disasm64())
{
// https://docs.microsoft.com/en-us/cpp/build/x64-software-conventions // https://docs.microsoft.com/en-us/cpp/build/x64-software-conventions
info(rax, Volatile); info(rax, Volatile);
info(rcx, Parameter); info(rcx, Parameter);
@ -298,89 +295,95 @@ Instruction_t QBeaEngine::DisassembleAt(const byte_t* data, duint size, duint or
info(ymm4, Parameter); info(ymm4, Parameter);
info(xmm5, Parameter); info(xmm5, Parameter);
info(ymm5, Parameter); info(ymm5, Parameter);
}
#else else
{
// https://en.wikipedia.org/wiki/X86_calling_conventions#Caller-saved_(volatile)_registers // https://en.wikipedia.org/wiki/X86_calling_conventions#Caller-saved_(volatile)_registers
info(eax, Volatile); info(eax, Volatile);
info(edx, Volatile); info(edx, Volatile);
info(ecx, Volatile); info(ecx, Volatile);
#endif // _WIN64 }
#undef info #undef info
} }
return wInst; return inst;
} }
Instruction_t QBeaEngine::DecodeDataAt(const byte_t* data, duint size, duint origBase, duint origInstRVA, ENCODETYPE type) Instruction_t QZydis::DecodeDataAt(const uint8_t* data, duint size, duint origBase, duint origInstRVA, ENCODETYPE type)
{ {
//tokenize //tokenize
ZydisTokenizer::InstructionToken cap; ZydisTokenizer::InstructionToken cap;
auto infoIter = dataInstMap.find(type); auto infoIter = mDataInstMap.find(type);
if(infoIter == dataInstMap.end()) if(infoIter == mDataInstMap.end())
infoIter = dataInstMap.find(enc_byte); infoIter = mDataInstMap.find(enc_byte);
int len = mEncodeMap->getDataSize(origBase + origInstRVA, 1); int len = mEncodeMap->getDataSize(origBase + origInstRVA, 1);
QString mnemonic = _bLongDataInst ? infoIter.value().longName : infoIter.value().shortName; QString mnemonic = mLongDataInst ? infoIter.value().longName : infoIter.value().shortName;
len = std::min(len, (int)size); len = std::min(len, (int)size);
QString datastr = GetDataTypeString(data, len, type); QString datastr = GetDataTypeString(data, len, type);
_tokenizer.TokenizeData(mnemonic, datastr, cap); mTokenizer.TokenizeData(mnemonic, datastr, cap);
Instruction_t wInst; Instruction_t inst;
wInst.instStr = mnemonic + " " + datastr; inst.instStr = mnemonic + " " + datastr;
wInst.dump = QByteArray((const char*)data, len); inst.dump = QByteArray((const char*)data, len);
wInst.rva = origInstRVA; inst.rva = origInstRVA;
wInst.length = len; inst.length = len;
wInst.branchType = Instruction_t::None; inst.branchType = Instruction_t::None;
wInst.branchDestination = 0; inst.branchDestination = 0;
wInst.tokens = cap; inst.tokens = cap;
wInst.prefixSize = 0; inst.prefixSize = 0;
wInst.opcodeSize = len; inst.opcodeSize = len;
wInst.group1Size = 0; inst.group1Size = 0;
wInst.group2Size = 0; inst.group2Size = 0;
wInst.group3Size = 0; inst.group3Size = 0;
wInst.vectorElementType[0] = Zydis::VETDefault; inst.vectorElementType[0] = Zydis::VETDefault;
wInst.vectorElementType[1] = Zydis::VETDefault; inst.vectorElementType[1] = Zydis::VETDefault;
wInst.vectorElementType[2] = Zydis::VETDefault; inst.vectorElementType[2] = Zydis::VETDefault;
wInst.vectorElementType[3] = Zydis::VETDefault; inst.vectorElementType[3] = Zydis::VETDefault;
return wInst; return inst;
} }
void QBeaEngine::UpdateDataInstructionMap() void QZydis::UpdateDataInstructionMap()
{ {
dataInstMap.clear(); mDataInstMap.clear();
dataInstMap.insert(enc_byte, {"db", "byte", "int8"}); mDataInstMap.insert(enc_byte, {"db", "byte", "int8"});
dataInstMap.insert(enc_word, {"dw", "word", "short"}); mDataInstMap.insert(enc_word, {"dw", "word", "short"});
dataInstMap.insert(enc_dword, {"dd", "dword", "int"}); mDataInstMap.insert(enc_dword, {"dd", "dword", "int"});
dataInstMap.insert(enc_fword, {"df", "fword", "fword"}); mDataInstMap.insert(enc_fword, {"df", "fword", "fword"});
dataInstMap.insert(enc_qword, {"dq", "qword", "long"}); mDataInstMap.insert(enc_qword, {"dq", "qword", "long"});
dataInstMap.insert(enc_tbyte, {"tbyte", "tbyte", "tbyte"}); mDataInstMap.insert(enc_tbyte, {"tbyte", "tbyte", "tbyte"});
dataInstMap.insert(enc_oword, {"oword", "oword", "oword"}); mDataInstMap.insert(enc_oword, {"oword", "oword", "oword"});
dataInstMap.insert(enc_mmword, {"mmword", "mmword", "long long"}); mDataInstMap.insert(enc_mmword, {"mmword", "mmword", "long long"});
dataInstMap.insert(enc_xmmword, {"xmmword", "xmmword", "_m128"}); mDataInstMap.insert(enc_xmmword, {"xmmword", "xmmword", "_m128"});
dataInstMap.insert(enc_ymmword, {"ymmword", "ymmword", "_m256"}); mDataInstMap.insert(enc_ymmword, {"ymmword", "ymmword", "_m256"});
dataInstMap.insert(enc_real4, {"real4", "real4", "float"}); mDataInstMap.insert(enc_real4, {"real4", "real4", "float"});
dataInstMap.insert(enc_real8, {"real8", "real8", "double"}); mDataInstMap.insert(enc_real8, {"real8", "real8", "double"});
dataInstMap.insert(enc_real10, {"real10", "real10", "long double"}); mDataInstMap.insert(enc_real10, {"real10", "real10", "long double"});
dataInstMap.insert(enc_ascii, {"ascii", "ascii", "string"}); mDataInstMap.insert(enc_ascii, {"ascii", "ascii", "string"});
dataInstMap.insert(enc_unicode, {"unicode", "unicode", "wstring"}); mDataInstMap.insert(enc_unicode, {"unicode", "unicode", "wstring"});
} }
void QBeaEngine::setCodeFoldingManager(CodeFoldingHelper* CodeFoldingManager) void QZydis::setCodeFoldingManager(CodeFoldingHelper* CodeFoldingManager)
{ {
mCodeFoldingManager = CodeFoldingManager; mCodeFoldingManager = CodeFoldingManager;
} }
void QBeaEngine::UpdateConfig() void QZydis::UpdateConfig()
{ {
_bLongDataInst = ConfigBool("Disassembler", "LongDataInstruction"); mLongDataInst = ConfigBool("Disassembler", "LongDataInstruction");
_tokenizer.UpdateConfig(); mTokenizer.UpdateConfig();
}
void QZydis::UpdateArchitecture()
{
mTokenizer.UpdateArchitecture();
} }
void formatOpcodeString(const Instruction_t & inst, RichTextPainter::List & list, std::vector<std::pair<size_t, bool>> & realBytes) void formatOpcodeString(const Instruction_t & inst, RichTextPainter::List & list, std::vector<std::pair<size_t, bool>> & realBytes)

View File

@ -0,0 +1,80 @@
#pragma once
#include <QString>
#include <vector>
#include "ZydisTokenizer.h"
class EncodeMap;
class CodeFoldingHelper;
struct Instruction_t
{
enum BranchType : uint8_t
{
None,
Conditional,
Unconditional,
Call
};
duint rva = 0;
duint branchDestination = 0;
int length = 0;
uint8_t vectorElementType[4];
uint8_t prefixSize = 0;
uint8_t opcodeSize = 0;
uint8_t group1Size = 0;
uint8_t group2Size = 0;
uint8_t group3Size = 0;
BranchType branchType = None;
QString instStr;
QByteArray dump;
std::vector<std::pair<const char*, uint8_t>> regsReferenced;
ZydisTokenizer::InstructionToken tokens;
Instruction_t()
{
memset(vectorElementType, 0, sizeof(vectorElementType));
}
};
class QZydis
{
public:
QZydis(int maxModuleSize, Architecture* architecture);
QZydis(const QZydis &) = delete;
QZydis(QZydis &&) = delete;
~QZydis();
ulong DisassembleBack(const uint8_t* data, duint base, duint size, duint ip, int n);
ulong DisassembleNext(const uint8_t* data, duint base, duint size, duint ip, int n);
Instruction_t DisassembleAt(const uint8_t* data, duint size, duint origBase, duint origInstRVA, bool datainstr = true);
Instruction_t DecodeDataAt(const uint8_t* data, duint size, duint origBase, duint origInstRVA, ENCODETYPE type);
void setCodeFoldingManager(CodeFoldingHelper* CodeFoldingManager);
void UpdateConfig();
void UpdateArchitecture();
EncodeMap* getEncodeMap()
{
return mEncodeMap;
}
private:
struct DataInstructionInfo
{
QString shortName;
QString longName;
QString cName;
};
void UpdateDataInstructionMap();
Architecture* mArchitecture = nullptr;
ZydisTokenizer mTokenizer;
QHash<ENCODETYPE, DataInstructionInfo> mDataInstMap;
bool mLongDataInst = false;
EncodeMap* mEncodeMap = nullptr;
CodeFoldingHelper* mCodeFoldingManager = nullptr;
};
void formatOpcodeString(const Instruction_t & inst, RichTextPainter::List & list, std::vector<std::pair<size_t, bool>> & realBytes);

View File

@ -2,19 +2,18 @@
#include "Configuration.h" #include "Configuration.h"
#include "StringUtil.h" #include "StringUtil.h"
#include "CachedFontMetrics.h" #include "CachedFontMetrics.h"
#include "Bridge.h"
ZydisTokenizer::ZydisTokenizer(int maxModuleLength) ZydisTokenizer::ZydisTokenizer(int maxModuleLength, Architecture* architecture)
: _maxModuleLength(maxModuleLength), : mMaxModuleLength(maxModuleLength),
_success(false), mZydis(architecture->disasm64()),
isNop(false), mArchitecture(architecture)
_mnemonicType(TokenType::Uncategorized)
{ {
SetConfig(false, false, false, false, false, false, false, false, false);
} }
static ZydisTokenizer::TokenColor colorNamesMap[size_t(ZydisTokenizer::TokenType::Last)]; static ZydisTokenizer::TokenColor colorNamesMap[size_t(ZydisTokenizer::TokenType::Last)];
QHash<QString, int> ZydisTokenizer::stringPoolMap; QHash<QString, int> ZydisTokenizer::gStringPool;
int ZydisTokenizer::poolId = 0; int ZydisTokenizer::gPoolId = 0;
void ZydisTokenizer::addColorName(TokenType type, QString color, QString backgroundColor) void ZydisTokenizer::addColorName(TokenType type, QString color, QString backgroundColor)
{ {
@ -28,10 +27,10 @@ ZydisTokenizer::TokenColor ZydisTokenizer::getTokenColor(TokenType type)
void ZydisTokenizer::addStringsToPool(const QString & strings) void ZydisTokenizer::addStringsToPool(const QString & strings)
{ {
QStringList stringList = strings.split(' ', QString::SkipEmptyParts); QStringList stringList = strings.split(' ', Qt::SkipEmptyParts);
for(const QString & string : stringList) for(const QString & string : stringList)
stringPoolMap.insert(string, poolId); gStringPool.insert(string, gPoolId);
poolId++; gPoolId++;
} }
void ZydisTokenizer::UpdateColors() void ZydisTokenizer::UpdateColors()
@ -77,8 +76,8 @@ void ZydisTokenizer::UpdateColors()
void ZydisTokenizer::UpdateStringPool() void ZydisTokenizer::UpdateStringPool()
{ {
poolId = 0; gPoolId = 0;
stringPoolMap.clear(); gStringPool.clear();
// These registers must be in lower case. // These registers must be in lower case.
addStringsToPool("rax eax ax al ah"); addStringsToPool("rax eax ax al ah");
addStringsToPool("rbx ebx bx bl bh"); addStringsToPool("rbx ebx bx bl bh");
@ -116,75 +115,75 @@ void ZydisTokenizer::UpdateStringPool()
bool ZydisTokenizer::Tokenize(duint addr, const unsigned char* data, int datasize, InstructionToken & instruction) bool ZydisTokenizer::Tokenize(duint addr, const unsigned char* data, int datasize, InstructionToken & instruction)
{ {
_inst = InstructionToken(); mInst = InstructionToken();
_success = _cp.DisassembleSafe(addr, data, datasize); mSuccess = mZydis.DisassembleSafe(addr, data, datasize);
if(_success) if(mSuccess)
{ {
if(!tokenizePrefix()) if(!tokenizePrefix())
return false; return false;
isNop = _cp.IsNop(); mIsNop = mZydis.IsNop();
if(!tokenizeMnemonic()) if(!tokenizeMnemonic())
return false; return false;
for(int i = 0; i < _cp.OpCount(); i++) for(int i = 0; i < mZydis.OpCount(); i++)
{ {
if(i == 1 && _cp[0].size >= 128 && _cp[1].type == ZYDIS_OPERAND_TYPE_REGISTER if(i == 1 && mZydis[0].size >= 128 && mZydis[1].type == ZYDIS_OPERAND_TYPE_REGISTER
&& ZydisRegisterGetClass(_cp[1].reg.value) == ZYDIS_REGCLASS_MASK) && ZydisRegisterGetClass(mZydis[1].reg.value) == ZYDIS_REGCLASS_MASK)
{ {
if(_bArgumentSpaces) if(mArgumentSpaces)
addToken(TokenType::ArgumentSpace, " "); addToken(TokenType::ArgumentSpace, " ");
addToken(TokenType::Comma, "{"); addToken(TokenType::Comma, "{");
if(!tokenizeOperand(_cp[i])) if(!tokenizeOperand(mZydis[i]))
return false; return false;
addToken(TokenType::Comma, "}"); addToken(TokenType::Comma, "}");
} }
else if(i) else if(i)
{ {
addToken(TokenType::Comma, ","); addToken(TokenType::Comma, ",");
if(_bArgumentSpaces) if(mArgumentSpaces)
addToken(TokenType::ArgumentSpace, " "); addToken(TokenType::ArgumentSpace, " ");
if(!tokenizeOperand(_cp[i])) if(!tokenizeOperand(mZydis[i]))
return false; return false;
} }
else else
{ {
if(!tokenizeOperand(_cp[i])) if(!tokenizeOperand(mZydis[i]))
return false; return false;
} }
} }
} }
else else
{ {
isNop = false; mIsNop = false;
addToken(TokenType::MnemonicUnusual, "???"); addToken(TokenType::MnemonicUnusual, "???");
} }
if(_bNoHighlightOperands) if(mNoHighlightOperands)
{ {
while(_inst.tokens.size() && _inst.tokens[_inst.tokens.size() - 1].type == TokenType::Space) while(mInst.tokens.size() && mInst.tokens[mInst.tokens.size() - 1].type == TokenType::Space)
_inst.tokens.pop_back(); mInst.tokens.pop_back();
for(SingleToken & token : _inst.tokens) for(SingleToken & token : mInst.tokens)
token.type = _mnemonicType; token.type = mMnemonicType;
} }
instruction = _inst; instruction = mInst;
return true; return true;
} }
bool ZydisTokenizer::TokenizeData(const QString & datatype, const QString & data, InstructionToken & instruction) bool ZydisTokenizer::TokenizeData(const QString & datatype, const QString & data, InstructionToken & instruction)
{ {
_inst = InstructionToken(); mInst = InstructionToken();
isNop = false; mIsNop = false;
if(!tokenizeMnemonic(TokenType::MnemonicNormal, datatype)) if(!tokenizeMnemonic(TokenType::MnemonicNormal, datatype))
return false; return false;
addToken(TokenType::Value, data); addToken(TokenType::Value, data);
instruction = _inst; instruction = mInst;
return true; return true;
} }
@ -218,40 +217,45 @@ void ZydisTokenizer::TokenizeTraceMemory(duint address, duint oldValue, duint ne
void ZydisTokenizer::UpdateConfig() void ZydisTokenizer::UpdateConfig()
{ {
SetConfig(ConfigBool("Disassembler", "Uppercase"), mUppercase = ConfigBool("Disassembler", "Uppercase");
ConfigBool("Disassembler", "TabbedMnemonic"), mTabbedMnemonic = ConfigBool("Disassembler", "TabbedMnemonic");
ConfigBool("Disassembler", "ArgumentSpaces"), mArgumentSpaces = ConfigBool("Disassembler", "ArgumentSpaces");
ConfigBool("Disassembler", "HidePointerSizes"), mHidePointerSizes = ConfigBool("Disassembler", "HidePointerSizes");
ConfigBool("Disassembler", "HideNormalSegments"), mHideNormalSegments = ConfigBool("Disassembler", "HideNormalSegments");
ConfigBool("Disassembler", "MemorySpaces"), mMemorySpaces = ConfigBool("Disassembler", "MemorySpaces");
ConfigBool("Disassembler", "NoHighlightOperands"), mNoHighlightOperands = ConfigBool("Disassembler", "NoHighlightOperands");
ConfigBool("Disassembler", "NoCurrentModuleText"), mNoCurrentModuleText = ConfigBool("Disassembler", "NoCurrentModuleText");
ConfigBool("Disassembler", "0xPrefixValues")); m0xPrefixValues = ConfigBool("Disassembler", "0xPrefixValues");
_maxModuleLength = (int)ConfigUint("Disassembler", "MaxModuleSize"); mMaxModuleLength = (int)ConfigUint("Disassembler", "MaxModuleSize");
UpdateStringPool(); UpdateStringPool();
} }
void ZydisTokenizer::UpdateArchitecture()
{
mZydis.Reset(mArchitecture->disasm64());
}
void ZydisTokenizer::SetConfig(bool bUppercase, bool bTabbedMnemonic, bool bArgumentSpaces, bool bHidePointerSizes, bool bHideNormalSegments, bool bMemorySpaces, bool bNoHighlightOperands, bool bNoCurrentModuleText, bool b0xPrefixValues) void ZydisTokenizer::SetConfig(bool bUppercase, bool bTabbedMnemonic, bool bArgumentSpaces, bool bHidePointerSizes, bool bHideNormalSegments, bool bMemorySpaces, bool bNoHighlightOperands, bool bNoCurrentModuleText, bool b0xPrefixValues)
{ {
_bUppercase = bUppercase; mUppercase = bUppercase;
_bTabbedMnemonic = bTabbedMnemonic; mTabbedMnemonic = bTabbedMnemonic;
_bArgumentSpaces = bArgumentSpaces; mArgumentSpaces = bArgumentSpaces;
_bHidePointerSizes = bHidePointerSizes; mHidePointerSizes = bHidePointerSizes;
_bHideNormalSegments = bHideNormalSegments; mHideNormalSegments = bHideNormalSegments;
_bMemorySpaces = bMemorySpaces; mMemorySpaces = bMemorySpaces;
_bNoHighlightOperands = bNoHighlightOperands; mNoHighlightOperands = bNoHighlightOperands;
_bNoCurrentModuleText = bNoCurrentModuleText; mNoCurrentModuleText = bNoCurrentModuleText;
_b0xPrefixValues = b0xPrefixValues; m0xPrefixValues = b0xPrefixValues;
} }
int ZydisTokenizer::Size() const int ZydisTokenizer::Size() const
{ {
return _success ? _cp.Size() : 1; return mSuccess ? mZydis.Size() : 1;
} }
const Zydis & ZydisTokenizer::GetZydis() const const Zydis & ZydisTokenizer::GetZydis() const
{ {
return _cp; return mZydis;
} }
void ZydisTokenizer::TokenToRichText(const InstructionToken & instr, RichTextPainter::List & richTextList, const SingleToken* highlightToken) void ZydisTokenizer::TokenToRichText(const InstructionToken & instr, RichTextPainter::List & richTextList, const SingleToken* highlightToken)
@ -317,17 +321,18 @@ bool ZydisTokenizer::IsHighlightableToken(const SingleToken & token)
case TokenType::MemoryOperator: case TokenType::MemoryOperator:
return false; return false;
break; break;
} default:
return true; return true;
}
} }
bool ZydisTokenizer::tokenTextPoolEquals(const QString & a, const QString & b) bool ZydisTokenizer::tokenTextPoolEquals(const QString & a, const QString & b)
{ {
if(a.compare(b, Qt::CaseInsensitive) == 0) if(a.compare(b, Qt::CaseInsensitive) == 0)
return true; return true;
auto found1 = stringPoolMap.find(a.toLower()); auto found1 = gStringPool.find(a.toLower());
auto found2 = stringPoolMap.find(b.toLower()); auto found2 = gStringPool.find(b.toLower());
if(found1 == stringPoolMap.end() || found2 == stringPoolMap.end()) if(found1 == gStringPool.end() || found2 == gStringPool.end())
return false; return false;
return found1.value() == found2.value(); return found1.value() == found2.value();
} }
@ -358,9 +363,9 @@ void ZydisTokenizer::addToken(TokenType type, QString text, const TokenValue & v
text = text.trimmed(); text = text.trimmed();
break; break;
} }
if(_bUppercase && !value.size) if(mUppercase && !value.size)
text = text.toUpper(); text = text.toUpper();
_inst.tokens.push_back(SingleToken(isNop ? TokenType::MnemonicNop : type, text, value)); mInst.tokens.push_back(SingleToken(mIsNop ? TokenType::MnemonicNop : type, text, value));
} }
void ZydisTokenizer::addToken(TokenType type, const QString & text) void ZydisTokenizer::addToken(TokenType type, const QString & text)
@ -370,39 +375,39 @@ void ZydisTokenizer::addToken(TokenType type, const QString & text)
void ZydisTokenizer::addMemoryOperator(char operatorText) void ZydisTokenizer::addMemoryOperator(char operatorText)
{ {
if(_bMemorySpaces) if(mMemorySpaces)
addToken(TokenType::MemoryOperatorSpace, " "); addToken(TokenType::MemoryOperatorSpace, " ");
QString text; QString text;
text += operatorText; text += operatorText;
addToken(TokenType::MemoryOperator, text); addToken(TokenType::MemoryOperator, text);
if(_bMemorySpaces) if(mMemorySpaces)
addToken(TokenType::MemoryOperatorSpace, " "); addToken(TokenType::MemoryOperatorSpace, " ");
} }
QString ZydisTokenizer::printValue(const TokenValue & value, bool expandModule, int maxModuleLength) const QString ZydisTokenizer::printValue(const TokenValue & value, bool expandModule) const
{ {
QString labelText; QString labelText;
char label_[MAX_LABEL_SIZE] = ""; char label[MAX_LABEL_SIZE] = "";
char module_[MAX_MODULE_SIZE] = ""; char module[MAX_MODULE_SIZE] = "";
QString moduleText; QString moduleText;
duint addr = value.value; duint addr = value.value;
bool bHasLabel = DbgGetLabelAt(addr, SEG_DEFAULT, label_); bool bHasLabel = DbgGetLabelAt(addr, SEG_DEFAULT, label);
labelText = QString(label_); labelText = QString(label);
bool bHasModule; bool bHasModule;
if(_bNoCurrentModuleText) if(mNoCurrentModuleText)
{ {
duint size, base; duint size, base;
base = DbgMemFindBaseAddr(this->GetZydis().Address(), &size); base = DbgMemFindBaseAddr(this->GetZydis().Address(), &size);
if(addr >= base && addr < base + size) if(addr >= base && addr < base + size)
bHasModule = false; bHasModule = false;
else else
bHasModule = (expandModule && DbgGetModuleAt(addr, module_) && !QString(labelText).startsWith("JMP.&")); bHasModule = (expandModule && DbgGetModuleAt(addr, module) && !QString(labelText).startsWith("JMP.&"));
} }
else else
bHasModule = (expandModule && DbgGetModuleAt(addr, module_) && !QString(labelText).startsWith("JMP.&")); bHasModule = (expandModule && DbgGetModuleAt(addr, module) && !QString(labelText).startsWith("JMP.&"));
moduleText = QString(module_); moduleText = QString(module);
if(maxModuleLength != -1) if(mMaxModuleLength != -1)
moduleText.truncate(maxModuleLength); moduleText.truncate(mMaxModuleLength);
if(moduleText.length()) if(moduleText.length())
moduleText += "."; moduleText += ".";
QString addrText = ToHexString(addr); QString addrText = ToHexString(addr);
@ -413,7 +418,7 @@ QString ZydisTokenizer::printValue(const TokenValue & value, bool expandModule,
finalText = QString("%1%2").arg(moduleText).arg(addrText); finalText = QString("%1%2").arg(moduleText).arg(addrText);
else if(bHasLabel) //<label> else if(bHasLabel) //<label>
finalText = QString("<%1>").arg(labelText); finalText = QString("<%1>").arg(labelText);
else if(_b0xPrefixValues) else if(m0xPrefixValues)
finalText = QString("0x") + addrText; finalText = QString("0x") + addrText;
else else
finalText = addrText; finalText = addrText;
@ -422,70 +427,69 @@ QString ZydisTokenizer::printValue(const TokenValue & value, bool expandModule,
bool ZydisTokenizer::tokenizePrefix() bool ZydisTokenizer::tokenizePrefix()
{ {
//TODO: what happens with multiple prefixes? auto addPrefix = [this](const QString & prefix)
bool hasPrefix = true;
QStringList prefixText;
auto attr = _cp.GetInstr()->attributes;
if(attr & ZYDIS_ATTRIB_HAS_LOCK)
prefixText += "lock";
else if(attr & ZYDIS_ATTRIB_HAS_REP)
prefixText += "rep";
else if(attr & ZYDIS_ATTRIB_HAS_REPE)
prefixText += "repe";
else if(attr & ZYDIS_ATTRIB_HAS_REPNE)
prefixText += "repne";
else if(attr & ZYDIS_ATTRIB_HAS_BOUND)
prefixText += "bnd";
else if(attr & ZYDIS_ATTRIB_HAS_XACQUIRE)
prefixText += "xacquire";
else if(attr & ZYDIS_ATTRIB_HAS_XRELEASE)
prefixText += "xrelease";
else
hasPrefix = false;
if(hasPrefix)
{ {
addToken(TokenType::Prefix, prefixText.join(' ')); addToken(TokenType::Prefix, prefix);
addToken(TokenType::Space, " "); addToken(TokenType::Space, " ");
} };
auto attr = mZydis.GetInstr()->info.attributes;
if(attr & ZYDIS_ATTRIB_HAS_LOCK)
addPrefix("lock");
if(attr & ZYDIS_ATTRIB_HAS_REP)
addPrefix("rep");
if(attr & ZYDIS_ATTRIB_HAS_REPE)
addPrefix("repe");
if(attr & ZYDIS_ATTRIB_HAS_REPNE)
addPrefix("repne");
if(attr & ZYDIS_ATTRIB_HAS_BND)
addPrefix("bnd");
if(attr & ZYDIS_ATTRIB_HAS_XACQUIRE)
addPrefix("xacquire");
if(attr & ZYDIS_ATTRIB_HAS_XRELEASE)
addPrefix("xrelease");
if(attr & ZYDIS_ATTRIB_HAS_BRANCH_NOT_TAKEN)
addPrefix("unlikely");
if(attr & ZYDIS_ATTRIB_HAS_BRANCH_TAKEN)
addPrefix("likely");
if(attr & ZYDIS_ATTRIB_HAS_NOTRACK)
addPrefix("notrack");
return true; return true;
} }
bool ZydisTokenizer::tokenizeMnemonic() bool ZydisTokenizer::tokenizeMnemonic()
{ {
QString mnemonic = QString(_cp.Mnemonic().c_str()); QString mnemonic = QString(mZydis.Mnemonic().c_str());
_mnemonicType = TokenType::MnemonicNormal; mMnemonicType = TokenType::MnemonicNormal;
if(_cp.IsBranchType(Zydis::BTFar)) if(mZydis.IsBranchType(Zydis::BTFar))
mnemonic += " far"; mnemonic += " far";
if(isNop) if(mIsNop)
_mnemonicType = TokenType::MnemonicNop; mMnemonicType = TokenType::MnemonicNop;
else if(_cp.IsInt3()) else if(mZydis.IsInt3())
_mnemonicType = TokenType::MnemonicInt3; mMnemonicType = TokenType::MnemonicInt3;
else if(_cp.IsUnusual()) else if(mZydis.IsUnusual())
_mnemonicType = TokenType::MnemonicUnusual; mMnemonicType = TokenType::MnemonicUnusual;
else if(_cp.IsBranchType(Zydis::BTCallSem)) else if(mZydis.IsBranchType(Zydis::BTCallSem))
_mnemonicType = TokenType::MnemonicCall; mMnemonicType = TokenType::MnemonicCall;
else if(_cp.IsBranchType(Zydis::BTCondJmpSem)) else if(mZydis.IsBranchType(Zydis::BTCondJmpSem))
_mnemonicType = TokenType::MnemonicCondJump; mMnemonicType = TokenType::MnemonicCondJump;
else if(_cp.IsBranchType(Zydis::BTUncondJmpSem)) else if(mZydis.IsBranchType(Zydis::BTUncondJmpSem))
_mnemonicType = TokenType::MnemonicUncondJump; mMnemonicType = TokenType::MnemonicUncondJump;
else if(_cp.IsBranchType(Zydis::BTRetSem)) else if(mZydis.IsBranchType(Zydis::BTRetSem))
_mnemonicType = TokenType::MnemonicRet; mMnemonicType = TokenType::MnemonicRet;
else if(_cp.IsPushPop()) else if(mZydis.IsPushPop())
_mnemonicType = TokenType::MnemonicPushPop; mMnemonicType = TokenType::MnemonicPushPop;
return tokenizeMnemonic(_mnemonicType, mnemonic); return tokenizeMnemonic(mMnemonicType, mnemonic);
} }
bool ZydisTokenizer::tokenizeMnemonic(TokenType type, const QString & mnemonic) bool ZydisTokenizer::tokenizeMnemonic(TokenType type, const QString & mnemonic)
{ {
addToken(type, mnemonic); addToken(type, mnemonic);
if(_bTabbedMnemonic) if(mTabbedMnemonic)
{ {
int spaceCount = 7 - mnemonic.length(); int spaceCount = 7 - mnemonic.length();
if(spaceCount > 0) if(spaceCount > 0)
@ -539,12 +543,14 @@ bool ZydisTokenizer::tokenizeRegOperand(const ZydisDecodedOperand & op)
case ZYDIS_REGCLASS_MASK: case ZYDIS_REGCLASS_MASK:
registerType = TokenType::ZmmRegister; registerType = TokenType::ZmmRegister;
break; break;
default:
break;
} }
if(reg.value == ArchValue(ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS)) if(reg.value == (mArchitecture->disasm64() ? ZYDIS_REGISTER_GS : ZYDIS_REGISTER_FS))
registerType = TokenType::MnemonicUnusual; registerType = TokenType::MnemonicUnusual;
addToken(registerType, _cp.RegName(reg.value)); addToken(registerType, mZydis.RegName(reg.value));
return true; return true;
} }
@ -552,20 +558,20 @@ bool ZydisTokenizer::tokenizeImmOperand(const ZydisDecodedOperand & op)
{ {
duint value; duint value;
TokenType valueType; TokenType valueType;
if(_cp.IsBranchType(Zydis::BTJmp | Zydis::BTCall | Zydis::BTLoop | Zydis::BTXbegin)) if(mZydis.IsBranchType(Zydis::BTJmp | Zydis::BTCall | Zydis::BTLoop | Zydis::BTXbegin))
{ {
valueType = TokenType::Address; valueType = TokenType::Address;
value = op.imm.value.u; value = op.imm.value.u;
} }
else else
{ {
auto opsize = _cp.GetInstr()->operandWidth; auto opsize = mZydis.GetInstr()->info.operand_width;
valueType = TokenType::Value; valueType = TokenType::Value;
value = duint(op.imm.value.u) & (duint(-1) >> (sizeof(duint) * 8 - opsize)); value = duint(op.imm.value.u) & (duint(-1) >> (sizeof(duint) * 8 - opsize));
} }
auto tokenValue = TokenValue(op.size / 8, value); auto tokenValue = TokenValue(op.size / 8, value);
addToken(valueType, printValue(tokenValue, true, _maxModuleLength), tokenValue); addToken(valueType, printValue(tokenValue, true), tokenValue);
return true; return true;
} }
@ -574,9 +580,9 @@ bool ZydisTokenizer::tokenizeMemOperand(const ZydisDecodedOperand & op)
auto opsize = op.size / 8; auto opsize = op.size / 8;
//memory size //memory size
if(!_bHidePointerSizes) if(!mHidePointerSizes)
{ {
const char* sizeText = _cp.MemSizeName(opsize); const char* sizeText = mZydis.MemSizeName(opsize);
if(sizeText) if(sizeText)
{ {
addToken(TokenType::MemorySize, QString(sizeText) + " ptr"); addToken(TokenType::MemorySize, QString(sizeText) + " ptr");
@ -588,11 +594,11 @@ bool ZydisTokenizer::tokenizeMemOperand(const ZydisDecodedOperand & op)
//memory segment //memory segment
bool bUnusualSegment = (mem.segment == ZYDIS_REGISTER_FS || mem.segment == ZYDIS_REGISTER_GS); bool bUnusualSegment = (mem.segment == ZYDIS_REGISTER_FS || mem.segment == ZYDIS_REGISTER_GS);
if(!_bHideNormalSegments || bUnusualSegment) if(!mHideNormalSegments || bUnusualSegment)
{ {
auto segmentType = mem.segment == ArchValue(ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS) auto segmentType = mem.segment == (mArchitecture->disasm64() ? ZYDIS_REGISTER_GS : ZYDIS_REGISTER_FS)
? TokenType::MnemonicUnusual : TokenType::MemorySegment; ? TokenType::MnemonicUnusual : TokenType::MemorySegment;
addToken(segmentType, _cp.RegName(mem.segment)); addToken(segmentType, mZydis.RegName(mem.segment));
addToken(TokenType::Uncategorized, ":"); addToken(TokenType::Uncategorized, ":");
} }
@ -613,28 +619,28 @@ bool ZydisTokenizer::tokenizeMemOperand(const ZydisDecodedOperand & op)
//stuff inside the brackets //stuff inside the brackets
if(mem.base == ZYDIS_REGISTER_RIP) //rip-relative (#replacement) if(mem.base == ZYDIS_REGISTER_RIP) //rip-relative (#replacement)
{ {
duint addr = _cp.Address() + duint(mem.disp.value) + _cp.Size(); duint addr = mZydis.Address() + duint(mem.disp.value) + mZydis.Size();
TokenValue value = TokenValue(opsize, addr); TokenValue value = TokenValue(opsize, addr);
auto displacementType = DbgMemIsValidReadPtr(addr) ? TokenType::Address : TokenType::Value; auto displacementType = DbgMemIsValidReadPtr(addr) ? TokenType::Address : TokenType::Value;
addToken(displacementType, printValue(value, false, _maxModuleLength), value); addToken(displacementType, printValue(value, false), value);
} }
else //#base + #index * #scale + #displacement else //#base + #index * #scale + #displacement
{ {
bool prependPlus = false; bool prependPlus = false;
if(mem.base != ZYDIS_REGISTER_NONE) //base register if(mem.base != ZYDIS_REGISTER_NONE) //base register
{ {
addToken(TokenType::MemoryBaseRegister, _cp.RegName(mem.base)); addToken(TokenType::MemoryBaseRegister, mZydis.RegName(mem.base));
prependPlus = true; prependPlus = true;
} }
if(mem.index != ZYDIS_REGISTER_NONE) //index register if(mem.index != ZYDIS_REGISTER_NONE) //index register
{ {
if(prependPlus) if(prependPlus)
addMemoryOperator('+'); addMemoryOperator('+');
addToken(TokenType::MemoryIndexRegister, _cp.RegName(mem.index)); addToken(TokenType::MemoryIndexRegister, mZydis.RegName(mem.index));
if(mem.scale > 1) if(mem.scale > 1)
{ {
addMemoryOperator('*'); addMemoryOperator('*');
addToken(TokenType::MemoryScale, QString().sprintf("%d", mem.scale)); addToken(TokenType::MemoryScale, QString("%1").arg(mem.scale));
} }
prependPlus = true; prependPlus = true;
} }
@ -647,10 +653,10 @@ bool ZydisTokenizer::tokenizeMemOperand(const ZydisDecodedOperand & op)
if(mem.disp.value < 0 && prependPlus) if(mem.disp.value < 0 && prependPlus)
{ {
operatorText = '-'; operatorText = '-';
valueText = printValue(TokenValue(opsize, duint(mem.disp.value * -1)), false, _maxModuleLength); valueText = printValue(TokenValue(opsize, duint(mem.disp.value * -1)), false);
} }
else else
valueText = printValue(value, false, _maxModuleLength); valueText = printValue(value, false);
if(prependPlus) if(prependPlus)
addMemoryOperator(operatorText); addMemoryOperator(operatorText);
addToken(displacementType, valueText, value); addToken(displacementType, valueText, value);
@ -667,12 +673,12 @@ bool ZydisTokenizer::tokenizeMemOperand(const ZydisDecodedOperand & op)
bool ZydisTokenizer::tokenizePtrOperand(const ZydisDecodedOperand & op) bool ZydisTokenizer::tokenizePtrOperand(const ZydisDecodedOperand & op)
{ {
auto segValue = TokenValue(2, op.ptr.segment); auto segValue = TokenValue(2, op.ptr.segment);
addToken(TokenType::MemorySegment, printValue(segValue, true, _maxModuleLength), segValue); addToken(TokenType::MemorySegment, printValue(segValue, true), segValue);
addToken(TokenType::Uncategorized, ":"); addToken(TokenType::Uncategorized, ":");
auto offsetValue = TokenValue(_cp.GetInstr()->operandWidth / 8, op.ptr.offset); auto offsetValue = TokenValue(mZydis.GetInstr()->info.operand_width / 8, op.ptr.offset);
addToken(TokenType::Address, printValue(offsetValue, true, _maxModuleLength), offsetValue); addToken(TokenType::Address, printValue(offsetValue, true), offsetValue);
return true; return true;
} }

View File

@ -6,6 +6,7 @@
#include <map> #include <map>
#include <QHash> #include <QHash>
#include <QtCore> #include <QtCore>
#include "Architecture.h"
class ZydisTokenizer class ZydisTokenizer
{ {
@ -109,13 +110,7 @@ public:
struct InstructionToken struct InstructionToken
{ {
std::vector<SingleToken> tokens; //list of tokens that form the instruction std::vector<SingleToken> tokens; //list of tokens that form the instruction
int x; //x of the first character int x = 0; //x of the first character
InstructionToken()
{
tokens.clear();
x = 0;
}
}; };
struct TokenColor struct TokenColor
@ -152,10 +147,11 @@ public:
} }
}; };
ZydisTokenizer(int maxModuleLength); ZydisTokenizer(int maxModuleLength, Architecture* architecture);
bool Tokenize(duint addr, const unsigned char* data, int datasize, InstructionToken & instruction); bool Tokenize(duint addr, const unsigned char* data, int datasize, InstructionToken & instruction);
bool TokenizeData(const QString & datatype, const QString & data, InstructionToken & instruction); bool TokenizeData(const QString & datatype, const QString & data, InstructionToken & instruction);
void UpdateConfig(); void UpdateConfig();
void UpdateArchitecture();
void SetConfig(bool bUppercase, bool bTabbedMnemonic, bool bArgumentSpaces, bool bHidePointerSizes, bool bHideNormalSegments, bool bMemorySpaces, bool bNoHighlightOperands, bool bNoCurrentModuleText, bool b0xPrefixValues); void SetConfig(bool bUppercase, bool bTabbedMnemonic, bool bArgumentSpaces, bool bHidePointerSizes, bool bHideNormalSegments, bool bMemorySpaces, bool bNoHighlightOperands, bool bNoCurrentModuleText, bool b0xPrefixValues);
int Size() const; int Size() const;
const Zydis & GetZydis() const; const Zydis & GetZydis() const;
@ -176,29 +172,30 @@ public:
private: private:
Zydis _cp; Architecture* mArchitecture;
bool isNop; Zydis mZydis;
InstructionToken _inst; bool mSuccess = false;
bool _success; bool mIsNop = false;
int _maxModuleLength; InstructionToken mInst;
bool _bUppercase; TokenType mMnemonicType = TokenType::Uncategorized;
bool _bTabbedMnemonic; int mMaxModuleLength = -1;
bool _bArgumentSpaces; bool mUppercase = false;
bool _bHidePointerSizes; bool mTabbedMnemonic = false;
bool _bHideNormalSegments; bool mArgumentSpaces = false;
bool _bMemorySpaces; bool mHidePointerSizes = false;
bool _bNoHighlightOperands; bool mHideNormalSegments = false;
bool _bNoCurrentModuleText; bool mMemorySpaces = false;
bool _b0xPrefixValues; bool mNoHighlightOperands = false;
TokenType _mnemonicType; bool mNoCurrentModuleText = false;
bool m0xPrefixValues = false;
void addToken(TokenType type, QString text, const TokenValue & value); void addToken(TokenType type, QString text, const TokenValue & value);
void addToken(TokenType type, const QString & text); void addToken(TokenType type, const QString & text);
void addMemoryOperator(char operatorText); void addMemoryOperator(char operatorText);
QString printValue(const TokenValue & value, bool expandModule, int maxModuleLength) const; QString printValue(const TokenValue & value, bool expandModule) const;
static QHash<QString, int> stringPoolMap; static QHash<QString, int> gStringPool;
static int poolId; static int gPoolId;
bool tokenizePrefix(); bool tokenizePrefix();
bool tokenizeMnemonic(); bool tokenizeMnemonic();

View File

@ -14,7 +14,7 @@ class AboutDialog : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit AboutDialog(UpdateChecker* updateChecker, QWidget* parent = 0); explicit AboutDialog(UpdateChecker* updateChecker, QWidget* parent = nullptr);
~AboutDialog(); ~AboutDialog();
protected: protected:

View File

@ -18,7 +18,7 @@ class AppearanceDialog : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit AppearanceDialog(QWidget* parent = 0); explicit AppearanceDialog(QWidget* parent = nullptr);
~AppearanceDialog(); ~AppearanceDialog();
private slots: private slots:

View File

@ -16,7 +16,7 @@ class AssembleDialog : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit AssembleDialog(QWidget* parent = 0); explicit AssembleDialog(QWidget* parent = nullptr);
~AssembleDialog(); ~AssembleDialog();
QString editText; QString editText;
static bool bWarningShowedOnce; static bool bWarningShowedOnce;

View File

@ -112,7 +112,7 @@ retryFindWindow:
refresh(); refresh();
QString pidText = QString().sprintf(ConfigBool("Gui", "PidTidInHex") ? "%.8X" : "%u", pid); QString pidText = QString().sprintf(ConfigBool("Gui", "PidTidInHex") ? "%.8X" : "%u", pid);
bool found = false; bool found = false;
for(int i = 0; i < mSearchListView->mCurList->getRowCount(); i++) for(duint i = 0; i < mSearchListView->mCurList->getRowCount(); i++)
{ {
if(mSearchListView->mCurList->getCellContent(i, ColPid) == pidText) if(mSearchListView->mCurList->getCellContent(i, ColPid) == pidText)
{ {
@ -138,12 +138,12 @@ retryFindWindow:
} }
} }
void AttachDialog::processListContextMenu(QMenu* wMenu) void AttachDialog::processListContextMenu(QMenu* menu)
{ {
// Don't show menu options if nothing is listed // Don't show menu options if nothing is listed
if(!mSearchListView->mCurList->getRowCount()) if(!mSearchListView->mCurList->getRowCount())
return; return;
wMenu->addAction(mAttachAction); menu->addAction(mAttachAction);
wMenu->addAction(mRefreshAction); menu->addAction(mRefreshAction);
} }

View File

@ -16,14 +16,14 @@ class AttachDialog : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit AttachDialog(QWidget* parent = 0); explicit AttachDialog(QWidget* parent = nullptr);
~AttachDialog(); ~AttachDialog();
private slots: private slots:
void on_btnAttach_clicked(); void on_btnAttach_clicked();
void on_btnFindWindow_clicked(); void on_btnFindWindow_clicked();
void refresh(); void refresh();
void processListContextMenu(QMenu* wMenu); void processListContextMenu(QMenu* menu);
private: private:
Ui::AttachDialog* ui; Ui::AttachDialog* ui;

View File

@ -5,6 +5,7 @@
#include "Bridge.h" #include "Bridge.h"
#include "MenuBuilder.h" #include "MenuBuilder.h"
#include "Breakpoints.h" #include "Breakpoints.h"
#include "DisassemblyPopup.h"
BreakpointsView::BreakpointsView(QWidget* parent) BreakpointsView::BreakpointsView(QWidget* parent)
: StdTable(parent), mExceptionMaxLength(0) : StdTable(parent), mExceptionMaxLength(0)
@ -22,14 +23,14 @@ BreakpointsView::BreakpointsView(QWidget* parent)
addColumnAt(0, tr("Summary"), true); addColumnAt(0, tr("Summary"), true);
loadColumnFromConfig("BreakpointsView"); loadColumnFromConfig("BreakpointsView");
mDisasm = new QBeaEngine(ConfigUint("Disassembler", "MaxModuleSize")); mDisasm = new QZydis(ConfigUint("Disassembler", "MaxModuleSize"), Bridge::getArchitecture());
mDisasm->UpdateConfig(); mDisasm->UpdateConfig();
enableMultiSelection(true); enableMultiSelection(true);
setupContextMenu(); setupContextMenu();
connect(Bridge::getBridge(), SIGNAL(updateBreakpoints()), this, SLOT(updateBreakpointsSlot())); connect(Bridge::getBridge(), SIGNAL(updateBreakpoints()), this, SLOT(updateBreakpointsSlot()));
connect(Bridge::getBridge(), SIGNAL(disassembleAt(dsint, dsint)), this, SLOT(disassembleAtSlot(dsint, dsint))); connect(Bridge::getBridge(), SIGNAL(disassembleAt(duint, duint)), this, SLOT(disassembleAtSlot(duint, duint)));
connect(Config(), SIGNAL(tokenizerConfigUpdated()), this, SLOT(tokenizerConfigUpdatedSlot())); connect(Config(), SIGNAL(tokenizerConfigUpdated()), this, SLOT(tokenizerConfigUpdatedSlot()));
connect(this, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(contextMenuSlot(QPoint))); connect(this, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(contextMenuSlot(QPoint)));
@ -37,6 +38,8 @@ BreakpointsView::BreakpointsView(QWidget* parent)
connect(this, SIGNAL(enterPressedSignal()), this, SLOT(followBreakpointSlot())); connect(this, SIGNAL(enterPressedSignal()), this, SLOT(followBreakpointSlot()));
Initialize(); Initialize();
new DisassemblyPopup(this, Bridge::getArchitecture());
} }
void BreakpointsView::setupContextMenu() void BreakpointsView::setupContextMenu()
@ -139,7 +142,7 @@ void BreakpointsView::updateColors()
updateBreakpointsSlot(); updateBreakpointsSlot();
} }
void BreakpointsView::sortRows(int column, bool ascending) void BreakpointsView::sortRows(duint column, bool ascending)
{ {
std::stable_sort(mData.begin(), mData.end(), [this, column, ascending](const std::vector<CellData> & a, const std::vector<CellData> & b) std::stable_sort(mData.begin(), mData.end(), [this, column, ascending](const std::vector<CellData> & a, const std::vector<CellData> & b)
{ {
@ -161,15 +164,15 @@ void BreakpointsView::sortRows(int column, bool ascending)
}); });
} }
QString BreakpointsView::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) QString BreakpointsView::paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h)
{ {
if(isSelected(rowBase, rowOffset)) if(isSelected(row))
painter->fillRect(QRect(x, y, w, h), QBrush(col == ColDisasm ? mDisasmSelectionColor : mSelectionColor)); painter->fillRect(QRect(x, y, w, h), QBrush(col == ColDisasm ? mDisasmSelectionColor : mSelectionColor));
else if(col == ColDisasm) else if(col == ColDisasm)
painter->fillRect(QRect(x, y, w, h), QBrush(mDisasmBackgroundColor)); painter->fillRect(QRect(x, y, w, h), QBrush(mDisasmBackgroundColor));
auto index = bpIndex(rowBase + rowOffset); auto index = bpIndex(row);
auto & bp = mBps.at(index); auto & bp = mBps.at(index);
auto cellContent = getCellContent(rowBase + rowOffset, col); auto cellContent = getCellContent(row, col);
if(col > ColType && !bp.addr && !bp.active) if(col > ColType && !bp.addr && !bp.active)
{ {
auto mid = h / 2.0; auto mid = h / 2.0;
@ -556,7 +559,7 @@ void BreakpointsView::updateBreakpointsSlot()
reloadData(); reloadData();
} }
void BreakpointsView::disassembleAtSlot(dsint addr, dsint cip) void BreakpointsView::disassembleAtSlot(duint addr, duint cip)
{ {
Q_UNUSED(addr); Q_UNUSED(addr);
mCip = cip; mCip = cip;
@ -570,10 +573,10 @@ void BreakpointsView::tokenizerConfigUpdatedSlot()
void BreakpointsView::contextMenuSlot(const QPoint & pos) void BreakpointsView::contextMenuSlot(const QPoint & pos)
{ {
QMenu wMenu(this); QMenu menu(this);
mMenuBuilder->build(&wMenu); mMenuBuilder->build(&menu);
if(!wMenu.actions().isEmpty()) if(!menu.actions().isEmpty())
wMenu.exec(mapToGlobal(pos)); menu.exec(mapToGlobal(pos));
} }
void BreakpointsView::followBreakpointSlot() void BreakpointsView::followBreakpointSlot()

View File

@ -3,7 +3,7 @@
#include <QWidget> #include <QWidget>
#include "Bridge.h" #include "Bridge.h"
#include "StdTable.h" #include "StdTable.h"
#include "QBeaEngine.h" #include "QZydis.h"
class MenuBuilder; class MenuBuilder;
@ -11,17 +11,17 @@ class BreakpointsView : public StdTable
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit BreakpointsView(QWidget* parent = 0); explicit BreakpointsView(QWidget* parent = nullptr);
protected: protected:
void setupContextMenu(); void setupContextMenu();
void updateColors() override; void updateColors() override;
void sortRows(int column, bool ascending) override; void sortRows(duint column, bool ascending) override;
QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) override; QString paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h) override;
private slots: private slots:
void updateBreakpointsSlot(); void updateBreakpointsSlot();
void disassembleAtSlot(dsint addr, dsint cip); void disassembleAtSlot(duint addr, duint cip);
void tokenizerConfigUpdatedSlot(); void tokenizerConfigUpdatedSlot();
void contextMenuSlot(const QPoint & pos); void contextMenuSlot(const QPoint & pos);
void followBreakpointSlot(); void followBreakpointSlot();
@ -64,7 +64,7 @@ private:
duint mCip = 0; duint mCip = 0;
MenuBuilder* mMenuBuilder; MenuBuilder* mMenuBuilder;
QAction* mEnableDisableAction; QAction* mEnableDisableAction;
QBeaEngine* mDisasm; QZydis* mDisasm;
const int bpIndex(int i) const const int bpIndex(int i) const
{ {

View File

@ -3,13 +3,10 @@
#include "Configuration.h" #include "Configuration.h"
#include "Bridge.h" #include "Bridge.h"
CPUArgumentWidget::CPUArgumentWidget(QWidget* parent) : CPUArgumentWidget::CPUArgumentWidget(Architecture* architecture, QWidget* parent) :
QWidget(parent), QWidget(parent),
ui(new Ui::CPUArgumentWidget), ui(new Ui::CPUArgumentWidget),
mTable(nullptr), mArchitecture(architecture)
mCurrentCallingConvention(-1),
mStackOffset(0),
mAllowUpdate(true)
{ {
ui->setupUi(this); ui->setupUi(this);
mTable = ui->table; mTable = ui->table;
@ -32,7 +29,7 @@ CPUArgumentWidget::CPUArgumentWidget(QWidget* parent) :
connect(mFollowAddrStack, SIGNAL(triggered()), this, SLOT(followStackSlot())); connect(mFollowAddrStack, SIGNAL(triggered()), this, SLOT(followStackSlot()));
connect(Bridge::getBridge(), SIGNAL(repaintTableView()), this, SLOT(refreshData())); connect(Bridge::getBridge(), SIGNAL(repaintTableView()), this, SLOT(refreshData()));
connect(Bridge::getBridge(), SIGNAL(disassembleAt(dsint, dsint)), this, SLOT(disassembleAtSlot(dsint, dsint))); connect(Bridge::getBridge(), SIGNAL(disassembleAt(duint, duint)), this, SLOT(disassembleAtSlot(duint, duint)));
} }
CPUArgumentWidget::~CPUArgumentWidget() CPUArgumentWidget::~CPUArgumentWidget()
@ -46,7 +43,7 @@ void CPUArgumentWidget::updateStackOffset(bool iscall)
mStackOffset = cur.getStackOffset() + (iscall ? 0 : cur.getCallOffset()); mStackOffset = cur.getStackOffset() + (iscall ? 0 : cur.getCallOffset());
} }
void CPUArgumentWidget::disassembleAtSlot(dsint addr, dsint cip) void CPUArgumentWidget::disassembleAtSlot(duint addr, duint cip)
{ {
Q_UNUSED(addr); Q_UNUSED(addr);
if(mCurrentCallingConvention == -1) //no calling conventions if(mCurrentCallingConvention == -1) //no calling conventions
@ -120,12 +117,12 @@ void CPUArgumentWidget::refreshData()
mTable->reloadData(); mTable->reloadData();
} }
static void configAction(QMenu & wMenu, const QIcon & icon, QAction* action, const QString & value, const QString & name) static void configAction(QMenu & menu, const QIcon & icon, QAction* action, const QString & value, const QString & name)
{ {
action->setText(QApplication::translate("CPUArgumentWidget", "Follow %1 in %2").arg(value).arg(name)); action->setText(QApplication::translate("CPUArgumentWidget", "Follow %1 in %2").arg(value).arg(name));
action->setIcon(icon); action->setIcon(icon);
action->setObjectName(value); action->setObjectName(value);
wMenu.addAction(action); menu.addAction(action);
} }
void CPUArgumentWidget::contextMenuSlot(QPoint pos) void CPUArgumentWidget::contextMenuSlot(QPoint pos)
@ -136,7 +133,7 @@ void CPUArgumentWidget::contextMenuSlot(QPoint pos)
if(int(mArgumentValues.size()) <= selection) if(int(mArgumentValues.size()) <= selection)
return; return;
auto value = mArgumentValues[selection]; auto value = mArgumentValues[selection];
QMenu wMenu(this); QMenu menu(this);
if(DbgMemIsValidReadPtr(value)) if(DbgMemIsValidReadPtr(value))
{ {
duint valueAddr; duint valueAddr;
@ -152,27 +149,27 @@ void CPUArgumentWidget::contextMenuSlot(QPoint pos)
return addr >= base && addr < base + size; return addr >= base && addr < base + size;
}; };
configAction(wMenu, DIcon(ArchValue("processor32", "processor64")), mFollowDisasm, valueText, tr("Disassembler")); configAction(menu, DIcon(ArchValue("processor32", "processor64")), mFollowDisasm, valueText, tr("Disassembler"));
configAction(wMenu, DIcon("dump"), mFollowDump, valueText, tr("Dump")); configAction(menu, DIcon("dump"), mFollowDump, valueText, tr("Dump"));
if(inStackRange(value)) if(inStackRange(value))
configAction(wMenu, DIcon("stack"), mFollowStack, valueText, tr("Stack")); configAction(menu, DIcon("stack"), mFollowStack, valueText, tr("Stack"));
if(DbgMemIsValidReadPtr(valueAddr)) if(DbgMemIsValidReadPtr(valueAddr))
{ {
configAction(wMenu, DIcon(ArchValue("processor32", "processor64")), mFollowAddrDisasm, valueAddrText, tr("Disassembler")); configAction(menu, DIcon(ArchValue("processor32", "processor64")), mFollowAddrDisasm, valueAddrText, tr("Disassembler"));
configAction(wMenu, DIcon("dump"), mFollowDump, valueAddrText, tr("Dump")); configAction(menu, DIcon("dump"), mFollowDump, valueAddrText, tr("Dump"));
if(inStackRange(valueAddr)) if(inStackRange(valueAddr))
configAction(wMenu, DIcon("stack"), mFollowAddrStack, valueAddrText, tr("Stack")); configAction(menu, DIcon("stack"), mFollowAddrStack, valueAddrText, tr("Stack"));
} }
} }
QMenu wCopyMenu(tr("&Copy")); QMenu copyMenu(tr("&Copy"));
wCopyMenu.setIcon(DIcon("copy")); copyMenu.setIcon(DIcon("copy"));
mTable->setupCopyMenu(&wCopyMenu); mTable->setupCopyMenu(&copyMenu);
if(wCopyMenu.actions().length()) if(copyMenu.actions().length())
{ {
wMenu.addSeparator(); menu.addSeparator();
wMenu.addMenu(&wCopyMenu); menu.addMenu(&copyMenu);
} }
wMenu.exec(mTable->mapToGlobal(pos)); menu.exec(mTable->mapToGlobal(pos));
} }
void CPUArgumentWidget::followDisasmSlot() void CPUArgumentWidget::followDisasmSlot()

View File

@ -4,6 +4,7 @@
#include <vector> #include <vector>
#include "StdTable.h" #include "StdTable.h"
#include "StringUtil.h" #include "StringUtil.h"
#include "Architecture.h"
namespace Ui namespace Ui
{ {
@ -15,7 +16,7 @@ class CPUArgumentWidget : public QWidget
Q_OBJECT Q_OBJECT
public: public:
explicit CPUArgumentWidget(QWidget* parent = 0); explicit CPUArgumentWidget(Architecture* architecture, QWidget* parent = nullptr);
~CPUArgumentWidget(); ~CPUArgumentWidget();
static QString defaultArgFormat(const QString & format, const QString & expression) static QString defaultArgFormat(const QString & format, const QString & expression)
@ -40,7 +41,7 @@ public:
} }
public slots: public slots:
void disassembleAtSlot(dsint addr, dsint cip); void disassembleAtSlot(duint addr, duint cip);
void refreshData(); void refreshData();
private slots: private slots:
@ -133,11 +134,12 @@ private:
} }
}; };
Ui::CPUArgumentWidget* ui; Architecture* mArchitecture = nullptr;
StdTable* mTable; Ui::CPUArgumentWidget* ui = nullptr;
int mCurrentCallingConvention; StdTable* mTable = nullptr;
duint mStackOffset; int mCurrentCallingConvention = -1;
bool mAllowUpdate; duint mStackOffset = 0;
bool mAllowUpdate = true;
std::vector<CallingConvention> mCallingConventions; std::vector<CallingConvention> mCallingConventions;
std::vector<duint> mArgumentValues; std::vector<duint> mArgumentValues;
QAction* mFollowDisasm; QAction* mFollowDisasm;

View File

@ -26,7 +26,8 @@
#include "BrowseDialog.h" #include "BrowseDialog.h"
#include "Tracer/TraceBrowser.h" #include "Tracer/TraceBrowser.h"
CPUDisassembly::CPUDisassembly(QWidget* parent, bool isMain) : Disassembly(parent, isMain) CPUDisassembly::CPUDisassembly(Architecture* architecture, bool isMain, QWidget* parent)
: Disassembly(architecture, isMain, parent)
{ {
setWindowTitle("Disassembly"); setWindowTitle("Disassembly");
@ -34,7 +35,7 @@ CPUDisassembly::CPUDisassembly(QWidget* parent, bool isMain) : Disassembly(paren
setupRightClickContextMenu(); setupRightClickContextMenu();
// Connect bridge<->disasm calls // Connect bridge<->disasm calls
connect(Bridge::getBridge(), SIGNAL(disassembleAt(dsint, dsint)), this, SLOT(disassembleAtSlot(dsint, dsint))); connect(Bridge::getBridge(), SIGNAL(disassembleAt(duint, duint)), this, SLOT(disassembleAtSlot(duint, duint)));
if(mIsMain) if(mIsMain)
{ {
connect(Bridge::getBridge(), SIGNAL(selectionDisasmGet(SELECTIONDATA*)), this, SLOT(selectionGetSlot(SELECTIONDATA*))); connect(Bridge::getBridge(), SIGNAL(selectionDisasmGet(SELECTIONDATA*)), this, SLOT(selectionGetSlot(SELECTIONDATA*)));
@ -133,7 +134,7 @@ void CPUDisassembly::mouseDoubleClickEvent(QMouseEvent* event)
} }
} }
void CPUDisassembly::addFollowReferenceMenuItem(QString name, dsint value, QMenu* menu, bool isReferences, bool isFollowInCPU) void CPUDisassembly::addFollowReferenceMenuItem(QString name, duint value, QMenu* menu, bool isReferences, bool isFollowInCPU)
{ {
foreach(QAction* action, menu->actions()) //check for duplicate action foreach(QAction* action, menu->actions()) //check for duplicate action
if(action->text() == name) if(action->text() == name)
@ -149,7 +150,7 @@ void CPUDisassembly::addFollowReferenceMenuItem(QString name, dsint value, QMenu
connect(newAction, SIGNAL(triggered()), this, SLOT(followActionSlot())); connect(newAction, SIGNAL(triggered()), this, SLOT(followActionSlot()));
} }
void CPUDisassembly::setupFollowReferenceMenu(dsint wVA, QMenu* menu, bool isReferences, bool isFollowInCPU) void CPUDisassembly::setupFollowReferenceMenu(duint va, QMenu* menu, bool isReferences, bool isFollowInCPU)
{ {
//remove previous actions //remove previous actions
QList<QAction*> list = menu->actions(); QList<QAction*> list = menu->actions();
@ -162,12 +163,12 @@ void CPUDisassembly::setupFollowReferenceMenu(dsint wVA, QMenu* menu, bool isRef
if(isReferences) if(isReferences)
menu->addAction(mReferenceSelectedAddressAction); menu->addAction(mReferenceSelectedAddressAction);
else else
addFollowReferenceMenuItem(tr("&Selected Address"), wVA, menu, isReferences, isFollowInCPU); addFollowReferenceMenuItem(tr("&Selected Address"), va, menu, isReferences, isFollowInCPU);
} }
//add follow actions //add follow actions
DISASM_INSTR instr; DISASM_INSTR instr;
DbgDisasmAt(wVA, &instr); DbgDisasmAt(va, &instr);
if(!isReferences) //follow in dump if(!isReferences) //follow in dump
{ {
@ -256,13 +257,13 @@ void CPUDisassembly::setupFollowReferenceMenu(dsint wVA, QMenu* menu, bool isRef
*/ */
void CPUDisassembly::contextMenuEvent(QContextMenuEvent* event) void CPUDisassembly::contextMenuEvent(QContextMenuEvent* event)
{ {
QMenu wMenu(this); QMenu menu(this);
if(!mHighlightContextMenu) if(!mHighlightContextMenu)
mMenuBuilder->build(&wMenu); mMenuBuilder->build(&menu);
else if(mHighlightToken.text.length()) else if(mHighlightToken.text.length())
mHighlightMenuBuilder->build(&wMenu); mHighlightMenuBuilder->build(&menu);
if(wMenu.actions().length()) if(menu.actions().length())
wMenu.exec(event->globalPos()); menu.exec(event->globalPos());
} }
/************************************************************************************ /************************************************************************************
@ -735,19 +736,19 @@ void CPUDisassembly::setLabelSlot()
{ {
if(!DbgIsDebugging()) if(!DbgIsDebugging())
return; return;
duint wVA = rvaToVa(getInitialSelection()); duint va = rvaToVa(getInitialSelection());
LineEditDialog mLineEdit(this); LineEditDialog mLineEdit(this);
mLineEdit.setTextMaxLength(MAX_LABEL_SIZE - 2); mLineEdit.setTextMaxLength(MAX_LABEL_SIZE - 2);
QString addr_text = ToPtrString(wVA); QString addr_text = ToPtrString(va);
char label_text[MAX_COMMENT_SIZE] = ""; char label_text[MAX_COMMENT_SIZE] = "";
if(DbgGetLabelAt((duint)wVA, SEG_DEFAULT, label_text)) if(DbgGetLabelAt((duint)va, SEG_DEFAULT, label_text))
mLineEdit.setText(QString(label_text)); mLineEdit.setText(QString(label_text));
mLineEdit.setWindowTitle(tr("Add label at ") + addr_text); mLineEdit.setWindowTitle(tr("Add label at ") + addr_text);
restart: restart:
if(mLineEdit.exec() != QDialog::Accepted) if(mLineEdit.exec() != QDialog::Accepted)
return; return;
QByteArray utf8data = mLineEdit.editText.toUtf8(); QByteArray utf8data = mLineEdit.editText.toUtf8();
if(!utf8data.isEmpty() && DbgIsValidExpression(utf8data.constData()) && DbgValFromString(utf8data.constData()) != wVA) if(!utf8data.isEmpty() && DbgIsValidExpression(utf8data.constData()) && DbgValFromString(utf8data.constData()) != va)
{ {
QMessageBox msg(QMessageBox::Warning, tr("The label may be in use"), QMessageBox msg(QMessageBox::Warning, tr("The label may be in use"),
tr("The label \"%1\" may be an existing label or a valid expression. Using such label might have undesired effects. Do you still want to continue?").arg(mLineEdit.editText), tr("The label \"%1\" may be an existing label or a valid expression. Using such label might have undesired effects. Do you still want to continue?").arg(mLineEdit.editText),
@ -758,7 +759,7 @@ restart:
if(msg.exec() == QMessageBox::No) if(msg.exec() == QMessageBox::No)
goto restart; goto restart;
} }
if(!DbgSetLabelAt(wVA, utf8data.constData())) if(!DbgSetLabelAt(va, utf8data.constData()))
SimpleErrorBox(this, tr("Error!"), tr("DbgSetLabelAt failed!")); SimpleErrorBox(this, tr("Error!"), tr("DbgSetLabelAt failed!"));
GuiUpdateAllViews(); GuiUpdateAllViews();
@ -898,12 +899,12 @@ void CPUDisassembly::assembleSlot()
do do
{ {
dsint wRVA = getInitialSelection(); dsint rva = getInitialSelection();
duint wVA = rvaToVa(wRVA); duint va = rvaToVa(rva);
unfold(wRVA); unfold(rva);
QString addr_text = ToPtrString(wVA); QString addr_text = ToPtrString(va);
Instruction_t instr = this->DisassembleAt(wRVA); Instruction_t instr = this->DisassembleAt(rva);
QString actual_inst = instr.instStr; QString actual_inst = instr.instStr;
@ -914,7 +915,7 @@ void CPUDisassembly::assembleSlot()
assembly_error = false; assembly_error = false;
assembleDialog.setSelectedInstrVa(wVA); assembleDialog.setSelectedInstrVa(va);
if(ConfigBool("Disassembler", "Uppercase")) if(ConfigBool("Disassembler", "Uppercase"))
actual_inst = actual_inst.toUpper().replace(QRegularExpression("0X([0-9A-F]+)"), "0x\\1"); actual_inst = actual_inst.toUpper().replace(QRegularExpression("0X([0-9A-F]+)"), "0x\\1");
assembleDialog.setTextEditValue(actual_inst); assembleDialog.setTextEditValue(actual_inst);
@ -937,7 +938,7 @@ void CPUDisassembly::assembleSlot()
if(expression == QString("???") || expression.toLower() == instr.instStr.toLower() || expression == QString("")) if(expression == QString("???") || expression.toLower() == instr.instStr.toLower() || expression == QString(""))
break; break;
if(!DbgFunctions()->AssembleAtEx(wVA, expression.toUtf8().constData(), error, assembleDialog.bFillWithNopsChecked)) if(!DbgFunctions()->AssembleAtEx(va, expression.toUtf8().constData(), error, assembleDialog.bFillWithNopsChecked))
{ {
QMessageBox msg(QMessageBox::Critical, tr("Error!"), tr("Failed to assemble instruction \" %1 \" (%2)").arg(expression).arg(error)); QMessageBox msg(QMessageBox::Critical, tr("Error!"), tr("Failed to assemble instruction \" %1 \" (%2)").arg(expression).arg(error));
msg.setWindowIcon(DIcon("compile-error")); msg.setWindowIcon(DIcon("compile-error"));
@ -951,20 +952,20 @@ void CPUDisassembly::assembleSlot()
while(assembly_error); while(assembly_error);
//select next instruction after assembling //select next instruction after assembling
setSingleSelection(wRVA); setSingleSelection(rva);
dsint botRVA = getTableOffset(); auto botRVA = getTableOffset();
dsint topRVA = getInstructionRVA(getTableOffset(), getNbrOfLineToPrint() - 1); auto topRVA = getInstructionRVA(getTableOffset(), getNbrOfLineToPrint() - 1);
dsint wInstrSize = getInstructionRVA(wRVA, 1) - wRVA - 1; // TODO: this seems dumb
auto instrSize = getInstructionRVA(rva, 1) - rva - 1;
expandSelectionUpTo(wRVA + wInstrSize); expandSelectionUpTo(rva + instrSize);
selectNext(false); selectNext(false);
if(getSelectionStart() < botRVA) if(getSelectionStart() < botRVA)
setTableOffset(getSelectionStart()); setTableOffset(getSelectionStart());
else if(getSelectionEnd() >= topRVA) else if(getSelectionEnd() >= topRVA)
setTableOffset(getInstructionRVA(getSelectionEnd(), -getNbrOfLineToPrint() + 2)); setTableOffset(getInstructionRVA(getSelectionEnd(), -(dsint)getNbrOfLineToPrint() + 2));
//refresh view //refresh view
GuiUpdateAllViews(); GuiUpdateAllViews();
@ -1533,7 +1534,8 @@ void CPUDisassembly::pushSelectionInto(bool copyBytes, QTextStream & stream, QTe
if(i) if(i)
stream << "\r\n"; stream << "\r\n";
duint cur_addr = rvaToVa(inst.rva); duint cur_addr = rvaToVa(inst.rva);
QString address = getAddrText(cur_addr, 0, addressLen > sizeof(duint) * 2 + 1); QString label;
QString address = getAddrText(cur_addr, label, addressLen > sizeof(duint) * 2 + 1);
QString bytes; QString bytes;
QString bytesHtml; QString bytesHtml;
if(copyBytes) if(copyBytes)

View File

@ -13,7 +13,7 @@ class CPUDisassembly : public Disassembly
Q_OBJECT Q_OBJECT
public: public:
CPUDisassembly(QWidget* parent, bool isMain); CPUDisassembly(Architecture* architecture, bool isMain, QWidget* parent = nullptr);
// Mouse management // Mouse management
void contextMenuEvent(QContextMenuEvent* event); void contextMenuEvent(QContextMenuEvent* event);
@ -22,8 +22,8 @@ public:
// Context menu management // Context menu management
void setupRightClickContextMenu(); void setupRightClickContextMenu();
void addFollowReferenceMenuItem(QString name, dsint value, QMenu* menu, bool isReferences, bool isFollowInCPU); void addFollowReferenceMenuItem(QString name, duint value, QMenu* menu, bool isReferences, bool isFollowInCPU);
void setupFollowReferenceMenu(dsint wVA, QMenu* menu, bool isReferences, bool isFollowInCPU); void setupFollowReferenceMenu(duint va, QMenu* menu, bool isReferences, bool isFollowInCPU);
void copySelectionSlot(bool copyBytes); void copySelectionSlot(bool copyBytes);
void copySelectionToFileSlot(bool copyBytes); void copySelectionToFileSlot(bool copyBytes);
void setSideBar(CPUSideBar* sideBar); void setSideBar(CPUSideBar* sideBar);

File diff suppressed because it is too large Load Diff

View File

@ -12,14 +12,14 @@ class CPUDump : public HexDump
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit CPUDump(CPUDisassembly* disas, CPUMultiDump* multiDump, QWidget* parent = 0); explicit CPUDump(CPUMultiDump* multiDump, CPUDisassembly* disasassembly, QWidget* parent = nullptr);
void getColumnRichText(int col, dsint rva, RichTextPainter::List & richText) override; void getColumnRichText(duint col, duint rva, RichTextPainter::List & richText) override;
QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h); QString paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h) override;
void setupContextMenu(); void setupContextMenu();
void getAttention(); void getAttention();
void contextMenuEvent(QContextMenuEvent* event); void contextMenuEvent(QContextMenuEvent* event) override;
void mouseDoubleClickEvent(QMouseEvent* event); void mouseDoubleClickEvent(QMouseEvent* event) override;
void mouseMoveEvent(QMouseEvent* event); void mouseMoveEvent(QMouseEvent* event) override;
signals: signals:
void displayReferencesWidget(); void displayReferencesWidget();
@ -82,7 +82,7 @@ public slots:
void syncWithExpressionSlot(); void syncWithExpressionSlot();
void allocMemorySlot(); void allocMemorySlot();
void headerButtonReleasedSlot(int colIndex); void headerButtonReleasedSlot(duint colIndex);
private: private:
MenuBuilder* mMenuBuilder; MenuBuilder* mMenuBuilder;
@ -94,8 +94,8 @@ private:
GotoDialog* mGoto = nullptr; GotoDialog* mGoto = nullptr;
GotoDialog* mGotoOffset = nullptr; GotoDialog* mGotoOffset = nullptr;
CPUDisassembly* mDisas; CPUDisassembly* mDisassembly = nullptr;
CPUMultiDump* mMultiDump; CPUMultiDump* mMultiDump = nullptr;
int mAsciiSeparator = 0; int mAsciiSeparator = 0;
enum ViewEnum_t enum ViewEnum_t

View File

@ -3,9 +3,11 @@
#include "WordEditDialog.h" #include "WordEditDialog.h"
#include "XrefBrowseDialog.h" #include "XrefBrowseDialog.h"
#include "Bridge.h" #include "Bridge.h"
#include "QBeaEngine.h" #include "QZydis.h"
CPUInfoBox::CPUInfoBox(QWidget* parent) : StdTable(parent) CPUInfoBox::CPUInfoBox(Architecture* architecture, QWidget* parent)
: StdTable(parent),
mArchitecture(architecture)
{ {
setWindowTitle("InfoBox"); setWindowTitle("InfoBox");
enableMultiSelection(false); enableMultiSelection(false);
@ -26,13 +28,13 @@ CPUInfoBox::CPUInfoBox(QWidget* parent) : StdTable(parent)
connect(Bridge::getBridge(), SIGNAL(addInfoLine(QString)), this, SLOT(addInfoLine(QString))); connect(Bridge::getBridge(), SIGNAL(addInfoLine(QString)), this, SLOT(addInfoLine(QString)));
connect(this, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(contextMenuSlot(QPoint))); connect(this, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(contextMenuSlot(QPoint)));
connect(this, SIGNAL(doubleClickedSignal()), this, SLOT(doubleClickedSlot())); connect(this, SIGNAL(doubleClickedSignal()), this, SLOT(doubleClickedSlot()));
curAddr = 0; mCurAddr = 0;
// Deselect any row (visual reasons only) // Deselect any row (visual reasons only)
setSingleSelection(-1); setSingleSelection(-1);
int maxModuleSize = (int)ConfigUint("Disassembler", "MaxModuleSize"); int maxModuleSize = (int)ConfigUint("Disassembler", "MaxModuleSize");
mDisasm = new QBeaEngine(maxModuleSize); mDisasm = new QZydis(maxModuleSize, architecture);
setupContextMenu(); setupContextMenu();
} }
@ -148,11 +150,11 @@ QString CPUInfoBox::formatSSEOperand(const QByteArray & data, unsigned char vect
return hex; return hex;
} }
void CPUInfoBox::disasmSelectionChanged(dsint parVA) void CPUInfoBox::disasmSelectionChanged(duint parVA)
{ {
curAddr = parVA; mCurAddr = parVA;
curRva = -1; mCurRva = -1;
curOffset = -1; mCurOffset = -1;
if(!DbgIsDebugging() || !DbgMemIsValidReadPtr(parVA)) if(!DbgIsDebugging() || !DbgMemIsValidReadPtr(parVA))
return; return;
@ -163,10 +165,10 @@ void CPUInfoBox::disasmSelectionChanged(dsint parVA)
setCellContent(1, 0, ""); setCellContent(1, 0, "");
setCellContent(2, 0, ""); setCellContent(2, 0, "");
Instruction_t wInst; Instruction_t inst;
unsigned char instructiondata[MAX_DISASM_BUFFER]; unsigned char instructiondata[MAX_DISASM_BUFFER];
DbgMemRead(parVA, &instructiondata, MAX_DISASM_BUFFER); DbgMemRead(parVA, &instructiondata, MAX_DISASM_BUFFER);
wInst = mDisasm->DisassembleAt(instructiondata, MAX_DISASM_BUFFER, 0, parVA); inst = mDisasm->DisassembleAt(instructiondata, MAX_DISASM_BUFFER, 0, parVA);
DISASM_INSTR instr; //Fix me: these disasm methods are so messy DISASM_INSTR instr; //Fix me: these disasm methods are so messy
DbgDisasmAt(parVA, &instr); DbgDisasmAt(parVA, &instr);
BASIC_INSTRUCTION_INFO basicinfo; BASIC_INSTRUCTION_INFO basicinfo;
@ -174,7 +176,7 @@ void CPUInfoBox::disasmSelectionChanged(dsint parVA)
int start = 0; int start = 0;
bool commentThis = !ConfigBool("Disassembler", "OnlyCipAutoComments") || parVA == DbgValFromString("cip"); bool commentThis = !ConfigBool("Disassembler", "OnlyCipAutoComments") || parVA == DbgValFromString("cip");
if(wInst.branchType == Instruction_t::Conditional && commentThis) //jump if(inst.branchType == Instruction_t::Conditional && commentThis) //jump
{ {
bool taken = DbgIsJumpGoingToExecute(parVA); bool taken = DbgIsJumpGoingToExecute(parVA);
if(taken) if(taken)
@ -262,7 +264,7 @@ void CPUInfoBox::disasmSelectionChanged(dsint parVA)
{ {
setInfoLine(j, sizeName + "[" + argMnemonic + "]=???"); setInfoLine(j, sizeName + "[" + argMnemonic + "]=???");
} }
else if(knownsize && wInst.vectorElementType[i] == Zydis::VETDefault) // MOVSD/MOVSS instruction else if(knownsize && inst.vectorElementType[i] == Zydis::VETDefault) // MOVSD/MOVSS instruction
{ {
QString addrText = getSymbolicNameStr(arg.memvalue); QString addrText = getSymbolicNameStr(arg.memvalue);
setInfoLine(j, sizeName + "[" + argMnemonic + "]=" + addrText); setInfoLine(j, sizeName + "[" + argMnemonic + "]=" + addrText);
@ -274,7 +276,7 @@ void CPUInfoBox::disasmSelectionChanged(dsint parVA)
memset(data.data(), 0, data.size()); memset(data.data(), 0, data.size());
if(DbgMemRead(arg.value, data.data(), data.size())) if(DbgMemRead(arg.value, data.data(), data.size()))
{ {
setInfoLine(j, sizeName + "[" + argMnemonic + "]=" + formatSSEOperand(data, wInst.vectorElementType[i])); setInfoLine(j, sizeName + "[" + argMnemonic + "]=" + formatSSEOperand(data, inst.vectorElementType[i]));
} }
else else
{ {
@ -315,72 +317,72 @@ void CPUInfoBox::disasmSelectionChanged(dsint parVA)
REGDUMP registers; REGDUMP registers;
DbgGetRegDumpEx(&registers, sizeof(registers)); DbgGetRegDumpEx(&registers, sizeof(registers));
if(mnemonic == "xmm0") if(mnemonic == "xmm0")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[0], 16), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[0], 16), inst.vectorElementType[i]);
else if(mnemonic == "xmm1") else if(mnemonic == "xmm1")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[1], 16), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[1], 16), inst.vectorElementType[i]);
else if(mnemonic == "xmm2") else if(mnemonic == "xmm2")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[2], 16), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[2], 16), inst.vectorElementType[i]);
else if(mnemonic == "xmm3") else if(mnemonic == "xmm3")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[3], 16), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[3], 16), inst.vectorElementType[i]);
else if(mnemonic == "xmm4") else if(mnemonic == "xmm4")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[4], 16), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[4], 16), inst.vectorElementType[i]);
else if(mnemonic == "xmm5") else if(mnemonic == "xmm5")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[5], 16), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[5], 16), inst.vectorElementType[i]);
else if(mnemonic == "xmm6") else if(mnemonic == "xmm6")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[6], 16), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[6], 16), inst.vectorElementType[i]);
else if(mnemonic == "xmm7") else if(mnemonic == "xmm7")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[7], 16), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[7], 16), inst.vectorElementType[i]);
#ifdef _WIN64 #ifdef _WIN64
else if(mnemonic == "xmm8") else if(mnemonic == "xmm8")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[8], 16), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[8], 16), inst.vectorElementType[i]);
else if(mnemonic == "xmm9") else if(mnemonic == "xmm9")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[9], 16), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[9], 16), inst.vectorElementType[i]);
else if(mnemonic == "xmm10") else if(mnemonic == "xmm10")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[10], 16), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[10], 16), inst.vectorElementType[i]);
else if(mnemonic == "xmm11") else if(mnemonic == "xmm11")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[11], 16), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[11], 16), inst.vectorElementType[i]);
else if(mnemonic == "xmm12") else if(mnemonic == "xmm12")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[12], 16), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[12], 16), inst.vectorElementType[i]);
else if(mnemonic == "xmm13") else if(mnemonic == "xmm13")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[13], 16), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[13], 16), inst.vectorElementType[i]);
else if(mnemonic == "xmm14") else if(mnemonic == "xmm14")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[14], 16), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[14], 16), inst.vectorElementType[i]);
else if(mnemonic == "xmm15") else if(mnemonic == "xmm15")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[15], 16), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.XmmRegisters[15], 16), inst.vectorElementType[i]);
#endif //_WIN64 #endif //_WIN64
else if(mnemonic == "ymm0") else if(mnemonic == "ymm0")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[0], 32), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[0], 32), inst.vectorElementType[i]);
else if(mnemonic == "ymm1") else if(mnemonic == "ymm1")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[1], 32), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[1], 32), inst.vectorElementType[i]);
else if(mnemonic == "ymm2") else if(mnemonic == "ymm2")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[2], 32), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[2], 32), inst.vectorElementType[i]);
else if(mnemonic == "ymm3") else if(mnemonic == "ymm3")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[3], 32), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[3], 32), inst.vectorElementType[i]);
else if(mnemonic == "ymm4") else if(mnemonic == "ymm4")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[4], 32), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[4], 32), inst.vectorElementType[i]);
else if(mnemonic == "ymm5") else if(mnemonic == "ymm5")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[5], 32), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[5], 32), inst.vectorElementType[i]);
else if(mnemonic == "ymm6") else if(mnemonic == "ymm6")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[6], 32), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[6], 32), inst.vectorElementType[i]);
else if(mnemonic == "ymm7") else if(mnemonic == "ymm7")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[7], 32), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[7], 32), inst.vectorElementType[i]);
#ifdef _WIN64 #ifdef _WIN64
else if(mnemonic == "ymm8") else if(mnemonic == "ymm8")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[8], 32), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[8], 32), inst.vectorElementType[i]);
else if(mnemonic == "ymm9") else if(mnemonic == "ymm9")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[9], 32), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[9], 32), inst.vectorElementType[i]);
else if(mnemonic == "ymm10") else if(mnemonic == "ymm10")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[10], 32), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[10], 32), inst.vectorElementType[i]);
else if(mnemonic == "ymm11") else if(mnemonic == "ymm11")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[11], 32), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[11], 32), inst.vectorElementType[i]);
else if(mnemonic == "ymm12") else if(mnemonic == "ymm12")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[12], 32), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[12], 32), inst.vectorElementType[i]);
else if(mnemonic == "ymm13") else if(mnemonic == "ymm13")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[13], 32), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[13], 32), inst.vectorElementType[i]);
else if(mnemonic == "ymm14") else if(mnemonic == "ymm14")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[14], 32), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[14], 32), inst.vectorElementType[i]);
else if(mnemonic == "ymm15") else if(mnemonic == "ymm15")
valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[15], 32), wInst.vectorElementType[i]); valText = formatSSEOperand(QByteArray((const char*)&registers.regcontext.YmmRegisters[15], 32), inst.vectorElementType[i]);
#endif //_WIN64 #endif //_WIN64
else if(mnemonic == "st0") else if(mnemonic == "st0")
valText = ToLongDoubleString(&registers.x87FPURegisters[registers.x87StatusWordFields.TOP & 7]); valText = ToLongDoubleString(&registers.x87FPURegisters[registers.x87StatusWordFields.TOP & 7]);
@ -498,13 +500,13 @@ void CPUInfoBox::disasmSelectionChanged(dsint parVA)
info += " " + QString(mod); info += " " + QString(mod);
// Module RVA // Module RVA
curRva = parVA - modbase; mCurRva = parVA - modbase;
if(modbase) if(modbase)
info += QString(":$%1").arg(ToHexString(curRva)); info += QString(":$%1").arg(ToHexString(mCurRva));
// File offset // File offset
curOffset = DbgFunctions()->VaToFileOffset(parVA); mCurOffset = DbgFunctions()->VaToFileOffset(parVA);
info += QString(" #%1").arg(ToHexString(curOffset)); info += QString(" #%1").arg(ToHexString(mCurOffset));
} }
// Function/label name // Function/label name
@ -554,13 +556,13 @@ void CPUInfoBox::modifySlot()
{ {
duint addrVal = 0; duint addrVal = 0;
DbgFunctions()->ValFromString(action->objectName().toUtf8().constData(), &addrVal); DbgFunctions()->ValFromString(action->objectName().toUtf8().constData(), &addrVal);
WordEditDialog wEditDialog(this); WordEditDialog editDialog(this);
dsint value = 0; dsint value = 0;
DbgMemRead(addrVal, &value, sizeof(dsint)); DbgMemRead(addrVal, &value, sizeof(dsint));
wEditDialog.setup(tr("Modify Value"), value, sizeof(dsint)); editDialog.setup(tr("Modify Value"), value, sizeof(dsint));
if(wEditDialog.exec() != QDialog::Accepted) if(editDialog.exec() != QDialog::Accepted)
return; return;
value = wEditDialog.getVal(); value = editDialog.getVal();
DbgMemWrite(addrVal, &value, sizeof(dsint)); DbgMemWrite(addrVal, &value, sizeof(dsint));
GuiUpdateAllViews(); GuiUpdateAllViews();
} }
@ -572,7 +574,7 @@ void CPUInfoBox::findXReferencesSlot()
return; return;
if(!mXrefDlg) if(!mXrefDlg)
mXrefDlg = new XrefBrowseDialog(this); mXrefDlg = new XrefBrowseDialog(this);
mXrefDlg->setup(curAddr, [](duint address) mXrefDlg->setup(mCurAddr, [](duint address)
{ {
DbgCmdExec(QString("disasm %1").arg(ToPtrString(address))); DbgCmdExec(QString("disasm %1").arg(ToPtrString(address)));
}); });
@ -590,13 +592,13 @@ void CPUInfoBox::addModifyValueMenuItem(QMenu* menu, QString name, duint value)
connect(newAction, SIGNAL(triggered()), this, SLOT(modifySlot())); connect(newAction, SIGNAL(triggered()), this, SLOT(modifySlot()));
} }
void CPUInfoBox::setupModifyValueMenu(QMenu* menu, duint wVA) void CPUInfoBox::setupModifyValueMenu(QMenu* menu, duint va)
{ {
menu->setIcon(DIcon("modify")); menu->setIcon(DIcon("modify"));
//add follow actions //add follow actions
DISASM_INSTR instr; DISASM_INSTR instr;
DbgDisasmAt(wVA, &instr); DbgDisasmAt(va, &instr);
for(int i = 0; i < instr.argcount; i++) for(int i = 0; i < instr.argcount; i++)
{ {
@ -650,17 +652,17 @@ void CPUInfoBox::addFollowMenuItem(QMenu* menu, QString name, duint value)
/** /**
* @brief CPUInfoBox::setupFollowMenu Set up a follow menu. * @brief CPUInfoBox::setupFollowMenu Set up a follow menu.
* @param menu The menu to create * @param menu The menu to create
* @param wVA The selected VA * @param va The selected VA
*/ */
void CPUInfoBox::setupFollowMenu(QMenu* menu, duint wVA) void CPUInfoBox::setupFollowMenu(QMenu* menu, duint va)
{ {
menu->setIcon(DIcon("dump")); menu->setIcon(DIcon("dump"));
//most basic follow action //most basic follow action
addFollowMenuItem(menu, tr("&Selected Address"), wVA); addFollowMenuItem(menu, tr("&Selected Address"), va);
//add follow actions //add follow actions
DISASM_INSTR instr; DISASM_INSTR instr;
DbgDisasmAt(wVA, &instr); DbgDisasmAt(va, &instr);
for(int i = 0; i < instr.argcount; i++) for(int i = 0; i < instr.argcount; i++)
{ {
@ -714,17 +716,17 @@ void CPUInfoBox::addWatchMenuItem(QMenu* menu, QString name, duint value)
/** /**
* @brief CPUInfoBox::setupFollowMenu Set up a follow menu. * @brief CPUInfoBox::setupFollowMenu Set up a follow menu.
* @param menu The menu to create * @param menu The menu to create
* @param wVA The selected VA * @param va The selected VA
*/ */
void CPUInfoBox::setupWatchMenu(QMenu* menu, duint wVA) void CPUInfoBox::setupWatchMenu(QMenu* menu, duint va)
{ {
menu->setIcon(DIcon("animal-dog")); menu->setIcon(DIcon("animal-dog"));
//most basic follow action //most basic follow action
addWatchMenuItem(menu, tr("&Selected Address"), wVA); addWatchMenuItem(menu, tr("&Selected Address"), va);
//add follow actions //add follow actions
DISASM_INSTR instr; DISASM_INSTR instr;
DbgDisasmAt(wVA, &instr); DbgDisasmAt(va, &instr);
for(int i = 0; i < instr.argcount; i++) for(int i = 0; i < instr.argcount; i++)
{ {
@ -758,7 +760,7 @@ void CPUInfoBox::setupWatchMenu(QMenu* menu, duint wVA)
} }
} }
int CPUInfoBox::followInDump(dsint wVA) int CPUInfoBox::followInDump(duint va)
{ {
// Copy pasta from setupFollowMenu for now // Copy pasta from setupFollowMenu for now
int tableOffset = getInitialSelection(); int tableOffset = getInitialSelection();
@ -771,12 +773,12 @@ int CPUInfoBox::followInDump(dsint wVA)
// Last line of infoBox => Current Address(EIP) in disassembly // Last line of infoBox => Current Address(EIP) in disassembly
if(tableOffset == 2) if(tableOffset == 2)
{ {
DbgCmdExec(QString("dump %1").arg(ToPtrString(wVA))); DbgCmdExec(QString("dump %1").arg(ToPtrString(va)));
return 0; return 0;
} }
DISASM_INSTR instr; DISASM_INSTR instr;
DbgDisasmAt(wVA, &instr); DbgDisasmAt(va, &instr);
if(instr.type == instr_branch && cellContent.contains("Jump")) if(instr.type == instr_branch && cellContent.contains("Jump"))
{ {
@ -805,55 +807,55 @@ int CPUInfoBox::followInDump(dsint wVA)
void CPUInfoBox::contextMenuSlot(QPoint pos) void CPUInfoBox::contextMenuSlot(QPoint pos)
{ {
QMenu wMenu(this); //create context menu QMenu menu(this); //create context menu
QMenu wFollowMenu(tr("&Follow in Dump"), this); QMenu followMenu(tr("&Follow in Dump"), this);
setupFollowMenu(&wFollowMenu, curAddr); setupFollowMenu(&followMenu, mCurAddr);
wMenu.addMenu(&wFollowMenu); menu.addMenu(&followMenu);
QMenu wModifyValueMenu(tr("&Modify Value"), this); QMenu modifyValueMenu(tr("&Modify Value"), this);
setupModifyValueMenu(&wModifyValueMenu, curAddr); setupModifyValueMenu(&modifyValueMenu, mCurAddr);
if(!wModifyValueMenu.isEmpty()) if(!modifyValueMenu.isEmpty())
wMenu.addMenu(&wModifyValueMenu); menu.addMenu(&modifyValueMenu);
QMenu wWatchMenu(tr("&Watch"), this); QMenu watchMenu(tr("&Watch"), this);
setupWatchMenu(&wWatchMenu, curAddr); setupWatchMenu(&watchMenu, mCurAddr);
wMenu.addMenu(&wWatchMenu); menu.addMenu(&watchMenu);
if(!getInfoLine(2).isEmpty()) if(!getInfoLine(2).isEmpty())
wMenu.addAction(makeAction(DIcon("xrefs"), tr("&Show References"), SLOT(findXReferencesSlot()))); menu.addAction(makeAction(DIcon("xrefs"), tr("&Show References"), SLOT(findXReferencesSlot())));
QMenu wCopyMenu(tr("&Copy"), this); QMenu copyMenu(tr("&Copy"), this);
setupCopyMenu(&wCopyMenu); setupCopyMenu(&copyMenu);
if(DbgIsDebugging()) if(DbgIsDebugging())
{ {
wCopyMenu.addAction(mCopyAddressAction); copyMenu.addAction(mCopyAddressAction);
if(curRva != -1) if(mCurRva != -1)
wCopyMenu.addAction(mCopyRvaAction); copyMenu.addAction(mCopyRvaAction);
if(curOffset != -1) if(mCurOffset != -1)
wCopyMenu.addAction(mCopyOffsetAction); copyMenu.addAction(mCopyOffsetAction);
} }
if(wCopyMenu.actions().length()) if(copyMenu.actions().length())
{ {
wMenu.addSeparator(); menu.addSeparator();
wMenu.addMenu(&wCopyMenu); menu.addMenu(&copyMenu);
} }
wMenu.exec(mapToGlobal(pos)); //execute context menu menu.exec(mapToGlobal(pos)); //execute context menu
} }
void CPUInfoBox::copyAddress() void CPUInfoBox::copyAddress()
{ {
Bridge::CopyToClipboard(ToPtrString(curAddr)); Bridge::CopyToClipboard(ToPtrString(mCurAddr));
} }
void CPUInfoBox::copyRva() void CPUInfoBox::copyRva()
{ {
Bridge::CopyToClipboard(ToHexString(curRva)); Bridge::CopyToClipboard(ToHexString(mCurRva));
} }
void CPUInfoBox::copyOffset() void CPUInfoBox::copyOffset()
{ {
Bridge::CopyToClipboard(ToHexString(curOffset)); Bridge::CopyToClipboard(ToHexString(mCurOffset));
} }
void CPUInfoBox::doubleClickedSlot() void CPUInfoBox::doubleClickedSlot()
{ {
followInDump(curAddr); followInDump(mCurAddr);
} }
void CPUInfoBox::setupShortcuts() void CPUInfoBox::setupShortcuts()

View File

@ -1,30 +1,31 @@
#pragma once #pragma once
#include "StdTable.h" #include "StdTable.h"
#include "Architecture.h"
class WordEditDialog; class WordEditDialog;
class XrefBrowseDialog; class XrefBrowseDialog;
class QBeaEngine; class QZydis;
class CPUInfoBox : public StdTable class CPUInfoBox : public StdTable
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit CPUInfoBox(QWidget* parent = 0); CPUInfoBox(Architecture* architecture, QWidget* parent = nullptr);
~CPUInfoBox(); ~CPUInfoBox();
int getHeight(); int getHeight();
void addFollowMenuItem(QMenu* menu, QString name, duint value); void addFollowMenuItem(QMenu* menu, QString name, duint value);
void setupFollowMenu(QMenu* menu, duint wVA); void setupFollowMenu(QMenu* menu, duint va);
void addModifyValueMenuItem(QMenu* menu, QString name, duint value); void addModifyValueMenuItem(QMenu* menu, QString name, duint value);
void setupModifyValueMenu(QMenu* menu, duint wVA); void setupModifyValueMenu(QMenu* menu, duint va);
void addWatchMenuItem(QMenu* menu, QString name, duint value); void addWatchMenuItem(QMenu* menu, QString name, duint value);
void setupWatchMenu(QMenu* menu, duint wVA); void setupWatchMenu(QMenu* menu, duint va);
int followInDump(dsint wVA); int followInDump(duint va);
static QString formatSSEOperand(const QByteArray & data, unsigned char vectorType); static QString formatSSEOperand(const QByteArray & data, unsigned char vectorType);
public slots: public slots:
void disasmSelectionChanged(dsint parVA); void disasmSelectionChanged(duint parVA);
void dbgStateChanged(DBGSTATE state); void dbgStateChanged(DBGSTATE state);
void contextMenuSlot(QPoint pos); void contextMenuSlot(QPoint pos);
void followActionSlot(); void followActionSlot();
@ -37,16 +38,17 @@ public slots:
void addInfoLine(const QString & infoLine); void addInfoLine(const QString & infoLine);
private: private:
dsint curAddr; Architecture* mArchitecture = nullptr;
dsint curRva; duint mCurAddr = 0;
dsint curOffset; duint mCurRva = 0;
duint mCurOffset = 0;
void setInfoLine(int line, QString text); void setInfoLine(int line, QString text);
QString getInfoLine(int line); QString getInfoLine(int line);
void clear(); void clear();
void setupContextMenu(); void setupContextMenu();
void setupShortcuts(); void setupShortcuts();
XrefBrowseDialog* mXrefDlg = nullptr; XrefBrowseDialog* mXrefDlg = nullptr;
QBeaEngine* mDisasm; QZydis* mDisasm;
QAction* mCopyAddressAction; QAction* mCopyAddressAction;
QAction* mCopyRvaAction; QAction* mCopyRvaAction;

View File

@ -9,8 +9,9 @@
#include <QMessageBox> #include <QMessageBox>
#include <QTabBar> #include <QTabBar>
CPUMultiDump::CPUMultiDump(CPUDisassembly* disas, int nbCpuDumpTabs, QWidget* parent) CPUMultiDump::CPUMultiDump(CPUDisassembly* disassembly, int nbCpuDumpTabs, QWidget* parent)
: MHTabWidget(parent, true) : MHTabWidget(parent, true),
mMainDisassembly(disassembly)
{ {
setWindowTitle("CPUMultiDump"); setWindowTitle("CPUMultiDump");
mMaxCPUDumpTabs = nbCpuDumpTabs; mMaxCPUDumpTabs = nbCpuDumpTabs;
@ -22,7 +23,7 @@ CPUMultiDump::CPUMultiDump(CPUDisassembly* disas, int nbCpuDumpTabs, QWidget* pa
for(uint i = 0; i < mMaxCPUDumpTabs; i++) for(uint i = 0; i < mMaxCPUDumpTabs; i++)
{ {
CPUDump* cpuDump = new CPUDump(disas, this); CPUDump* cpuDump = new CPUDump(this, mMainDisassembly);
//cpuDump->loadColumnFromConfig(QString("CPUDump%1").arg(i + 1)); //TODO: needs a workaround because the columns change //cpuDump->loadColumnFromConfig(QString("CPUDump%1").arg(i + 1)); //TODO: needs a workaround because the columns change
connect(cpuDump, SIGNAL(displayReferencesWidget()), this, SLOT(displayReferencesWidgetSlot())); connect(cpuDump, SIGNAL(displayReferencesWidget()), this, SLOT(displayReferencesWidgetSlot()));
connect(cpuDump, SIGNAL(showDisassemblyTab(duint, duint, duint)), this, SLOT(showDisassemblyTabSlot(duint, duint, duint))); connect(cpuDump, SIGNAL(showDisassemblyTab(duint, duint, duint)), this, SLOT(showDisassemblyTabSlot(duint, duint, duint)));
@ -50,7 +51,7 @@ CPUMultiDump::CPUMultiDump(CPUDisassembly* disas, int nbCpuDumpTabs, QWidget* pa
connect(this, SIGNAL(currentChanged(int)), this, SLOT(updateCurrentTabSlot(int))); connect(this, SIGNAL(currentChanged(int)), this, SLOT(updateCurrentTabSlot(int)));
connect(tabBar(), SIGNAL(OnDoubleClickTabIndex(int)), this, SLOT(openChangeTabTitleDialogSlot(int))); connect(tabBar(), SIGNAL(OnDoubleClickTabIndex(int)), this, SLOT(openChangeTabTitleDialogSlot(int)));
connect(Bridge::getBridge(), SIGNAL(dumpAt(dsint)), this, SLOT(printDumpAtSlot(dsint))); connect(Bridge::getBridge(), SIGNAL(dumpAt(duint)), this, SLOT(printDumpAtSlot(duint)));
connect(Bridge::getBridge(), SIGNAL(dumpAtN(duint, int)), this, SLOT(printDumpAtNSlot(duint, int))); connect(Bridge::getBridge(), SIGNAL(dumpAtN(duint, int)), this, SLOT(printDumpAtNSlot(duint, int)));
connect(Bridge::getBridge(), SIGNAL(selectionDumpGet(SELECTIONDATA*)), this, SLOT(selectionGetSlot(SELECTIONDATA*))); connect(Bridge::getBridge(), SIGNAL(selectionDumpGet(SELECTIONDATA*)), this, SLOT(selectionGetSlot(SELECTIONDATA*)));
connect(Bridge::getBridge(), SIGNAL(selectionDumpSet(const SELECTIONDATA*)), this, SLOT(selectionSetSlot(const SELECTIONDATA*))); connect(Bridge::getBridge(), SIGNAL(selectionDumpSet(const SELECTIONDATA*)), this, SLOT(selectionSetSlot(const SELECTIONDATA*)));
@ -61,6 +62,11 @@ CPUMultiDump::CPUMultiDump(CPUDisassembly* disas, int nbCpuDumpTabs, QWidget* pa
connect(mCurrentCPUDump, SIGNAL(selectionUpdated()), mCurrentCPUDump, SLOT(selectionUpdatedSlot())); connect(mCurrentCPUDump, SIGNAL(selectionUpdated()), mCurrentCPUDump, SLOT(selectionUpdatedSlot()));
} }
Architecture* CPUMultiDump::getArchitecture() const
{
return mMainDisassembly->getArchitecture();
}
CPUDump* CPUMultiDump::getCurrentCPUDump() CPUDump* CPUMultiDump::getCurrentCPUDump()
{ {
return mCurrentCPUDump; return mCurrentCPUDump;
@ -152,7 +158,7 @@ void CPUMultiDump::updateCurrentTabSlot(int tabIndex)
mCurrentCPUDump = t; mCurrentCPUDump = t;
} }
void CPUMultiDump::printDumpAtSlot(dsint parVa) void CPUMultiDump::printDumpAtSlot(duint va)
{ {
if(mInitAllDumpTabs) if(mInitAllDumpTabs)
{ {
@ -165,8 +171,8 @@ void CPUMultiDump::printDumpAtSlot(dsint parVa)
if(cpuDump) if(cpuDump)
{ {
cpuDump->mHistory.historyClear(); cpuDump->mHistory.historyClear();
cpuDump->mHistory.addVaToHistory(parVa); cpuDump->mHistory.addVaToHistory(va);
cpuDump->printDumpAt(parVa); cpuDump->printDumpAt(va);
} }
} }
@ -175,12 +181,12 @@ void CPUMultiDump::printDumpAtSlot(dsint parVa)
else else
{ {
SwitchToDumpWindow(); SwitchToDumpWindow();
mCurrentCPUDump->printDumpAt(parVa); mCurrentCPUDump->printDumpAt(va);
mCurrentCPUDump->mHistory.addVaToHistory(parVa); mCurrentCPUDump->mHistory.addVaToHistory(va);
} }
} }
void CPUMultiDump::printDumpAtNSlot(duint parVa, int index) void CPUMultiDump::printDumpAtNSlot(duint va, int index)
{ {
int tabindex = GetDumpWindowIndex(index); int tabindex = GetDumpWindowIndex(index);
if(tabindex == 2147483647) if(tabindex == 2147483647)
@ -189,8 +195,8 @@ void CPUMultiDump::printDumpAtNSlot(duint parVa, int index)
if(!current) if(!current)
return; return;
setCurrentIndex(tabindex); setCurrentIndex(tabindex);
current->printDumpAt(parVa); current->printDumpAt(va);
current->mHistory.addVaToHistory(parVa); current->mHistory.addVaToHistory(va);
} }
void CPUMultiDump::selectionGetSlot(SELECTIONDATA* selectionData) void CPUMultiDump::selectionGetSlot(SELECTIONDATA* selectionData)
@ -238,23 +244,23 @@ void CPUMultiDump::focusCurrentDumpSlot()
void CPUMultiDump::showDisassemblyTabSlot(duint selectionStart, duint selectionEnd, duint firstAddress) void CPUMultiDump::showDisassemblyTabSlot(duint selectionStart, duint selectionEnd, duint firstAddress)
{ {
Q_UNUSED(firstAddress); // TODO: implement setTableOffset(firstAddress) Q_UNUSED(firstAddress); // TODO: implement setTableOffset(firstAddress)
if(!mDisassembly) if(!mExtraDisassembly)
{ {
mDisassembly = new CPUDisassembly(this, false); mExtraDisassembly = new CPUDisassembly(mMainDisassembly->getArchitecture(), false, this);
this->addTabEx(mDisassembly, DIcon(ArchValue("processor32", "processor64")), tr("Disassembly"), "DumpDisassembly"); this->addTabEx(mExtraDisassembly, DIcon(ArchValue("processor32", "processor64")), tr("Disassembly"), "DumpDisassembly");
} }
// Set CIP // Set CIP
auto clearHistory = mDisassembly->getBase() == 0; auto clearHistory = mExtraDisassembly->getBase() == 0;
mDisassembly->disassembleAtSlot(selectionStart, Bridge::getBridge()->mLastCip); mExtraDisassembly->disassembleAtSlot(selectionStart, Bridge::getBridge()->mLastCip);
if(clearHistory) if(clearHistory)
mDisassembly->historyClear(); mExtraDisassembly->historyClear();
// Make the address visisble in memory // Make the address visisble in memory
mDisassembly->disassembleAt(selectionStart, true, -1); mExtraDisassembly->disassembleAt(selectionStart, true, -1);
// Set selection to match the dump // Set selection to match the dump
mDisassembly->setSingleSelection(selectionStart - mDisassembly->getBase()); mExtraDisassembly->setSingleSelection(selectionStart - mExtraDisassembly->getBase());
mDisassembly->expandSelectionUpTo(selectionEnd - mDisassembly->getBase()); mExtraDisassembly->expandSelectionUpTo(selectionEnd - mExtraDisassembly->getBase());
// Show the tab // Show the tab
setCurrentWidget(mDisassembly); setCurrentWidget(mExtraDisassembly);
} }
void CPUMultiDump::getDumpAttention() void CPUMultiDump::getDumpAttention()

View File

@ -14,11 +14,12 @@ class CPUMultiDump : public MHTabWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit CPUMultiDump(CPUDisassembly* disas, int nbCpuDumpTabs = 1, QWidget* parent = 0); explicit CPUMultiDump(CPUDisassembly* disassembly, int nbCpuDumpTabs = 1, QWidget* parent = nullptr);
Architecture* getArchitecture() const;
CPUDump* getCurrentCPUDump(); CPUDump* getCurrentCPUDump();
void getTabNames(QList<QString> & names); void getTabNames(QList<QString> & names);
int getMaxCPUTabs(); int getMaxCPUTabs();
QMenu* mDumpPluginMenu; QMenu* mDumpPluginMenu; // TODO: no
void saveWindowSettings(); void saveWindowSettings();
void loadWindowSettings(); void loadWindowSettings();
@ -27,8 +28,8 @@ signals:
public slots: public slots:
void updateCurrentTabSlot(int tabIndex); void updateCurrentTabSlot(int tabIndex);
void printDumpAtSlot(dsint parVa); void printDumpAtSlot(duint va);
void printDumpAtNSlot(duint parVa, int index); void printDumpAtNSlot(duint va, int index);
void selectionGetSlot(SELECTIONDATA* selectionData); void selectionGetSlot(SELECTIONDATA* selectionData);
void selectionSetSlot(const SELECTIONDATA* selectionData); void selectionSetSlot(const SELECTIONDATA* selectionData);
void dbgStateChangedSlot(DBGSTATE dbgState); void dbgStateChangedSlot(DBGSTATE dbgState);
@ -46,7 +47,8 @@ private:
WatchView* mWatch; WatchView* mWatch;
LocalVarsView* mLocalVars; LocalVarsView* mLocalVars;
StructWidget* mStructWidget; StructWidget* mStructWidget;
CPUDisassembly* mDisassembly = nullptr; CPUDisassembly* mMainDisassembly = nullptr;
CPUDisassembly* mExtraDisassembly = nullptr;
int GetDumpWindowIndex(int dump); int GetDumpWindowIndex(int dump);
int GetWatchWindowIndex(); int GetWatchWindowIndex();

View File

@ -37,7 +37,7 @@ CPURegistersView::CPURegistersView(CPUWidget* parent) : RegistersView(parent), m
connect(Bridge::getBridge(), SIGNAL(updateRegisters()), this, SLOT(updateRegistersSlot())); connect(Bridge::getBridge(), SIGNAL(updateRegisters()), this, SLOT(updateRegistersSlot()));
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(displayCustomContextMenuSlot(QPoint))); connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(displayCustomContextMenuSlot(QPoint)));
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(debugStateChangedSlot(DBGSTATE))); connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(debugStateChangedSlot(DBGSTATE)));
connect(parent->getDisasmWidget(), SIGNAL(selectionChanged(dsint)), this, SLOT(disasmSelectionChangedSlot(dsint))); connect(parent->getDisasmWidget(), SIGNAL(selectionChanged(duint)), this, SLOT(disasmSelectionChangedSlot(duint)));
// context menu actions // context menu actions
connect(wCM_Incrementx87Stack, SIGNAL(triggered()), this, SLOT(onIncrementx87StackAction())); connect(wCM_Incrementx87Stack, SIGNAL(triggered()), this, SLOT(onIncrementx87StackAction()));
connect(wCM_Decrementx87Stack, SIGNAL(triggered()), this, SLOT(onDecrementx87StackAction())); connect(wCM_Decrementx87Stack, SIGNAL(triggered()), this, SLOT(onDecrementx87StackAction()));
@ -252,17 +252,17 @@ void CPURegistersView::displayEditDialog()
updateRegistersSlot(); updateRegistersSlot();
} }
else if(mFPUYMM.contains(mSelected)) else if(mFPUYMM.contains(mSelected))
editSIMDRegister(this, 256, tr("Edit YMM register"), registerValue(&wRegDumpStruct, mSelected), mSelected); editSIMDRegister(this, 256, tr("Edit YMM register"), registerValue(&mRegDumpStruct, mSelected), mSelected);
else if(mFPUXMM.contains(mSelected)) else if(mFPUXMM.contains(mSelected))
editSIMDRegister(this, 128, tr("Edit XMM register"), registerValue(&wRegDumpStruct, mSelected), mSelected); editSIMDRegister(this, 128, tr("Edit XMM register"), registerValue(&mRegDumpStruct, mSelected), mSelected);
else if(mFPUMMX.contains(mSelected)) else if(mFPUMMX.contains(mSelected))
editSIMDRegister(this, 64, tr("Edit MMX register"), registerValue(&wRegDumpStruct, mSelected), mSelected); editSIMDRegister(this, 64, tr("Edit MMX register"), registerValue(&mRegDumpStruct, mSelected), mSelected);
else else
{ {
bool errorinput = false; bool errorinput = false;
LineEditDialog mLineEdit(this); LineEditDialog mLineEdit(this);
mLineEdit.setText(GetRegStringValueFromValue(mSelected, registerValue(&wRegDumpStruct, mSelected))); mLineEdit.setText(GetRegStringValueFromValue(mSelected, registerValue(&mRegDumpStruct, mSelected)));
mLineEdit.setWindowTitle(tr("Edit FPU register")); mLineEdit.setWindowTitle(tr("Edit FPU register"));
mLineEdit.setWindowIcon(DIcon("log")); mLineEdit.setWindowIcon(DIcon("log"));
mLineEdit.setCursorPosition(0); mLineEdit.setCursorPosition(0);
@ -357,7 +357,7 @@ void CPURegistersView::displayEditDialog()
{ {
bool errorinput = false; bool errorinput = false;
LineEditDialog mLineEdit(this); LineEditDialog mLineEdit(this);
LASTERROR* error = (LASTERROR*)registerValue(&wRegDumpStruct, LastError); LASTERROR* error = (LASTERROR*)registerValue(&mRegDumpStruct, LastError);
mLineEdit.setText(QString::number(error->code, 16)); mLineEdit.setText(QString::number(error->code, 16));
mLineEdit.setWindowTitle(tr("Set Last Error")); mLineEdit.setWindowTitle(tr("Set Last Error"));
mLineEdit.setCursorPosition(0); mLineEdit.setCursorPosition(0);
@ -378,7 +378,7 @@ void CPURegistersView::displayEditDialog()
{ {
bool statusinput = false; bool statusinput = false;
LineEditDialog mLineEdit(this); LineEditDialog mLineEdit(this);
LASTSTATUS* status = (LASTSTATUS*)registerValue(&wRegDumpStruct, LastStatus); LASTSTATUS* status = (LASTSTATUS*)registerValue(&mRegDumpStruct, LastStatus);
mLineEdit.setText(QString::number(status->code, 16)); mLineEdit.setText(QString::number(status->code, 16));
mLineEdit.setWindowTitle(tr("Set Last Status")); mLineEdit.setWindowTitle(tr("Set Last Status"));
mLineEdit.setCursorPosition(0); mLineEdit.setCursorPosition(0);
@ -397,10 +397,10 @@ void CPURegistersView::displayEditDialog()
} }
else else
{ {
WordEditDialog wEditDial(this); WordEditDialog editDialog(this);
wEditDial.setup(tr("Edit"), (* ((duint*) registerValue(&wRegDumpStruct, mSelected))), sizeof(dsint)); editDialog.setup(tr("Edit"), (* ((duint*) registerValue(&mRegDumpStruct, mSelected))), sizeof(dsint));
if(wEditDial.exec() == QDialog::Accepted) //OK button clicked if(editDialog.exec() == QDialog::Accepted) //OK button clicked
setRegister(mSelected, wEditDial.getVal()); setRegister(mSelected, editDialog.getVal());
} }
} }
@ -423,13 +423,13 @@ void CPURegistersView::CreateDumpNMenu(QMenu* dumpMenu)
void CPURegistersView::onIncrementx87StackAction() void CPURegistersView::onIncrementx87StackAction()
{ {
if(mFPUx87_80BITSDISPLAY.contains(mSelected)) if(mFPUx87_80BITSDISPLAY.contains(mSelected))
setRegister(x87SW_TOP, ((* ((duint*) registerValue(&wRegDumpStruct, x87SW_TOP))) + 1) % 8); setRegister(x87SW_TOP, ((* ((duint*) registerValue(&mRegDumpStruct, x87SW_TOP))) + 1) % 8);
} }
void CPURegistersView::onDecrementx87StackAction() void CPURegistersView::onDecrementx87StackAction()
{ {
if(mFPUx87_80BITSDISPLAY.contains(mSelected)) if(mFPUx87_80BITSDISPLAY.contains(mSelected))
setRegister(x87SW_TOP, ((* ((duint*) registerValue(&wRegDumpStruct, x87SW_TOP))) - 1) % 8); setRegister(x87SW_TOP, ((* ((duint*) registerValue(&mRegDumpStruct, x87SW_TOP))) - 1) % 8);
} }
void CPURegistersView::onModifyAction() void CPURegistersView::onModifyAction()
@ -442,7 +442,7 @@ void CPURegistersView::onIncrementAction()
{ {
if(mINCREMENTDECREMET.contains(mSelected)) if(mINCREMENTDECREMET.contains(mSelected))
{ {
duint value = *((duint*) registerValue(&wRegDumpStruct, mSelected)); duint value = *((duint*) registerValue(&mRegDumpStruct, mSelected));
setRegister(mSelected, value + 1); setRegister(mSelected, value + 1);
} }
} }
@ -451,7 +451,7 @@ void CPURegistersView::onDecrementAction()
{ {
if(mINCREMENTDECREMET.contains(mSelected)) if(mINCREMENTDECREMET.contains(mSelected))
{ {
duint value = *((duint*) registerValue(&wRegDumpStruct, mSelected)); duint value = *((duint*) registerValue(&mRegDumpStruct, mSelected));
setRegister(mSelected, value - 1); setRegister(mSelected, value - 1);
} }
} }
@ -466,7 +466,7 @@ void CPURegistersView::onToggleValueAction()
{ {
if(mBOOLDISPLAY.contains(mSelected)) if(mBOOLDISPLAY.contains(mSelected))
{ {
int value = (int)(* (bool*) registerValue(&wRegDumpStruct, mSelected)); int value = (int)(* (bool*) registerValue(&mRegDumpStruct, mSelected));
setRegister(mSelected, value ^ 1); setRegister(mSelected, value ^ 1);
} }
} }
@ -476,9 +476,9 @@ void CPURegistersView::onUndoAction()
if(mUNDODISPLAY.contains(mSelected)) if(mUNDODISPLAY.contains(mSelected))
{ {
if(mFPUMMX.contains(mSelected) || mFPUXMM.contains(mSelected) || mFPUYMM.contains(mSelected) || mFPUx87_80BITSDISPLAY.contains(mSelected)) if(mFPUMMX.contains(mSelected) || mFPUXMM.contains(mSelected) || mFPUYMM.contains(mSelected) || mFPUx87_80BITSDISPLAY.contains(mSelected))
setRegister(mSelected, (duint)registerValue(&wCipRegDumpStruct, mSelected)); setRegister(mSelected, (duint)registerValue(&mCipRegDumpStruct, mSelected));
else else
setRegister(mSelected, *(duint*)registerValue(&wCipRegDumpStruct, mSelected)); setRegister(mSelected, *(duint*)registerValue(&mCipRegDumpStruct, mSelected));
} }
} }
@ -507,8 +507,8 @@ void CPURegistersView::onFollowInDisassembly()
{ {
if(mCANSTOREADDRESS.contains(mSelected)) if(mCANSTOREADDRESS.contains(mSelected))
{ {
QString addr = QString("%1").arg((* ((duint*) registerValue(&wRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); QString addr = QString("%1").arg((* ((duint*) registerValue(&mRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper();
if(DbgMemIsValidReadPtr((* ((duint*) registerValue(&wRegDumpStruct, mSelected))))) if(DbgMemIsValidReadPtr((* ((duint*) registerValue(&mRegDumpStruct, mSelected)))))
DbgCmdExec(QString().sprintf("disasm \"%s\"", addr.toUtf8().constData())); DbgCmdExec(QString().sprintf("disasm \"%s\"", addr.toUtf8().constData()));
} }
} }
@ -517,8 +517,8 @@ void CPURegistersView::onFollowInDump()
{ {
if(mCANSTOREADDRESS.contains(mSelected)) if(mCANSTOREADDRESS.contains(mSelected))
{ {
QString addr = QString("%1").arg((* ((duint*) registerValue(&wRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); QString addr = QString("%1").arg((* ((duint*) registerValue(&mRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper();
if(DbgMemIsValidReadPtr((* ((duint*) registerValue(&wRegDumpStruct, mSelected))))) if(DbgMemIsValidReadPtr((* ((duint*) registerValue(&mRegDumpStruct, mSelected)))))
DbgCmdExec(QString().sprintf("dump \"%s\"", addr.toUtf8().constData())); DbgCmdExec(QString().sprintf("dump \"%s\"", addr.toUtf8().constData()));
} }
} }
@ -527,8 +527,8 @@ void CPURegistersView::onFollowInDumpN()
{ {
if(mCANSTOREADDRESS.contains(mSelected)) if(mCANSTOREADDRESS.contains(mSelected))
{ {
QString addr = QString("%1").arg((* ((duint*) registerValue(&wRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); QString addr = QString("%1").arg((* ((duint*) registerValue(&mRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper();
if(DbgMemIsValidReadPtr((* ((duint*) registerValue(&wRegDumpStruct, mSelected))))) if(DbgMemIsValidReadPtr((* ((duint*) registerValue(&mRegDumpStruct, mSelected)))))
{ {
QAction* action = qobject_cast<QAction*>(sender()); QAction* action = qobject_cast<QAction*>(sender());
int numDump = action->data().toInt(); int numDump = action->data().toInt();
@ -541,8 +541,8 @@ void CPURegistersView::onFollowInStack()
{ {
if(mCANSTOREADDRESS.contains(mSelected)) if(mCANSTOREADDRESS.contains(mSelected))
{ {
QString addr = QString("%1").arg((* ((duint*) registerValue(&wRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); QString addr = QString("%1").arg((* ((duint*) registerValue(&mRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper();
if(DbgMemIsValidReadPtr((* ((duint*) registerValue(&wRegDumpStruct, mSelected))))) if(DbgMemIsValidReadPtr((* ((duint*) registerValue(&mRegDumpStruct, mSelected)))))
DbgCmdExec(QString().sprintf("sdump \"%s\"", addr.toUtf8().constData())); DbgCmdExec(QString().sprintf("sdump \"%s\"", addr.toUtf8().constData()));
} }
} }
@ -551,8 +551,8 @@ void CPURegistersView::onFollowInMemoryMap()
{ {
if(mCANSTOREADDRESS.contains(mSelected)) if(mCANSTOREADDRESS.contains(mSelected))
{ {
QString addr = QString("%1").arg((* ((duint*) registerValue(&wRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); QString addr = QString("%1").arg((* ((duint*) registerValue(&mRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper();
if(DbgMemIsValidReadPtr((* ((duint*) registerValue(&wRegDumpStruct, mSelected))))) if(DbgMemIsValidReadPtr((* ((duint*) registerValue(&mRegDumpStruct, mSelected)))))
DbgCmdExec(QString().sprintf("memmapdump \"%s\"", addr.toUtf8().constData())); DbgCmdExec(QString().sprintf("memmapdump \"%s\"", addr.toUtf8().constData()));
} }
} }
@ -561,7 +561,7 @@ void CPURegistersView::onRemoveHardware()
{ {
if(mSelected == DR0 || mSelected == DR1 || mSelected == DR2 || mSelected == DR3) if(mSelected == DR0 || mSelected == DR1 || mSelected == DR2 || mSelected == DR3)
{ {
QString addr = QString("%1").arg((* ((duint*) registerValue(&wRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); QString addr = QString("%1").arg((* ((duint*) registerValue(&mRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper();
DbgCmdExec(QString().sprintf("bphc \"%s\"", addr.toUtf8().constData())); DbgCmdExec(QString().sprintf("bphc \"%s\"", addr.toUtf8().constData()));
} }
} }
@ -570,7 +570,7 @@ void CPURegistersView::displayCustomContextMenuSlot(QPoint pos)
{ {
if(!isActive) if(!isActive)
return; return;
QMenu wMenu(this); QMenu menu(this);
QMenu* followInDumpNMenu = nullptr; QMenu* followInDumpNMenu = nullptr;
setupSIMDModeMenu(); setupSIMDModeMenu();
@ -578,111 +578,111 @@ void CPURegistersView::displayCustomContextMenuSlot(QPoint pos)
{ {
if(mMODIFYDISPLAY.contains(mSelected)) if(mMODIFYDISPLAY.contains(mSelected))
{ {
wMenu.addAction(wCM_Modify); menu.addAction(wCM_Modify);
} }
if(mINCREMENTDECREMET.contains(mSelected)) if(mINCREMENTDECREMET.contains(mSelected))
{ {
wMenu.addAction(wCM_Increment); menu.addAction(wCM_Increment);
wMenu.addAction(wCM_Decrement); menu.addAction(wCM_Decrement);
wMenu.addAction(wCM_Zero); menu.addAction(wCM_Zero);
} }
if(mCANSTOREADDRESS.contains(mSelected)) if(mCANSTOREADDRESS.contains(mSelected))
{ {
duint addr = (* ((duint*) registerValue(&wRegDumpStruct, mSelected))); duint addr = (* ((duint*) registerValue(&mRegDumpStruct, mSelected)));
if(DbgMemIsValidReadPtr(addr)) if(DbgMemIsValidReadPtr(addr))
{ {
wMenu.addAction(wCM_FollowInDump); menu.addAction(wCM_FollowInDump);
followInDumpNMenu = new QMenu(tr("Follow in &Dump"), &wMenu); followInDumpNMenu = new QMenu(tr("Follow in &Dump"), &menu);
CreateDumpNMenu(followInDumpNMenu); CreateDumpNMenu(followInDumpNMenu);
wMenu.addMenu(followInDumpNMenu); menu.addMenu(followInDumpNMenu);
wMenu.addAction(wCM_FollowInDisassembly); menu.addAction(wCM_FollowInDisassembly);
wMenu.addAction(wCM_FollowInMemoryMap); menu.addAction(wCM_FollowInMemoryMap);
duint size = 0; duint size = 0;
duint base = DbgMemFindBaseAddr(DbgValFromString("csp"), &size); duint base = DbgMemFindBaseAddr(DbgValFromString("csp"), &size);
if(addr >= base && addr < base + size) if(addr >= base && addr < base + size)
wMenu.addAction(wCM_FollowInStack); menu.addAction(wCM_FollowInStack);
} }
} }
if(mSelected == DR0 || mSelected == DR1 || mSelected == DR2 || mSelected == DR3) if(mSelected == DR0 || mSelected == DR1 || mSelected == DR2 || mSelected == DR3)
{ {
if(* ((duint*) registerValue(&wRegDumpStruct, mSelected)) != 0) if(* ((duint*) registerValue(&mRegDumpStruct, mSelected)) != 0)
wMenu.addAction(wCM_RemoveHardware); menu.addAction(wCM_RemoveHardware);
} }
wMenu.addAction(wCM_CopyToClipboard); menu.addAction(wCM_CopyToClipboard);
if(mFPUx87_80BITSDISPLAY.contains(mSelected)) if(mFPUx87_80BITSDISPLAY.contains(mSelected))
{ {
wMenu.addAction(wCM_CopyFloatingPointValueToClipboard); menu.addAction(wCM_CopyFloatingPointValueToClipboard);
} }
if(mLABELDISPLAY.contains(mSelected)) if(mLABELDISPLAY.contains(mSelected))
{ {
QString symbol = getRegisterLabel(mSelected); QString symbol = getRegisterLabel(mSelected);
if(symbol != "") if(symbol != "")
wMenu.addAction(wCM_CopySymbolToClipboard); menu.addAction(wCM_CopySymbolToClipboard);
} }
wMenu.addAction(wCM_CopyAll); menu.addAction(wCM_CopyAll);
if((mGPR.contains(mSelected) && mSelected != REGISTER_NAME::EFLAGS) || mSEGMENTREGISTER.contains(mSelected) || mFPUMMX.contains(mSelected) || mFPUXMM.contains(mSelected) || mFPUYMM.contains(mSelected)) if((mGPR.contains(mSelected) && mSelected != REGISTER_NAME::EFLAGS) || mSEGMENTREGISTER.contains(mSelected) || mFPUMMX.contains(mSelected) || mFPUXMM.contains(mSelected) || mFPUYMM.contains(mSelected))
{ {
wMenu.addAction(wCM_Highlight); menu.addAction(wCM_Highlight);
} }
if(mUNDODISPLAY.contains(mSelected) && CompareRegisters(mSelected, &wRegDumpStruct, &wCipRegDumpStruct) != 0) if(mUNDODISPLAY.contains(mSelected) && CompareRegisters(mSelected, &mRegDumpStruct, &mCipRegDumpStruct) != 0)
{ {
wMenu.addAction(wCM_Undo); menu.addAction(wCM_Undo);
wCM_CopyPrevious->setData(GetRegStringValueFromValue(mSelected, registerValue(&wCipRegDumpStruct, mSelected))); wCM_CopyPrevious->setData(GetRegStringValueFromValue(mSelected, registerValue(&mCipRegDumpStruct, mSelected)));
wCM_CopyPrevious->setText(tr("Copy old value: %1").arg(wCM_CopyPrevious->data().toString())); wCM_CopyPrevious->setText(tr("Copy old value: %1").arg(wCM_CopyPrevious->data().toString()));
wMenu.addAction(wCM_CopyPrevious); menu.addAction(wCM_CopyPrevious);
} }
if(mBOOLDISPLAY.contains(mSelected)) if(mBOOLDISPLAY.contains(mSelected))
{ {
wMenu.addAction(wCM_ToggleValue); menu.addAction(wCM_ToggleValue);
} }
if(mFPUx87_80BITSDISPLAY.contains(mSelected)) if(mFPUx87_80BITSDISPLAY.contains(mSelected))
{ {
wMenu.addAction(wCM_Incrementx87Stack); menu.addAction(wCM_Incrementx87Stack);
wMenu.addAction(wCM_Decrementx87Stack); menu.addAction(wCM_Decrementx87Stack);
} }
if(mFPUMMX.contains(mSelected) || mFPUXMM.contains(mSelected) || mFPUYMM.contains(mSelected)) if(mFPUMMX.contains(mSelected) || mFPUXMM.contains(mSelected) || mFPUYMM.contains(mSelected))
{ {
wMenu.addMenu(mSwitchSIMDDispMode); menu.addMenu(mSwitchSIMDDispMode);
} }
if(mFPUMMX.contains(mSelected) || mFPUx87_80BITSDISPLAY.contains(mSelected)) if(mFPUMMX.contains(mSelected) || mFPUx87_80BITSDISPLAY.contains(mSelected))
{ {
if(mFpuMode != 0) if(mFpuMode != 0)
wMenu.addAction(mDisplaySTX); menu.addAction(mDisplaySTX);
if(mFpuMode != 1) if(mFpuMode != 1)
wMenu.addAction(mDisplayx87rX); menu.addAction(mDisplayx87rX);
if(mFpuMode != 2) if(mFpuMode != 2)
wMenu.addAction(mDisplayMMX); menu.addAction(mDisplayMMX);
} }
wMenu.exec(this->mapToGlobal(pos)); menu.exec(this->mapToGlobal(pos));
} }
else else
{ {
wMenu.addSeparator(); menu.addSeparator();
wMenu.addAction(wCM_ChangeFPUView); menu.addAction(wCM_ChangeFPUView);
wMenu.addAction(wCM_CopyAll); menu.addAction(wCM_CopyAll);
wMenu.addMenu(mSwitchSIMDDispMode); menu.addMenu(mSwitchSIMDDispMode);
if(mFpuMode != 0) if(mFpuMode != 0)
wMenu.addAction(mDisplaySTX); menu.addAction(mDisplaySTX);
if(mFpuMode != 1) if(mFpuMode != 1)
wMenu.addAction(mDisplayx87rX); menu.addAction(mDisplayx87rX);
if(mFpuMode != 2) if(mFpuMode != 2)
wMenu.addAction(mDisplayMMX); menu.addAction(mDisplayMMX);
wMenu.addSeparator(); menu.addSeparator();
QAction* wHwbpCsp = wMenu.addAction(DIcon("breakpoint"), tr("Set Hardware Breakpoint on %1").arg(ArchValue("ESP", "RSP"))); QAction* hwbpCsp = menu.addAction(DIcon("breakpoint"), tr("Set Hardware Breakpoint on %1").arg(ArchValue("ESP", "RSP")));
QAction* wAction = wMenu.exec(this->mapToGlobal(pos)); QAction* action = menu.exec(this->mapToGlobal(pos));
if(wAction == wHwbpCsp) if(action == hwbpCsp)
DbgCmdExec("bphws csp,rw"); DbgCmdExec("bphws csp,rw");
} }
} }
@ -693,31 +693,31 @@ void CPURegistersView::setRegister(REGISTER_NAME reg, duint value)
if(mRegisterMapping.contains(reg)) if(mRegisterMapping.contains(reg))
{ {
// map x87st0 to x87r0 // map x87st0 to x87r0
QString wRegName; QString regName;
if(reg >= x87st0 && reg <= x87st7) if(reg >= x87st0 && reg <= x87st7)
wRegName = QString().sprintf("st%d", reg - x87st0); regName = QString().sprintf("st%d", reg - x87st0);
else else
// map "cax" to "eax" or "rax" // map "cax" to "eax" or "rax"
wRegName = mRegisterMapping.constFind(reg).value(); regName = mRegisterMapping.constFind(reg).value();
// flags need to '_' infront // flags need to '_' infront
if(mFlags.contains(reg)) if(mFlags.contains(reg))
wRegName = "_" + wRegName; regName = "_" + regName;
// we change the value (so highlight it) // we change the value (so highlight it)
mRegisterUpdates.insert(reg); mRegisterUpdates.insert(reg);
// tell everything the compiler // tell everything the compiler
if(mFPU.contains(reg)) if(mFPU.contains(reg))
wRegName = "_" + wRegName; regName = "_" + regName;
DbgValToString(wRegName.toUtf8().constData(), value); DbgValToString(regName.toUtf8().constData(), value);
// force repaint // force repaint
emit refresh(); emit refresh();
} }
} }
void CPURegistersView::disasmSelectionChangedSlot(dsint va) void CPURegistersView::disasmSelectionChangedSlot(duint va)
{ {
mHighlightRegs = mParent->getDisasmWidget()->DisassembleAt(va - mParent->getDisasmWidget()->getBase()).regsReferenced; mHighlightRegs = mParent->getDisasmWidget()->DisassembleAt(va - mParent->getDisasmWidget()->getBase()).regsReferenced;
emit refresh(); emit refresh();

View File

@ -6,7 +6,7 @@ class CPURegistersView : public RegistersView
{ {
Q_OBJECT Q_OBJECT
public: public:
CPURegistersView(CPUWidget* parent = 0); CPURegistersView(CPUWidget* parent = nullptr);
public slots: public slots:
void setRegister(REGISTER_NAME reg, duint value); void setRegister(REGISTER_NAME reg, duint value);
@ -36,7 +36,7 @@ protected slots:
void onRemoveHardware(); void onRemoveHardware();
void onHighlightSlot(); void onHighlightSlot();
void ModifyFields(const QString & title, STRING_VALUE_TABLE_t* table, SIZE_T size); void ModifyFields(const QString & title, STRING_VALUE_TABLE_t* table, SIZE_T size);
void disasmSelectionChangedSlot(dsint va); void disasmSelectionChangedSlot(duint va);
private: private:
void CreateDumpNMenu(QMenu* dumpMenu); void CreateDumpNMenu(QMenu* dumpMenu);

View File

@ -5,24 +5,17 @@
#include "CachedFontMetrics.h" #include "CachedFontMetrics.h"
#include <QToolTip> #include <QToolTip>
CPUSideBar::CPUSideBar(CPUDisassembly* Ptr, QWidget* parent) : QAbstractScrollArea(parent) CPUSideBar::CPUSideBar(CPUDisassembly* disassembly, QWidget* parent)
: QAbstractScrollArea(parent)
{ {
setWindowTitle("SideBar"); setWindowTitle("SideBar");
topVA = -1;
selectedVA = -1;
viewableRows = 0;
mFontMetrics = nullptr;
mDisas = Ptr; mDisassembly = disassembly;
mInstrBuffer = mDisassembly->instructionsBuffer();
mInstrBuffer = mDisas->instructionsBuffer();
memset(&regDump, 0, sizeof(REGDUMP));
updateSlots(); updateSlots();
this->setMouseTracking(true); setMouseTracking(true);
} }
CPUSideBar::~CPUSideBar() CPUSideBar::~CPUSideBar()
@ -73,21 +66,21 @@ void CPUSideBar::updateColors()
void CPUSideBar::updateFonts() void CPUSideBar::updateFonts()
{ {
mDefaultFont = mDisas->font(); mDefaultFont = mDisassembly->font();
this->setFont(mDefaultFont); setFont(mDefaultFont);
delete mFontMetrics; delete mFontMetrics;
mFontMetrics = new CachedFontMetrics(this, mDefaultFont); mFontMetrics = new CachedFontMetrics(this, mDefaultFont);
fontWidth = mFontMetrics->width(' '); mFontWidth = mFontMetrics->width(' ');
fontHeight = mFontMetrics->height(); mFontHeight = mFontMetrics->height();
mBulletYOffset = 2; mBulletYOffset = 2;
mBulletRadius = fontHeight - 2 * mBulletYOffset; mBulletRadius = mFontHeight - 2 * mBulletYOffset;
} }
QSize CPUSideBar::sizeHint() const QSize CPUSideBar::sizeHint() const
{ {
return QSize(40, this->viewport()->height()); return QSize(40, viewport()->height());
} }
void CPUSideBar::debugStateChangedSlot(DBGSTATE state) void CPUSideBar::debugStateChangedSlot(DBGSTATE state)
@ -100,27 +93,27 @@ void CPUSideBar::debugStateChangedSlot(DBGSTATE state)
void CPUSideBar::reload() void CPUSideBar::reload()
{ {
fontHeight = mDisas->getRowHeight(); mFontHeight = mDisassembly->getRowHeight();
viewport()->update(); viewport()->update();
} }
void CPUSideBar::changeTopmostAddress(dsint i) void CPUSideBar::changeTopmostAddress(duint i)
{ {
topVA = i; mTopVA = i;
DbgGetRegDumpEx(&regDump, sizeof(REGDUMP)); DbgGetRegDumpEx(&mRegDump, sizeof(REGDUMP));
reload(); reload();
} }
void CPUSideBar::setViewableRows(int rows) void CPUSideBar::setViewableRows(duint rows)
{ {
viewableRows = rows; mViewableRows = rows;
} }
void CPUSideBar::setSelection(dsint selVA) void CPUSideBar::setSelection(duint selVA)
{ {
if(selVA != selectedVA) if(selVA != mSelectedVA)
{ {
selectedVA = selVA; mSelectedVA = selVA;
reload(); reload();
} }
} }
@ -134,8 +127,8 @@ bool CPUSideBar::isJump(int i) const
Instruction_t::BranchType branchType = instr.branchType; Instruction_t::BranchType branchType = instr.branchType;
if(branchType == Instruction_t::Unconditional || branchType == Instruction_t::Conditional) if(branchType == Instruction_t::Unconditional || branchType == Instruction_t::Conditional)
{ {
duint start = mDisas->getBase(); duint start = mDisassembly->getBase();
duint end = start + mDisas->getSize(); duint end = start + mDisassembly->getSize();
duint addr = DbgGetBranchDestination(start + instr.rva); duint addr = DbgGetBranchDestination(start + instr.rva);
if(!addr) if(!addr)
@ -151,7 +144,7 @@ void CPUSideBar::paintEvent(QPaintEvent* event)
{ {
Q_UNUSED(event); Q_UNUSED(event);
QPainter painter(this->viewport()); QPainter painter(viewport());
// Paints background // Paints background
painter.fillRect(painter.viewport(), mBackgroundColor); painter.fillRect(painter.viewport(), mBackgroundColor);
@ -160,16 +153,16 @@ void CPUSideBar::paintEvent(QPaintEvent* event)
if(mInstrBuffer->size() == 0) if(mInstrBuffer->size() == 0)
return; return;
if(mCodeFoldingManager.isFolded(regDump.regcontext.cip)) if(mCodeFoldingManager.isFolded(mRegDump.regcontext.cip))
{ {
mCodeFoldingManager.expandFoldSegment(regDump.regcontext.cip); mCodeFoldingManager.expandFoldSegment(mRegDump.regcontext.cip);
mDisas->reloadData(); mDisassembly->reloadData();
} }
int jumpoffset = 0; int jumpoffset = 0;
duint last_va = mInstrBuffer->last().rva + mDisas->getBase(); duint last_va = mInstrBuffer->last().rva + mDisassembly->getBase();
duint first_va = mInstrBuffer->first().rva + mDisas->getBase(); duint first_va = mInstrBuffer->first().rva + mDisassembly->getBase();
QVector<std::pair<QString, duint>> regLabel; QVector<std::pair<QString, duint>> regLabel;
auto appendReg = [&regLabel, last_va, first_va](const QString & name, duint value) auto appendReg = [&regLabel, last_va, first_va](const QString & name, duint value)
@ -178,33 +171,33 @@ void CPUSideBar::paintEvent(QPaintEvent* event)
regLabel.append(std::make_pair(name, value)); regLabel.append(std::make_pair(name, value));
}; };
#ifdef _WIN64 #ifdef _WIN64
appendReg("RIP", regDump.regcontext.cip); appendReg("RIP", mRegDump.regcontext.cip);
appendReg("RAX", regDump.regcontext.cax); appendReg("RAX", mRegDump.regcontext.cax);
appendReg("RCX", regDump.regcontext.ccx); appendReg("RCX", mRegDump.regcontext.ccx);
appendReg("RDX", regDump.regcontext.cdx); appendReg("RDX", mRegDump.regcontext.cdx);
appendReg("RBX", regDump.regcontext.cbx); appendReg("RBX", mRegDump.regcontext.cbx);
appendReg("RSP", regDump.regcontext.csp); appendReg("RSP", mRegDump.regcontext.csp);
appendReg("RBP", regDump.regcontext.cbp); appendReg("RBP", mRegDump.regcontext.cbp);
appendReg("RSI", regDump.regcontext.csi); appendReg("RSI", mRegDump.regcontext.csi);
appendReg("RDI", regDump.regcontext.cdi); appendReg("RDI", mRegDump.regcontext.cdi);
appendReg("R8", regDump.regcontext.r8); appendReg("R8", mRegDump.regcontext.r8);
appendReg("R9", regDump.regcontext.r9); appendReg("R9", mRegDump.regcontext.r9);
appendReg("R10", regDump.regcontext.r10); appendReg("R10", mRegDump.regcontext.r10);
appendReg("R11", regDump.regcontext.r11); appendReg("R11", mRegDump.regcontext.r11);
appendReg("R12", regDump.regcontext.r12); appendReg("R12", mRegDump.regcontext.r12);
appendReg("R13", regDump.regcontext.r13); appendReg("R13", mRegDump.regcontext.r13);
appendReg("R14", regDump.regcontext.r14); appendReg("R14", mRegDump.regcontext.r14);
appendReg("R15", regDump.regcontext.r15); appendReg("R15", mRegDump.regcontext.r15);
#else //x86 #else //x86
appendReg("EIP", regDump.regcontext.cip); appendReg("EIP", mRegDump.regcontext.cip);
appendReg("EAX", regDump.regcontext.cax); appendReg("EAX", mRegDump.regcontext.cax);
appendReg("ECX", regDump.regcontext.ccx); appendReg("ECX", mRegDump.regcontext.ccx);
appendReg("EDX", regDump.regcontext.cdx); appendReg("EDX", mRegDump.regcontext.cdx);
appendReg("EBX", regDump.regcontext.cbx); appendReg("EBX", mRegDump.regcontext.cbx);
appendReg("ESP", regDump.regcontext.csp); appendReg("ESP", mRegDump.regcontext.csp);
appendReg("EBP", regDump.regcontext.cbp); appendReg("EBP", mRegDump.regcontext.cbp);
appendReg("ESI", regDump.regcontext.csi); appendReg("ESI", mRegDump.regcontext.csi);
appendReg("EDI", regDump.regcontext.cdi); appendReg("EDI", mRegDump.regcontext.cdi);
#endif //_WIN64 #endif //_WIN64
if(ConfigBool("Gui", "SidebarWatchLabels")) if(ConfigBool("Gui", "SidebarWatchLabels"))
{ {
@ -222,13 +215,13 @@ void CPUSideBar::paintEvent(QPaintEvent* event)
std::vector<JumpLine> jumpLines; std::vector<JumpLine> jumpLines;
std::vector<LabelArrow> labelArrows; std::vector<LabelArrow> labelArrows;
for(int line = 0; line < viewableRows; line++) for(duint line = 0; line < mViewableRows; line++)
{ {
if(line >= mInstrBuffer->size()) //at the end of the page it will crash otherwise if(line >= mInstrBuffer->size()) //at the end of the page it will crash otherwise
break; break;
const Instruction_t & instr = mInstrBuffer->at(line); const Instruction_t & instr = mInstrBuffer->at(line);
duint instrVA = instr.rva + mDisas->getBase(); duint instrVA = instr.rva + mDisassembly->getBase();
duint instrVAEnd = instrVA + instr.length; duint instrVAEnd = instrVA + instr.length;
// draw bullet // draw bullet
@ -236,12 +229,12 @@ void CPUSideBar::paintEvent(QPaintEvent* event)
if(isJump(line)) //handle jumps if(isJump(line)) //handle jumps
{ {
duint baseAddr = mDisas->getBase(); duint baseAddr = mDisassembly->getBase();
duint destVA = DbgGetBranchDestination(baseAddr + instr.rva); duint destVA = DbgGetBranchDestination(baseAddr + instr.rva);
JumpLine jmp; JumpLine jmp;
jmp.isJumpGoingToExecute = DbgIsJumpGoingToExecute(instrVA); jmp.isJumpGoingToExecute = DbgIsJumpGoingToExecute(instrVA);
jmp.isSelected = (selectedVA == instrVA || selectedVA == destVA); jmp.isSelected = (mSelectedVA == instrVA || mSelectedVA == destVA);
jmp.isConditional = instr.branchType == Instruction_t::Conditional; jmp.isConditional = instr.branchType == Instruction_t::Conditional;
jmp.line = line; jmp.line = line;
@ -253,7 +246,7 @@ void CPUSideBar::paintEvent(QPaintEvent* event)
jumpoffset++; jumpoffset++;
// Do not draw jumps that leave the memory range // Do not draw jumps that leave the memory range
if(destVA >= mDisas->getBase() + mDisas->getSize() || destVA < mDisas->getBase()) if(destVA >= mDisassembly->getBase() + mDisassembly->getSize() || destVA < mDisassembly->getBase())
continue; continue;
if(destVA <= last_va && destVA >= first_va) if(destVA <= last_va && destVA >= first_va)
@ -261,7 +254,7 @@ void CPUSideBar::paintEvent(QPaintEvent* event)
int destLine = line; int destLine = line;
while(destLine > -1 && destLine < mInstrBuffer->size()) while(destLine > -1 && destLine < mInstrBuffer->size())
{ {
duint va = mInstrBuffer->at(destLine).rva + mDisas->getBase(); duint va = mInstrBuffer->at(destLine).rva + mDisassembly->getBase();
if(destVA > instrVA) //jump goes down if(destVA > instrVA) //jump goes down
{ {
duint vaEnd = va + mInstrBuffer->at(destLine).length - 1; duint vaEnd = va + mInstrBuffer->at(destLine).length - 1;
@ -279,7 +272,7 @@ void CPUSideBar::paintEvent(QPaintEvent* event)
jmp.destLine = destLine; jmp.destLine = destLine;
} }
else if(destVA > last_va) else if(destVA > last_va)
jmp.destLine = viewableRows + 6; jmp.destLine = mViewableRows + 6;
else if(destVA < first_va) else if(destVA < first_va)
jmp.destLine = -6; jmp.destLine = -6;
jumpLines.emplace_back(jmp); jumpLines.emplace_back(jmp);
@ -300,16 +293,16 @@ void CPUSideBar::paintEvent(QPaintEvent* event)
if(isFoldingGraphicsPresent(line) == 1) if(isFoldingGraphicsPresent(line) == 1)
{ {
if(mCodeFoldingManager.isFoldStart(instrVA)) if(mCodeFoldingManager.isFoldStart(instrVA))
drawFoldingCheckbox(&painter, line * fontHeight, mCodeFoldingManager.isFolded(instrVA)); drawFoldingCheckbox(&painter, line * mFontHeight, mCodeFoldingManager.isFolded(instrVA));
else else
drawFoldingCheckbox(&painter, line * fontHeight, false); drawFoldingCheckbox(&painter, line * mFontHeight, false);
} }
else if(mCodeFoldingManager.isFoldBody(instrVA)) else if(mCodeFoldingManager.isFoldBody(instrVA))
{ {
painter.setPen(QColor(Qt::black)); painter.setPen(QColor(Qt::black));
painter.drawLine(QPointF(viewport()->width() - fontHeight / 2 - mBulletXOffset - mBulletRadius, line * fontHeight), QPointF(viewport()->width() - fontHeight / 2 - mBulletXOffset - mBulletRadius, (line + 1) * fontHeight)); painter.drawLine(QPointF(viewport()->width() - mFontHeight / 2 - mBulletXOffset - mBulletRadius, line * mFontHeight), QPointF(viewport()->width() - mFontHeight / 2 - mBulletXOffset - mBulletRadius, (line + 1) * mFontHeight));
if(mCodeFoldingManager.isFoldEnd(instrVA + instr.length - 1)) if(mCodeFoldingManager.isFoldEnd(instrVA + instr.length - 1))
painter.drawLine(QPointF(viewport()->width() - fontHeight / 2 - mBulletXOffset - mBulletRadius, (line + 1) * fontHeight), QPointF(viewport()->width(), (line + 1) * fontHeight)); painter.drawLine(QPointF(viewport()->width() - mFontHeight / 2 - mBulletXOffset - mBulletRadius, (line + 1) * mFontHeight), QPointF(viewport()->width(), (line + 1) * mFontHeight));
} }
} }
if(jumpLines.size()) if(jumpLines.size())
@ -321,7 +314,7 @@ void CPUSideBar::paintEvent(QPaintEvent* event)
else else
{ {
for(auto i = labelArrows.begin(); i != labelArrows.end(); i++) for(auto i = labelArrows.begin(); i != labelArrows.end(); i++)
i->endX = viewport()->width() - 1 - 11 - (isFoldingGraphicsPresent(i->line) != 0 ? mBulletRadius + fontHeight : 0); i->endX = viewport()->width() - 1 - 11 - (isFoldingGraphicsPresent(i->line) != 0 ? mBulletRadius + mFontHeight : 0);
} }
drawLabelArrows(&painter, labelArrows); drawLabelArrows(&painter, labelArrows);
} }
@ -335,12 +328,12 @@ void CPUSideBar::mouseReleaseEvent(QMouseEvent* e)
// get clicked line // get clicked line
const int x = e->pos().x(); const int x = e->pos().x();
const int y = e->pos().y(); const int y = e->pos().y();
const int line = y / fontHeight; const int line = y / mFontHeight;
if(line >= mInstrBuffer->size()) if(line >= mInstrBuffer->size())
return; return;
const int width = viewport()->width(); const int width = viewport()->width();
const int bulletRadius = fontHeight / 2 + 1; //14/2=7 const int bulletRadius = mFontHeight / 2 + 1; //14/2=7
const int bulletX = width - mBulletXOffset; const int bulletX = width - mBulletXOffset;
//const int bulletY = line * fontHeight + mBulletYOffset; //const int bulletY = line * fontHeight + mBulletYOffset;
@ -349,30 +342,30 @@ void CPUSideBar::mouseReleaseEvent(QMouseEvent* e)
if(x > bulletX + bulletRadius) if(x > bulletX + bulletRadius)
return; return;
// calculate virtual address of clicked line // calculate virtual address of clicked line
duint wVA = mInstrBuffer->at(line).rva + mDisas->getBase(); duint va = mInstrBuffer->at(line).rva + mDisassembly->getBase();
if(CheckBoxPresent) if(CheckBoxPresent)
{ {
if(x > width - fontHeight - mBulletXOffset - mBulletRadius && x < width - mBulletXOffset - mBulletRadius) if(x > width - mFontHeight - mBulletXOffset - mBulletRadius && x < width - mBulletXOffset - mBulletRadius)
{ {
if(e->button() == Qt::LeftButton) if(e->button() == Qt::LeftButton)
{ {
duint start, end; duint start, end;
const Instruction_t* instr = &mInstrBuffer->at(line); const Instruction_t* instr = &mInstrBuffer->at(line);
const dsint SelectionStart = mDisas->getSelectionStart(); const dsint SelectionStart = mDisassembly->getSelectionStart();
const dsint SelectionEnd = mDisas->getSelectionEnd(); const dsint SelectionEnd = mDisassembly->getSelectionEnd();
if(mCodeFoldingManager.isFoldStart(wVA)) if(mCodeFoldingManager.isFoldStart(va))
{ {
mCodeFoldingManager.setFolded(wVA, !mCodeFoldingManager.isFolded(wVA)); mCodeFoldingManager.setFolded(va, !mCodeFoldingManager.isFolded(va));
} }
else if(instr->rva == SelectionStart && (SelectionEnd - SelectionStart + 1) != instr->length) else if(instr->rva == SelectionStart && (SelectionEnd - SelectionStart + 1) != instr->length)
{ {
bool success = mCodeFoldingManager.addFoldSegment(wVA, mDisas->getSelectionEnd() - mDisas->getSelectionStart()); bool success = mCodeFoldingManager.addFoldSegment(va, mDisassembly->getSelectionEnd() - mDisassembly->getSelectionStart());
if(!success) if(!success)
GuiAddLogMessage(tr("Cannot fold selection.\n").toUtf8().constData()); GuiAddLogMessage(tr("Cannot fold selection.\n").toUtf8().constData());
} }
else if((DbgArgumentGet(wVA, &start, &end) || DbgFunctionGet(wVA, &start, &end)) && wVA == start) else if((DbgArgumentGet(va, &start, &end) || DbgFunctionGet(va, &start, &end)) && va == start)
{ {
bool success = mCodeFoldingManager.addFoldSegment(wVA, end - start); bool success = mCodeFoldingManager.addFoldSegment(va, end - start);
if(!success) if(!success)
GuiAddLogMessage(tr("Cannot fold selection.\n").toUtf8().constData()); GuiAddLogMessage(tr("Cannot fold selection.\n").toUtf8().constData());
} }
@ -381,9 +374,9 @@ void CPUSideBar::mouseReleaseEvent(QMouseEvent* e)
} }
else if(e->button() == Qt::RightButton) else if(e->button() == Qt::RightButton)
{ {
mCodeFoldingManager.delFoldSegment(wVA); mCodeFoldingManager.delFoldSegment(va);
} }
mDisas->reloadData(); mDisassembly->reloadData();
viewport()->update(); viewport()->update();
} }
} }
@ -394,52 +387,52 @@ void CPUSideBar::mouseReleaseEvent(QMouseEvent* e)
if(e->button() == Qt::LeftButton) if(e->button() == Qt::LeftButton)
{ {
QString wCmd; QString cmd;
// create --> disable --> delete --> create --> ... // create --> disable --> delete --> create --> ...
switch(Breakpoints::BPState(bp_normal, wVA)) switch(Breakpoints::BPState(bp_normal, va))
{ {
case bp_enabled: case bp_enabled:
// breakpoint exists and is enabled --> disable breakpoint // breakpoint exists and is enabled --> disable breakpoint
wCmd = "bd "; cmd = "bd ";
break; break;
case bp_disabled: case bp_disabled:
// is disabled --> delete or enable // is disabled --> delete or enable
if(Breakpoints::BPTrival(bp_normal, wVA)) if(Breakpoints::BPTrival(bp_normal, va))
wCmd = "bc "; cmd = "bc ";
else else
wCmd = "be "; cmd = "be ";
break; break;
case bp_non_existent: case bp_non_existent:
// no breakpoint was found --> create breakpoint // no breakpoint was found --> create breakpoint
wCmd = "bp "; cmd = "bp ";
break; break;
} }
wCmd += ToPtrString(wVA); cmd += ToPtrString(va);
DbgCmdExec(wCmd); DbgCmdExec(cmd);
} }
} }
void CPUSideBar::mouseDoubleClickEvent(QMouseEvent* event) void CPUSideBar::mouseDoubleClickEvent(QMouseEvent* event)
{ {
const int line = event->y() / fontHeight; const int line = event->y() / mFontHeight;
if(line >= mInstrBuffer->size()) if(line >= mInstrBuffer->size())
return; return;
const bool CheckBoxPresent = isFoldingGraphicsPresent(line); const bool CheckBoxPresent = isFoldingGraphicsPresent(line);
if(CheckBoxPresent) if(CheckBoxPresent)
{ {
if(event->x() > width() - fontHeight - mBulletXOffset - mBulletRadius && event->x() < width() - mBulletXOffset - mBulletRadius) if(event->x() > width() - mFontHeight - mBulletXOffset - mBulletRadius && event->x() < width() - mBulletXOffset - mBulletRadius)
{ {
if(event->button() == Qt::LeftButton) if(event->button() == Qt::LeftButton)
{ {
duint wVA = mInstrBuffer->at(line).rva + mDisas->getBase(); duint va = mInstrBuffer->at(line).rva + mDisassembly->getBase();
duint start = mCodeFoldingManager.getFoldBegin(wVA); duint start = mCodeFoldingManager.getFoldBegin(va);
duint end = mCodeFoldingManager.getFoldEnd(wVA); duint end = mCodeFoldingManager.getFoldEnd(va);
if(mCodeFoldingManager.isFolded(wVA) || (start <= regDump.regcontext.cip && end >= regDump.regcontext.cip)) if(mCodeFoldingManager.isFolded(va) || (start <= mRegDump.regcontext.cip && end >= mRegDump.regcontext.cip))
{ {
mDisas->setSingleSelection(start - mDisas->getBase()); mDisassembly->setSingleSelection(start - mDisassembly->getBase());
mDisas->expandSelectionUpTo(end - mDisas->getBase()); mDisassembly->expandSelectionUpTo(end - mDisassembly->getBase());
mDisas->setFocus(); mDisassembly->setFocus();
} }
} }
} }
@ -460,33 +453,33 @@ void CPUSideBar::mouseMoveEvent(QMouseEvent* event)
const QPoint & globalMousePos = event->globalPos(); const QPoint & globalMousePos = event->globalPos();
const int width = viewport()->width(); const int width = viewport()->width();
const int mLine = mousePos.y() / fontHeight; const int mLine = mousePos.y() / mFontHeight;
const bool lineInBounds = mLine > 0 && mLine < mInstrBuffer->size(); const bool lineInBounds = mLine > 0 && mLine < mInstrBuffer->size();
const int mBulletX = width - mBulletXOffset; const int mBulletX = width - mBulletXOffset;
const int mBulletY = mLine * fontHeight + mBulletYOffset; const int mBulletY = mLine * mFontHeight + mBulletYOffset;
const int mouseBulletXOffset = abs(mBulletX - mousePos.x()); const int mouseBulletXOffset = abs(mBulletX - mousePos.x());
const int mouseBulletYOffset = abs(mBulletY - mousePos.y()); const int mouseBulletYOffset = abs(mBulletY - mousePos.y());
// calculate virtual address of clicked line // calculate virtual address of clicked line
duint wVA = 0; duint va = 0;
if(lineInBounds) if(lineInBounds)
wVA = mInstrBuffer->at(mLine).rva + mDisas->getBase(); va = mInstrBuffer->at(mLine).rva + mDisassembly->getBase();
// check if mouse is on a code folding box // check if mouse is on a code folding box
if(mousePos.x() > width - fontHeight - mBulletXOffset - mBulletRadius && mousePos.x() < width - mBulletXOffset - mBulletRadius) if(mousePos.x() > width - mFontHeight - mBulletXOffset - mBulletRadius && mousePos.x() < width - mBulletXOffset - mBulletRadius)
{ {
if(isFoldingGraphicsPresent(mLine)) if(isFoldingGraphicsPresent(mLine))
{ {
if(mCodeFoldingManager.isFolded(wVA)) if(mCodeFoldingManager.isFolded(va))
{ {
QToolTip::showText(globalMousePos, tr("Click to unfold, right click to delete.")); QToolTip::showText(globalMousePos, tr("Click to unfold, right click to delete."));
} }
else else
{ {
if(mCodeFoldingManager.isFoldStart(wVA)) if(mCodeFoldingManager.isFoldStart(va))
QToolTip::showText(globalMousePos, tr("Click to fold, right click to delete.")); QToolTip::showText(globalMousePos, tr("Click to fold, right click to delete."));
else else
QToolTip::showText(globalMousePos, tr("Click to fold.")); QToolTip::showText(globalMousePos, tr("Click to fold."));
@ -501,7 +494,7 @@ void CPUSideBar::mouseMoveEvent(QMouseEvent* event)
} }
else else
{ {
switch(Breakpoints::BPState(bp_normal, wVA)) switch(Breakpoints::BPState(bp_normal, va))
{ {
case bp_enabled: case bp_enabled:
QToolTip::showText(globalMousePos, tr("Breakpoint Enabled")); QToolTip::showText(globalMousePos, tr("Breakpoint Enabled"));
@ -524,8 +517,8 @@ void CPUSideBar::drawJump(QPainter* painter, int startLine, int endLine, int jum
// Pixel adjustment to make drawing lines even // Pixel adjustment to make drawing lines even
int pixel_y_offs = 0; int pixel_y_offs = 0;
int y_start = fontHeight * (1 + startLine) - 0.5 * fontHeight - pixel_y_offs; int y_start = mFontHeight * (1 + startLine) - 0.5 * mFontHeight - pixel_y_offs;
int y_end = fontHeight * (1 + endLine) - 0.5 * fontHeight; int y_end = mFontHeight * (1 + endLine) - 0.5 * mFontHeight;
int y_diff = y_end >= y_start ? 1 : -1; int y_diff = y_end >= y_start ? 1 : -1;
if(conditional) if(conditional)
@ -581,21 +574,21 @@ void CPUSideBar::drawJump(QPainter* painter, int startLine, int endLine, int jum
const int viewportHeight = viewport()->height(); const int viewportHeight = viewport()->height();
const int JumpPadding = 11; const int JumpPadding = 11;
int x = viewportWidth - jumpoffset * JumpPadding - 15 - fontHeight; int x = viewportWidth - jumpoffset * JumpPadding - 15 - mFontHeight;
int x_right = viewportWidth - 12; int x_right = viewportWidth - 12;
// special handling of self-jumping // special handling of self-jumping
if(startLine == endLine) if(startLine == endLine)
{ {
y_start -= fontHeight / 4; y_start -= mFontHeight / 4;
y_end += fontHeight / 4; y_end += mFontHeight / 4;
} }
// Horizontal (<----) // Horizontal (<----)
if(!isFoldingGraphicsPresent(startLine) != 0) if(!isFoldingGraphicsPresent(startLine) != 0)
painter->drawLine(x_right, y_start, x, y_start); painter->drawLine(x_right, y_start, x, y_start);
else else
painter->drawLine(x_right - mBulletRadius - fontHeight, y_start, x, y_start); painter->drawLine(x_right - mBulletRadius - mFontHeight, y_start, x, y_start);
// Vertical // Vertical
painter->drawLine(x, y_start, x, y_end); painter->drawLine(x, y_start, x, y_end);
@ -609,82 +602,82 @@ void CPUSideBar::drawJump(QPainter* painter, int startLine, int endLine, int jum
{ {
// Horizontal (---->) // Horizontal (---->)
if(isFoldingGraphicsPresent(endLine) != 0) if(isFoldingGraphicsPresent(endLine) != 0)
painter->drawLine(x, y_end, x_right - mBulletRadius - fontHeight, y_end); painter->drawLine(x, y_end, x_right - mBulletRadius - mFontHeight, y_end);
else else
painter->drawLine(x, y_end, x_right, y_end); painter->drawLine(x, y_end, x_right, y_end);
if(endLine == viewableRows + 6) if(endLine == mViewableRows + 6)
{ {
int y = viewportHeight - 1; int y = viewportHeight - 1;
if(y > y_start) if(y > y_start)
{ {
painter->setPen(solidLine); painter->setPen(solidLine);
QPoint wPoints[] = QPoint points[] =
{ {
QPoint(x - 3, y - 3), QPoint(x - 3, y - 3),
QPoint(x, y), QPoint(x, y),
QPoint(x + 3, y - 3), QPoint(x + 3, y - 3),
}; };
painter->drawPolyline(wPoints, 3); painter->drawPolyline(points, 3);
} }
} }
else if(endLine == -6) else if(endLine == -6)
{ {
int y = 0; int y = 0;
painter->setPen(solidLine); painter->setPen(solidLine);
QPoint wPoints[] = QPoint points[] =
{ {
QPoint(x - 3, y + 3), QPoint(x - 3, y + 3),
QPoint(x, y), QPoint(x, y),
QPoint(x + 3, y + 3), QPoint(x + 3, y + 3),
}; };
painter->drawPolyline(wPoints, 3); painter->drawPolyline(points, 3);
} }
else else
{ {
if(isFoldingGraphicsPresent(endLine) != 0) if(isFoldingGraphicsPresent(endLine) != 0)
x_right -= mBulletRadius + fontHeight; x_right -= mBulletRadius + mFontHeight;
painter->setPen(solidLine); painter->setPen(solidLine);
QPoint wPoints[] = QPoint points[] =
{ {
QPoint(x_right - 3, y_end - 3), QPoint(x_right - 3, y_end - 3),
QPoint(x_right, y_end), QPoint(x_right, y_end),
QPoint(x_right - 3, y_end + 3), QPoint(x_right - 3, y_end + 3),
}; };
painter->drawPolyline(wPoints, 3); painter->drawPolyline(points, 3);
} }
} }
else else
{ {
if(endLine == viewableRows + 6) if(endLine == mViewableRows + 6)
{ {
int y = viewportHeight - 1; int y = viewportHeight - 1;
x--; x--;
painter->setPen(solidLine); painter->setPen(solidLine);
QPoint wPoints[] = QPoint points[] =
{ {
QPoint(x - 3, y - 3), QPoint(x - 3, y - 3),
QPoint(x, y), QPoint(x, y),
QPoint(x + 3, y - 3), QPoint(x + 3, y - 3),
}; };
painter->drawPolyline(wPoints, 3); painter->drawPolyline(points, 3);
} }
else if(endLine == -6) else if(endLine == -6)
{ {
int y = 0; int y = 0;
painter->setPen(solidLine); painter->setPen(solidLine);
QPoint wPoints[] = QPoint points[] =
{ {
QPoint(x - 3, y + 3), QPoint(x - 3, y + 3),
QPoint(x, y), QPoint(x, y),
QPoint(x + 3, y + 3), QPoint(x + 3, y + 3),
}; };
painter->drawPolyline(wPoints, 3); painter->drawPolyline(points, 3);
} }
else else
{ {
if(isFoldingGraphicsPresent(endLine) != 0) if(isFoldingGraphicsPresent(endLine) != 0)
drawStraightArrow(painter, x, y_end, x_right - mBulletRadius - fontHeight, y_end); drawStraightArrow(painter, x, y_end, x_right - mBulletRadius - mFontHeight, y_end);
else else
drawStraightArrow(painter, x, y_end, x_right, y_end); drawStraightArrow(painter, x, y_end, x_right, y_end);
} }
@ -706,7 +699,7 @@ void CPUSideBar::drawBullets(QPainter* painter, int line, bool isbp, bool isbpdi
painter->setPen(mBackgroundColor); painter->setPen(mBackgroundColor);
const int x = viewport()->width() - mBulletXOffset; //initial x const int x = viewport()->width() - mBulletXOffset; //initial x
const int y = line * fontHeight; //initial y const int y = line * mFontHeight; //initial y
painter->setRenderHint(QPainter::Antialiasing, true); painter->setRenderHint(QPainter::Antialiasing, true);
if(isbpdisabled) //disabled breakpoint if(isbpdisabled) //disabled breakpoint
@ -720,16 +713,16 @@ void CPUSideBar::drawBullets(QPainter* painter, int line, bool isbp, bool isbpdi
CPUSideBar::LabelArrow CPUSideBar::drawLabel(QPainter* painter, int Line, const QString & Text) CPUSideBar::LabelArrow CPUSideBar::drawLabel(QPainter* painter, int Line, const QString & Text)
{ {
painter->save(); painter->save();
const int LineCoordinate = fontHeight * (1 + Line); const int LineCoordinate = mFontHeight * (1 + Line);
const QColor & IPLabel = mCipLabelColor; const QColor & IPLabel = mCipLabelColor;
const QColor & IPLabelBG = mCipLabelBackgroundColor; const QColor & IPLabelBG = mCipLabelBackgroundColor;
int width = mFontMetrics->width(Text); int width = mFontMetrics->width(Text);
int x = 1; int x = 1;
int y = LineCoordinate - fontHeight; int y = LineCoordinate - mFontHeight;
QRect rect(x, y, width, fontHeight - 1); QRect rect(x, y, width, mFontHeight - 1);
// Draw rectangle // Draw rectangle
painter->setBrush(IPLabelBG); painter->setBrush(IPLabelBG);
@ -745,7 +738,7 @@ CPUSideBar::LabelArrow CPUSideBar::drawLabel(QPainter* painter, int Line, const
painter->setPen(QPen(IPLabelBG, 2.0)); painter->setPen(QPen(IPLabelBG, 2.0));
painter->setBrush(QBrush(IPLabelBG)); painter->setBrush(QBrush(IPLabelBG));
drawStraightArrow(painter, rect.right() + 2, y, this->viewport()->width() - x - 11 - (isFoldingGraphicsPresent(Line) != 0 ? mBulletRadius + fontHeight : 0), y);*/ drawStraightArrow(painter, rect.right() + 2, y, viewport()->width() - x - 11 - (isFoldingGraphicsPresent(Line) != 0 ? mBulletRadius + fontHeight : 0), y);*/
LabelArrow labelArrow; LabelArrow labelArrow;
labelArrow.line = Line; labelArrow.line = Line;
@ -767,7 +760,7 @@ void CPUSideBar::drawLabelArrows(QPainter* painter, const std::vector<LabelArrow
{ {
if(i.startX < i.endX) if(i.startX < i.endX)
{ {
int y = fontHeight * (1 + i.line) - 0.5 * fontHeight; int y = mFontHeight * (1 + i.line) - 0.5 * mFontHeight;
drawStraightArrow(painter, i.startX, y, i.endX, y); drawStraightArrow(painter, i.startX, y, i.endX, y);
} }
} }
@ -777,16 +770,16 @@ void CPUSideBar::drawLabelArrows(QPainter* painter, const std::vector<LabelArrow
void CPUSideBar::drawFoldingCheckbox(QPainter* painter, int y, bool state) void CPUSideBar::drawFoldingCheckbox(QPainter* painter, int y, bool state)
{ {
int x = viewport()->width() - fontHeight - mBulletXOffset - mBulletRadius; int x = viewport()->width() - mFontHeight - mBulletXOffset - mBulletRadius;
painter->save(); painter->save();
painter->setBrush(QBrush(mChkBoxBackColor)); painter->setBrush(QBrush(mChkBoxBackColor));
painter->setPen(QColor(mChkBoxForeColor)); painter->setPen(QColor(mChkBoxForeColor));
QRect rect(x, y, fontHeight, fontHeight); QRect rect(x, y, mFontHeight, mFontHeight);
painter->drawRect(rect); painter->drawRect(rect);
painter->drawLine(QPointF(x + fontHeight / 4, y + fontHeight / 2), QPointF(x + 3 * fontHeight / 4, y + fontHeight / 2)); painter->drawLine(QPointF(x + mFontHeight / 4, y + mFontHeight / 2), QPointF(x + 3 * mFontHeight / 4, y + mFontHeight / 2));
if(state) // "+" if(state) // "+"
painter->drawLine(QPointF(x + fontHeight / 2, y + fontHeight / 4), QPointF(x + fontHeight / 2, y + 3 * fontHeight / 4)); painter->drawLine(QPointF(x + mFontHeight / 2, y + mFontHeight / 4), QPointF(x + mFontHeight / 2, y + 3 * mFontHeight / 4));
painter->restore(); painter->restore();
} }
@ -804,8 +797,8 @@ void CPUSideBar::drawStraightArrow(QPainter* painter, int x1, int y1, int x2, in
void CPUSideBar::AllocateJumpOffsets(std::vector<JumpLine> & jumpLines, std::vector<LabelArrow> & labelArrows) void CPUSideBar::AllocateJumpOffsets(std::vector<JumpLine> & jumpLines, std::vector<LabelArrow> & labelArrows)
{ {
unsigned int* numLines = new unsigned int[viewableRows * 2]; // Low:jump offsets of the vertical jumping line, High:jump offsets of the horizontal jumping line. unsigned int* numLines = new unsigned int[mViewableRows * 2]; // Low:jump offsets of the vertical jumping line, High:jump offsets of the horizontal jumping line.
memset(numLines, 0, sizeof(unsigned int) * viewableRows * 2); memset(numLines, 0, sizeof(unsigned int) * mViewableRows * 2);
// preprocessing // preprocessing
for(size_t i = 0; i < jumpLines.size(); i++) for(size_t i = 0; i < jumpLines.size(); i++)
{ {
@ -824,7 +817,7 @@ void CPUSideBar::AllocateJumpOffsets(std::vector<JumpLine> & jumpLines, std::vec
unsigned int maxJmpOffset = 0; unsigned int maxJmpOffset = 0;
if(jmp.line < jmp.destLine) if(jmp.line < jmp.destLine)
{ {
for(int j = jmp.line; j <= jmp.destLine && j < viewableRows; j++) for(int j = jmp.line; j <= jmp.destLine && j < mViewableRows; j++)
{ {
if(numLines[j] > maxJmpOffset) if(numLines[j] > maxJmpOffset)
maxJmpOffset = numLines[j]; maxJmpOffset = numLines[j];
@ -841,7 +834,7 @@ void CPUSideBar::AllocateJumpOffsets(std::vector<JumpLine> & jumpLines, std::vec
jmp.jumpOffset = maxJmpOffset + 1; jmp.jumpOffset = maxJmpOffset + 1;
if(jmp.line < jmp.destLine) if(jmp.line < jmp.destLine)
{ {
for(int j = jmp.line; j <= jmp.destLine && j < viewableRows; j++) for(int j = jmp.line; j <= jmp.destLine && j < mViewableRows; j++)
numLines[j] = jmp.jumpOffset; numLines[j] = jmp.jumpOffset;
} }
else else
@ -849,20 +842,20 @@ void CPUSideBar::AllocateJumpOffsets(std::vector<JumpLine> & jumpLines, std::vec
for(int j = jmp.line; j >= jmp.destLine && j >= 0; j--) for(int j = jmp.line; j >= jmp.destLine && j >= 0; j--)
numLines[j] = jmp.jumpOffset; numLines[j] = jmp.jumpOffset;
} }
if(jmp.line >= 0 && jmp.line < viewableRows) if(jmp.line >= 0 && jmp.line < mViewableRows)
numLines[jmp.line + viewableRows] = jmp.jumpOffset; numLines[jmp.line + mViewableRows] = jmp.jumpOffset;
if(jmp.destLine >= 0 && jmp.destLine < viewableRows) if(jmp.destLine >= 0 && jmp.destLine < mViewableRows)
numLines[jmp.destLine + viewableRows] = jmp.jumpOffset; numLines[jmp.destLine + mViewableRows] = jmp.jumpOffset;
} }
// set label arrows according to jump offsets // set label arrows according to jump offsets
auto viewportWidth = viewport()->width(); auto viewportWidth = viewport()->width();
const int JumpPadding = 11; const int JumpPadding = 11;
for(auto i = labelArrows.begin(); i != labelArrows.end(); i++) for(auto i = labelArrows.begin(); i != labelArrows.end(); i++)
{ {
if(numLines[i->line + viewableRows] != 0) if(numLines[i->line + mViewableRows] != 0)
i->endX = viewportWidth - numLines[i->line + viewableRows] * JumpPadding - 15 - fontHeight; // This expression should be consistent with drawJump i->endX = viewportWidth - numLines[i->line + mViewableRows] * JumpPadding - 15 - mFontHeight; // This expression should be consistent with drawJump
else else
i->endX = viewportWidth - 1 - 11 - (isFoldingGraphicsPresent(i->line) != 0 ? mBulletRadius + fontHeight : 0); i->endX = viewportWidth - 1 - 11 - (isFoldingGraphicsPresent(i->line) != 0 ? mBulletRadius + mFontHeight : 0);
} }
delete[] numLines; delete[] numLines;
} }
@ -874,13 +867,13 @@ int CPUSideBar::isFoldingGraphicsPresent(int line)
const Instruction_t* instr = &mInstrBuffer->at(line); const Instruction_t* instr = &mInstrBuffer->at(line);
if(instr == nullptr) //Selection out of a memory page if(instr == nullptr) //Selection out of a memory page
return 0; return 0;
auto wVA = instr->rva + mDisas->getBase(); auto va = instr->rva + mDisassembly->getBase();
if(mCodeFoldingManager.isFoldStart(wVA)) //Code is already folded if(mCodeFoldingManager.isFoldStart(va)) //Code is already folded
return 1; return 1;
const dsint SelectionStart = mDisas->getSelectionStart(); const dsint SelectionStart = mDisassembly->getSelectionStart();
const dsint SelectionEnd = mDisas->getSelectionEnd(); const dsint SelectionEnd = mDisassembly->getSelectionEnd();
duint start, end; duint start, end;
if((DbgArgumentGet(wVA, &start, &end) || DbgFunctionGet(wVA, &start, &end)) && wVA == start) if((DbgArgumentGet(va, &start, &end) || DbgFunctionGet(va, &start, &end)) && va == start)
{ {
return end - start + 1 != instr->length ? 1 : 0; return end - start + 1 != instr->length ? 1 : 0;
} }

View File

@ -2,7 +2,7 @@
#include <QAbstractScrollArea> #include <QAbstractScrollArea>
#include <QPen> #include <QPen>
#include "QBeaEngine.h" #include "QZydis.h"
#include "CodeFolding.h" #include "CodeFolding.h"
#include "Imports.h" #include "Imports.h"
@ -11,11 +11,11 @@ class CPUDisassembly;
class CPUSideBar : public QAbstractScrollArea class CPUSideBar : public QAbstractScrollArea
{ {
Q_OBJECT Q_OBJECT
QPair<dsint, dsint> mHighlightedJump; QPair<duint, duint> mHighlightedJump;
public: public:
// Constructors // Constructors
explicit CPUSideBar(CPUDisassembly* Ptr, QWidget* parent = 0); CPUSideBar(CPUDisassembly* disassembly, QWidget* parent = nullptr);
~CPUSideBar(); ~CPUSideBar();
QSize sizeHint() const; QSize sizeHint() const;
@ -38,9 +38,9 @@ public slots:
void debugStateChangedSlot(DBGSTATE state); void debugStateChangedSlot(DBGSTATE state);
void reload(); void reload();
void changeTopmostAddress(dsint i); void changeTopmostAddress(duint i);
void setViewableRows(int rows); void setViewableRows(duint rows);
void setSelection(dsint selVA); void setSelection(duint selVA);
void foldDisassembly(duint startAddress, duint length); void foldDisassembly(duint startAddress, duint length);
protected: protected:
@ -56,19 +56,19 @@ protected:
CodeFoldingHelper mCodeFoldingManager; CodeFoldingHelper mCodeFoldingManager;
private: private:
CachedFontMetrics* mFontMetrics; CachedFontMetrics* mFontMetrics = nullptr;
dsint topVA; duint mTopVA = -1;
dsint selectedVA; duint mSelectedVA = -1;
QFont mDefaultFont; QFont mDefaultFont;
int fontWidth, fontHeight; int mFontWidth = 0;
int viewableRows; int mFontHeight = 0;
int mBulletRadius; duint mViewableRows = 0;
int mBulletRadius = 0;
int mBulletYOffset = 10; int mBulletYOffset = 10;
const int mBulletXOffset = 10; const int mBulletXOffset = 10;
CPUDisassembly* mDisassembly = nullptr;
CPUDisassembly* mDisas;
QList<Instruction_t>* mInstrBuffer; QList<Instruction_t>* mInstrBuffer;
REGDUMP regDump; REGDUMP mRegDump = {};
struct JumpLine struct JumpLine
{ {

View File

@ -9,36 +9,37 @@
#include "CPUMultiDump.h" #include "CPUMultiDump.h"
#include "GotoDialog.h" #include "GotoDialog.h"
CPUStack::CPUStack(CPUMultiDump* multiDump, QWidget* parent) : HexDump(parent) CPUStack::CPUStack(CPUMultiDump* multiDump, QWidget* parent)
: HexDump(multiDump->getArchitecture(), parent)
{ {
setWindowTitle("Stack"); setWindowTitle("Stack");
setShowHeader(false); setShowHeader(false);
int charwidth = getCharWidth(); int charwidth = getCharWidth();
ColumnDescriptor wColDesc; ColumnDescriptor colDesc;
DataDescriptor dDesc; DataDescriptor dDesc;
mMultiDump = multiDump; mMultiDump = multiDump;
mForceColumn = 1; mForceColumn = 1;
wColDesc.isData = true; //void* colDesc.isData = true; //void*
wColDesc.itemCount = 1; colDesc.itemCount = 1;
wColDesc.separator = 0; colDesc.separator = 0;
#ifdef _WIN64 #ifdef _WIN64
wColDesc.data.itemSize = Qword; colDesc.data.itemSize = Qword;
wColDesc.data.qwordMode = HexQword; colDesc.data.qwordMode = HexQword;
#else #else
wColDesc.data.itemSize = Dword; colDesc.data.itemSize = Dword;
wColDesc.data.dwordMode = HexDword; colDesc.data.dwordMode = HexDword;
#endif #endif
appendDescriptor(10 + charwidth * 2 * sizeof(duint), "void*", false, wColDesc); appendDescriptor(10 + charwidth * 2 * sizeof(duint), "void*", false, colDesc);
wColDesc.isData = false; //comments colDesc.isData = false; //comments
wColDesc.itemCount = 0; colDesc.itemCount = 0;
wColDesc.separator = 0; colDesc.separator = 0;
dDesc.itemSize = Byte; dDesc.itemSize = Byte;
dDesc.byteMode = AsciiByte; dDesc.byteMode = AsciiByte;
wColDesc.data = dDesc; colDesc.data = dDesc;
appendDescriptor(2000, tr("Comments"), false, wColDesc); appendDescriptor(2000, tr("Comments"), false, colDesc);
setupContextMenu(); setupContextMenu();
@ -309,12 +310,12 @@ void CPUStack::updateFreezeStackAction()
mFreezeStack->setChecked(bStackFrozen); mFreezeStack->setChecked(bStackFrozen);
} }
void CPUStack::getColumnRichText(int col, dsint rva, RichTextPainter::List & richText) void CPUStack::getColumnRichText(duint col, duint rva, RichTextPainter::List & richText)
{ {
// Compute VA // Compute VA
duint wVa = rvaToVa(rva); duint va = rvaToVa(rva);
bool wActiveStack = (wVa >= mCsp); //inactive stack bool activeStack = (va >= mCsp); //inactive stack
STACK_COMMENT comment; STACK_COMMENT comment;
RichTextPainter::CustomRichText_t curData; RichTextPainter::CustomRichText_t curData;
@ -325,7 +326,7 @@ void CPUStack::getColumnRichText(int col, dsint rva, RichTextPainter::List & ric
if(col && mDescriptor.at(col - 1).isData == true) //paint stack data if(col && mDescriptor.at(col - 1).isData == true) //paint stack data
{ {
HexDump::getColumnRichText(col, rva, richText); HexDump::getColumnRichText(col, rva, richText);
if(!wActiveStack) if(!activeStack)
{ {
QColor inactiveColor = ConfigColor("StackInactiveTextColor"); QColor inactiveColor = ConfigColor("StackInactiveTextColor");
for(int i = 0; i < int(richText.size()); i++) for(int i = 0; i < int(richText.size()); i++)
@ -335,9 +336,9 @@ void CPUStack::getColumnRichText(int col, dsint rva, RichTextPainter::List & ric
} }
} }
} }
else if(col && DbgStackCommentGet(wVa, &comment)) //paint stack comments else if(col && DbgStackCommentGet(va, &comment)) //paint stack comments
{ {
if(wActiveStack) if(activeStack)
{ {
if(*comment.color) if(*comment.color)
{ {
@ -365,24 +366,24 @@ void CPUStack::getColumnRichText(int col, dsint rva, RichTextPainter::List & ric
HexDump::getColumnRichText(col, rva, richText); HexDump::getColumnRichText(col, rva, richText);
} }
QString CPUStack::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) QString CPUStack::paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h)
{ {
// Compute RVA // Compute RVA
int wBytePerRowCount = getBytePerRowCount(); auto bytePerRowCount = getBytePerRowCount();
dsint wRva = (rowBase + rowOffset) * wBytePerRowCount - mByteOffset; dsint rva = row * bytePerRowCount - mByteOffset;
duint wVa = rvaToVa(wRva); duint va = rvaToVa(rva);
bool wIsSelected = isSelected(wRva); bool rowSelected = isSelected(rva);
if(wIsSelected) //highlight if selected if(rowSelected) //highlight if selected
painter->fillRect(QRect(x, y, w, h), QBrush(mSelectionColor)); painter->fillRect(QRect(x, y, w, h), QBrush(mSelectionColor));
if(col == 0) // paint stack address if(col == 0) // paint stack address
{ {
QColor background; QColor background;
char labelText[MAX_LABEL_SIZE] = ""; char labelText[MAX_LABEL_SIZE] = "";
if(DbgGetLabelAt(wVa, SEG_DEFAULT, labelText)) //label if(DbgGetLabelAt(va, SEG_DEFAULT, labelText)) //label
{ {
if(wVa == mCsp) //CSP if(va == mCsp) //CSP
{ {
background = ConfigColor("StackCspBackgroundColor"); background = ConfigColor("StackCspBackgroundColor");
painter->setPen(QPen(ConfigColor("StackCspColor"))); painter->setPen(QPen(ConfigColor("StackCspColor")));
@ -395,12 +396,12 @@ QString CPUStack::paintContent(QPainter* painter, dsint rowBase, int rowOffset,
} }
else //no label else //no label
{ {
if(wVa == mCsp) //CSP if(va == mCsp) //CSP
{ {
background = ConfigColor("StackCspBackgroundColor"); background = ConfigColor("StackCspBackgroundColor");
painter->setPen(QPen(ConfigColor("StackCspColor"))); painter->setPen(QPen(ConfigColor("StackCspColor")));
} }
else if(wIsSelected) //selected normal address else if(rowSelected) //selected normal address
{ {
background = ConfigColor("StackSelectedAddressBackgroundColor"); background = ConfigColor("StackSelectedAddressBackgroundColor");
painter->setPen(QPen(ConfigColor("StackSelectedAddressColor"))); //black address (DisassemblySelectedAddressColor) painter->setPen(QPen(ConfigColor("StackSelectedAddressColor"))); //black address (DisassemblySelectedAddressColor)
@ -413,7 +414,7 @@ QString CPUStack::paintContent(QPainter* painter, dsint rowBase, int rowOffset,
} }
if(background.alpha()) if(background.alpha())
painter->fillRect(QRect(x, y, w, h), QBrush(background)); //fill background when defined painter->fillRect(QRect(x, y, w, h), QBrush(background)); //fill background when defined
painter->drawText(QRect(x + 4, y, w - 4, h), Qt::AlignVCenter | Qt::AlignLeft, makeAddrText(wVa)); painter->drawText(QRect(x + 4, y, w - 4, h), Qt::AlignVCenter | Qt::AlignLeft, makeAddrText(va));
return QString(); return QString();
} }
else if(col == 1) // paint stack data else if(col == 1) // paint stack data
@ -422,14 +423,14 @@ QString CPUStack::paintContent(QPainter* painter, dsint rowBase, int rowOffset,
{ {
int stackFrameBitfield = 0; // 0:none, 1:top of stack frame, 2:bottom of stack frame, 4:middle of stack frame int stackFrameBitfield = 0; // 0:none, 1:top of stack frame, 2:bottom of stack frame, 4:middle of stack frame
int party = 0; int party = 0;
if(wVa >= mCallstack[0].addr) if(va >= mCallstack[0].addr)
{ {
for(size_t i = 0; i < mCallstack.size() - 1; i++) for(size_t i = 0; i < mCallstack.size() - 1; i++)
{ {
if(wVa >= mCallstack[i].addr && wVa < mCallstack[i + 1].addr) if(va >= mCallstack[i].addr && va < mCallstack[i + 1].addr)
{ {
stackFrameBitfield |= (mCallstack[i].addr == wVa) ? 1 : 0; stackFrameBitfield |= (mCallstack[i].addr == va) ? 1 : 0;
stackFrameBitfield |= (mCallstack[i + 1].addr == wVa + sizeof(duint)) ? 2 : 0; stackFrameBitfield |= (mCallstack[i + 1].addr == va + sizeof(duint)) ? 2 : 0;
if(stackFrameBitfield == 0) if(stackFrameBitfield == 0)
stackFrameBitfield = 4; stackFrameBitfield = 4;
party = mCallstack[i].party; party = mCallstack[i].party;
@ -438,14 +439,14 @@ QString CPUStack::paintContent(QPainter* painter, dsint rowBase, int rowOffset,
} }
// draw stack frame // draw stack frame
if(stackFrameBitfield == 0) if(stackFrameBitfield == 0)
return HexDump::paintContent(painter, rowBase, rowOffset, 1, x, y, w, h); return HexDump::paintContent(painter, row, 1, x, y, w, h);
else else
{ {
int height = getRowHeight(); int height = getRowHeight();
int halfHeight = height / 2; int halfHeight = height / 2;
int width = 5; int width = 5;
int offset = 2; int offset = 2;
auto result = HexDump::paintContent(painter, rowBase, rowOffset, 1, x + (width - 2), y, w - (width - 2), h); auto result = HexDump::paintContent(painter, row, 1, x + (width - 2), y, w - (width - 2), h);
if(party == mod_user) if(party == mod_user)
painter->setPen(QPen(mUserStackFrameColor, 2)); painter->setPen(QPen(mUserStackFrameColor, 2));
else else
@ -468,20 +469,20 @@ QString CPUStack::paintContent(QPainter* painter, dsint rowBase, int rowOffset,
} }
} }
else else
return HexDump::paintContent(painter, rowBase, rowOffset, 1, x, y, w, h); return HexDump::paintContent(painter, row, 1, x, y, w, h);
} }
else else
return HexDump::paintContent(painter, rowBase, rowOffset, 1, x, y, w, h); return HexDump::paintContent(painter, row, 1, x, y, w, h);
} }
else else
return HexDump::paintContent(painter, rowBase, rowOffset, col, x, y, w, h); return HexDump::paintContent(painter, row, col, x, y, w, h);
} }
void CPUStack::contextMenuEvent(QContextMenuEvent* event) void CPUStack::contextMenuEvent(QContextMenuEvent* event)
{ {
QMenu wMenu(this); //create context menu QMenu menu(this); //create context menu
mMenuBuilder->build(&wMenu); mMenuBuilder->build(&menu);
wMenu.exec(event->globalPos()); menu.exec(event->globalPos());
} }
void CPUStack::mouseDoubleClickEvent(QMouseEvent* event) void CPUStack::mouseDoubleClickEvent(QMouseEvent* event)
@ -493,12 +494,14 @@ void CPUStack::mouseDoubleClickEvent(QMouseEvent* event)
case 0: //address case 0: //address
{ {
//very ugly way to calculate the base of the current row (no clue why it works) //very ugly way to calculate the base of the current row (no clue why it works)
dsint deltaRowBase = getInitialSelection() % getBytePerRowCount() + mByteOffset; auto deltaRowBase = getInitialSelection() % getBytePerRowCount() + mByteOffset;
if(deltaRowBase >= getBytePerRowCount()) if(deltaRowBase >= getBytePerRowCount())
deltaRowBase -= getBytePerRowCount(); deltaRowBase -= getBytePerRowCount();
dsint mSelectedVa = rvaToVa(getInitialSelection() - deltaRowBase); dsint mSelectedVa = rvaToVa(getInitialSelection() - deltaRowBase);
if(mRvaDisplayEnabled && mSelectedVa == mRvaDisplayBase) if(mRvaDisplayEnabled && mSelectedVa == mRvaDisplayBase)
{
mRvaDisplayEnabled = false; mRvaDisplayEnabled = false;
}
else else
{ {
mRvaDisplayEnabled = true; mRvaDisplayEnabled = true;
@ -517,9 +520,9 @@ void CPUStack::mouseDoubleClickEvent(QMouseEvent* event)
default: default:
{ {
duint wVa = rvaToVa(getInitialSelection()); duint va = rvaToVa(getInitialSelection());
STACK_COMMENT comment; STACK_COMMENT comment;
if(DbgStackCommentGet(wVa, &comment) && strcmp(comment.color, "!rtnclr") == 0) if(DbgStackCommentGet(va, &comment) && strcmp(comment.color, "!rtnclr") == 0)
followDisasmSlot(); followDisasmSlot();
} }
break; break;
@ -600,7 +603,7 @@ void CPUStack::updateSlot()
} }
} }
void CPUStack::disasmSelectionChanged(dsint parVA) void CPUStack::disasmSelectionChanged(duint parVA)
{ {
// When the selected instruction is changed, select the argument that is in the stack. // When the selected instruction is changed, select the argument that is in the stack.
DISASM_INSTR instr; DISASM_INSTR instr;
@ -653,11 +656,11 @@ void CPUStack::gotoCbpSlot()
DbgCmdExec("sdump cbp"); DbgCmdExec("sdump cbp");
} }
int CPUStack::getCurrentFrame(const std::vector<CPUStack::CPUCallStack> & mCallstack, duint wVA) int CPUStack::getCurrentFrame(const std::vector<CPUStack::CPUCallStack> & mCallstack, duint va)
{ {
if(mCallstack.size()) if(mCallstack.size())
for(size_t i = 0; i < mCallstack.size() - 1; i++) for(size_t i = 0; i < mCallstack.size() - 1; i++)
if(wVA >= mCallstack[i].addr && wVA < mCallstack[i + 1].addr) if(va >= mCallstack[i].addr && va < mCallstack[i + 1].addr)
return int(i); return int(i);
return -1; return -1;
} }
@ -889,13 +892,13 @@ void CPUStack::undoSelectionSlot()
void CPUStack::modifySlot() void CPUStack::modifySlot()
{ {
dsint addr = getInitialSelection(); dsint addr = getInitialSelection();
WordEditDialog wEditDialog(this); WordEditDialog editDialog(this);
dsint value = 0; dsint value = 0;
mMemPage->read(&value, addr, sizeof(dsint)); mMemPage->read(&value, addr, sizeof(dsint));
wEditDialog.setup(tr("Modify"), value, sizeof(dsint)); editDialog.setup(tr("Modify"), value, sizeof(dsint));
if(wEditDialog.exec() != QDialog::Accepted) if(editDialog.exec() != QDialog::Accepted)
return; return;
value = wEditDialog.getVal(); value = editDialog.getVal();
mMemPage->write(&value, addr, sizeof(dsint)); mMemPage->write(&value, addr, sizeof(dsint));
GuiUpdateAllViews(); GuiUpdateAllViews();
} }

View File

@ -11,16 +11,16 @@ class CPUStack : public HexDump
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit CPUStack(CPUMultiDump* multiDump, QWidget* parent = 0); explicit CPUStack(CPUMultiDump* multiDump, QWidget* parent = nullptr);
// Configuration // Configuration
virtual void updateColors(); void updateColors() override;
virtual void updateFonts(); void updateFonts() override;
void getColumnRichText(int col, dsint rva, RichTextPainter::List & richText) override; void getColumnRichText(duint col, duint rva, RichTextPainter::List & richText) override;
QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) override; QString paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h) override;
void contextMenuEvent(QContextMenuEvent* event); void contextMenuEvent(QContextMenuEvent* event) override;
void mouseDoubleClickEvent(QMouseEvent* event); void mouseDoubleClickEvent(QMouseEvent* event) override;
void wheelEvent(QWheelEvent* event) override; void wheelEvent(QWheelEvent* event) override;
void setupContextMenu(); void setupContextMenu();
void updateFreezeStackAction(); void updateFreezeStackAction();
@ -52,7 +52,7 @@ public slots:
void realignSlot(); void realignSlot();
void freezeStackSlot(); void freezeStackSlot();
void dbgStateChangedSlot(DBGSTATE state); void dbgStateChangedSlot(DBGSTATE state);
void disasmSelectionChanged(dsint parVA); void disasmSelectionChanged(duint parVA);
void updateSlot(); void updateSlot();
void copyPtrColumnSlot(); void copyPtrColumnSlot();
void copyCommentsColumnSlot(); void copyCommentsColumnSlot();
@ -82,5 +82,5 @@ private:
CommonActions* mCommonActions; CommonActions* mCommonActions;
std::vector<CPUCallStack> mCallstack; std::vector<CPUCallStack> mCallstack;
static int CPUStack::getCurrentFrame(const std::vector<CPUStack::CPUCallStack> & mCallstack, duint wVA); static int CPUStack::getCurrentFrame(const std::vector<CPUStack::CPUCallStack> & mCallstack, duint va);
}; };

View File

@ -14,22 +14,25 @@
#include "Configuration.h" #include "Configuration.h"
#include "TabWidget.h" #include "TabWidget.h"
CPUWidget::CPUWidget(QWidget* parent) : QWidget(parent), ui(new Ui::CPUWidget) CPUWidget::CPUWidget(Architecture* architecture, QWidget* parent)
: QWidget(parent),
ui(new Ui::CPUWidget),
mArchitecture(architecture)
{ {
ui->setupUi(this); ui->setupUi(this);
setDefaultDisposition(); setDefaultDisposition();
setStyleSheet("AbstractTableView:focus, CPURegistersView:focus, CPUSideBar:focus { border: 1px solid #000000; }"); setStyleSheet("AbstractTableView:focus, CPURegistersView:focus, CPUSideBar:focus { border: 1px solid #000000; }");
mDisas = new CPUDisassembly(this, true); mDisassembly = new CPUDisassembly(architecture, true, this);
mSideBar = new CPUSideBar(mDisas); mSideBar = new CPUSideBar(mDisassembly);
mDisas->setSideBar(mSideBar); mDisassembly->setSideBar(mSideBar);
mArgumentWidget = new CPUArgumentWidget(this); mArgumentWidget = new CPUArgumentWidget(architecture, this);
mGraph = new DisassemblerGraphView(this); mGraph = new DisassemblerGraphView(architecture, this);
connect(mDisas, SIGNAL(tableOffsetChanged(dsint)), mSideBar, SLOT(changeTopmostAddress(dsint))); connect(mDisassembly, SIGNAL(tableOffsetChanged(duint)), mSideBar, SLOT(changeTopmostAddress(duint)));
connect(mDisas, SIGNAL(viewableRowsChanged(int)), mSideBar, SLOT(setViewableRows(int))); connect(mDisassembly, SIGNAL(viewableRowsChanged(duint)), mSideBar, SLOT(setViewableRows(duint)));
connect(mDisas, SIGNAL(selectionChanged(dsint)), mSideBar, SLOT(setSelection(dsint))); connect(mDisassembly, SIGNAL(selectionChanged(duint)), mSideBar, SLOT(setSelection(duint)));
connect(mGraph, SIGNAL(detachGraph()), this, SLOT(detachGraph())); connect(mGraph, SIGNAL(detachGraph()), this, SLOT(detachGraph()));
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), mSideBar, SLOT(debugStateChangedSlot(DBGSTATE))); connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), mSideBar, SLOT(debugStateChangedSlot(DBGSTATE)));
connect(Bridge::getBridge(), SIGNAL(updateSideBar()), mSideBar, SLOT(reload())); connect(Bridge::getBridge(), SIGNAL(updateSideBar()), mSideBar, SLOT(reload()));
@ -37,12 +40,12 @@ CPUWidget::CPUWidget(QWidget* parent) : QWidget(parent), ui(new Ui::CPUWidget)
connect(Bridge::getBridge(), SIGNAL(focusDisasm()), this, SLOT(setDisasmFocus())); connect(Bridge::getBridge(), SIGNAL(focusDisasm()), this, SLOT(setDisasmFocus()));
connect(Bridge::getBridge(), SIGNAL(focusGraph()), this, SLOT(setGraphFocus())); connect(Bridge::getBridge(), SIGNAL(focusGraph()), this, SLOT(setGraphFocus()));
mDisas->setCodeFoldingManager(mSideBar->getCodeFoldingManager()); mDisassembly->setCodeFoldingManager(mSideBar->getCodeFoldingManager());
ui->mTopLeftUpperHSplitter->setCollapsible(0, true); //allow collapsing of the side bar ui->mTopLeftUpperHSplitter->setCollapsible(0, true); //allow collapsing of the side bar
ui->mTopLeftUpperLeftFrameLayout->addWidget(mSideBar); ui->mTopLeftUpperLeftFrameLayout->addWidget(mSideBar);
ui->mTopLeftUpperRightFrameLayout->addWidget(mDisas); ui->mTopLeftUpperRightFrameLayout->addWidget(mDisassembly);
ui->mTopLeftUpperRightFrameLayout->addWidget(mGraph); ui->mTopLeftUpperRightFrameLayout->addWidget(mGraph);
mGraph->hide(); mGraph->hide();
disasMode = 0; disasMode = 0;
@ -51,14 +54,14 @@ CPUWidget::CPUWidget(QWidget* parent) : QWidget(parent), ui(new Ui::CPUWidget)
ui->mTopLeftVSplitter->setCollapsible(1, true); //allow collapsing of the InfoBox ui->mTopLeftVSplitter->setCollapsible(1, true); //allow collapsing of the InfoBox
connect(ui->mTopLeftVSplitter, SIGNAL(splitterMoved(int, int)), this, SLOT(splitterMoved(int, int))); connect(ui->mTopLeftVSplitter, SIGNAL(splitterMoved(int, int)), this, SLOT(splitterMoved(int, int)));
mInfo = new CPUInfoBox(); mInfo = new CPUInfoBox(architecture);
ui->mTopLeftLowerFrameLayout->addWidget(mInfo); ui->mTopLeftLowerFrameLayout->addWidget(mInfo);
int height = mInfo->getHeight(); int height = mInfo->getHeight();
ui->mTopLeftLowerFrame->setMinimumHeight(height + 2); ui->mTopLeftLowerFrame->setMinimumHeight(height + 2);
connect(mDisas, SIGNAL(selectionChanged(dsint)), mInfo, SLOT(disasmSelectionChanged(dsint))); connect(mDisassembly, SIGNAL(selectionChanged(duint)), mInfo, SLOT(disasmSelectionChanged(duint)));
mDump = new CPUMultiDump(mDisas, 5, this); //dump widget mDump = new CPUMultiDump(mDisassembly, 5, this); //dump widget
ui->mBotLeftFrameLayout->addWidget(mDump); ui->mBotLeftFrameLayout->addWidget(mDump);
mGeneralRegs = new CPURegistersView(this); mGeneralRegs = new CPURegistersView(this);
@ -85,9 +88,9 @@ CPUWidget::CPUWidget(QWidget* parent) : QWidget(parent), ui(new Ui::CPUWidget)
mStack = new CPUStack(mDump, 0); //stack widget mStack = new CPUStack(mDump, 0); //stack widget
ui->mBotRightFrameLayout->addWidget(mStack); ui->mBotRightFrameLayout->addWidget(mStack);
connect(mDisas, SIGNAL(selectionChanged(dsint)), mStack, SLOT(disasmSelectionChanged(dsint))); connect(mDisassembly, SIGNAL(selectionChanged(duint)), mStack, SLOT(disasmSelectionChanged(duint)));
mDisas->setAccessibleName(tr("Disassembly")); mDisassembly->setAccessibleName(tr("Disassembly"));
mStack->setAccessibleName(tr("Stack")); mStack->setAccessibleName(tr("Stack"));
upperScrollArea->setAccessibleName(tr("Registers")); upperScrollArea->setAccessibleName(tr("Registers"));
mDump->setAccessibleName(tr("Dump")); mDump->setAccessibleName(tr("Dump"));
@ -96,7 +99,7 @@ CPUWidget::CPUWidget(QWidget* parent) : QWidget(parent), ui(new Ui::CPUWidget)
mInfo->setAccessibleName(tr("InfoBox")); mInfo->setAccessibleName(tr("InfoBox"));
// load column config // load column config
mDisas->loadColumnFromConfig("CPUDisassembly"); mDisassembly->loadColumnFromConfig("CPUDisassembly");
mStack->loadColumnFromConfig("CPUStack"); mStack->loadColumnFromConfig("CPUStack");
} }
@ -146,6 +149,11 @@ CPUWidget::~CPUWidget()
delete ui; delete ui;
} }
Architecture* CPUWidget::getArchitecture() const
{
return mArchitecture;
}
void CPUWidget::setDefaultDisposition() void CPUWidget::setDefaultDisposition()
{ {
// This is magic, don't touch it... // This is magic, don't touch it...
@ -180,18 +188,18 @@ void CPUWidget::setDisasmFocus()
if(disasMode == 1) if(disasMode == 1)
{ {
mGraph->hide(); mGraph->hide();
mDisas->show(); mDisassembly->show();
mSideBar->show(); mSideBar->show();
ui->mTopLeftUpperHSplitter->restoreState(mDisasmSidebarSplitterStatus); ui->mTopLeftUpperHSplitter->restoreState(mDisasmSidebarSplitterStatus);
disasMode = 0; disasMode = 0;
connect(mDisas, SIGNAL(selectionChanged(dsint)), mInfo, SLOT(disasmSelectionChanged(dsint))); connect(mDisassembly, SIGNAL(selectionChanged(duint)), mInfo, SLOT(disasmSelectionChanged(duint)));
disconnect(mGraph, SIGNAL(selectionChanged(dsint)), mInfo, SLOT(disasmSelectionChanged(dsint))); disconnect(mGraph, SIGNAL(selectionChanged(duint)), mInfo, SLOT(disasmSelectionChanged(duint)));
} }
else if(disasMode == 2) else if(disasMode == 2)
{ {
activateWindow(); activateWindow();
} }
mDisas->setFocus(); mDisassembly->setFocus();
} }
void CPUWidget::setGraphFocus() void CPUWidget::setGraphFocus()
@ -199,14 +207,14 @@ void CPUWidget::setGraphFocus()
if(disasMode == 0) if(disasMode == 0)
{ {
mDisasmSidebarSplitterStatus = ui->mTopLeftUpperHSplitter->saveState(); mDisasmSidebarSplitterStatus = ui->mTopLeftUpperHSplitter->saveState();
mDisas->hide(); mDisassembly->hide();
mSideBar->hide(); mSideBar->hide();
mGraph->show(); mGraph->show();
// Hide the sidebar area // Hide the sidebar area
ui->mTopLeftUpperHSplitter->setSizes(QList<int>({0, 100})); ui->mTopLeftUpperHSplitter->setSizes(QList<int>({0, 100}));
disasMode = 1; disasMode = 1;
disconnect(mDisas, SIGNAL(selectionChanged(dsint)), mInfo, SLOT(disasmSelectionChanged(dsint))); disconnect(mDisassembly, SIGNAL(selectionChanged(duint)), mInfo, SLOT(disasmSelectionChanged(duint)));
connect(mGraph, SIGNAL(selectionChanged(dsint)), mInfo, SLOT(disasmSelectionChanged(dsint))); connect(mGraph, SIGNAL(selectionChanged(duint)), mInfo, SLOT(disasmSelectionChanged(duint)));
} }
else if(disasMode == 2) else if(disasMode == 2)
{ {
@ -250,12 +258,12 @@ void CPUWidget::detachGraph()
disasMode = 2; disasMode = 2;
mDisas->show(); mDisassembly->show();
mSideBar->show(); mSideBar->show();
// restore the sidebar splitter so that the sidebar is visible // restore the sidebar splitter so that the sidebar is visible
ui->mTopLeftUpperHSplitter->restoreState(mDisasmSidebarSplitterStatus); ui->mTopLeftUpperHSplitter->restoreState(mDisasmSidebarSplitterStatus);
connect(mDisas, SIGNAL(selectionChanged(dsint)), mInfo, SLOT(disasmSelectionChanged(dsint))); connect(mDisassembly, SIGNAL(selectionChanged(duint)), mInfo, SLOT(disasmSelectionChanged(duint)));
connect(mGraph, SIGNAL(selectionChanged(dsint)), mInfo, SLOT(disasmSelectionChanged(dsint))); connect(mGraph, SIGNAL(selectionChanged(duint)), mInfo, SLOT(disasmSelectionChanged(duint)));
} }
} }
@ -266,7 +274,7 @@ void CPUWidget::attachGraph(QWidget* widget)
ui->mTopLeftUpperRightFrameLayout->addWidget(mGraph); ui->mTopLeftUpperRightFrameLayout->addWidget(mGraph);
mGraph->hide(); mGraph->hide();
mGraphWindow->close(); mGraphWindow->close();
disconnect(mGraph, SIGNAL(selectionChanged(dsint)), mInfo, SLOT(disasmSelectionChanged(dsint))); disconnect(mGraph, SIGNAL(selectionChanged(duint)), mInfo, SLOT(disasmSelectionChanged(duint)));
delete mGraphWindow; delete mGraphWindow;
mGraphWindow = nullptr; mGraphWindow = nullptr;
disasMode = 0; disasMode = 0;
@ -276,9 +284,9 @@ void CPUWidget::attachGraph(QWidget* widget)
duint CPUWidget::getSelectionVa() duint CPUWidget::getSelectionVa()
{ {
if(disasMode < 2) if(disasMode < 2)
return disasMode == 0 ? mDisas->getSelectedVa() : mGraph->get_cursor_pos(); return disasMode == 0 ? mDisassembly->getSelectedVa() : mGraph->get_cursor_pos();
else else
return !mGraph->hasFocus() ? mDisas->getSelectedVa() : mGraph->get_cursor_pos(); return !mGraph->hasFocus() ? mDisassembly->getSelectedVa() : mGraph->get_cursor_pos();
} }
CPUSideBar* CPUWidget::getSidebarWidget() CPUSideBar* CPUWidget::getSidebarWidget()
@ -288,7 +296,7 @@ CPUSideBar* CPUWidget::getSidebarWidget()
CPUDisassembly* CPUWidget::getDisasmWidget() CPUDisassembly* CPUWidget::getDisasmWidget()
{ {
return mDisas; return mDisassembly;
} }
DisassemblerGraphView* CPUWidget::getGraphWidget() DisassemblerGraphView* CPUWidget::getGraphWidget()

View File

@ -24,8 +24,9 @@ class CPUWidget : public QWidget
Q_OBJECT Q_OBJECT
public: public:
explicit CPUWidget(QWidget* parent = 0); explicit CPUWidget(Architecture* architecture, QWidget* parent = nullptr);
~CPUWidget(); ~CPUWidget();
Architecture* getArchitecture() const;
// Misc // Misc
void setDefaultDisposition(); void setDefaultDisposition();
@ -49,7 +50,7 @@ public slots:
protected: protected:
CPUSideBar* mSideBar; CPUSideBar* mSideBar;
CPUDisassembly* mDisas; CPUDisassembly* mDisassembly;
DisassemblerGraphView* mGraph; DisassemblerGraphView* mGraph;
MHDetachedWindow* mGraphWindow; MHDetachedWindow* mGraphWindow;
CPUMultiDump* mDump; CPUMultiDump* mDump;
@ -61,6 +62,7 @@ protected:
int disasMode; int disasMode;
private: private:
Architecture* mArchitecture = nullptr;
Ui::CPUWidget* ui; Ui::CPUWidget* ui;
QByteArray mDisasmSidebarSplitterStatus; QByteArray mDisasmSidebarSplitterStatus;

View File

@ -29,7 +29,7 @@ class CalculatorDialog : public QDialog
QString inFormat(const duint val, CalculatorDialog::Format format) const; QString inFormat(const duint val, CalculatorDialog::Format format) const;
public: public:
explicit CalculatorDialog(QWidget* parent = 0); explicit CalculatorDialog(QWidget* parent = nullptr);
~CalculatorDialog(); ~CalculatorDialog();
void validateExpression(QString expression); void validateExpression(QString expression);
void setExpressionFocus(); void setExpressionFocus();

View File

@ -1,6 +1,7 @@
#include "CallStackView.h" #include "CallStackView.h"
#include "CommonActions.h" #include "CommonActions.h"
#include "Bridge.h" #include "Bridge.h"
#include "DisassemblyPopup.h"
CallStackView::CallStackView(StdTable* parent) : StdIconTable(parent) CallStackView::CallStackView(StdTable* parent) : StdIconTable(parent)
{ {
@ -21,6 +22,8 @@ CallStackView::CallStackView(StdTable* parent) : StdIconTable(parent)
connect(this, SIGNAL(doubleClickedSignal()), this, SLOT(followFrom())); connect(this, SIGNAL(doubleClickedSignal()), this, SLOT(followFrom()));
setupContextMenu(); setupContextMenu();
new DisassemblyPopup(this, Bridge::getArchitecture());
} }
void CallStackView::setupContextMenu() void CallStackView::setupContextMenu()
@ -53,16 +56,16 @@ void CallStackView::setupContextMenu()
// TODO: Is Label/Comment/Bookmark useful? // TODO: Is Label/Comment/Bookmark useful?
mCommonActions->build(mMenuBuilder, CommonActions::ActionBreakpoint); mCommonActions->build(mMenuBuilder, CommonActions::ActionBreakpoint);
mMenuBuilder->addSeparator(); mMenuBuilder->addSeparator();
QAction* wShowSuspectedCallStack = makeAction(tr("Show Suspected Call Stack Frame"), SLOT(showSuspectedCallStack())); QAction* showSuspectedCallStack = makeAction(tr("Show Suspected Call Stack Frame"), SLOT(showSuspectedCallStack()));
mMenuBuilder->addAction(wShowSuspectedCallStack, [wShowSuspectedCallStack](QMenu*) mMenuBuilder->addAction(showSuspectedCallStack, [showSuspectedCallStack](QMenu*)
{ {
duint i; duint i;
if(!BridgeSettingGetUint("Engine", "ShowSuspectedCallStack", &i)) if(!BridgeSettingGetUint("Engine", "ShowSuspectedCallStack", &i))
i = 0; i = 0;
if(i != 0) if(i != 0)
wShowSuspectedCallStack->setText(tr("Show Active Call Stack Frame")); showSuspectedCallStack->setText(tr("Show Active Call Stack Frame"));
else else
wShowSuspectedCallStack->setText(tr("Show Suspected Call Stack Frame")); showSuspectedCallStack->setText(tr("Show Suspected Call Stack Frame"));
return true; return true;
}); });
MenuBuilder* mCopyMenu = new MenuBuilder(this); MenuBuilder* mCopyMenu = new MenuBuilder(this);
@ -73,16 +76,16 @@ void CallStackView::setupContextMenu()
mMenuBuilder->loadFromConfig(); mMenuBuilder->loadFromConfig();
} }
QString CallStackView::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) QString CallStackView::paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h)
{ {
if(isSelected(rowBase, rowOffset)) if(isSelected(row))
painter->fillRect(QRect(x, y, w, h), QBrush(mSelectionColor)); painter->fillRect(QRect(x, y, w, h), QBrush(mSelectionColor));
bool isSpaceRow = !getCellContent(rowBase + rowOffset, ColThread).isEmpty(); bool isSpaceRow = !getCellContent(row, ColThread).isEmpty();
if(col == ColThread && !(rowBase + rowOffset)) if(col == ColThread && row == 0)
{ {
QString ret = getCellContent(rowBase + rowOffset, col); QString ret = getCellContent(row, col);
if(!ret.isEmpty()) if(!ret.isEmpty())
{ {
painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("ThreadCurrentBackgroundColor"))); painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("ThreadCurrentBackgroundColor")));
@ -98,8 +101,8 @@ QString CallStackView::paintContent(QPainter* painter, dsint rowBase, int rowOff
} }
else if(col == ColFrom || col == ColTo || col == ColAddress) else if(col == ColFrom || col == ColTo || col == ColAddress)
{ {
QString ret = getCellContent(rowBase + rowOffset, col); QString ret = getCellContent(row, col);
BPXTYPE bpxtype = DbgGetBpxTypeAt(getCellUserdata(rowBase + rowOffset, col)); BPXTYPE bpxtype = DbgGetBpxTypeAt(getCellUserdata(row, col));
if(bpxtype & bp_normal) if(bpxtype & bp_normal)
{ {
painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("DisassemblyBreakpointBackgroundColor"))); painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("DisassemblyBreakpointBackgroundColor")));
@ -115,7 +118,7 @@ QString CallStackView::paintContent(QPainter* painter, dsint rowBase, int rowOff
return ""; return "";
} }
} }
return StdIconTable::paintContent(painter, rowBase, rowOffset, col, x, y, w, h); return StdIconTable::paintContent(painter, row, col, x, y, w, h);
} }
void CallStackView::updateCallStack() void CallStackView::updateCallStack()
@ -196,10 +199,10 @@ void CallStackView::updateCallStack()
void CallStackView::contextMenuSlot(const QPoint pos) void CallStackView::contextMenuSlot(const QPoint pos)
{ {
QMenu wMenu(this); //create context menu QMenu menu(this); //create context menu
mMenuBuilder->build(&wMenu); mMenuBuilder->build(&menu);
if(!wMenu.isEmpty()) if(!menu.isEmpty())
wMenu.exec(mapToGlobal(pos)); //execute context menu menu.exec(mapToGlobal(pos)); //execute context menu
} }
void CallStackView::followAddress() void CallStackView::followAddress()

View File

@ -7,12 +7,12 @@ class CallStackView : public StdIconTable
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit CallStackView(StdTable* parent = 0); explicit CallStackView(StdTable* parent = nullptr);
void setupContextMenu(); void setupContextMenu();
duint getSelectionVa(); duint getSelectionVa();
protected: protected:
QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) override; QString paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h) override;
protected slots: protected slots:
void updateCallStack(); void updateCallStack();

View File

@ -14,7 +14,7 @@ class CloseDialog : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit CloseDialog(QWidget* parent = 0); explicit CloseDialog(QWidget* parent = nullptr);
~CloseDialog(); ~CloseDialog();
void closeEvent(QCloseEvent* event); void closeEvent(QCloseEvent* event);
void allowClose(); void allowClose();

View File

@ -12,7 +12,7 @@ class CodepageSelectionDialog : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit CodepageSelectionDialog(QWidget* parent = 0); explicit CodepageSelectionDialog(QWidget* parent = nullptr);
~CodepageSelectionDialog(); ~CodepageSelectionDialog();
QByteArray getSelectedCodepage(); QByteArray getSelectedCodepage();

View File

@ -10,7 +10,7 @@ ColumnReorderDialog::ColumnReorderDialog(AbstractTableView* parent) :
{ {
ui->setupUi(this); ui->setupUi(this);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint | Qt::MSWindowsFixedSizeDialogHint); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint | Qt::MSWindowsFixedSizeDialogHint);
for(int j = 0; j < parent->getColumnCount(); j++) for(duint j = 0; j < parent->getColumnCount(); j++)
{ {
int i = parent->mColumnOrder[j]; int i = parent->mColumnOrder[j];
if(parent->getColumnHidden(i)) if(parent->getColumnHidden(i))

View File

@ -14,7 +14,7 @@ class ColumnReorderDialog : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit ColumnReorderDialog(AbstractTableView* parent = 0); explicit ColumnReorderDialog(AbstractTableView* parent = nullptr);
~ColumnReorderDialog(); ~ColumnReorderDialog();
private slots: private slots:

View File

@ -12,7 +12,7 @@ class ComboBoxDialog : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit ComboBoxDialog(QWidget* parent = 0); explicit ComboBoxDialog(QWidget* parent = nullptr);
~ComboBoxDialog(); ~ComboBoxDialog();
bool bChecked; bool bChecked;
QString currentText(); QString currentText();

View File

@ -12,7 +12,7 @@ class CommandLineEdit : public HistoryLineEdit
Q_OBJECT Q_OBJECT
public: public:
explicit CommandLineEdit(QWidget* parent = 0); explicit CommandLineEdit(QWidget* parent = nullptr);
~CommandLineEdit(); ~CommandLineEdit();
void keyPressEvent(QKeyEvent* event); void keyPressEvent(QKeyEvent* event);

View File

@ -12,7 +12,7 @@ class CustomizeMenuDialog : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit CustomizeMenuDialog(QWidget* parent = 0); explicit CustomizeMenuDialog(QWidget* parent = nullptr);
~CustomizeMenuDialog(); ~CustomizeMenuDialog();
public slots: public slots:

View File

@ -10,7 +10,7 @@ class DebugStatusLabel : public QLabel
public: public:
Q_PROPERTY(QString state READ state NOTIFY stateChanged) Q_PROPERTY(QString state READ state NOTIFY stateChanged)
explicit DebugStatusLabel(QStatusBar* parent = 0); explicit DebugStatusLabel(QStatusBar* parent = nullptr);
QString state() const; QString state() const;
public slots: public slots:

View File

@ -1,7 +1,7 @@
#include "DisassemblerGraphView.h" #include "DisassemblerGraphView.h"
#include "MenuBuilder.h" #include "MenuBuilder.h"
#include "CachedFontMetrics.h" #include "CachedFontMetrics.h"
#include "QBeaEngine.h" #include "QZydis.h"
#include "GotoDialog.h" #include "GotoDialog.h"
#include "XrefBrowseDialog.h" #include "XrefBrowseDialog.h"
#include <vector> #include <vector>
@ -17,18 +17,12 @@
#include "MiscUtil.h" #include "MiscUtil.h"
#include <QMainWindow> #include <QMainWindow>
DisassemblerGraphView::DisassemblerGraphView(QWidget* parent) DisassemblerGraphView::DisassemblerGraphView(Architecture* architecture, QWidget* parent)
: QAbstractScrollArea(parent), : QAbstractScrollArea(parent),
mFontMetrics(nullptr), mArchitecture(architecture),
currentGraph(duint(0)), currentGraph(0),
disasm(ConfigUint("Disassembler", "MaxModuleSize")), disasm(ConfigUint("Disassembler", "MaxModuleSize"), architecture),
mCip(0), layoutType(LayoutType::Medium)
mGoto(nullptr),
syncOrigin(false),
forceCenter(false),
layoutType(LayoutType::Medium),
mHistoryLock(false),
mXrefDlg(nullptr)
{ {
this->status = "Loading..."; this->status = "Loading...";
@ -72,7 +66,7 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget* parent)
connect(Bridge::getBridge(), SIGNAL(graphAt(duint)), this, SLOT(graphAtSlot(duint))); connect(Bridge::getBridge(), SIGNAL(graphAt(duint)), this, SLOT(graphAtSlot(duint)));
connect(Bridge::getBridge(), SIGNAL(updateGraph()), this, SLOT(updateGraphSlot())); connect(Bridge::getBridge(), SIGNAL(updateGraph()), this, SLOT(updateGraphSlot()));
connect(Bridge::getBridge(), SIGNAL(selectionGraphGet(SELECTIONDATA*)), this, SLOT(selectionGetSlot(SELECTIONDATA*))); connect(Bridge::getBridge(), SIGNAL(selectionGraphGet(SELECTIONDATA*)), this, SLOT(selectionGetSlot(SELECTIONDATA*)));
connect(Bridge::getBridge(), SIGNAL(disassembleAt(dsint, dsint)), this, SLOT(disassembleAtSlot(dsint, dsint))); connect(Bridge::getBridge(), SIGNAL(disassembleAt(duint, duint)), this, SLOT(disassembleAtSlot(duint, duint)));
connect(Bridge::getBridge(), SIGNAL(getCurrentGraph(BridgeCFGraphList*)), this, SLOT(getCurrentGraphSlot(BridgeCFGraphList*))); connect(Bridge::getBridge(), SIGNAL(getCurrentGraph(BridgeCFGraphList*)), this, SLOT(getCurrentGraphSlot(BridgeCFGraphList*)));
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(dbgStateChangedSlot(DBGSTATE))); connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(dbgStateChangedSlot(DBGSTATE)));
@ -1026,14 +1020,14 @@ bool DisassemblerGraphView::getTokenForMouseEvent(QMouseEvent* event, ZydisToken
int row = int(blocky / this->charHeight); int row = int(blocky / this->charHeight);
//Check tokens to see if one was clicked //Check tokens to see if one was clicked
int selectedCodeRow = row - block.block.header_text.lines.size(); int selectedCodeRow = row - (int)block.block.header_text.lines.size();
if(selectedCodeRow < 0) if(selectedCodeRow < 0)
return false; // skip the header return false; // skip the header
int rowIndex = 0; int rowIndex = 0;
for(auto & instr : block.block.instrs) for(auto & instr : block.block.instrs)
{ {
int lineCount = instr.text.lines.size(); auto lineCount = (int)instr.text.lines.size();
if(rowIndex + lineCount > selectedCodeRow) if(rowIndex + lineCount > selectedCodeRow)
{ {
@ -1111,9 +1105,9 @@ void DisassemblerGraphView::mousePressEvent(QMouseEvent* event)
} }
else if(event->button() == Qt::RightButton) else if(event->button() == Qt::RightButton)
{ {
QMenu wMenu(this); QMenu menu(this);
mMenuBuilder->build(&wMenu); mMenuBuilder->build(&menu);
wMenu.exec(event->globalPos()); //execute context menu menu.exec(event->globalPos()); //execute context menu
} }
} }
else if(event->button() & (Qt::LeftButton | Qt::RightButton)) else if(event->button() & (Qt::LeftButton | Qt::RightButton))
@ -1182,9 +1176,9 @@ void DisassemblerGraphView::mousePressEvent(QMouseEvent* event)
if(overrideCtxMenu && !mHighlightToken.text.isEmpty()) if(overrideCtxMenu && !mHighlightToken.text.isEmpty())
{ {
// show the "copy highlighted token" context menu // show the "copy highlighted token" context menu
QMenu wMenu(this); QMenu menu(this);
mHighlightMenuBuilder->build(&wMenu); mHighlightMenuBuilder->build(&menu);
wMenu.exec(event->globalPos()); menu.exec(event->globalPos());
lastRightClickPosition.pos = {}; lastRightClickPosition.pos = {};
} }
else if(!overrideCtxMenu) else if(!overrideCtxMenu)
@ -2415,9 +2409,9 @@ void DisassemblerGraphView::setupContextMenu()
void DisassemblerGraphView::showContextMenu(QMouseEvent* event) void DisassemblerGraphView::showContextMenu(QMouseEvent* event)
{ {
QMenu wMenu(this); QMenu menu(this);
mMenuBuilder->build(&wMenu); mMenuBuilder->build(&menu);
wMenu.exec(event->globalPos()); menu.exec(event->globalPos());
lastRightClickPosition.pos = {}; lastRightClickPosition.pos = {};
} }
@ -2522,7 +2516,7 @@ void DisassemblerGraphView::selectionGetSlot(SELECTIONDATA* selection)
Bridge::getBridge()->setResult(BridgeResult::SelectionGet, 1); Bridge::getBridge()->setResult(BridgeResult::SelectionGet, 1);
} }
void DisassemblerGraphView::disassembleAtSlot(dsint va, dsint cip) void DisassemblerGraphView::disassembleAtSlot(duint va, duint cip)
{ {
Q_UNUSED(va); Q_UNUSED(va);
auto cipChanged = mCip != cip; auto cipChanged = mCip != cip;
@ -2596,17 +2590,17 @@ void DisassemblerGraphView::xrefSlot()
{ {
if(!DbgIsDebugging()) if(!DbgIsDebugging())
return; return;
duint wVA = this->get_cursor_pos(); duint va = this->get_cursor_pos();
if(!DbgMemIsValidReadPtr(wVA)) if(!DbgMemIsValidReadPtr(va))
return; return;
XREF_INFO mXrefInfo; XREF_INFO mXrefInfo;
DbgXrefGet(wVA, &mXrefInfo); DbgXrefGet(va, &mXrefInfo);
if(!mXrefInfo.refcount) if(!mXrefInfo.refcount)
return; return;
BridgeFree(mXrefInfo.references); BridgeFree(mXrefInfo.references);
if(!mXrefDlg) if(!mXrefDlg)
mXrefDlg = new XrefBrowseDialog(this); mXrefDlg = new XrefBrowseDialog(this);
mXrefDlg->setup(wVA, [](duint addr) mXrefDlg->setup(va, [](duint addr)
{ {
DbgCmdExec(QString("graph %1").arg(ToPtrString(addr))); DbgCmdExec(QString("graph %1").arg(ToPtrString(addr)));
}); });

View File

@ -14,7 +14,7 @@
#include <QMutex> #include <QMutex>
#include "Bridge.h" #include "Bridge.h"
#include "RichTextPainter.h" #include "RichTextPainter.h"
#include "QBeaEngine.h" #include "QZydis.h"
#include "ActionHelpers.h" #include "ActionHelpers.h"
#include "VaHistory.h" #include "VaHistory.h"
@ -206,7 +206,7 @@ public:
bool inBlock = false; bool inBlock = false;
}; };
DisassemblerGraphView(QWidget* parent = nullptr); DisassemblerGraphView(Architecture* architecture, QWidget* parent = nullptr);
~DisassemblerGraphView(); ~DisassemblerGraphView();
void resetGraph(); void resetGraph();
void initFont(); void initFont();
@ -273,7 +273,7 @@ public slots:
void selectionGetSlot(SELECTIONDATA* selection); void selectionGetSlot(SELECTIONDATA* selection);
void tokenizerConfigUpdatedSlot(); void tokenizerConfigUpdatedSlot();
void loadCurrentGraph(); void loadCurrentGraph();
void disassembleAtSlot(dsint va, dsint cip); void disassembleAtSlot(duint va, duint cip);
void gotoExpressionSlot(); void gotoExpressionSlot();
void gotoOriginSlot(); void gotoOriginSlot();
void gotoPreviousSlot(); void gotoPreviousSlot();
@ -294,6 +294,7 @@ public slots:
void enableHighlightingModeSlot(); void enableHighlightingModeSlot();
private: private:
Architecture* mArchitecture = nullptr;
bool graphZoomMode; bool graphZoomMode;
qreal zoomLevel; qreal zoomLevel;
qreal zoomLevelOld; qreal zoomLevelOld;
@ -329,23 +330,23 @@ private:
std::unordered_map<duint, DisassemblerBlock> blocks; std::unordered_map<duint, DisassemblerBlock> blocks;
std::vector<int> col_edge_x; std::vector<int> col_edge_x;
std::vector<int> row_edge_y; std::vector<int> row_edge_y;
CachedFontMetrics* mFontMetrics; CachedFontMetrics* mFontMetrics = nullptr;
MenuBuilder* mMenuBuilder; MenuBuilder* mMenuBuilder = nullptr;
CommonActions* mCommonActions; CommonActions* mCommonActions = nullptr;
QMenu* mPluginMenu; QMenu* mPluginMenu = nullptr;
bool drawOverview; bool drawOverview;
bool onlySummary; bool onlySummary;
bool syncOrigin; bool syncOrigin = false;
int overviewXOfs; int overviewXOfs;
int overviewYOfs; int overviewYOfs;
qreal overviewScale; qreal overviewScale;
duint mCip; duint mCip = 0;
bool forceCenter; bool forceCenter = false;
bool saveGraph; bool saveGraph;
bool mHistoryLock; //Don't add a history while going to previous/next bool mHistoryLock = false; //Don't add a history while going to previous/next
LayoutType layoutType; LayoutType layoutType;
MenuBuilder* mHighlightMenuBuilder; MenuBuilder* mHighlightMenuBuilder = nullptr;
ZydisTokenizer::SingleToken mHighlightToken; ZydisTokenizer::SingleToken mHighlightToken;
bool mHighlightingModeEnabled; bool mHighlightingModeEnabled;
bool mPermanentHighlightingMode; bool mPermanentHighlightingMode;
@ -386,9 +387,9 @@ private:
BridgeCFGraph currentGraph; BridgeCFGraph currentGraph;
std::unordered_map<duint, duint> currentBlockMap; std::unordered_map<duint, duint> currentBlockMap;
QBeaEngine disasm; QZydis disasm;
GotoDialog* mGoto; GotoDialog* mGoto = nullptr;
XrefBrowseDialog* mXrefDlg; XrefBrowseDialog* mXrefDlg = nullptr;
void addReferenceAction(QMenu* menu, duint addr, const QString & description); void addReferenceAction(QMenu* menu, duint addr, const QString & description);
bool getHighlightedTokenValueText(QString & text); bool getHighlightedTokenValueText(QString & text);

View File

@ -5,14 +5,19 @@
#include "MiscUtil.h" #include "MiscUtil.h"
#include <QPainter> #include <QPainter>
#include <QStyleOptionFrame> #include <QStyleOptionFrame>
#include "Bridge.h"
DisassemblyPopup::DisassemblyPopup(QWidget* parent) : DisassemblyPopup::DisassemblyPopup(AbstractTableView* parent, Architecture* architecture) :
QFrame(parent, Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::WindowDoesNotAcceptFocus), QFrame(parent, Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::WindowDoesNotAcceptFocus),
mFontMetrics(nullptr), mFontMetrics(nullptr),
mDisasm(ConfigUint("Disassembler", "MaxModuleSize")) mDisasm(ConfigUint("Disassembler", "MaxModuleSize"), architecture),
mParent(parent)
{ {
addr = 0; parent->installEventFilter(this);
addrText = nullptr; parent->setMouseTracking(true);
connect(parent->verticalScrollBar(), SIGNAL(actionTriggered(int)), this, SLOT(hide()));
connect(parent->horizontalScrollBar(), SIGNAL(actionTriggered(int)), this, SLOT(hide()));
connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(updateFont())); connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(updateFont()));
connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(updateColors())); connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(updateColors()));
connect(Config(), SIGNAL(tokenizerConfigUpdated()), this, SLOT(tokenizerConfigUpdated())); connect(Config(), SIGNAL(tokenizerConfigUpdated()), this, SLOT(tokenizerConfigUpdated()));
@ -20,22 +25,18 @@ DisassemblyPopup::DisassemblyPopup(QWidget* parent) :
updateColors(); updateColors();
setFrameStyle(QFrame::Panel); setFrameStyle(QFrame::Panel);
setLineWidth(2); setLineWidth(2);
mMaxInstructions = 20;
} }
void DisassemblyPopup::updateColors() void DisassemblyPopup::updateColors()
{ {
disassemblyBackgroundColor = ConfigColor("DisassemblyBackgroundColor"); mDisassemblyBackgroundColor = ConfigColor("DisassemblyBackgroundColor");
disassemblyTracedColor = ConfigColor("DisassemblyTracedBackgroundColor"); mDisassemblyTracedColor = ConfigColor("DisassemblyTracedBackgroundColor");
labelColor = ConfigColor("DisassemblyLabelColor"); mLabelColor = ConfigColor("DisassemblyLabelColor");
labelBackgroundColor = ConfigColor("DisassemblyLabelBackgroundColor"); mLabelBackgroundColor = ConfigColor("DisassemblyLabelBackgroundColor");
commentColor = ConfigColor("DisassemblyCommentColor"); mCommentColor = ConfigColor("DisassemblyCommentColor");
commentBackgroundColor = ConfigColor("DisassemblyCommentBackgroundColor"); mCommentBackgroundColor = ConfigColor("DisassemblyCommentBackgroundColor");
commentAutoColor = ConfigColor("DisassemblyAutoCommentColor"); mCommentAutoColor = ConfigColor("DisassemblyAutoCommentColor");
commentAutoBackgroundColor = ConfigColor("DisassemblyAutoCommentBackgroundColor"); mCommentAutoBackgroundColor = ConfigColor("DisassemblyAutoCommentBackgroundColor");
QPalette palette;
palette.setColor(QPalette::Foreground, ConfigColor("AbstractTableViewSeparatorColor"));
setPalette(palette);
} }
void DisassemblyPopup::tokenizerConfigUpdated() void DisassemblyPopup::tokenizerConfigUpdated()
@ -50,8 +51,8 @@ void DisassemblyPopup::updateFont()
QFontMetricsF metrics(font()); QFontMetricsF metrics(font());
mFontMetrics = new CachedFontMetrics(this, font()); mFontMetrics = new CachedFontMetrics(this, font());
// Update font size, used in layout calculations. // Update font size, used in layout calculations.
charWidth = mFontMetrics->width('W'); mCharWidth = mFontMetrics->width('W');
charHeight = metrics.height(); mCharHeight = metrics.height();
} }
void DisassemblyPopup::paintEvent(QPaintEvent* event) void DisassemblyPopup::paintEvent(QPaintEvent* event)
@ -61,29 +62,29 @@ void DisassemblyPopup::paintEvent(QPaintEvent* event)
p.setFont(font()); p.setFont(font());
// Render background // Render background
p.fillRect(viewportRect, disassemblyBackgroundColor); p.fillRect(viewportRect, mDisassemblyBackgroundColor);
// Draw Address // Draw Address
p.setPen(QPen(labelColor)); p.setPen(QPen(mLabelColor));
int addrWidth = mFontMetrics->width(addrText); int addrWidth = mFontMetrics->width(mAddrText);
p.fillRect(3, 2 + lineWidth(), addrWidth, charHeight, QBrush(labelBackgroundColor)); p.fillRect(3, 2 + lineWidth(), addrWidth, mCharHeight, QBrush(mLabelBackgroundColor));
p.drawText(3, 2, addrWidth, charHeight, 0, addrText); p.drawText(3, 2, addrWidth, mCharHeight, 0, mAddrText);
// Draw Comments // Draw Comments
if(!addrComment.isEmpty()) if(!mAddrComment.isEmpty())
{ {
int commentWidth = mFontMetrics->width(addrComment); int commentWidth = mFontMetrics->width(mAddrComment);
QBrush background = QBrush(addrCommentAuto ? commentAutoBackgroundColor : commentBackgroundColor); QBrush background = QBrush(mAddrCommentAuto ? mCommentAutoBackgroundColor : mCommentBackgroundColor);
p.setPen(addrCommentAuto ? commentAutoColor : commentColor); p.setPen(mAddrCommentAuto ? mCommentAutoColor : mCommentColor);
p.fillRect(3 + addrWidth, 2, commentWidth, charHeight, background); p.fillRect(3 + addrWidth, 2, commentWidth, mCharHeight, background);
p.drawText(3 + addrWidth, 2, commentWidth, charHeight, 0, addrComment); p.drawText(3 + addrWidth, 2, commentWidth, mCharHeight, 0, mAddrComment);
} }
// Draw Instructions // Draw Instructions
int y = charHeight + 1; int y = mCharHeight + 1;
for(auto & instruction : mDisassemblyToken) for(auto & instruction : mDisassemblyToken)
{ {
if(instruction.second) if(instruction.second)
p.fillRect(QRect(3, y, mWidth - 3, charHeight), disassemblyTracedColor); p.fillRect(QRect(3, y, mWidth - 3, mCharHeight), mDisassemblyTracedColor);
RichTextPainter::paintRichText(&p, 3, y, mWidth - 3, charHeight, 0, instruction.first, mFontMetrics); RichTextPainter::paintRichText(&p, 3, y, mWidth - 3, mCharHeight, 0, instruction.first, mFontMetrics);
y += charHeight; y += mCharHeight;
} }
// The code above will destroy the stylesheet adjustments, making it impossible to change the border color. // The code above will destroy the stylesheet adjustments, making it impossible to change the border color.
@ -95,16 +96,92 @@ void DisassemblyPopup::paintEvent(QPaintEvent* event)
QFrame::paintEvent(event); QFrame::paintEvent(event);
} }
void DisassemblyPopup::setAddress(duint Address) bool DisassemblyPopup::eventFilter(QObject* object, QEvent* event)
{ {
addr = Address; if(object == parent())
{
switch(event->type())
{
case QEvent::Leave:
case QEvent::Hide:
case QEvent::KeyPress:
{
hide();
stopPopupTimer();
}
break;
case QEvent::MouseMove:
{
auto mouseEvent = (QMouseEvent*)event;
auto x = mouseEvent->x();
auto y = mouseEvent->y();
// TODO: make sure the cursor isn't on the column separators
if(y > mParent->getHeaderHeight())
{
// Show the popup if relevant for the current position
auto addr = mParent->getAddressForPosition(x, y);
if(getAddress() != addr)
{
if(DbgFunctions()->MemIsCodePage(addr, false))
{
move(mParent->mapToGlobal(QPoint(x + 20, y + fontMetrics().height() * 2)));
setAddress(addr);
if(mPopupTimer == 0)
mPopupTimer = startTimer(QApplication::startDragTime());
}
else
{
hide();
stopPopupTimer();
}
}
}
}
break;
default:
break;
}
}
return QFrame::eventFilter(object, event);
}
void DisassemblyPopup::timerEvent(QTimerEvent* event)
{
if(event->timerId() == mPopupTimer)
{
// Show the popup
show();
stopPopupTimer();
}
QFrame::timerEvent(event);
}
void DisassemblyPopup::stopPopupTimer()
{
if(mPopupTimer != 0)
{
killTimer(mPopupTimer);
mPopupTimer = 0;
}
}
void DisassemblyPopup::setAddress(duint addr)
{
mAddr = addr;
QList<Instruction_t> instBuffer; QList<Instruction_t> instBuffer;
mDisassemblyToken.clear(); mDisassemblyToken.clear();
if(addr != 0) mDisasm.UpdateArchitecture();
if(mAddr != 0)
{ {
mWidth = 1; mWidth = 1;
// Get RVA // Get RVA
auto addr = Address;
duint size; duint size;
duint base = DbgMemFindBaseAddr(addr, &size); duint base = DbgMemFindBaseAddr(addr, &size);
// Prepare RVA of every instruction // Prepare RVA of every instruction
@ -113,7 +190,7 @@ void DisassemblyPopup::setAddress(duint Address)
auto nextAddr = addr; auto nextAddr = addr;
bool hadBranch = false; bool hadBranch = false;
duint bestBranch = 0; duint bestBranch = 0;
byte data[64]; uint8_t data[64];
do do
{ {
if(nextAddr >= base + size) if(nextAddr >= base + size)
@ -160,27 +237,27 @@ void DisassemblyPopup::setAddress(duint Address)
mDisassemblyToken.push_back(std::make_pair(std::move(richText), DbgFunctions()->GetTraceRecordHitCount(instruction.rva) != 0)); mDisassemblyToken.push_back(std::make_pair(std::move(richText), DbgFunctions()->GetTraceRecordHitCount(instruction.rva) != 0));
} }
// Address // Address
addrText = getSymbolicName(addr); mAddrText = getSymbolicName(addr);
// Comments // Comments
GetCommentFormat(addr, addrComment, &addrCommentAuto); GetCommentFormat(addr, mAddrComment, &mAddrCommentAuto);
if(addrComment.length()) if(mAddrComment.length())
addrText.append(' '); mAddrText.append(' ');
// Calculate width of address // Calculate width of address
mWidth = std::max(mWidth, mFontMetrics->width(addrText) + mFontMetrics->width(addrComment)); mWidth = std::max(mWidth, mFontMetrics->width(mAddrText) + mFontMetrics->width(mAddrComment));
mWidth += charWidth * 6; mWidth += mCharWidth * 6;
// Resize popup // Resize popup
resize(mWidth + 2, charHeight * int(mDisassemblyToken.size() + 1) + 2); resize(mWidth + 2, mCharHeight * int(mDisassemblyToken.size() + 1) + 2);
} }
update(); update();
} }
duint DisassemblyPopup::getAddress() duint DisassemblyPopup::getAddress() const
{ {
return addr; return mAddr;
} }
void DisassemblyPopup::hide() void DisassemblyPopup::hide()
{ {
addr = 0; mAddr = 0;
QFrame::hide(); QFrame::hide();
} }

View File

@ -2,7 +2,9 @@
#include <QFrame> #include <QFrame>
#include "Imports.h" #include "Imports.h"
#include "QBeaEngine.h" #include "QZydis.h"
#include "AbstractTableView.h"
#include "StdSearchListView.h"
class CachedFontMetrics; class CachedFontMetrics;
@ -10,10 +12,9 @@ class DisassemblyPopup : public QFrame
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit DisassemblyPopup(QWidget* parent); DisassemblyPopup(AbstractTableView* parent, Architecture* architecture);
void paintEvent(QPaintEvent* event);
void setAddress(duint Address); void setAddress(duint Address);
duint getAddress(); duint getAddress() const;
public slots: public slots:
void hide(); void hide();
@ -22,25 +23,32 @@ public slots:
void tokenizerConfigUpdated(); void tokenizerConfigUpdated();
protected: protected:
CachedFontMetrics* mFontMetrics; void paintEvent(QPaintEvent* event) override;
duint addr; bool eventFilter(QObject* object, QEvent* event) override;
QString addrText; void timerEvent(QTimerEvent* event) override;
QString addrComment; void stopPopupTimer();
bool addrCommentAuto;
int charWidth;
int charHeight;
int mWidth;
unsigned int mMaxInstructions;
QColor disassemblyBackgroundColor; CachedFontMetrics* mFontMetrics = nullptr;
QColor disassemblyTracedColor; duint mAddr = 0;
QColor labelColor; QString mAddrText;
QColor labelBackgroundColor; QString mAddrComment;
QColor commentColor; bool mAddrCommentAuto = false;
QColor commentBackgroundColor; int mCharWidth = 0;
QColor commentAutoColor; int mCharHeight = 0;
QColor commentAutoBackgroundColor; int mWidth = 0;
QBeaEngine mDisasm; int mPopupTimer = 0;
unsigned int mMaxInstructions = 20;
QColor mDisassemblyBackgroundColor;
QColor mDisassemblyTracedColor;
QColor mLabelColor;
QColor mLabelBackgroundColor;
QColor mCommentColor;
QColor mCommentBackgroundColor;
QColor mCommentAutoColor;
QColor mCommentAutoBackgroundColor;
QZydis mDisasm;
AbstractTableView* mParent = nullptr;
std::vector<std::pair<RichTextPainter::List, bool>> mDisassemblyToken; std::vector<std::pair<RichTextPainter::List, bool>> mDisassemblyToken;
}; };

View File

@ -16,7 +16,7 @@ class EditFloatRegister : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit EditFloatRegister(int RegisterSize, QWidget* parent = 0); explicit EditFloatRegister(int RegisterSize, QWidget* parent = nullptr);
void loadData(const char* RegisterData); void loadData(const char* RegisterData);
const char* getData() const; const char* getData() const;
void selectAllText(); void selectAllText();

Some files were not shown because too many files have changed in this diff Show More