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
|
duint icount; //number of instructions in node
|
||||||
bool terminal; //node is a RET
|
bool terminal; //node is a RET
|
||||||
bool split; //node is a split (brtrue points to the next node)
|
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
|
void* userdata; //user data
|
||||||
ListInfo exits; //exits (including brtrue and brfalse, duint)
|
ListInfo exits; //exits (including brtrue and brfalse, duint)
|
||||||
ListInfo instrs; //block instructions
|
ListInfo instrs; //block instructions
|
||||||
|
@ -47,6 +48,7 @@ struct BridgeCFNode
|
||||||
duint icount; //number of instructions in node
|
duint icount; //number of instructions in node
|
||||||
bool terminal; //node is a RET
|
bool terminal; //node is a RET
|
||||||
bool split; //node is a split (brtrue points to the next node)
|
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
|
void* userdata; //user data
|
||||||
std::vector<duint> exits; //exits (including brtrue and brfalse)
|
std::vector<duint> exits; //exits (including brtrue and brfalse)
|
||||||
std::vector<BridgeCFInstruction> instrs; //block instructions
|
std::vector<BridgeCFInstruction> instrs; //block instructions
|
||||||
|
@ -70,6 +72,7 @@ struct BridgeCFNode
|
||||||
brfalse = nodeList->brfalse;
|
brfalse = nodeList->brfalse;
|
||||||
icount = nodeList->icount;
|
icount = nodeList->icount;
|
||||||
terminal = nodeList->terminal;
|
terminal = nodeList->terminal;
|
||||||
|
indirectcall = nodeList->indirectcall;
|
||||||
split = nodeList->split;
|
split = nodeList->split;
|
||||||
userdata = nodeList->userdata;
|
userdata = nodeList->userdata;
|
||||||
if(!BridgeList<duint>::ToVector(&nodeList->exits, exits, freedata))
|
if(!BridgeList<duint>::ToVector(&nodeList->exits, exits, freedata))
|
||||||
|
@ -86,6 +89,7 @@ struct BridgeCFNode
|
||||||
brfalse(0),
|
brfalse(0),
|
||||||
icount(0),
|
icount(0),
|
||||||
terminal(false),
|
terminal(false),
|
||||||
|
indirectcall(false),
|
||||||
split(false),
|
split(false),
|
||||||
userdata(nullptr)
|
userdata(nullptr)
|
||||||
{
|
{
|
||||||
|
@ -114,6 +118,7 @@ struct BridgeCFNode
|
||||||
out.brfalse = brfalse;
|
out.brfalse = brfalse;
|
||||||
out.icount = icount;
|
out.icount = icount;
|
||||||
out.terminal = terminal;
|
out.terminal = terminal;
|
||||||
|
out.indirectcall = indirectcall;
|
||||||
out.split = split;
|
out.split = split;
|
||||||
out.userdata = userdata;
|
out.userdata = userdata;
|
||||||
BridgeList<duint>::CopyData(&out.exits, exits);
|
BridgeList<duint>::CopyData(&out.exits, exits);
|
||||||
|
|
|
@ -191,9 +191,25 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
|
||||||
continue;
|
continue;
|
||||||
node.instrs.reserve(node.icount);
|
node.instrs.reserve(node.icount);
|
||||||
auto addr = node.start;
|
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;
|
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;
|
BridgeCFInstruction instr;
|
||||||
instr.addr = addr;
|
instr.addr = addr;
|
||||||
for(int i = 0; i < size; i++)
|
for(int i = 0; i < size; i++)
|
||||||
|
|
|
@ -550,6 +550,7 @@ void AppearanceDialog::colorInfoListInit()
|
||||||
colorInfoListAppend(tr("Background"), "GraphBackgroundColor", "");
|
colorInfoListAppend(tr("Background"), "GraphBackgroundColor", "");
|
||||||
colorInfoListAppend(tr("Node"), "GraphNodeColor", "GraphNodeBackgroundColor");
|
colorInfoListAppend(tr("Node"), "GraphNodeColor", "GraphNodeBackgroundColor");
|
||||||
colorInfoListAppend(tr("Terminal node shadow"), "GraphRetShadowColor", "");
|
colorInfoListAppend(tr("Terminal node shadow"), "GraphRetShadowColor", "");
|
||||||
|
colorInfoListAppend(tr("Indirect call shadow"), "GraphIndirectcallShadowColor", "");
|
||||||
colorInfoListAppend(tr("Unconditional branch line"), "GraphJmpColor", "");
|
colorInfoListAppend(tr("Unconditional branch line"), "GraphJmpColor", "");
|
||||||
colorInfoListAppend(tr("True branch line"), "GraphBrtrueColor", "");
|
colorInfoListAppend(tr("True branch line"), "GraphBrtrueColor", "");
|
||||||
colorInfoListAppend(tr("False branch line"), "GraphBrfalseColor", "");
|
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));
|
p.setPen(QColor(0, 0, 0, 0));
|
||||||
if(block.block.terminal)
|
if(block.block.terminal)
|
||||||
p.setBrush(retShadowColor);
|
p.setBrush(retShadowColor);
|
||||||
|
else if(block.block.indirectcall)
|
||||||
|
p.setBrush(indirectcallShadowColor);
|
||||||
else
|
else
|
||||||
p.setBrush(QColor(0, 0, 0, 128));
|
p.setBrush(QColor(0, 0, 0, 128));
|
||||||
p.drawRect(block.x + this->charWidth + 4, block.y + this->charWidth + 4,
|
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
|
//Render node background
|
||||||
p.setPen(graphNodeColor);
|
p.setPen(graphNodeColor);
|
||||||
p.setBrush(QBrush(disassemblyBackgroundColor));
|
p.setBrush(disassemblyBackgroundColor);
|
||||||
p.drawRect(block.x + this->charWidth, block.y + this->charWidth,
|
p.drawRect(block.x + this->charWidth, block.y + this->charWidth,
|
||||||
block.width - (4 + 2 * this->charWidth), block.height - (4 + 2 * 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
|
//Render shadow
|
||||||
p.setPen(QColor(0, 0, 0, 0));
|
p.setPen(QColor(0, 0, 0, 0));
|
||||||
if(traceCount && block.block.terminal)
|
if((isCip || traceCount) && block.block.terminal)
|
||||||
p.setBrush(retShadowColor);
|
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));
|
p.setBrush(QColor(0, 0, 0, 0));
|
||||||
else
|
else
|
||||||
p.setBrush(QColor(0, 0, 0, 128));
|
p.setBrush(QColor(0, 0, 0, 128));
|
||||||
|
@ -353,7 +357,7 @@ void DisassemblerGraphView::paintOverview(QPainter & p, QRect & viewportRect, in
|
||||||
pen.setColor(graphNodeColor);
|
pen.setColor(graphNodeColor);
|
||||||
p.setPen(pen);
|
p.setPen(pen);
|
||||||
if(isCip)
|
if(isCip)
|
||||||
p.setBrush(QBrush(mCipBackgroundColor));
|
p.setBrush(mCipBackgroundColor);
|
||||||
else if(traceCount)
|
else if(traceCount)
|
||||||
{
|
{
|
||||||
// Color depending on how often a sequence of code is executed
|
// 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)
|
if(disassemblyTracedColor.blue() > 160)
|
||||||
colorDiff *= -1;
|
colorDiff *= -1;
|
||||||
|
|
||||||
p.setBrush(QBrush(QColor(disassemblyTracedColor.red(),
|
p.setBrush(QColor(disassemblyTracedColor.red(),
|
||||||
disassemblyTracedColor.green(),
|
disassemblyTracedColor.green(),
|
||||||
std::max(0, std::min(256, disassemblyTracedColor.blue() + colorDiff)))));
|
std::max(0, std::min(256, disassemblyTracedColor.blue() + colorDiff))));
|
||||||
}
|
}
|
||||||
else if(block.block.terminal)
|
else if(block.block.terminal)
|
||||||
p.setBrush(QBrush(retShadowColor));
|
p.setBrush(retShadowColor);
|
||||||
|
else if(block.block.indirectcall)
|
||||||
|
p.setBrush(indirectcallShadowColor);
|
||||||
else
|
else
|
||||||
p.setBrush(QBrush(disassemblyBackgroundColor));
|
p.setBrush(disassemblyBackgroundColor);
|
||||||
p.drawRect(block.x + this->charWidth, block.y + this->charWidth,
|
p.drawRect(block.x + this->charWidth, block.y + this->charWidth,
|
||||||
block.width - (4 + 2 * this->charWidth), block.height - (4 + 2 * 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
|
//Render background
|
||||||
QRect viewportRect(this->viewport()->rect().topLeft(), this->viewport()->rect().bottomRight() - QPoint(1, 1));
|
QRect viewportRect(this->viewport()->rect().topLeft(), this->viewport()->rect().bottomRight() - QPoint(1, 1));
|
||||||
p.setBrush(QBrush(backgroundColor));
|
p.setBrush(backgroundColor);
|
||||||
p.drawRect(viewportRect);
|
p.drawRect(viewportRect);
|
||||||
p.setBrush(Qt::black);
|
p.setBrush(Qt::black);
|
||||||
|
|
||||||
|
@ -1498,6 +1504,7 @@ void DisassemblerGraphView::loadCurrentGraph()
|
||||||
block.false_path = node.brfalse;
|
block.false_path = node.brfalse;
|
||||||
block.true_path = node.brtrue;
|
block.true_path = node.brtrue;
|
||||||
block.terminal = node.terminal;
|
block.terminal = node.terminal;
|
||||||
|
block.indirectcall = node.indirectcall;
|
||||||
block.header_text = Text(getSymbolicName(block.entry), mLabelColor, mLabelBackgroundColor);
|
block.header_text = Text(getSymbolicName(block.entry), mLabelColor, mLabelBackgroundColor);
|
||||||
{
|
{
|
||||||
Instr instr;
|
Instr instr;
|
||||||
|
@ -1676,6 +1683,7 @@ void DisassemblerGraphView::colorsUpdatedSlot()
|
||||||
brtrueColor = ConfigColor("GraphBrtrueColor");
|
brtrueColor = ConfigColor("GraphBrtrueColor");
|
||||||
brfalseColor = ConfigColor("GraphBrfalseColor");
|
brfalseColor = ConfigColor("GraphBrfalseColor");
|
||||||
retShadowColor = ConfigColor("GraphRetShadowColor");
|
retShadowColor = ConfigColor("GraphRetShadowColor");
|
||||||
|
indirectcallShadowColor = ConfigColor("GraphIndirectcallShadowColor");
|
||||||
backgroundColor = ConfigColor("GraphBackgroundColor");
|
backgroundColor = ConfigColor("GraphBackgroundColor");
|
||||||
if(!backgroundColor.alpha())
|
if(!backgroundColor.alpha())
|
||||||
backgroundColor = disassemblySelectionColor;
|
backgroundColor = disassemblySelectionColor;
|
||||||
|
|
|
@ -143,6 +143,7 @@ public:
|
||||||
duint true_path = 0;
|
duint true_path = 0;
|
||||||
duint false_path = 0;
|
duint false_path = 0;
|
||||||
bool terminal = false;
|
bool terminal = false;
|
||||||
|
bool indirectcall = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DisassemblerBlock
|
struct DisassemblerBlock
|
||||||
|
@ -320,6 +321,7 @@ private:
|
||||||
QColor brtrueColor;
|
QColor brtrueColor;
|
||||||
QColor brfalseColor;
|
QColor brfalseColor;
|
||||||
QColor retShadowColor;
|
QColor retShadowColor;
|
||||||
|
QColor indirectcallShadowColor;
|
||||||
QColor backgroundColor;
|
QColor backgroundColor;
|
||||||
QColor mAutoCommentColor;
|
QColor mAutoCommentColor;
|
||||||
QColor mAutoCommentBackgroundColor;
|
QColor mAutoCommentBackgroundColor;
|
||||||
|
|
|
@ -204,6 +204,7 @@ Configuration::Configuration() : QObject(), noMoreMsgbox(false)
|
||||||
defaultColors.insert("GraphBrtrueColor", QColor("#387804"));
|
defaultColors.insert("GraphBrtrueColor", QColor("#387804"));
|
||||||
defaultColors.insert("GraphBrfalseColor", QColor("#ED4630"));
|
defaultColors.insert("GraphBrfalseColor", QColor("#ED4630"));
|
||||||
defaultColors.insert("GraphRetShadowColor", QColor("#900000"));
|
defaultColors.insert("GraphRetShadowColor", QColor("#900000"));
|
||||||
|
defaultColors.insert("GraphIndirectcallShadowColor", QColor("#008080"));
|
||||||
defaultColors.insert("GraphBackgroundColor", Qt::transparent);
|
defaultColors.insert("GraphBackgroundColor", Qt::transparent);
|
||||||
defaultColors.insert("GraphNodeColor", QColor("#000000"));
|
defaultColors.insert("GraphNodeColor", QColor("#000000"));
|
||||||
defaultColors.insert("GraphNodeBackgroundColor", Qt::transparent);
|
defaultColors.insert("GraphNodeBackgroundColor", Qt::transparent);
|
||||||
|
|
Loading…
Reference in New Issue