模拟器与程序分析-3-用程序分析器pin和valgrind获得callgraph

引言

Pin是一个Intel公司maintain针对IA-32和X86-64体系结构的动态二进制指令分析的framework。可以对基于LINUX和Windows平台的user space的程序进行分析。既然是Dynamic的程序分析tool,所以。。。。。你懂的。

 

与valgrind不同,pin不是opensource的,但他提供了非常rich的API,咱么可以用这些API,弄出很多咱们想要的程序分析工具。就好像咱们用OS的API可能编出很多不同功能的软件一样。

此外,Pin is proprietary software developed and supported by Intel and is supplied free of charge for non-commercial use.

 

程序分析方面,callgraph很重要。

3.1install

pin的安装很简单,这里就不说了。for more details,plz click the link:

http://pintool.org/

 

3.2 test

pin提供了很多例子,放在 source/tool/SimpleExamples和source/tool/ManualExamples

你会看到好多*.cpp和*.py的文件,

make之后会生成*.so文件,就是对应的pintool。

然后可以用以下命令测试:

pin -t [pintool_name].so -- /bin/ls

之后,会生成[pintool_name].out文件,就是分析结果。

 

3.3 callgraph generation

callgraph的获得跟其他的tool有一些区别,他不是用C++写的,而是用python写的。具体usage在callgraph.py里面有。

步骤:以获得rill.c的callgraph为例:

1,编译程序,生成可执行img

gcc rill.c -o rill

2,生成symbol文件:symbol.txt

readelf -s rill | grep FUNC > symbol.txt

3,生成edge 文件:edgcnt.out

pin -t edgcnt.so -- rill

4,生成callgraph,这个有点曲折,需要解决两个问题

python callgraph.py -t 2 symbol.txt edgcnt.out

会出现问题1: too many values to be unpacked

这是callgraph.py脚本里面分析的symbol文件与用readelf生成的稍微有区别导致的。callgraph.py脚本要求symbol.txt每一行是8列,但是实际生成的可能多一列,手工修改symbol.txt,把最后一列去掉,OK。

 

再执行以下命令,出现问题2:unsupported edge file version 4.0。

这是callgraph.py脚本支持的edge文件的版本与实际用pin生成的有区别导致。callgraph.py里面调用的解析edge 文件的函数(python的库函数,ProcessEdgProfile())支持2.0和3.0,但是我用pin生成的edge文件时4.0。请参考:同样,手动修改edgcun.out文件中的版本,将4.0改为3.0或2.0,OK!

http://162.105.203.28/svn/vs/xen/branches/pebs/pin/source/tools/SimpleExamples/flowgraph.py

下面是截图:

模拟器与程序分析-3-用程序分析器pin和valgrind获得callgraph_第1张图片

 

最后,再重新执行以下命令,就可以看到分析结果了,当然可能还有其他问题,那就是脚本本身或者参数设置的问题了,这已经超出了本小节的内容。

调试callgrapy.py,可以得到分析结果:

Reading Symbols
two routines with same address 0: __libc_start_main@GLIBC_2.0 vs printf@GLIBC_2.0
two routines with same address 0: __libc_start_main@GLIBC_2.0 vs __libc_start_main@@GLIBC_
two routines with same address 0: __libc_start_main@GLIBC_2.0 vs printf@@GLIBC_2.0
found 12 symbols
Reading edges
Read 0 edges
// ###################################################################################
// VCG Callgraph: cutoff 1,  threshold 1
// ###################################################################################
graph:
{
title: "Call Graph"
label: "Call Graph"
display_edge_labels: yes
layout_downfactor: 100
layout_nearfactor: 10
layout_upfactor: 1
layout_algorithm: mindepth
manhatten_edges: yes
edge.arrowsize: 15
late_edge_labels: yes
        node:
        {
                title: "0x0L"
                label: "__libc_start_main@GLIBC_2.0: 0x0L\nicnt: 0  ocnt: 0"   }

        node:
        {
                title: "0x8048250L"
                label: "_init: 0x8048250L\nicnt: 0  ocnt: 0"    }

        node:
        {
                title: "0x80482B0L"
                label: "_start: 0x80482B0L\nicnt: 0  ocnt: 0"   }

        node:
        {
                title: "0x80482D4L"
                label: "call_gmon_start: 0x80482D4L\nicnt: 0  ocnt: 0"  }

        node:
        {
                title: "0x8048300L"
                label: "__do_global_dtors_aux: 0x8048300L\nicnt: 0  ocnt: 0"   }

        node:
        {
                title: "0x8048360L"
                label: "frame_dummy: 0x8048360L\nicnt: 0  ocnt: 0"      }

        node:
        {
                title: "0x8048384L"
                label: "main: 0x8048384L\nicnt: 0  ocnt: 0"     }

        node:
        {
                title: "0x80483D0L"
                label: "__libc_csu_fini: 0x80483D0L\nicnt: 0  ocnt: 0"  }

        node:
        {
                title: "0x80483E0L"
                label: "__libc_csu_init: 0x80483E0L\nicnt: 0  ocnt: 0"  }

        node:
        {
                title: "0x8048449L"
                label: "__i686.get_pc_thunk.bx: 0x8048449L\nicnt: 0  ocnt: 0"  }

        node:
        {
                title: "0x8048450L"
                label: "__do_global_ctors_aux: 0x8048450L\nicnt: 0  ocnt: 0"   }

        node:
        {
                title: "0x8048478L"
                label: "_fini: 0x8048478L\nicnt: 0  ocnt: 0"    }

}


 

3.4 用valgrind产生callgraph

valgrind也可以得到程序的callgraph,请参考:

http://valgrind.org/docs/manual/cl-manual.html

自己可以写一个GUI,将文本弄成图形的,如图:

模拟器与程序分析-3-用程序分析器pin和valgrind获得callgraph_第2张图片

 

3.5 小结

pin和valgrind都会用了吧。enjoy!any questions,plz let me know.

你可能感兴趣的:(模拟器与程序分析-3-用程序分析器pin和valgrind获得callgraph)