DBG+BRIDGE+GUI: highlight indirect calls in the graph + fixed shadow in certain situations
This commit is contained in:
parent
62b8e4fe11
commit
fe4db70717
|
@ -17,6 +17,7 @@ typedef struct
|
|||
duint icount; //number of instructions in node
|
||||
bool terminal; //node is a RET
|
||||
bool split; //node is a split (brtrue points to the next node)
|
||||
bool indirectcall; //node contains indirect calls (call reg, call [reg+X])
|
||||
void* userdata; //user data
|
||||
ListInfo exits; //exits (including brtrue and brfalse, duint)
|
||||
ListInfo instrs; //block instructions
|
||||
|
@ -47,6 +48,7 @@ struct BridgeCFNode
|
|||
duint icount; //number of instructions in node
|
||||
bool terminal; //node is a RET
|
||||
bool split; //node is a split (brtrue points to the next node)
|
||||
bool indirectcall; //node contains indirect calls (call reg, call [reg+X])
|
||||
void* userdata; //user data
|
||||
std::vector<duint> exits; //exits (including brtrue and brfalse)
|
||||
std::vector<BridgeCFInstruction> instrs; //block instructions
|
||||
|
@ -70,6 +72,7 @@ struct BridgeCFNode
|
|||
brfalse = nodeList->brfalse;
|
||||
icount = nodeList->icount;
|
||||
terminal = nodeList->terminal;
|
||||
indirectcall = nodeList->indirectcall;
|
||||
split = nodeList->split;
|
||||
userdata = nodeList->userdata;
|
||||
if(!BridgeList<duint>::ToVector(&nodeList->exits, exits, freedata))
|
||||
|
@ -86,6 +89,7 @@ struct BridgeCFNode
|
|||
brfalse(0),
|
||||
icount(0),
|
||||
terminal(false),
|
||||
indirectcall(false),
|
||||
split(false),
|
||||
userdata(nullptr)
|
||||
{
|
||||
|
@ -114,6 +118,7 @@ struct BridgeCFNode
|
|||
out.brfalse = brfalse;
|
||||
out.icount = icount;
|
||||
out.terminal = terminal;
|
||||
out.indirectcall = indirectcall;
|
||||
out.split = split;
|
||||
out.userdata = userdata;
|
||||
BridgeList<duint>::CopyData(&out.exits, exits);
|
||||
|
|
|
@ -138,11 +138,11 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
|
|||
|
||||
break;
|
||||
}
|
||||
if(mCp.InGroup(CS_GRP_CALL)) //call
|
||||
if(mCp.InGroup(CS_GRP_CALL)) //call
|
||||
{
|
||||
//TODO: add this to a queue to be analyzed later
|
||||
}
|
||||
if(mCp.InGroup(CS_GRP_RET)) //return
|
||||
if(mCp.InGroup(CS_GRP_RET)) //return
|
||||
{
|
||||
node.terminal = true;
|
||||
graph.AddNode(node);
|
||||
|
@ -191,9 +191,25 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
|
|||
continue;
|
||||
node.instrs.reserve(node.icount);
|
||||
auto addr = node.start;
|
||||
while(addr <= node.end)
|
||||
while(addr <= node.end) //disassemble all instructions
|
||||
{
|
||||
auto size = mCp.Disassemble(addr, translateAddr(addr)) ? mCp.Size() : 1;
|
||||
if(mCp.InGroup(CS_GRP_CALL) && mCp.OpCount()) //call reg / call [reg+X]
|
||||
{
|
||||
auto & op = mCp[0];
|
||||
switch(op.type)
|
||||
{
|
||||
case X86_OP_REG:
|
||||
node.indirectcall = true;
|
||||
break;
|
||||
case X86_OP_MEM:
|
||||
node.indirectcall |= op.mem.base != X86_REG_RIP &&
|
||||
(op.mem.base != X86_REG_INVALID || op.mem.index != X86_REG_INVALID);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
BridgeCFInstruction instr;
|
||||
instr.addr = addr;
|
||||
for(int i = 0; i < size; i++)
|
||||
|
|
|
@ -550,6 +550,7 @@ void AppearanceDialog::colorInfoListInit()
|
|||
colorInfoListAppend(tr("Background"), "GraphBackgroundColor", "");
|
||||
colorInfoListAppend(tr("Node"), "GraphNodeColor", "GraphNodeBackgroundColor");
|
||||
colorInfoListAppend(tr("Terminal node shadow"), "GraphRetShadowColor", "");
|
||||
colorInfoListAppend(tr("Indirect call shadow"), "GraphIndirectcallShadowColor", "");
|
||||
colorInfoListAppend(tr("Unconditional branch line"), "GraphJmpColor", "");
|
||||
colorInfoListAppend(tr("True branch line"), "GraphBrtrueColor", "");
|
||||
colorInfoListAppend(tr("False branch line"), "GraphBrfalseColor", "");
|
||||
|
|
|
@ -192,6 +192,8 @@ void DisassemblerGraphView::paintNormal(QPainter & p, QRect & viewportRect, int
|
|||
p.setPen(QColor(0, 0, 0, 0));
|
||||
if(block.block.terminal)
|
||||
p.setBrush(retShadowColor);
|
||||
else if(block.block.indirectcall)
|
||||
p.setBrush(indirectcallShadowColor);
|
||||
else
|
||||
p.setBrush(QColor(0, 0, 0, 128));
|
||||
p.drawRect(block.x + this->charWidth + 4, block.y + this->charWidth + 4,
|
||||
|
@ -199,7 +201,7 @@ void DisassemblerGraphView::paintNormal(QPainter & p, QRect & viewportRect, int
|
|||
|
||||
//Render node background
|
||||
p.setPen(graphNodeColor);
|
||||
p.setBrush(QBrush(disassemblyBackgroundColor));
|
||||
p.setBrush(disassemblyBackgroundColor);
|
||||
p.drawRect(block.x + this->charWidth, block.y + this->charWidth,
|
||||
block.width - (4 + 2 * this->charWidth), block.height - (4 + 2 * this->charWidth));
|
||||
|
||||
|
@ -340,9 +342,11 @@ void DisassemblerGraphView::paintOverview(QPainter & p, QRect & viewportRect, in
|
|||
|
||||
//Render shadow
|
||||
p.setPen(QColor(0, 0, 0, 0));
|
||||
if(traceCount && block.block.terminal)
|
||||
if((isCip || traceCount) && block.block.terminal)
|
||||
p.setBrush(retShadowColor);
|
||||
else if(block.block.terminal || isCip)
|
||||
else if((isCip || traceCount) && block.block.indirectcall)
|
||||
p.setBrush(indirectcallShadowColor);
|
||||
else if(isCip)
|
||||
p.setBrush(QColor(0, 0, 0, 0));
|
||||
else
|
||||
p.setBrush(QColor(0, 0, 0, 128));
|
||||
|
@ -353,7 +357,7 @@ void DisassemblerGraphView::paintOverview(QPainter & p, QRect & viewportRect, in
|
|||
pen.setColor(graphNodeColor);
|
||||
p.setPen(pen);
|
||||
if(isCip)
|
||||
p.setBrush(QBrush(mCipBackgroundColor));
|
||||
p.setBrush(mCipBackgroundColor);
|
||||
else if(traceCount)
|
||||
{
|
||||
// Color depending on how often a sequence of code is executed
|
||||
|
@ -366,14 +370,16 @@ void DisassemblerGraphView::paintOverview(QPainter & p, QRect & viewportRect, in
|
|||
if(disassemblyTracedColor.blue() > 160)
|
||||
colorDiff *= -1;
|
||||
|
||||
p.setBrush(QBrush(QColor(disassemblyTracedColor.red(),
|
||||
disassemblyTracedColor.green(),
|
||||
std::max(0, std::min(256, disassemblyTracedColor.blue() + colorDiff)))));
|
||||
p.setBrush(QColor(disassemblyTracedColor.red(),
|
||||
disassemblyTracedColor.green(),
|
||||
std::max(0, std::min(256, disassemblyTracedColor.blue() + colorDiff))));
|
||||
}
|
||||
else if(block.block.terminal)
|
||||
p.setBrush(QBrush(retShadowColor));
|
||||
p.setBrush(retShadowColor);
|
||||
else if(block.block.indirectcall)
|
||||
p.setBrush(indirectcallShadowColor);
|
||||
else
|
||||
p.setBrush(QBrush(disassemblyBackgroundColor));
|
||||
p.setBrush(disassemblyBackgroundColor);
|
||||
p.drawRect(block.x + this->charWidth, block.y + this->charWidth,
|
||||
block.width - (4 + 2 * this->charWidth), block.height - (4 + 2 * this->charWidth));
|
||||
}
|
||||
|
@ -400,7 +406,7 @@ void DisassemblerGraphView::paintEvent(QPaintEvent* event)
|
|||
|
||||
//Render background
|
||||
QRect viewportRect(this->viewport()->rect().topLeft(), this->viewport()->rect().bottomRight() - QPoint(1, 1));
|
||||
p.setBrush(QBrush(backgroundColor));
|
||||
p.setBrush(backgroundColor);
|
||||
p.drawRect(viewportRect);
|
||||
p.setBrush(Qt::black);
|
||||
|
||||
|
@ -1498,6 +1504,7 @@ void DisassemblerGraphView::loadCurrentGraph()
|
|||
block.false_path = node.brfalse;
|
||||
block.true_path = node.brtrue;
|
||||
block.terminal = node.terminal;
|
||||
block.indirectcall = node.indirectcall;
|
||||
block.header_text = Text(getSymbolicName(block.entry), mLabelColor, mLabelBackgroundColor);
|
||||
{
|
||||
Instr instr;
|
||||
|
@ -1676,6 +1683,7 @@ void DisassemblerGraphView::colorsUpdatedSlot()
|
|||
brtrueColor = ConfigColor("GraphBrtrueColor");
|
||||
brfalseColor = ConfigColor("GraphBrfalseColor");
|
||||
retShadowColor = ConfigColor("GraphRetShadowColor");
|
||||
indirectcallShadowColor = ConfigColor("GraphIndirectcallShadowColor");
|
||||
backgroundColor = ConfigColor("GraphBackgroundColor");
|
||||
if(!backgroundColor.alpha())
|
||||
backgroundColor = disassemblySelectionColor;
|
||||
|
|
|
@ -143,6 +143,7 @@ public:
|
|||
duint true_path = 0;
|
||||
duint false_path = 0;
|
||||
bool terminal = false;
|
||||
bool indirectcall = false;
|
||||
};
|
||||
|
||||
struct DisassemblerBlock
|
||||
|
@ -320,6 +321,7 @@ private:
|
|||
QColor brtrueColor;
|
||||
QColor brfalseColor;
|
||||
QColor retShadowColor;
|
||||
QColor indirectcallShadowColor;
|
||||
QColor backgroundColor;
|
||||
QColor mAutoCommentColor;
|
||||
QColor mAutoCommentBackgroundColor;
|
||||
|
|
|
@ -204,6 +204,7 @@ Configuration::Configuration() : QObject(), noMoreMsgbox(false)
|
|||
defaultColors.insert("GraphBrtrueColor", QColor("#387804"));
|
||||
defaultColors.insert("GraphBrfalseColor", QColor("#ED4630"));
|
||||
defaultColors.insert("GraphRetShadowColor", QColor("#900000"));
|
||||
defaultColors.insert("GraphIndirectcallShadowColor", QColor("#008080"));
|
||||
defaultColors.insert("GraphBackgroundColor", Qt::transparent);
|
||||
defaultColors.insert("GraphNodeColor", QColor("#000000"));
|
||||
defaultColors.insert("GraphNodeBackgroundColor", Qt::transparent);
|
||||
|
|
Loading…
Reference in New Issue