UInt64 test
This commit is contained in:
parent
3f697969f0
commit
c38375c1ce
|
@ -20,12 +20,10 @@ namespace fa
|
||||||
AnalysisRunner::AnalysisRunner(const duint addrOEP,const duint BaseAddress,const duint Size) : OEP(addrOEP), baseAddress(BaseAddress), codeSize(Size)
|
AnalysisRunner::AnalysisRunner(const duint addrOEP,const duint BaseAddress,const duint Size) : OEP(addrOEP), baseAddress(BaseAddress), codeSize(Size)
|
||||||
{
|
{
|
||||||
// we start at the original entry point
|
// we start at the original entry point
|
||||||
disasmRoot.insert(addrOEP);
|
disasmRoot.insert(std::make_pair<UInt64,UInt64>((duint)addrOEP,(duint)addrOEP));
|
||||||
codeWasCopied = initialise();
|
codeWasCopied = initialise();
|
||||||
if(codeWasCopied){
|
if(codeWasCopied){
|
||||||
Grph = new FlowGraph;
|
Grph = new FlowGraph;
|
||||||
Node_t *cipNode = new Node_t(OEP);
|
|
||||||
Grph->insertNode(cipNode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -64,35 +62,56 @@ namespace fa
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool AnalysisRunner::disasmChilds(duint rootAddress)
|
bool AnalysisRunner::disasmChilds(const UInt64 currentAddress,UInt64 parentAddress)
|
||||||
{
|
{
|
||||||
|
parentAddress = currentAddress;
|
||||||
|
// Dear contributors (unless you are Chuck Norris):
|
||||||
|
//
|
||||||
|
// if you think about 'optimizing' or 'debugging' this methods and then
|
||||||
|
// realize what a terrible mistake that was, please pray that this function will
|
||||||
|
// not fail and increment the following counter as a warning to the next guy:
|
||||||
|
//
|
||||||
|
// total_hours_wasted_here = 3
|
||||||
|
dprintf("-----------------------------------------------------------------------------\n");
|
||||||
|
dprintf("processing subtree starting in node at address "fhex" as child of "fhex"\n", currentAddress,parentAddress);
|
||||||
// this function will run until an unconditional branching (JMP,RET) or unkown OpCode
|
// this function will run until an unconditional branching (JMP,RET) or unkown OpCode
|
||||||
if (contains(instructionBuffer,(UInt64)rootAddress))
|
if (contains(instructionBuffer,(UInt64)currentAddress))
|
||||||
{
|
{
|
||||||
// we already were here -->stop!
|
// we already were here -->stop!
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// is there code?
|
||||||
|
if((base() > currentAddress) && (base() + size() <= currentAddress)){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
DISASM disasm;
|
DISASM disasm;
|
||||||
memset(&disasm, 0, sizeof(disasm));
|
memset(&disasm, 0, sizeof(disasm));
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
disasm.Archi = 64;
|
disasm.Archi = 64;
|
||||||
#endif
|
#endif
|
||||||
// indent pointer relative to current virtual address
|
// indent pointer relative to current virtual address
|
||||||
disasm.EIP = (UIntPtr)codeBuffer + (rootAddress - baseAddress);
|
disasm.EIP = (UIntPtr)codeBuffer + (currentAddress - baseAddress);
|
||||||
disasm.VirtualAddr = (UInt64)rootAddress;
|
disasm.VirtualAddr = (UInt64)currentAddress;
|
||||||
|
|
||||||
|
|
||||||
|
dprintf("loop end test: \n");
|
||||||
|
dprintf(" va "fhex"\n",disasm.VirtualAddr);
|
||||||
|
dprintf(" base "fhex"\n",baseAddress);
|
||||||
|
dprintf(" diff "fhex"\n",(UInt64)(disasm.VirtualAddr- baseAddress));
|
||||||
// while there is code in the buffer
|
// while there is code in the buffer
|
||||||
while(disasm.VirtualAddr - baseAddress < codeSize)
|
while(disasm.VirtualAddr - baseAddress < codeSize)
|
||||||
{
|
{
|
||||||
// disassemble instruction
|
// disassemble instruction
|
||||||
int instrLength = Disasm(&disasm);
|
const int instrLength = Disasm(&disasm);
|
||||||
// everything ok?
|
// everything ok?
|
||||||
if(instrLength != UNKNOWN_OPCODE)
|
if(instrLength != UNKNOWN_OPCODE)
|
||||||
{
|
{
|
||||||
// create a new structure
|
// create a new structure
|
||||||
Instruction_t instr(&disasm, instrLength);
|
const Instruction_t instr(&disasm, instrLength);
|
||||||
// cache instruction
|
//dprintf("analyse %s at "fhex" \n", disasm.CompleteInstr,currentAddress);
|
||||||
|
// cache instruction, we will later look at it
|
||||||
instructionBuffer.insert(std::pair<UInt64, Instruction_t>(disasm.VirtualAddr, instr));
|
instructionBuffer.insert(std::pair<UInt64, Instruction_t>(disasm.VirtualAddr, instr));
|
||||||
|
|
||||||
// handle all kind of branching (cond. jumps, uncond. jumps, ret, unkown OpCode, calls)
|
// handle all kind of branching (cond. jumps, uncond. jumps, ret, unkown OpCode, calls)
|
||||||
|
@ -107,16 +126,18 @@ namespace fa
|
||||||
// end of a function
|
// end of a function
|
||||||
// --> start was probably "rootAddress"
|
// --> start was probably "rootAddress"
|
||||||
// --> edge from current VA to rootAddress
|
// --> edge from current VA to rootAddress
|
||||||
endNode = new Node_t(instruction_t(rootAddress));
|
endNode = new Node_t(parentAddress);
|
||||||
Edge_t *e = new Edge_t(startNode,endNode,fa::RET);
|
Edge_t *e = new Edge_t(startNode,endNode,fa::RET);
|
||||||
Grph->insertEdge(e);
|
//dprintf("try to insert edge from "fhex" to "fhex" \n", e->start->vaddr, e->end->vaddr);
|
||||||
|
dprintf("--> try to insert ret-edge from "fhex" to "fhex" \n", disasm.VirtualAddr, (UInt64) parentAddress);
|
||||||
|
//###Grph->insertEdge(e);
|
||||||
// no need to disassemble more
|
// no need to disassemble more
|
||||||
// "rootAddress" is from "call <rootAddress>"
|
// "rootAddress" is *only sometimes* from "call <rootAddress>"
|
||||||
return true;
|
return true;
|
||||||
}else{
|
}else{
|
||||||
// this is a "call","jmp","ret","jne","jnz","jz",...
|
// this is a "call","jmp","jne","jnz","jz",...
|
||||||
// were we are going to?
|
// were we are going to?
|
||||||
endNode = new Node_t(instruction_t(rootAddress));
|
//### endNode = new Node_t(instruction_t(disasm.Instruction.AddrValue));
|
||||||
// determine the type of flow-control-modification
|
// determine the type of flow-control-modification
|
||||||
fa::EdgeType currentEdgeType;
|
fa::EdgeType currentEdgeType;
|
||||||
|
|
||||||
|
@ -124,8 +145,7 @@ namespace fa
|
||||||
// simply a call
|
// simply a call
|
||||||
currentEdgeType = fa::CALL;
|
currentEdgeType = fa::CALL;
|
||||||
}else if(BT == JmpType){
|
}else if(BT == JmpType){
|
||||||
// external Jump ?
|
// external Jump to known api call?
|
||||||
// TODO: this is currently x86 only!
|
|
||||||
bool extjmp;
|
bool extjmp;
|
||||||
#ifndef _WIN64
|
#ifndef _WIN64
|
||||||
extjmp =( disasm.Instruction.Opcode == 0xFF);
|
extjmp =( disasm.Instruction.Opcode == 0xFF);
|
||||||
|
@ -139,7 +159,7 @@ namespace fa
|
||||||
extjmp = !f.invalid;
|
extjmp = !f.invalid;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if(extjmp){
|
if(extjmp ){
|
||||||
currentEdgeType = fa::EXTERNJMP;
|
currentEdgeType = fa::EXTERNJMP;
|
||||||
}else{
|
}else{
|
||||||
currentEdgeType = fa::UNCONDJMP;
|
currentEdgeType = fa::UNCONDJMP;
|
||||||
|
@ -150,11 +170,19 @@ namespace fa
|
||||||
}
|
}
|
||||||
// create a new edge for this EIP change
|
// create a new edge for this EIP change
|
||||||
Edge_t *edge = new Edge_t(startNode,endNode,currentEdgeType);
|
Edge_t *edge = new Edge_t(startNode,endNode,currentEdgeType);
|
||||||
Grph->insertEdge(edge);
|
dprintf("--> try to insert edge from "fhex" to "fhex" \n", disasm.VirtualAddr, (UInt64) disasm.Instruction.AddrValue);
|
||||||
|
//####Grph->insertEdge(edge);
|
||||||
|
|
||||||
if(currentEdgeType != fa::EXTERNJMP){
|
if(currentEdgeType != fa::EXTERNJMP){
|
||||||
// the target must be disassembled too --> insert on todo-list
|
// the target must be disassembled too --> insert on todo-list
|
||||||
disasmRoot.insert(endNode->virtualAddress);
|
if(currentEdgeType == fa::CALL){
|
||||||
|
// pass new address for correct resolving function-header addresses
|
||||||
|
disasmRoot.insert(std::make_pair<UInt64,UInt64>(disasm.Instruction.AddrValue,disasm.VirtualAddr));
|
||||||
|
}else{
|
||||||
|
// we are in some functions --> propagate current function start
|
||||||
|
disasmRoot.insert(std::make_pair<UInt64,UInt64>(disasm.Instruction.AddrValue,parentAddress));
|
||||||
|
}
|
||||||
|
dprintf("add todo at "fhex" from "fhex" \n", disasm.Instruction.AddrValue,disasm.VirtualAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( BT == JmpType ){
|
if( BT == JmpType ){
|
||||||
|
@ -175,6 +203,11 @@ namespace fa
|
||||||
// we are allowed to analyze the next instruction
|
// we are allowed to analyze the next instruction
|
||||||
disasm.EIP += instrLength;
|
disasm.EIP += instrLength;
|
||||||
disasm.VirtualAddr += instrLength;
|
disasm.VirtualAddr += instrLength;
|
||||||
|
|
||||||
|
dprintf("loop end test: \n");
|
||||||
|
dprintf(" va "fhex"\n",disasm.VirtualAddr);
|
||||||
|
dprintf(" base "fhex"\n",baseAddress);
|
||||||
|
dprintf(" diff "fhex"\n",(UInt64)(disasm.VirtualAddr- baseAddress));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -182,22 +215,33 @@ namespace fa
|
||||||
|
|
||||||
void AnalysisRunner::buildGraph()
|
void AnalysisRunner::buildGraph()
|
||||||
{
|
{
|
||||||
|
int i=15;
|
||||||
// execute todo list
|
// execute todo list
|
||||||
while(disasmRoot.size() != 0){
|
while(disasmRoot.size() != 0){
|
||||||
// get any address
|
// get any address
|
||||||
UInt64 addr = *(disasmRoot.begin());
|
std::pair<UInt64,UInt64> addr = *(disasmRoot.begin());
|
||||||
|
|
||||||
|
// does the address makes sense?
|
||||||
|
if( (addr.first >= baseAddress) && (addr.first < baseAddress + codeSize) ){
|
||||||
// did we already analyzed that address?
|
// did we already analyzed that address?
|
||||||
if(!contains(instructionBuffer,addr)){
|
if(!contains(instructionBuffer,addr.first)){
|
||||||
// analyze until branching
|
// analyze until branching
|
||||||
disasmChilds(addr);
|
disasmChilds(addr.first,addr.second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// delete it from todo list
|
// delete it from todo list
|
||||||
disasmRoot.erase(disasmRoot.find(addr));
|
disasmRoot.erase(disasmRoot.find(addr));
|
||||||
|
|
||||||
|
if(i==0)
|
||||||
|
return;
|
||||||
|
i--;
|
||||||
}
|
}
|
||||||
// we do not need the buffer anymore
|
// we do not need the buffer anymore
|
||||||
delete codeBuffer;
|
delete codeBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::map<UInt64, Instruction_t>::const_iterator AnalysisRunner::instruction(UInt64 addr) const
|
std::map<UInt64, Instruction_t>::const_iterator AnalysisRunner::instruction(UInt64 addr) const
|
||||||
{
|
{
|
||||||
return instructionBuffer.find(addr);
|
return instructionBuffer.find(addr);
|
||||||
|
@ -206,7 +250,7 @@ namespace fa
|
||||||
{
|
{
|
||||||
return instructionBuffer.end();
|
return instructionBuffer.end();
|
||||||
}
|
}
|
||||||
duint AnalysisRunner::base() const
|
UInt64 AnalysisRunner::base() const
|
||||||
{
|
{
|
||||||
return baseAddress;
|
return baseAddress;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
namespace fa
|
namespace fa
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// BeaEngine uses "UInt64" as default size type. We will do the same here in contrast to "duint"
|
||||||
|
|
||||||
class StackEmulator;
|
class StackEmulator;
|
||||||
class RegisterEmulator;
|
class RegisterEmulator;
|
||||||
class FunctionInfo;
|
class FunctionInfo;
|
||||||
|
@ -14,13 +16,13 @@ namespace fa
|
||||||
class AnalysisRunner
|
class AnalysisRunner
|
||||||
{
|
{
|
||||||
// we will place all VA here that should be a start address for disassembling
|
// we will place all VA here that should be a start address for disassembling
|
||||||
std::set<UInt64> disasmRoot;
|
std::set< std::pair<UInt64,UInt64> > disasmRoot;
|
||||||
// all known disassemling should be cached
|
// all known disassemling should be cached
|
||||||
std::map<UInt64, Instruction_t> instructionBuffer;
|
std::map<UInt64, Instruction_t> instructionBuffer;
|
||||||
// baseaddress for current thread
|
// baseaddress for current thread
|
||||||
duint baseAddress;
|
UInt64 baseAddress;
|
||||||
// size of code for security while disassembling
|
// size of code for security while disassembling
|
||||||
duint codeSize;
|
UInt64 codeSize;
|
||||||
// copy of all instructions bytes
|
// copy of all instructions bytes
|
||||||
unsigned char* codeBuffer;
|
unsigned char* codeBuffer;
|
||||||
// temporal value of EIP
|
// temporal value of EIP
|
||||||
|
@ -44,7 +46,7 @@ protected:
|
||||||
private:
|
private:
|
||||||
void buildGraph();
|
void buildGraph();
|
||||||
void emulateInstructions();
|
void emulateInstructions();
|
||||||
bool disasmChilds(duint addr);
|
bool disasmChilds(const UInt64 addr,UInt64 paddr);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -56,7 +58,7 @@ public:
|
||||||
Instruction_t instruction_t(UInt64 va) const;
|
Instruction_t instruction_t(UInt64 va) const;
|
||||||
std::map<UInt64, Instruction_t>::const_iterator lastInstruction() const;
|
std::map<UInt64, Instruction_t>::const_iterator lastInstruction() const;
|
||||||
|
|
||||||
duint base() const;
|
UInt64 base() const;
|
||||||
UInt64 oep() const;
|
UInt64 oep() const;
|
||||||
duint size() const;
|
duint size() const;
|
||||||
FlowGraph* graph() const;
|
FlowGraph* graph() const;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "FlowGraph.h"
|
#include "FlowGraph.h"
|
||||||
#include "AnalysisRunner.h"
|
#include "AnalysisRunner.h"
|
||||||
#include "StackEmulator.h"
|
#include "StackEmulator.h"
|
||||||
|
#include "FunctionInfo.h"
|
||||||
|
|
||||||
namespace fa
|
namespace fa
|
||||||
{
|
{
|
||||||
|
@ -30,7 +31,7 @@ namespace fa
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
if(hasLabel){
|
if(hasLabel){
|
||||||
FunctionInfo_t f = Analysis->functioninfo()->find(labelText);
|
fa::FunctionInfo_t f = Analysis->functioninfo()->find(labelText);
|
||||||
if(!f.invalid)
|
if(!f.invalid)
|
||||||
{
|
{
|
||||||
// yeah we know everything about the dll-call!
|
// yeah we know everything about the dll-call!
|
||||||
|
@ -40,7 +41,7 @@ namespace fa
|
||||||
|
|
||||||
#ifndef _WIN64
|
#ifndef _WIN64
|
||||||
// set comments for the arguments
|
// set comments for the arguments
|
||||||
for(auto i = 0; i < f.Arguments.size(); i++)
|
for(size_t i = 0; i < f.Arguments.size(); i++)
|
||||||
{
|
{
|
||||||
std::string ArgComment = f.arg(i).Type + " " + f.arg(i).Name;
|
std::string ArgComment = f.arg(i).Type + " " + f.arg(i).Name;
|
||||||
uint commentAddr = stack->lastAccessAtOffset(f.Arguments.size() - i - 1);
|
uint commentAddr = stack->lastAccessAtOffset(f.Arguments.size() - i - 1);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "FlowGraph.h"
|
#include "FlowGraph.h"
|
||||||
#include "Node_t.h"
|
#include "Node_t.h"
|
||||||
#include "Edge_t.h"
|
#include "Edge_t.h"
|
||||||
|
#include "../console.h"
|
||||||
|
|
||||||
namespace fa{
|
namespace fa{
|
||||||
|
|
||||||
|
@ -11,27 +12,37 @@ namespace fa{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::set<Node_t*>::iterator,bool> FlowGraph::insertNode( Node_t* node )
|
bool FlowGraph::insertNode( Node_t* node )
|
||||||
{
|
{
|
||||||
return nodes.insert(node);
|
if (!contains(nodes,(UInt64)node->vaddr))
|
||||||
|
{
|
||||||
|
return (nodes.insert(std::make_pair<UInt64,Node_t*>(node->vaddr,node))).second;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::set<Edge_t*>::iterator,bool> FlowGraph::insertEdge( Edge_t* edge )
|
bool FlowGraph::insertEdge( Edge_t* edge )
|
||||||
{
|
{
|
||||||
// until here a node just contains an address!
|
// until here a node just contains an address!
|
||||||
// we search for these address to get most updated information (like incoming edges)
|
// we search for these address to get most updated information (like incoming edges)
|
||||||
std::pair<std::set<Node_t*>::iterator,bool> start = insertNode(edge->start);
|
|
||||||
std::pair<std::set<Node_t*>::iterator,bool> end = insertNode(edge->end);
|
|
||||||
|
|
||||||
// insert current edge into these nodes
|
dprintf("try to insert edge from "fhex" to "fhex" \n", edge->start->vaddr, edge->end->vaddr);
|
||||||
(*start.first)->outEdge.insert(edge);
|
return true;
|
||||||
(*end.first)->inEdges.insert(edge);
|
insertNode(edge->start);
|
||||||
|
std::map<UInt64,Node_t*>::iterator it = nodes.find(edge->start->vaddr);
|
||||||
|
it->second->outEdge = edge;
|
||||||
|
|
||||||
// update edge
|
insertNode(edge->end);
|
||||||
edge->start = (*start.first);
|
std::map<UInt64,Node_t*>::iterator it2 = nodes.find(edge->end->vaddr);
|
||||||
edge->end = (*end.first);
|
it2->second->inEdges.insert(edge);
|
||||||
|
|
||||||
return edges.insert(edge);
|
edge->start = (it->second);
|
||||||
|
edge->end = (it2->second);
|
||||||
|
bool ans = edges.insert(std::make_pair<UInt64,Edge_t*>(edge->start->vaddr,edge)).second;
|
||||||
|
std::map<UInt64,Edge_t*>::iterator e = edges.find(edge->start->vaddr);
|
||||||
|
|
||||||
|
return ans;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -39,32 +50,32 @@ namespace fa{
|
||||||
void FlowGraph::clean()
|
void FlowGraph::clean()
|
||||||
{
|
{
|
||||||
// first delete all edges whoses aks for it
|
// first delete all edges whoses aks for it
|
||||||
std::set<Edge_t*>::iterator e = edges.begin();
|
std::map<UInt64,Edge_t*>::iterator e = edges.begin();
|
||||||
while(e != edges.end()) {
|
while(e != edges.end()) {
|
||||||
std::set<Edge_t*>::iterator current = e++;
|
std::map<UInt64,Edge_t*>::iterator current = e++;
|
||||||
if((*current)->askForRemove){
|
if((*current->second).askForRemove){
|
||||||
delete *current;
|
delete current->second;
|
||||||
edges.erase(current);
|
edges.erase(current);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// find and delete isolated nodes, i.e. nodes without incoming and outgoing edges
|
// find and delete isolated nodes, i.e. nodes without incoming and outgoing edges
|
||||||
std::set<Node_t*>::iterator n = nodes.begin();
|
std::map<UInt64,Node_t*>::iterator n = nodes.begin();
|
||||||
while(n != nodes.end()) {
|
while(n != nodes.end()) {
|
||||||
std::set<Node_t*>::iterator current = n++;
|
std::map<UInt64,Node_t*>::iterator current = n++;
|
||||||
if( (!(*current)->outEdge) && ((*current)->inEdges.size()==0) ){
|
if( (!(*current->second).outEdge) && ((*current->second).inEdges.size()==0) ){
|
||||||
delete *current;
|
delete current->second;
|
||||||
nodes.erase(current);
|
nodes.erase(current);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FlowGraph::find(const UInt64 va , Node_t *node)
|
bool FlowGraph::find(const UInt64 va , Node_t *node)
|
||||||
{
|
{
|
||||||
// try to find a node
|
// try to find a node
|
||||||
std::set<Node_t*>::iterator it = nodes.find(Node_t(va));
|
std::map<UInt64,Node_t*>::iterator it = nodes.find(va);
|
||||||
node = *it;
|
Node_t* n = it->second;
|
||||||
|
node = n;
|
||||||
return (it != nodes.end());
|
return (it != nodes.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,30 +1,31 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <set>
|
#include <set>
|
||||||
#include "../_global.h"
|
#include "../_global.h"
|
||||||
|
#include "Node_t.h"
|
||||||
|
#include "Edge_t.h"
|
||||||
|
|
||||||
namespace fa{
|
namespace fa{
|
||||||
|
|
||||||
class Edge_t;
|
|
||||||
class Node_t;
|
|
||||||
class FlowGraph
|
class FlowGraph
|
||||||
{
|
{
|
||||||
// this class represents the program flow including branches likes JMP, JNE, ... , CALL, RET
|
// this class represents the program flow including branches likes JMP, JNE, ... , CALL, RET
|
||||||
// all existing edges
|
// all existing edges
|
||||||
std::set<Edge_t*> edges;
|
std::map<UInt64,Edge_t*> edges;
|
||||||
// all existing nodes
|
// all existing nodes
|
||||||
std::set<Node_t*> nodes;
|
std::map<UInt64,Node_t*> nodes;
|
||||||
public:
|
public:
|
||||||
FlowGraph(void);
|
FlowGraph(void);
|
||||||
~FlowGraph(void);
|
~FlowGraph(void);
|
||||||
void clean();
|
void clean();
|
||||||
// insert a new node an returns the existing node if there was already the node
|
// insert a new node an returns the existing node if there was already the node
|
||||||
// WARNING: this should only be called from the corresponding edge!!!
|
// WARNING: this should only be called from the corresponding edge!!!
|
||||||
std::pair<std::set<Node_t*>::iterator,bool> insertNode(Node_t* node);
|
bool insertNode(Node_t* node);
|
||||||
// insert a new edge an returns the existing edge if there was already the edge
|
// insert a new edge an returns the existing edge if there was already the edge
|
||||||
std::pair<std::set<Edge_t*>::iterator,bool> FlowGraph::insertEdge( Edge_t* edge );
|
bool FlowGraph::insertEdge( Edge_t* edge );
|
||||||
|
|
||||||
bool find(const UInt64 va , Node_t *node);
|
bool find(const UInt64 va, Node_t *node);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
namespace fa
|
namespace fa
|
||||||
{
|
{
|
||||||
|
|
||||||
enum EdgeType{RET,CALL,CONDJMP,UNCONDJMP,EXTERNJMP,INF,UNKOWN};
|
enum EdgeType{RET,CALL,EXTERNCALL,CONDJMP,UNCONDJMP,EXTERNJMP,INF,UNKOWN};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ namespace fa
|
||||||
|
|
||||||
Instruction_t()
|
Instruction_t()
|
||||||
{
|
{
|
||||||
|
BeaStruct = DISASM();
|
||||||
Length = UNKNOWN_OPCODE;
|
Length = UNKNOWN_OPCODE;
|
||||||
}
|
}
|
||||||
} Instruction_t;
|
} Instruction_t;
|
||||||
|
@ -72,14 +73,15 @@ namespace fa
|
||||||
Arguments = args;
|
Arguments = args;
|
||||||
invalid = false;
|
invalid = false;
|
||||||
}
|
}
|
||||||
|
// !! suppresses the warning (ugly solution)
|
||||||
bool operator==(const FunctionInfo_t & rhs) const
|
bool operator==(const FunctionInfo_t & rhs) const
|
||||||
{
|
{
|
||||||
return static_cast<bool>((_strcmpi(Name.c_str(), rhs.Name.c_str()) < 0));
|
return static_cast<bool>(!!(_strcmpi(Name.c_str(), rhs.Name.c_str()) < 0));
|
||||||
}
|
}
|
||||||
|
// !! suppresses the warning (ugly solution)
|
||||||
bool operator<(const FunctionInfo_t & rhs) const
|
bool operator<(const FunctionInfo_t & rhs) const
|
||||||
{
|
{
|
||||||
return static_cast<bool>(_strcmpi(Name.c_str(), rhs.Name.c_str()));
|
return static_cast<bool>(!!_strcmpi(Name.c_str(), rhs.Name.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
ArgumentInfo_t arg(int i)
|
ArgumentInfo_t arg(int i)
|
||||||
|
|
|
@ -9,10 +9,18 @@ namespace fa
|
||||||
Node_t::Node_t(Instruction_t t){
|
Node_t::Node_t(Instruction_t t){
|
||||||
outEdge = NULL;
|
outEdge = NULL;
|
||||||
instruction = t;
|
instruction = t;
|
||||||
|
vaddr = t.BeaStruct.VirtualAddr;
|
||||||
}
|
}
|
||||||
Node_t::Node_t(){
|
Node_t::Node_t(){
|
||||||
outEdge = NULL;
|
outEdge = NULL;
|
||||||
instruction = Instruction_t();
|
instruction = Instruction_t();
|
||||||
|
vaddr = 0;
|
||||||
|
}
|
||||||
|
Node_t::Node_t(UInt64 va){
|
||||||
|
outEdge = NULL;
|
||||||
|
instruction = Instruction_t();
|
||||||
|
instruction.BeaStruct.VirtualAddr = va;
|
||||||
|
vaddr = va;
|
||||||
}
|
}
|
||||||
Node_t::~Node_t(){
|
Node_t::~Node_t(){
|
||||||
|
|
||||||
|
@ -31,17 +39,14 @@ namespace fa
|
||||||
// nodes are unique with respect to their virtual address
|
// nodes are unique with respect to their virtual address
|
||||||
bool Node_t::operator==(const Node_t & rhs) const
|
bool Node_t::operator==(const Node_t & rhs) const
|
||||||
{
|
{
|
||||||
if(instruction.Length != UNKNOWN_OPCODE)
|
return static_cast<bool>(vaddr == rhs.vaddr);
|
||||||
return static_cast<bool>(instruction.BeaStruct.VirtualAddr == rhs.instruction.BeaStruct.VirtualAddr);
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
bool Node_t::operator<(const Node_t & rhs) const
|
bool Node_t::operator<(const Node_t & rhs) const
|
||||||
{
|
{
|
||||||
if(instruction.Length != UNKNOWN_OPCODE)
|
|
||||||
return static_cast<bool>(instruction.BeaStruct.VirtualAddr < rhs.instruction.BeaStruct.VirtualAddr);
|
return static_cast<bool>(vaddr < rhs.vaddr);
|
||||||
else
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,10 @@ namespace fa
|
||||||
Edge_t* outEdge; // all outgoing edges
|
Edge_t* outEdge; // all outgoing edges
|
||||||
std::set<Edge_t*> inEdges; // all incoming edges
|
std::set<Edge_t*> inEdges; // all incoming edges
|
||||||
Instruction_t instruction;
|
Instruction_t instruction;
|
||||||
|
UInt64 vaddr;
|
||||||
|
|
||||||
Node_t(Instruction_t t);
|
Node_t(Instruction_t t);
|
||||||
|
Node_t(UInt64 t);
|
||||||
Node_t();
|
Node_t();
|
||||||
~Node_t();
|
~Node_t();
|
||||||
void remove();
|
void remove();
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include "simplescript.h"
|
#include "simplescript.h"
|
||||||
#include "symbolinfo.h"
|
#include "symbolinfo.h"
|
||||||
#include "Analysis/AnalysisRunner.h"
|
#include "Analysis/AnalysisRunner.h"
|
||||||
#include "Analysis/ApiDB.h"
|
|
||||||
|
|
||||||
static bool bScyllaLoaded = false;
|
static bool bScyllaLoaded = false;
|
||||||
|
|
||||||
|
@ -999,28 +999,25 @@ CMDRESULT cbDebugBcDll(int argc, char* argv[])
|
||||||
}
|
}
|
||||||
CMDRESULT cbDebugAnalyse(int argc, char* argv[])
|
CMDRESULT cbDebugAnalyse(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
dputs("start analysis");
|
dputs("init analysis");
|
||||||
uint addr = GetContextData(UE_CIP);
|
uint cipAddr = GetContextData(UE_CIP);
|
||||||
if(argc > 1 and !valfromstring(argv[1], &addr))
|
|
||||||
{
|
|
||||||
dprintf("invalid address \"%s\"!\n", argv[1]);
|
|
||||||
return STATUS_ERROR;
|
|
||||||
}
|
|
||||||
dprintf("valid cip "fhex"!\n", addr);
|
|
||||||
uint size;
|
uint size;
|
||||||
uint base = memfindbaseaddr(addr, &size);
|
uint base = memfindbaseaddr(cipAddr, &size);
|
||||||
if(!base)
|
if(!base)
|
||||||
{
|
{
|
||||||
dprintf("invalid address "fhex"!\n", addr);
|
dprintf("invalid address "fhex"!\n", base);
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
dprintf("valid base "fhex"!\n", base);
|
|
||||||
dprintf("valid size "fhex"!\n", size);
|
|
||||||
|
|
||||||
tr4ce::ApiDB* db = new tr4ce::ApiDB();
|
dprintf("start analysis, assuming oep="fhex", baseaddr="fhex", size="fhex"!\n", cipAddr,base,size);
|
||||||
tr4ce::AnalysisRunner AR(base, size);
|
|
||||||
AR.setFunctionInformation(db);
|
|
||||||
|
// tr4ce::ApiDB* db = new tr4ce::ApiDB();
|
||||||
|
fa::AnalysisRunner AR(cipAddr,base, size);
|
||||||
AR.start();
|
AR.start();
|
||||||
|
// AR.setFunctionInformation(db);
|
||||||
|
// AR.start();
|
||||||
|
|
||||||
|
|
||||||
//GuiAnalyseCode(base, size);
|
//GuiAnalyseCode(base, size);
|
||||||
|
|
|
@ -13,12 +13,13 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="addrinfo.cpp" />
|
<ClCompile Include="addrinfo.cpp" />
|
||||||
<ClCompile Include="Analysis\AnalysisRunner.cpp" />
|
<ClCompile Include="Analysis\AnalysisRunner.cpp" />
|
||||||
<ClCompile Include="Analysis\ApiDB.cpp" />
|
<ClCompile Include="Analysis\ClientApiResolver.cpp" />
|
||||||
<ClCompile Include="Analysis\BeaInterpreter.cpp" />
|
<ClCompile Include="Analysis\ClientFunctionFinder.cpp" />
|
||||||
<ClCompile Include="Analysis\FunctionDetector.cpp" />
|
<ClCompile Include="Analysis\ClientInterface.cpp" />
|
||||||
<ClCompile Include="Analysis\ICommand.cpp" />
|
<ClCompile Include="Analysis\Edge_t.cpp" />
|
||||||
<ClCompile Include="Analysis\IntermodularCallsX64.cpp" />
|
<ClCompile Include="Analysis\FlowGraph.cpp" />
|
||||||
<ClCompile Include="Analysis\IntermodularCallsX86.cpp" />
|
<ClCompile Include="Analysis\FunctionInfo.cpp" />
|
||||||
|
<ClCompile Include="Analysis\Node_t.cpp" />
|
||||||
<ClCompile Include="Analysis\RegisterEmulator.cpp" />
|
<ClCompile Include="Analysis\RegisterEmulator.cpp" />
|
||||||
<ClCompile Include="Analysis\StackEmulator.cpp" />
|
<ClCompile Include="Analysis\StackEmulator.cpp" />
|
||||||
<ClCompile Include="argument.cpp" />
|
<ClCompile Include="argument.cpp" />
|
||||||
|
@ -55,12 +56,14 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="addrinfo.h" />
|
<ClInclude Include="addrinfo.h" />
|
||||||
<ClInclude Include="Analysis\AnalysisRunner.h" />
|
<ClInclude Include="Analysis\AnalysisRunner.h" />
|
||||||
<ClInclude Include="Analysis\ApiDB.h" />
|
<ClInclude Include="Analysis\ClientApiResolver.h" />
|
||||||
<ClInclude Include="Analysis\BeaInterpreter.h" />
|
<ClInclude Include="Analysis\ClientFunctionFinder.h" />
|
||||||
<ClInclude Include="Analysis\FunctionDetector.h" />
|
<ClInclude Include="Analysis\ClientInterface.h" />
|
||||||
<ClInclude Include="Analysis\ICommand.h" />
|
<ClInclude Include="Analysis\Edge_t.h" />
|
||||||
<ClInclude Include="Analysis\IntermodularCalls.h" />
|
<ClInclude Include="Analysis\FlowGraph.h" />
|
||||||
|
<ClInclude Include="Analysis\FunctionInfo.h" />
|
||||||
<ClInclude Include="Analysis\Meta.h" />
|
<ClInclude Include="Analysis\Meta.h" />
|
||||||
|
<ClInclude Include="Analysis\Node_t.h" />
|
||||||
<ClInclude Include="Analysis\RegisterEmulator.h" />
|
<ClInclude Include="Analysis\RegisterEmulator.h" />
|
||||||
<ClInclude Include="Analysis\StackEmulator.h" />
|
<ClInclude Include="Analysis\StackEmulator.h" />
|
||||||
<ClInclude Include="argument.h" />
|
<ClInclude Include="argument.h" />
|
||||||
|
|
|
@ -34,12 +34,12 @@
|
||||||
<Filter Include="Header Files\lz4">
|
<Filter Include="Header Files\lz4">
|
||||||
<UniqueIdentifier>{6a8d58f0-1417-4bff-aecd-0f9f5e0641f9}</UniqueIdentifier>
|
<UniqueIdentifier>{6a8d58f0-1417-4bff-aecd-0f9f5e0641f9}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter Include="Analysis">
|
|
||||||
<UniqueIdentifier>{70e48ca5-7813-4da6-95c8-3717ace25093}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Source Files\Analysis">
|
<Filter Include="Source Files\Analysis">
|
||||||
<UniqueIdentifier>{68e04c31-9f66-4c9a-ae1d-54b2f6cf2d1c}</UniqueIdentifier>
|
<UniqueIdentifier>{68e04c31-9f66-4c9a-ae1d-54b2f6cf2d1c}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="Header Files\fa">
|
||||||
|
<UniqueIdentifier>{70e48ca5-7813-4da6-95c8-3717ace25093}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="_exports.cpp">
|
<ClCompile Include="_exports.cpp">
|
||||||
|
@ -135,32 +135,35 @@
|
||||||
<ClCompile Include="debugger_commands.cpp">
|
<ClCompile Include="debugger_commands.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Analysis\Node_t.cpp">
|
||||||
|
<Filter>Header Files\fa</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Analysis\Edge_t.cpp">
|
||||||
|
<Filter>Header Files\fa</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="Analysis\AnalysisRunner.cpp">
|
<ClCompile Include="Analysis\AnalysisRunner.cpp">
|
||||||
<Filter>Source Files\Analysis</Filter>
|
<Filter>Header Files\fa</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Analysis\StackEmulator.cpp">
|
<ClCompile Include="Analysis\StackEmulator.cpp">
|
||||||
<Filter>Source Files\Analysis</Filter>
|
<Filter>Header Files\fa</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Analysis\FlowGraph.cpp">
|
||||||
|
<Filter>Header Files\fa</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Analysis\RegisterEmulator.cpp">
|
<ClCompile Include="Analysis\RegisterEmulator.cpp">
|
||||||
<Filter>Source Files\Analysis</Filter>
|
<Filter>Header Files\fa</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Analysis\IntermodularCallsX64.cpp">
|
<ClCompile Include="Analysis\ClientApiResolver.cpp">
|
||||||
<Filter>Source Files\Analysis</Filter>
|
<Filter>Header Files\fa</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Analysis\IntermodularCallsX86.cpp">
|
<ClCompile Include="Analysis\ClientInterface.cpp">
|
||||||
<Filter>Source Files\Analysis</Filter>
|
<Filter>Header Files\fa</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Analysis\ICommand.cpp">
|
<ClCompile Include="Analysis\FunctionInfo.cpp">
|
||||||
<Filter>Source Files\Analysis</Filter>
|
<Filter>Header Files\fa</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Analysis\ApiDB.cpp">
|
<ClCompile Include="Analysis\ClientFunctionFinder.cpp">
|
||||||
<Filter>Source Files\Analysis</Filter>
|
<Filter>Header Files\fa</Filter>
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Analysis\FunctionDetector.cpp">
|
|
||||||
<Filter>Source Files\Analysis</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Analysis\BeaInterpreter.cpp">
|
|
||||||
<Filter>Source Files\Analysis</Filter>
|
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -308,32 +311,38 @@
|
||||||
<ClInclude Include="dynamicmem.h">
|
<ClInclude Include="dynamicmem.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Analysis\Meta.h">
|
|
||||||
<Filter>Analysis</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Analysis\AnalysisRunner.h">
|
<ClInclude Include="Analysis\AnalysisRunner.h">
|
||||||
<Filter>Analysis</Filter>
|
<Filter>Header Files\fa</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Analysis\StackEmulator.h">
|
<ClInclude Include="Analysis\StackEmulator.h">
|
||||||
<Filter>Analysis</Filter>
|
<Filter>Header Files\fa</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Analysis\RegisterEmulator.h">
|
<ClInclude Include="Analysis\RegisterEmulator.h">
|
||||||
<Filter>Analysis</Filter>
|
<Filter>Header Files\fa</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Analysis\IntermodularCalls.h">
|
<ClInclude Include="Analysis\FlowGraph.h">
|
||||||
<Filter>Analysis</Filter>
|
<Filter>Header Files\fa</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Analysis\ICommand.h">
|
<ClInclude Include="Analysis\Meta.h">
|
||||||
<Filter>Analysis</Filter>
|
<Filter>Header Files\fa</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Analysis\ApiDB.h">
|
<ClInclude Include="Analysis\Node_t.h">
|
||||||
<Filter>Analysis</Filter>
|
<Filter>Header Files\fa</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Analysis\FunctionDetector.h">
|
<ClInclude Include="Analysis\Edge_t.h">
|
||||||
<Filter>Analysis</Filter>
|
<Filter>Header Files\fa</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Analysis\BeaInterpreter.h">
|
<ClInclude Include="Analysis\ClientApiResolver.h">
|
||||||
<Filter>Analysis</Filter>
|
<Filter>Header Files\fa</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Analysis\ClientInterface.h">
|
||||||
|
<Filter>Header Files\fa</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Analysis\FunctionInfo.h">
|
||||||
|
<Filter>Header Files\fa</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Analysis\ClientFunctionFinder.h">
|
||||||
|
<Filter>Header Files\fa</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
Loading…
Reference in New Issue