1
0
Fork 0

DBG+BRIDGE+GUI: highlight indirect calls in the graph + fixed shadow in certain situations

This commit is contained in:
mrexodia 2017-03-14 08:13:39 +01:00
parent 62b8e4fe11
commit fe4db70717
No known key found for this signature in database
GPG Key ID: FC89E0AAA0C1AAD8
6 changed files with 46 additions and 13 deletions

View File

@ -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);

View File

@ -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++)

View File

@ -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", "");

View File

@ -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;

View File

@ -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;

View File

@ -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);