通过二进制程序得到函数间的调用关系的探究

【背景介绍】

      通过静态分析反汇编后的代码取得函数调用关系的一种探究linux ELF Executable and Linkable Format,就是我们比较常见linux下可执行二进制程序,这个世上任何文件都有它自己的格式,linux下二进制程序文件也不例外即elf。windows下的为PE格式(传说pe格式是由elf格式演变来的)。elf包含了程序文件的大量的信息,本文就是分析了这些信息实现了函数调用关系的产出。

 

 一、 elf格式二进制程序的信息采集
     Objdump是个强大的工具,命令行显示程序反汇编
     Objdump –d targetfile
     Tagetfile就是要分析的二进制程序
     效果如图:

      反汇编后的代码形式虽然是汇编代码组成但与cpp源代码一样,也是由N个函数体所组成,但函数体变得更规范且把所以函数体放在一个文体里方便分析,所有函数调用的地方都是”callq”关键字(与编译器有关),这一点很助于数据格式的抽取与分析,如上图函数名为”_Z6thr_fnPv”,编译器碰到C++函数就会把它变成这种形状,linux自带了另一个非常强大的工具c++filt:
得到了函数的原形“thr_fn(void*)”。
如果你想得到函数调用的源代码位置也可以
在编译程序时加上-g选项,你会得到更多的程序信息,
Objdump –S -l targetfile
反汇编请见下图:


         

如图所示,这是源代码与反汇编混合的代码形式,我们可以取得每一个函数定义的代码位置。

    可见main函数的代码位置threadtest.cpp:40
    也可以得到每次调用函数时的代码位置

     可见pthread_create函数的被main函数的调用代码位置为threadtest.cpp:42

      至此,我们可以得到函数的名字,函数定义的代码位置,函数体内调用某函数时代码位置,根据这些要素,我们就可以知道,函数的调用关系及其代码位置。下面是怎么获取并保存关系图的算法。

二、  算法
    1、函数调用要素的采集算法 (shell代码实现)
       A、  函数定义的信息采集
             “000000000043a03c:"
               if [[ "$linetmp" =~ " <.*>:" ]]; then 认为本行为函数定义
callfun=`echo $line|awk -F “<" '{print $2}' |awk -F ">” ‘{print $1}’|sed ‘s/@plt$//g’|c++filt`,可以取得定义的函数名。

              如果它有源代码信息它的下一行要满足if [[ "$linetmp" =~ "):$" ]]; then,
            第三行满足if [[ "$linetmp" =~ "[a-zA-Z][:][0-9][0-9]*$” ]]; then 此时就可以 取得函数定义的源代码位置

      B、函数调用的信息采集

     if [[ "$linetmp" =~ " callq " ]]; then认为是调用函数的位置
             callfun=`echo $line|awk -F ” 取得被调用的函数名
             调用位置的前面最近的代码位置就是调用函数时的代码位置

      2、函数调用图算法(c++代码实现)
      每个函数的关联就是它们之间的直接调用关系,
      struct functionnode
      {
      string funname; //函数全名
      string definefuncpp; //定义的代码代置
      list fatherfunlist; //调用此函数的函数list
      list callthislist; //父函数调用本函数的代码位置,与fatherfunlist对应
      list childfunlist; //此函数调用的函数列表
      };

       如同一个双向链表,每一个函数结点,都有指向被它调用的函数列表,和调用的函数列表。
这样就形成了一张网络图,如图

                         


大咖招募
欢迎App研发/测试方面的大牛来投稿,开设专栏。我们提供丰厚的稿酬,预约个人专访,帮助建立个人技术品牌!
立即投稿

我要评论

字数不能超过140字,谢谢!
提交

评论({{allComments.length}})

{{comment.create_time.substr(0,16)}}

显示所有评论
复制成功!