突然要做一个项目要用到pin,当时我是一脸懵逼的,pin是什么,遂上网查找一番得到官网解释。
pin简介
Pin 是程序检测工具。它支持 IA-32、英特尔 (r) 64 和英特尔 (r) 许多集成核心体系结构的 Android、Linux、OS X 和 windows* 操作系统和可执行文件。
Pin 允许工具在可执行文件的任意位置插入任意代码 (用 c 或 c++ 编写)。代码在可执行文件运行时动态添加。这也使得将 Pin 附加到已运行的进程是可能的。
看样子跟编译c有关,支持多平台,不过是Intel的工具,AMD的电脑想用是不可能的了,也不是开源的呵呵。
接下来是pin的使用,为了跑出测试用例,我花了三天,搞得快吐血了,谁说的pin易上手,给我粗来(小声bb)
我原打算在Windows平台上跑的,打开官网文档
用于构建 Windows 工具的说明
由于pin工具使用make, 所以一定要先安装 cygwin。
打开与目标体系结构 (即 x86 或 x64) 对应的 Visual Studio 命令提示符, 然后按照 “生成示例工具” 部分中的步骤进行操作。
OK讲的很清楚,需要cygwin + vs,因为没有vs又不想下,所以放弃,另外尝试了在cygwin里跑pin的Linux版,但是失败了,想尝试的朋友还是放弃吧,山寨的果然还是太鸡肋了…
还是Linux下跑吧,我这win10的机子要么装虚拟机,听说win10可开启Linux子系统(WSL),便也想试试(什么虚拟机又大又慢,还不如用wsl,此处立下flag)。开启开发人员模式,安装Ubuntu LTS,登录运行美滋滋。不得不说wsl做的确实可以,比类Unix的终端强多了,但毕竟不是完善的产品。这是我踩的坑:
$ make inscount0.test TARGET=intel64
>
./pin: cannot execute binary file: Exec format error
一直以为是官网的包有问题,官网的包是32位的但我的系统是64位的,不知道为什么64位系统不能执行32位可执行文件,但是上网找了不少答案装了一堆包还是没有,让人绝望,最后意识到可能是我用的是WSL,又上网查找一番,找到WSL的issue:https://github.com/Microsoft/WSL/issues/2468 评论给了个暂时的解决方案:https://github.com/Microsoft/WSL/issues/2468#issuecomment-374904520
sudo dpkg --add-architecture i386
sudo apt install gcc:i386
sudo apt update
sudo apt install qemu-user-static
sudo update-binfmts --install i386 /usr/bin/qemu-i386-static --magic '\x7fELF\x01\x01\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x03\x00\x01\x00\x00\x00'
这样可以让win10下的Linux系统编译32位ELF文件,但还是执行不了pin:
$ ../../../pin -t obj-intel64/inscount0.so -- /bin/ls
>
qemu: Unsupported syscall: 26
Killed
E: Attach to pid 41 failed: Function not implemented
google一番,貌似是qemu-user-static这个包的bug,我居然一直在用有bug的工具,吐血···
最后还是装了虚拟机,为了照顾我的渣机特地选了VirtualBox 5.2 + Ubuntu Server 18.04 LTS,装机过程一直下一步就OK。
要是需要安装VirtualBox增强工具,见我另一篇博客
把我们下载的pin.xxx.tar.gz扔到共享文件夹,在Ubuntu的挂载文件夹输入:
$ tar -xzf pin.xxx.tar.gz
当然也可以用wget直接下载
$ wget http://software.intel.com/sites/landingpage/pintool/downloads/pin-2.14-71313-gcc.4.4.7-linux.tar
把解压的文件夹重命名
$ mv pin.xxx pin
$ cd pin
运行一个官网样例
构建一个不运行的特定示例 (例如, inscount0):
$ cd source/tools/ManualExamples
$ make obj-intel64/inscount0.so TARGET=intel64
当前目录下执行一个简单的指令计数 (指示仪器)程序来计算执行指令的总数,这里直接用官网的示例:
$ ../../../pin -t obj-intel64/inscount0.so -- /bin/ls
Makefile atrace.o imageload.out itrace proccount
Makefile.example imageload inscount0 itrace.o proccount.o
atrace imageload.o inscount0.o itrace.out
$ cat inscount.out
Count 422838
$
ok,大功告成!