1
0
Fork 0

BRIDGE+DBG+GUI: changed BridgeCFGraph to use BridgeCFInstruction instead of flat data

This commit is contained in:
mrexodia 2016-10-18 01:44:11 +02:00
parent fe5388dfa6
commit a034ddd940
No known key found for this signature in database
GPG Key ID: FC89E0AAA0C1AAD8
5 changed files with 34 additions and 21 deletions

View File

@ -1,6 +1,12 @@
#ifndef _GRAPH_H
#define _GRAPH_H
typedef struct
{
duint addr; //virtual address of the instruction
unsigned char data[15]; //instruction bytes
} BridgeCFInstruction;
typedef struct
{
duint parentGraph; //function of which this node is a part
@ -13,7 +19,7 @@ typedef struct
bool split; //node is a split (brtrue points to the next node)
void* userdata; //user data
ListInfo exits; //exits (including brtrue and brfalse, duint)
ListInfo data; //block data
ListInfo instrs; //block instructions
} BridgeCFNodeList;
typedef struct
@ -43,7 +49,7 @@ struct BridgeCFNode
bool split; //node is a split (brtrue points to the next node)
void* userdata; //user data
std::vector<duint> exits; //exits (including brtrue and brfalse)
std::vector<unsigned char> data; //block data
std::vector<BridgeCFInstruction> instrs; //block instructions
explicit BridgeCFNode(BridgeCFNodeList* nodeList, bool freedata = true)
{
@ -60,7 +66,7 @@ struct BridgeCFNode
userdata = nodeList->userdata;
if(!BridgeList<duint>::ToVector(&nodeList->exits, exits, freedata))
__debugbreak();
if(!BridgeList<unsigned char>::ToVector(&nodeList->data, data, freedata))
if(!BridgeList<BridgeCFInstruction>::ToVector(&nodeList->instrs, instrs, freedata))
__debugbreak();
}
@ -95,7 +101,7 @@ struct BridgeCFNode
out.split = split;
out.userdata = userdata;
BridgeList<duint>::CopyData(&out.exits, exits);
BridgeList<unsigned char>::CopyData(&out.data, data);
BridgeList<BridgeCFInstruction>::CopyData(&out.instrs, instrs);
return std::move(out);
}
};

View File

@ -187,10 +187,18 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
node.brtrue = 0;
if(!node.icount)
continue;
auto size = node.end - node.start + (mCp.Disassemble(node.end, translateAddr(node.end)) ? mCp.Size() : 1);
node.data.resize(size);
for(duint i = 0; i < size; i++)
node.data[i] = inRange(node.start + i) ? *translateAddr(node.start + i) : 0;
node.instrs.reserve(node.icount);
auto addr = node.start;
while(addr <= node.end)
{
auto size = mCp.Disassemble(addr, translateAddr(addr)) ? mCp.Size() : 1;
BridgeCFInstruction instr;
instr.addr = addr;
for(duint i = 0; i < size; i++)
instr.data[i] = inRange(addr + i) ? *translateAddr(addr + i) : 0;
node.instrs.push_back(instr);
addr += size;
}
}
mFunctions.push_back(graph);
}

View File

@ -181,12 +181,15 @@ ulong QBeaEngine::DisassembleNext(byte_t* data, duint base, duint size, duint ip
*
* @return Return the disassembled instruction
*/
Instruction_t QBeaEngine::DisassembleAt(byte_t* data, duint size, duint origBase, duint origInstRVA)
Instruction_t QBeaEngine::DisassembleAt(byte_t* data, duint size, duint origBase, duint origInstRVA, bool datainstr)
{
ENCODETYPE type = mEncodeMap->getDataType(origBase + origInstRVA);
if(datainstr)
{
ENCODETYPE type = mEncodeMap->getDataType(origBase + origInstRVA);
if(type != enc_unknown && type != enc_code && type != enc_middle)
return DecodeDataAt(data, size, origBase, origInstRVA, type);
if(type != enc_unknown && type != enc_code && type != enc_middle)
return DecodeDataAt(data, size, origBase, origInstRVA, type);
}
//tokenize
CapstoneTokenizer::InstructionToken cap;
_tokenizer.Tokenize(origBase + origInstRVA, data, size, cap);

View File

@ -42,7 +42,7 @@ public:
~QBeaEngine();
ulong DisassembleBack(byte_t* data, duint base, duint size, duint ip, int n);
ulong DisassembleNext(byte_t* data, duint base, duint size, duint ip, int n);
Instruction_t DisassembleAt(byte_t* data, duint size, duint origBase, duint origInstRVA);
Instruction_t DisassembleAt(byte_t* data, duint size, duint origBase, duint origInstRVA, bool datainstr = true);
Instruction_t DecodeDataAt(byte_t* data, duint size, duint origBase, duint origInstRVA, ENCODETYPE type);
void setCodeFoldingManager(CodeFoldingHelper* CodeFoldingManager);
void UpdateConfig();

View File

@ -1355,21 +1355,18 @@ void DisassemblerGraphView::loadCurrentGraph()
block.header_text = Text(getSymbolicName(block.entry), mLabelColor, mLabelBackgroundColor);
{
Instr instr;
unsigned char data[MAX_DISASM_BUFFER];
for(size_t i = 0; i < node.data.size();)
for(const BridgeCFInstruction & nodeInstr : node.instrs)
{
data[0] = 0xFF;
memcpy(data, node.data.data() + i, qMin(sizeof(data), node.data.size() - i));
auto addr = node.start + i;
auto addr = nodeInstr.addr;
currentBlockMap[addr] = block.entry;
Instruction_t instrTok = disasm.DisassembleAt((byte_t*)data, sizeof(data), 0, addr);
Instruction_t instrTok = disasm.DisassembleAt((byte_t*)nodeInstr.data, sizeof(nodeInstr.data), 0, addr, false);
RichTextPainter::List richText;
CapstoneTokenizer::TokenToRichText(instrTok.tokens, richText, 0);
auto size = instrTok.length;
instr.addr = addr;
instr.opcode.resize(size);
for(int j = 0; j < size; j++)
instr.opcode[j] = data[j];
instr.opcode[j] = nodeInstr.data[j];
QString comment;
bool autoComment = false;
@ -1410,7 +1407,6 @@ void DisassemblerGraphView::loadCurrentGraph()
instr.text = Text(richText);
block.instrs.push_back(instr);
i += size;
}
}
func.blocks.push_back(block);