Algorithm 使用程序计数器(指令指针)值中的模式检测循环

Algorithm 使用程序计数器(指令指针)值中的模式检测循环,algorithm,parsing,reverse-engineering,Algorithm,Parsing,Reverse Engineering,我有程序计数器在执行特定代码时所取的值序列。使用这个,我想对生成这个可执行文件的原始代码进行一些静态分析(要清楚:原始代码不可用)-特别是,有多少个循环,以及它们是如何嵌套的。举个例子, A: for() B: if () C: ... D: else E: ... F: for () { G: ... H: ... I: } 在这种情况下,程序计数器序列可能是:A B C D F{G H I G

我有程序计数器在执行特定代码时所取的值序列。使用这个,我想对生成这个可执行文件的原始代码进行一些静态分析(要清楚:原始代码不可用)-特别是,有多少个循环,以及它们是如何嵌套的。举个例子,

A: for()
B:     if () 
C:         ...
D:     else
E:         ...
F:     for () {
G:         ...
H:         ...
I:     }
在这种情况下,程序计数器序列可能是:A B C D F{G H I G H I}A B D E F{G H I G H I}A B D E F{G H I G H H I}

从上面的序列中,我如何知道有两个循环,一个嵌套在另一个循环中?仅仅是指向要使用的适当解析技术的指针也会有所帮助

可以进行一些简化的假设,例如原始代码中没有goto和编译器优化的循环展开

  • 从程序计数器序列生成一个图,其中每个程序计数器是一个顶点,序列中的每对连续程序计数器是一条有向边。(如果从一个顶点到另一个顶点有多条边,则只保留其中一条边)
  • 从序列中第一个程序计数器生成的顶点开始,执行深度优先搜索以查找循环。找到每个循环后,将此循环的最后一条边移动到单独的列表中
  • 找到所有循环并将其移出图后,就有了一个DAG(有向无环图)。在此DAG上执行拓扑排序,以恢复程序中正确的语句序列,与源代码中的语句序列完全相同,但if/else块除外(您无法从程序计数器序列中确定哪个是“if”,哪个是“else”)。为了得到正确的结果,在拓扑排序没有规定任何特定顺序的情况下,应使用深度优先搜索顺序。为了正确放置while/for循环体,可以使用步骤2中的一些附加信息:循环检测算法可以标记每个循环的第二个节点
  • 要分析if/else块,请在图中创建单独的拆分/合并列表
  • 将循环列表(第2步提取)和if/else列表(第4步提取)合并为一个间隔列表。使用这些间隔的关系(其中一个嵌套在另一个内)为所有for/if/else语句构建树
  • 在某些情况下,“while”循环
    末尾的“if”块,而{…if{}}
    可能被错误地检测到,就像while{loop{}…},具有相同的起始地址“while”和“loop”。由于“while”的起始地址不能与任何嵌套循环的起始地址一致,因此可以很容易地将其后处理回
    while{…if{}
    。(嵌套的'do-while'循环可能具有相同的起始地址,但它们与嵌套的'if'没有任何问题)


  • 此方法仅在最简单的情况下有效,即没有“goto”、“break”或任何其他跳出循环,并且“for”循环仅检查单个条件。

    为什么不分析原始代码并检测其包含的循环(使用标准控制流分析算法)?PC值提供了什么(除了验证特定点实际上是代码之外)?[这对于故意将未执行跳转到无意义位置的模糊代码可能很有用]。。。我的反应来自这样一个事实:你声称拥有源代码,这是一个非常高质量的信息源,但你似乎在别处寻找同样的信息。@IraBaxter我编辑了这个问题,以澄清原始源代码不可用。抱歉搞混了。啊哈。好啊你通过执行某个东西获得了PC数据;你为什么不分析二进制文件?