BVB Source Codes

x64dbg Show recursiveanalysis.cpp Source code

Return Download x64dbg: download recursiveanalysis.cpp Source code - Download x64dbg Source code - Type:.cpp
  1. #include "recursiveanalysis.h"
  2. #include <queue>
  3. #include "console.h"
  4. #include "filehelper.h"
  5. #include "function.h"
  6. #include "xrefs.h"
  7. #include "plugin_loader.h"
  8.  
  9. RecursiveAnalysis::RecursiveAnalysis(duint base, duint size, duint entryPoint, duint maxDepth, bool usePlugins, bool dump)
  10.     : Analysis(base, size),
  11.       mEntryPoint(entryPoint),
  12.       mMaxDepth(maxDepth),
  13.       mUsePlugins(usePlugins),
  14.       mDump(dump)
  15. {
  16. }
  17.  
  18. void RecursiveAnalysis::Analyse()
  19. {
  20.     //TODO: implement queue to analyze multiple functions
  21.     analyzeFunction(mEntryPoint);
  22. }
  23.  
  24. void RecursiveAnalysis::SetMarkers()
  25. {
  26.     if(mDump)
  27.         for(const auto & function : mFunctions)
  28.             FileHelper::WriteAllText(StringUtils::sprintf("cfgraph_%p.dot", function.entryPoint), GraphToDot(function));
  29.  
  30.     //set function ranges
  31.     for(const auto & function : mFunctions)
  32.     {
  33.         duint start = ~0;
  34.         duint end = 0;
  35.         duint icount = 0;
  36.         for(const auto & node : function.nodes)
  37.         {
  38.             if(!inRange(node.second.start))
  39.                 continue;
  40.             icount += node.second.icount;
  41.             start = min(node.second.start, start);
  42.             end = max(node.second.end, end);
  43.         }
  44.         XrefDelRange(start, end);
  45.         if(!FunctionAdd(start, end, false, icount))
  46.         {
  47.             FunctionDelete(start);
  48.             FunctionDelete(end);
  49.             FunctionAdd(start, end, false, icount);
  50.         }
  51.     }
  52.  
  53.     //set xrefs
  54.     for(const auto & xref : mXrefs)
  55.         XrefAdd(xref.addr, xref.from);
  56.  
  57.     GuiUpdateAllViews();
  58. }
  59.  
  60. void RecursiveAnalysis::analyzeFunction(duint entryPoint)
  61. {
  62.     //first pass: BFS through the disassembly starting at entryPoint
  63.     CFGraph graph(entryPoint);
  64.     UintSet visited;
  65.     std::queue<duint> queue;
  66.     queue.push(graph.entryPoint);
  67.     while(!queue.empty())
  68.     {
  69.         auto start = queue.front();
  70.         queue.pop();
  71.         if(visited.count(start)) //already visited
  72.             continue;
  73.         visited.insert(start);
  74.  
  75.         CFNode node(graph.entryPoint, start, start);
  76.  
  77.         if(!inRange(start)) //out of range
  78.         {
  79.             graph.AddNode(node);
  80.             continue;
  81.         }
  82.  
  83.         while(true)
  84.         {
  85.             if(!inRange(node.end))
  86.             {
  87.                 node.end = mCp.Address();
  88.                 node.terminal = true;
  89.                 graph.AddNode(node);
  90.                 break;
  91.             }
  92.  
  93.             node.icount++;
  94.             if(!mCp.Disassemble(node.end, translateAddr(node.end)))
  95.             {
  96.                 node.end++;
  97.                 continue;
  98.             }
  99.  
  100.             //do xref analysis on the instruction
  101.             XREF xref;
  102.             xref.addr = 0;
  103.             xref.from = mCp.Address();
  104.             for(auto i = 0; i < mCp.OpCount(); i++)
  105.             {
  106.                 duint dest = mCp.ResolveOpValue(i, [](x86_reg)->size_t
  107.                 {
  108.                     return 0;
  109.                 });
  110.                 if(inRange(dest))
  111.                 {
  112.                     xref.addr = dest;
  113.                     break;
  114.                 }
  115.             }
  116.             if(xref.addr)
  117.                 mXrefs.push_back(xref);
  118.  
  119.             if(mCp.InGroup(CS_GRP_JUMP) || mCp.IsLoop()) //jump
  120.             {
  121.                 //set the branch destinations
  122.                 node.brtrue = mCp.BranchDestination();
  123.                 if(mCp.GetId() != X86_INS_JMP && mCp.GetId() != X86_INS_LJMP)  //unconditional jumps dont have a brfalse
  124.                     node.brfalse = node.end + mCp.Size();
  125.  
  126.                 //consider register/memory branches as terminal nodes
  127.                 if(mCp[0].type != X86_OP_IMM)
  128.                     node.terminal = true;
  129.  
  130.                 //add node to the function graph
  131.                 graph.AddNode(node);
  132.  
  133.                 //enqueue branch destinations
  134.                 if(node.brtrue)
  135.                     queue.push(node.brtrue);
  136.                 if(node.brfalse)
  137.                     queue.push(node.brfalse);
  138.  
  139.                 break;
  140.             }
  141.             if(mCp.InGroup(CS_GRP_CALL))  //call
  142.             {
  143.                 //TODO: add this to a queue to be analyzed later
  144.             }
  145.             if(mCp.InGroup(CS_GRP_RET))  //return
  146.             {
  147.                 node.terminal = true;
  148.                 graph.AddNode(node);
  149.                 break;
  150.             }
  151.             node.end += mCp.Size();
  152.         }
  153.     }
  154.     //second pass: split overlapping blocks introduced by backedges
  155.     for(auto & nodeIt : graph.nodes)
  156.     {
  157.         auto & node = nodeIt.second;
  158.         duint addr = node.start;
  159.         duint icount = 0;
  160.         while(addr < node.end)
  161.         {
  162.             icount++;
  163.             auto size = mCp.Disassemble(addr, translateAddr(addr)) ? mCp.Size() : 1;
  164.             if(graph.nodes.count(addr + size))
  165.             {
  166.                 node.end = addr;
  167.                 node.split = true;
  168.                 node.brtrue = addr + size;
  169.                 node.brfalse = 0;
  170.                 node.terminal = false;
  171.                 node.icount = icount;
  172.                 break;
  173.             }
  174.             addr += size;
  175.         }
  176.     }
  177.     //third pass: correct the parents + add brtrue and brfalse to the exits + get data
  178.     graph.parents.clear();
  179.     for(auto & nodeIt : graph.nodes)
  180.     {
  181.         auto & node = nodeIt.second;
  182.         graph.AddParent(node.start, node.brtrue);
  183.         graph.AddParent(node.start, node.brfalse);
  184.         if(node.brtrue)
  185.             node.exits.push_back(node.brtrue);
  186.         if(node.brfalse)
  187.             node.exits.push_back(node.brfalse);
  188.         if(node.brtrue && !node.brfalse)
  189.             node.brtrue = 0;
  190.         if(!node.icount)
  191.             continue;
  192.         node.instrs.reserve(node.icount);
  193.         auto addr = node.start;
  194.         while(addr <= node.end)
  195.         {
  196.             auto size = mCp.Disassemble(addr, translateAddr(addr)) ? mCp.Size() : 1;
  197.             BridgeCFInstruction instr;
  198.             instr.addr = addr;
  199.             for(int i = 0; i < size; i++)
  200.                 instr.data[i] = inRange(addr + i) ? *translateAddr(addr + i) : 0;
  201.             node.instrs.push_back(instr);
  202.             addr += size;
  203.         }
  204.     }
  205.     //fourth pass: allow plugins to manipulate the graph
  206.     if(mUsePlugins && !plugincbempty(CB_ANALYZE))
  207.     {
  208.         PLUG_CB_ANALYZE info;
  209.         info.graph = graph.ToGraphList();
  210.         plugincbcall(CB_ANALYZE, &info);
  211.         graph = BridgeCFGraph(&info.graph, true);
  212.     }
  213.     mFunctions.push_back(graph);
  214. }
  215.  
downloadrecursiveanalysis.cpp Source code - Download x64dbg Source code
Related Source Codes/Software:
pencil - Multiplatform GUI Prototyping/Wireframing 2017-04-16
rainloop-webmail - Simple, modern & fast web-based email client ... 2017-04-16
qt - Qt binding for Go (Golang) which supports Windows ... 2017-04-16
MLeaksFinder - Find memory leaks in your iOS app at develop time. 2017-04-16
jsfeat - JavaScript Computer Vision library. 2017-04-16
later - A javascript library for defining recurring schedu... 2017-04-16
Android-ItemTouchHelper-Demo - Basic example of using ItemTouchHelper to add drag... 2017-04-16
onionshare - Securely and anonymously share a file of any size ... 2017-04-16
android-viewflow - A horizontal view scroller library for Android 2017-04-16
css-in-js - React: CSS in JS techniques comparison. 2017-04-16
mama2 - Mother plan - all firewood high flame 2017-04-23
BlurEffectForAndroidDesign - Sample to show how to implement blur graphical tri... 2017-04-23
sphinx_rtd_theme - Sphinx theme for readthedocs.org 2017-04-23
rouge - A pure-ruby code highlighter that is compatible wi... 2017-04-23
spring-security-oauth - Support for adding OAuth1(a) and OAuth2 features (... 2017-04-23
Toucan - Fabulous Image Processing in Swift 2017-04-23
CoffeeScriptRedux - 2017-04-23
breakpoint - Really simple media queries in Sa 2017-04-23
libsvm - 2017-04-22
grr - GRR Rapid Response: remote live forensics for inci... 2017-04-22

 Back to top