1
0
Fork 0

DBG (ANALYSIS): formatting

This commit is contained in:
Mr. eXoDia 2014-08-27 15:20:53 +02:00
parent 8399a77015
commit 3cb5805d5c
8 changed files with 224 additions and 218 deletions

View File

@ -62,7 +62,7 @@ void AnalysisRunner::start()
return; return;
dputs("[StaticAnalysis] analysis started ..."); dputs("[StaticAnalysis] analysis started ...");
buildGraph(); buildGraph();
Grph->fillNodes(); Grph->fillNodes();
emulateInstructions(); emulateInstructions();
dputs("[StaticAnalysis] analysis finished ..."); dputs("[StaticAnalysis] analysis finished ...");
} }
@ -111,8 +111,8 @@ bool AnalysisRunner::disasmChilds(const duint subTreeStartAddress, const duint p
{ {
// disassemble instruction // disassemble instruction
const int instrLength = Disasm(&disasm); const int instrLength = Disasm(&disasm);
DISASM *disasm2 = new DISASM; DISASM* disasm2 = new DISASM;
*disasm2 = disasm; *disasm2 = disasm;
// everything ok? // everything ok?
if(instrLength != UNKNOWN_OPCODE) if(instrLength != UNKNOWN_OPCODE)
{ {
@ -304,7 +304,7 @@ void AnalysisRunner::emulateInstructions()
Register->emulate(&(it->second.BeaStruct)); Register->emulate(&(it->second.BeaStruct));
//for(std::vector<ClientInterface>::iterator itt = interfaces.begin();itt!=interfaces.end();itt++) //for(std::vector<ClientInterface>::iterator itt = interfaces.begin();itt!=interfaces.end();itt++)
a->see(it->second,Register,Stack); a->see(it->second, Register, Stack);
b->see(it->second, Register, Stack); b->see(it->second, Register, Stack);
// next instruction // next instruction
it++; it++;

View File

@ -21,32 +21,33 @@ void ClientApiResolver::see(const Instruction_t Instr, const RegisterEmulator* r
Node_t* n; Node_t* n;
if(Analysis->graph()->find((duint)Instr.BeaStruct.VirtualAddr, n)) if(Analysis->graph()->find((duint)Instr.BeaStruct.VirtualAddr, n))
{ {
n = Analysis->graph()->node((duint)Instr.BeaStruct.VirtualAddr); n = Analysis->graph()->node((duint)Instr.BeaStruct.VirtualAddr);
// is there an edge going out? // is there an edge going out?
if(n->outEdge != NULL) if(n->outEdge != NULL)
{ {
if(n->outEdge->type == fa::CALL) if(n->outEdge->type == fa::CALL)
{ {
ttDebug("api: found call at "fhex" to "fhex" \n", (duint)Instr.BeaStruct.VirtualAddr,n->outEdge->end->vaddr); ttDebug("api: found call at "fhex" to "fhex" \n", (duint)Instr.BeaStruct.VirtualAddr, n->outEdge->end->vaddr);
// test if the end has an edge, too // test if the end has an edge, too
ttDebug("api: opcode is %x \n",(((n->outEdge->end))->instruction.BeaStruct.Instruction.Opcode)&0xFF); ttDebug("api: opcode is %x \n", (((n->outEdge->end))->instruction.BeaStruct.Instruction.Opcode) & 0xFF);
ttDebug("api: opcode is %x \n",Analysis->graph()->node(n->outEdge->end->vaddr)->instruction.BeaStruct.Instruction.Opcode); ttDebug("api: opcode is %x \n", Analysis->graph()->node(n->outEdge->end->vaddr)->instruction.BeaStruct.Instruction.Opcode);
if(((n->outEdge->end))->instruction.BeaStruct.Instruction.Opcode == 0xFF){ if(((n->outEdge->end))->instruction.BeaStruct.Instruction.Opcode == 0xFF)
tDebug("api: --> is API CALL\n", (duint)n->outEdge->end->instruction.BeaStruct.VirtualAddr); {
// there is an api call tDebug("api: --> is API CALL\n", (duint)n->outEdge->end->instruction.BeaStruct.VirtualAddr);
//DbgSetAutoCommentAt((duint)Instr.BeaStruct.VirtualAddr, "hi"); // there is an api call
//DbgSetAutoCommentAt((duint)Instr.BeaStruct.VirtualAddr, "hi");
}
return;
}
}
} }
return;
}
}
}
// test if node exists // test if node exists
// Node_t n; // Node_t n;
// if(Analysis->graph()->find((duint)Instr.BeaStruct.VirtualAddr,n)){ // if(Analysis->graph()->find((duint)Instr.BeaStruct.VirtualAddr,n)){

View File

@ -45,12 +45,13 @@ void ClientFunctionFinder::see(const Instruction_t Instr, const RegisterEmulator
// there is a branching! // there is a branching!
if(n->outEdge->type == fa::RET) if(n->outEdge->type == fa::RET)
{ {
if((duint) n->outEdge->end->instruction.BeaStruct.Instruction.AddrValue != Analysis->oep()){ if((duint) n->outEdge->end->instruction.BeaStruct.Instruction.AddrValue != Analysis->oep())
// internal call {
DbgSetAutoFunctionAt((duint)n->outEdge->end->instruction.BeaStruct.Instruction.AddrValue, (duint)Instr.BeaStruct.VirtualAddr); // internal call
tDebug("add function from "fhex" to "fhex"\n",(duint) n->outEdge->end->instruction.BeaStruct.Instruction.AddrValue, (duint)Instr.BeaStruct.VirtualAddr); DbgSetAutoFunctionAt((duint)n->outEdge->end->instruction.BeaStruct.Instruction.AddrValue, (duint)Instr.BeaStruct.VirtualAddr);
} tDebug("add function from "fhex" to "fhex"\n", (duint) n->outEdge->end->instruction.BeaStruct.Instruction.AddrValue, (duint)Instr.BeaStruct.VirtualAddr);
}
} }
} }

View File

@ -6,126 +6,130 @@
namespace fa namespace fa
{ {
FlowGraph::FlowGraph(AnalysisRunner * ana) : analysis(ana) FlowGraph::FlowGraph(AnalysisRunner* ana) : analysis(ana)
{ {
} }
FlowGraph::~FlowGraph(void) FlowGraph::~FlowGraph(void)
{ {
} }
bool FlowGraph::insertNode(Node_t* node) bool FlowGraph::insertNode(Node_t* node)
{ {
// if (!contains(nodes,(duint)node->vaddr)) // if (!contains(nodes,(duint)node->vaddr))
// { // {
// return (nodes.insert(std::make_pair<duint,Node_t*>(node->vaddr,node))).second; // return (nodes.insert(std::make_pair<duint,Node_t*>(node->vaddr,node))).second;
// } // }
return true; return true;
} }
bool FlowGraph::insertEdge(Node_t* startNode, Node_t* endNode, EdgeType currentEdgeType) bool FlowGraph::insertEdge(Node_t* startNode, Node_t* endNode, EdgeType currentEdgeType)
{ {
Node_t *workStart; Node_t* workStart;
Node_t *workEnd; Node_t* workEnd;
if(!contains(nodes,startNode->vaddr)){ if(!contains(nodes, startNode->vaddr))
nodes.insert(std::pair<duint,Node_t*>(startNode->vaddr, startNode)); {
} nodes.insert(std::pair<duint, Node_t*>(startNode->vaddr, startNode));
if(!contains(nodes,endNode->vaddr)){ }
nodes.insert(std::pair<duint,Node_t*>(endNode->vaddr, endNode)); if(!contains(nodes, endNode->vaddr))
} {
nodes.insert(std::pair<duint, Node_t*>(endNode->vaddr, endNode));
}
workStart = &*(nodes.find(startNode->vaddr)->second); workStart = &*(nodes.find(startNode->vaddr)->second);
workEnd = &*(nodes.find(endNode->vaddr)->second); workEnd = &*(nodes.find(endNode->vaddr)->second);
if (startNode->hasInstr && !((nodes.find(startNode->vaddr)->second))->hasInstr){ if(startNode->hasInstr && !((nodes.find(startNode->vaddr)->second))->hasInstr)
ttDebug("updating old startnode"); {
workStart->instruction = startNode->instruction; ttDebug("updating old startnode");
} workStart->instruction = startNode->instruction;
}
// now workStart and workEnd are most up-to-date information // now workStart and workEnd are most up-to-date information
Edge_t* edge = new Edge_t(workStart, workEnd, currentEdgeType); Edge_t* edge = new Edge_t(workStart, workEnd, currentEdgeType);
edges.insert(std::pair<duint,Edge_t*>(workStart->vaddr,edge)); edges.insert(std::pair<duint, Edge_t*>(workStart->vaddr, edge));
std::map<duint,Edge_t*>::iterator ansiter = edges.find(workStart->vaddr); std::map<duint, Edge_t*>::iterator ansiter = edges.find(workStart->vaddr);
edge = &*(ansiter->second); edge = &*(ansiter->second);
edge->start = workStart; edge->start = workStart;
edge->end = workEnd; edge->end = workEnd;
workStart->outEdge = edge; workStart->outEdge = edge;
workEnd->inEdges.insert(edge); workEnd->inEdges.insert(edge);
return true; return true;
} }
void FlowGraph::clean() void FlowGraph::clean()
{ {
// first delete all edges whoses aks for it // first delete all edges whoses aks for it
std::map<duint, Edge_t*>::iterator e = edges.begin(); std::map<duint, Edge_t*>::iterator e = edges.begin();
while(e != edges.end()) while(e != edges.end())
{ {
std::map<duint, Edge_t*>::iterator current = e++; std::map<duint, Edge_t*>::iterator current = e++;
if((*current->second).askForRemove) if((*current->second).askForRemove)
{ {
delete current->second; 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::map<duint, Node_t*>::iterator n = nodes.begin(); std::map<duint, Node_t*>::iterator n = nodes.begin();
while(n != nodes.end()) while(n != nodes.end())
{ {
std::map<duint, Node_t*>::iterator current = n++; std::map<duint, Node_t*>::iterator current = n++;
if((!(*current->second).outEdge) && ((*current->second).inEdges.size() == 0)) if((!(*current->second).outEdge) && ((*current->second).inEdges.size() == 0))
{ {
delete current->second; delete current->second;
nodes.erase(current); nodes.erase(current);
} }
} }
} }
bool FlowGraph::find(const duint va , Node_t* node) bool FlowGraph::find(const duint va , Node_t* node)
{ {
if(contains(nodes, va)) if(contains(nodes, va))
{ {
std::map<duint, Node_t*>::iterator iter = nodes.find(va); std::map<duint, Node_t*>::iterator iter = nodes.find(va);
node = (iter->second); node = (iter->second);
tDebug("-> found node at "fhex" \n", node->vaddr); tDebug("-> found node at "fhex" \n", node->vaddr);
tDebug("Node_t address is "fhex" \n", node); tDebug("Node_t address is "fhex" \n", node);
return true; return true;
} }
return false; return false;
} }
Node_t* FlowGraph::node(const duint va) Node_t* FlowGraph::node(const duint va)
{ {
if(contains(nodes, va)) if(contains(nodes, va))
{ {
std::map<duint, Node_t*>::iterator iter = nodes.find(va); std::map<duint, Node_t*>::iterator iter = nodes.find(va);
Node_t* node = (iter->second); Node_t* node = (iter->second);
return node; return node;
} }
return NULL; return NULL;
} }
void FlowGraph::fillNodes() void FlowGraph::fillNodes()
{ {
for(std::map<duint, Node_t*>::iterator i=nodes.begin();i!=nodes.end();i++){ for(std::map<duint, Node_t*>::iterator i = nodes.begin(); i != nodes.end(); i++)
i->second->hasInstr=true; {
i->second->instruction.BeaStruct = analysis->instruction_t(i->first).BeaStruct; i->second->hasInstr = true;
if(i->second->instruction.BeaStruct.Instruction.Opcode == 0xFF) i->second->instruction.BeaStruct = analysis->instruction_t(i->first).BeaStruct;
ttDebug("ext jump at %x",i->first); if(i->second->instruction.BeaStruct.Instruction.Opcode == 0xFF)
} ttDebug("ext jump at %x", i->first);
} }
}

View File

@ -18,9 +18,9 @@ class FlowGraph
// all existing nodes // all existing nodes
std::map<duint, Node_t*> nodes; std::map<duint, Node_t*> nodes;
AnalysisRunner *analysis; AnalysisRunner* analysis;
public: public:
FlowGraph(AnalysisRunner *ana); FlowGraph(AnalysisRunner* ana);
~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
@ -28,7 +28,7 @@ public:
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
bool insertEdge(Node_t* start, Node_t* end, EdgeType btype); bool insertEdge(Node_t* start, Node_t* end, EdgeType btype);
void fillNodes(); void fillNodes();
bool find(const duint va, Node_t* node); bool find(const duint va, Node_t* node);
Node_t* FlowGraph::node(const duint va); Node_t* FlowGraph::node(const duint va);

View File

@ -28,92 +28,92 @@
namespace fa namespace fa
{ {
enum EdgeType{RET,CALL,EXTERNCALL,CONDJMP,UNCONDJMP,EXTERNJMP,INF,UNKOWN}; enum EdgeType {RET, CALL, EXTERNCALL, CONDJMP, UNCONDJMP, EXTERNJMP, INF, UNKOWN};
// every edge in the application flow graph is an instruction that active modifies the EIP
typedef struct Instruction_t
{
DISASM BeaStruct;
unsigned int Length;
Instruction_t(DISASM* dis, unsigned int len)
{
BeaStruct = *dis;
Length = len;
}
Instruction_t()
{
BeaStruct = DISASM();
Length = UNKNOWN_OPCODE;
}
} Instruction_t;
struct ArgumentInfo_t
{
std::string Type;
std::string Name;
ArgumentInfo_t(std::string t, std::string n)
{
Type = t;
Name = n;
}
ArgumentInfo_t() {}
};
struct FunctionInfo_t
{
std::string DLLName;
std::string ReturnType;
std::string Name;
std::vector<ArgumentInfo_t> Arguments;
bool invalid;
FunctionInfo_t()
{
invalid = false;
}
FunctionInfo_t(std::string dll, std::string ret, std::string name, std::vector<ArgumentInfo_t> args)
{
DLLName = dll;
ReturnType = ret;
Name = name;
Arguments = args;
invalid = false;
}
// !! suppresses the warning (ugly solution)
bool operator==(const FunctionInfo_t & rhs) const
{
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
{
return static_cast<bool>(!!_strcmpi(Name.c_str(), rhs.Name.c_str()));
}
ArgumentInfo_t arg(int i)
{
return Arguments.at(i);
}
};
template<typename T, typename D> // every edge in the application flow graph is an instruction that active modifies the EIP
bool contains(std::map<T, D> s, T key)
{
std::map<T, D>::iterator it = s.find(key);
return (it != s.end());
}
typedef std::map<duint, Instruction_t>::const_iterator instrIter; typedef struct Instruction_t
{
DISASM BeaStruct;
unsigned int Length;
Instruction_t(DISASM* dis, unsigned int len)
{
BeaStruct = *dis;
Length = len;
}
Instruction_t()
{
BeaStruct = DISASM();
Length = UNKNOWN_OPCODE;
}
} Instruction_t;
struct ArgumentInfo_t
{
std::string Type;
std::string Name;
ArgumentInfo_t(std::string t, std::string n)
{
Type = t;
Name = n;
}
ArgumentInfo_t() {}
};
struct FunctionInfo_t
{
std::string DLLName;
std::string ReturnType;
std::string Name;
std::vector<ArgumentInfo_t> Arguments;
bool invalid;
FunctionInfo_t()
{
invalid = false;
}
FunctionInfo_t(std::string dll, std::string ret, std::string name, std::vector<ArgumentInfo_t> args)
{
DLLName = dll;
ReturnType = ret;
Name = name;
Arguments = args;
invalid = false;
}
// !! suppresses the warning (ugly solution)
bool operator==(const FunctionInfo_t & rhs) const
{
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
{
return static_cast<bool>(!!_strcmpi(Name.c_str(), rhs.Name.c_str()));
}
ArgumentInfo_t arg(int i)
{
return Arguments.at(i);
}
};
template<typename T, typename D>
bool contains(std::map<T, D> s, T key)
{
std::map<T, D>::iterator it = s.find(key);
return (it != s.end());
}
typedef std::map<duint, Instruction_t>::const_iterator instrIter;

View File

@ -11,7 +11,7 @@ Node_t::Node_t(Instruction_t t)
outEdge = NULL; outEdge = NULL;
instruction = t; instruction = t;
vaddr = (duint)t.BeaStruct.VirtualAddr; vaddr = (duint)t.BeaStruct.VirtualAddr;
hasInstr=true; hasInstr = true;
} }
Node_t::Node_t(duint va) Node_t::Node_t(duint va)
@ -19,7 +19,7 @@ Node_t::Node_t(duint va)
outEdge = NULL; outEdge = NULL;
instruction = Instruction_t(); instruction = Instruction_t();
vaddr = va; vaddr = va;
hasInstr = false; hasInstr = false;
} }
Node_t::~Node_t() Node_t::~Node_t()

View File

@ -14,7 +14,7 @@ public:
std::set<Edge_t*> inEdges; // all incoming edges std::set<Edge_t*> inEdges; // all incoming edges
Instruction_t instruction; Instruction_t instruction;
duint vaddr; duint vaddr;
bool hasInstr; bool hasInstr;
Node_t(Instruction_t t); Node_t(Instruction_t t);
Node_t(duint t); Node_t(duint t);