跳转至

实验步骤

1. 导入虚拟机

  本实验提供已安装好实验环境的Debian 11.5.0虚拟机。实验开始前,需要在VirtualBox中导入虚拟机镜像。

特别说明 🔥

  T2-102实验室的PC机已完成虚拟机的导入,但需要在虚拟机的设置中把“处理器数量”改成不大于4的数值。

  首先,安装并打开VirtualBox。

  然后,按照如图4-1所示,依次点击相应的按钮以导入虚拟机。

图4-1 导入虚拟机

  点击“打开”按钮后,检查图4-2所示的设置是否与物理机兼容。如果出现不兼容,需根据物理机的配置进行相应的修改

图4-2 检查虚拟机配置是否需要修改

  检查无误后,点击窗口右下方的“导入”按钮,耐心等待虚拟机导入完成。

补充说明 📣

  导入虚拟机时,如果不确定哪些参数需要改,不妨先完成导入操作。导入完成后,打开虚拟机的设置,检查VirtualBox是否提示“发现无效设置”,如图4-3所示。

图4-3 打开虚拟机设置,查看是否存在无效设置

  如果存在无效设置,把鼠标悬停在图4-3底下的警告图标上,此时VirtualBox将弹出提示信息。按照提示信息,修改相应设置,直到不存在无效设置即可。

2. 运行Pin

  启动虚拟机后,以用户名debian、密码123登录系统。然后,双击桌面上的“主文件夹”以打开/home/debian目录,其中以“pin-3.24”开头的压缩包即为Pin工具包。

  在主文件夹上右键打开终端,并输入tar命令解压Pin的压缩包,如图4-4所示。

图4-4 解压下载的Pin压缩包

  解压得到的文件夹名字冗长,不妨将其重命名为pin-3.24

  进入Pin工具包的根目录,可以看到类似图4-5的目录结构。

图4-5 Pin工具包根目录

  其中,doc文件夹存放的是网页形式的Pin文档,内含API说明文档。

  接着,使用cd命令进入到Pin工具根目录下的source/tools/ManualExamples目录,如图4-6所示。该目录存放的是基于Pin工具包开发的插桩工具范例。

图4-6 查看插桩工具demo

  然后,执行make命令,编译ManualExamples目录下的插桩工具。

  编译完成后,即可通过Pin工具包调用所生成的插桩工具对可执行文件进行插桩分析,其语法如图4-7所示。

图4-7 Pin命令格式

  其中,toolname表示插桩工具,指编译后存放在obj文件夹下的.so文件output_file表示插桩工具输出到文件;target_executable则表示被插桩分析的可执行文件。例如,基于上述命令,可以使用inscount0的指令计数插桩工具,对ls命令进行插桩,并将插桩工具的输出保存到result.txt,如图4-8所示。

图4-8 运行inscount插桩工具

  执行上述命令后,Pin将在当前的ManualExamples目录下调用ls工具,从而在终端中打印出当前目录的文件列表。此时,可查看inscount0插桩工具的输出信息,如图4-9所示。

图4-9 inscount0对ls插桩分析的输出

3. 编写insDependDist插桩工具

  在虚拟机的/home/debian目录下,以“workspace”开头的压缩包即为本实验的实验包。

  使用unzip命令解压,或在右键菜单解压,然后将解压后的workspace目录移动到Pin工具包的根目录下,如图4-10所示。

图4-10 解压workspace到Pin根目录下

  打开workspace目录,可见如图4-11所示的文件夹及文件。

图4-11 workspace目录中的内容

注意 📢

  本实验只需修改insDependDist.cppmakefile.rules其余文件夹和文件请勿删改

  其中,inscount0.cpp是Pin自带的指令计数插桩工具的范例程序;insDependDist.cpp是本实验的指令依赖距离的插桩工具,该工具将获取可执行文件的指令依赖信息,并将这些信息输出到insDependDist.csv文件;paintInsDependDist.py的绘图程序读取insDependDist.csv文件并绘制被分析可执行文件的指令依赖分布图;obj-intel64文件夹存放编译workspace时生成的ELF文件;makefilemakefile.rulesConfig文件夹存放编译workspace所需的编译规则及配置;divide_by_zero_unix.c是编译workspace所需的工具源文件。

  然后,打开insDependDist.cpp文件,根据注释中的代码提示,补全5处空缺的功能代码。在insDependDist.cpp中,全局数组insDependDistance[]用于存放被插桩程序的指令依赖距离信息——insDependDistance[i]表示依赖距离为i+1的出现次数。例如,在图3-5所示的代码中,SI寄存器的依赖距离为2和3,CX寄存器的依赖距离为1,则插桩工具分析完这4条指令之后,insDependDistance[0]insDependDistance[1]insDependDistance[2]的值都将+1。

  insDependDist.cpp的代码补全完毕后,右键选择Mousepad打开makefile.rules文件,将指令依赖距离插桩工具的名字添加到TEST_TOOL_ROOTS变量的后面,如图4-12所示。

图4-12 在makefile.rules中添加新的插桩工具

  所有代码编写完成后,打开终端,使用cd命令进入到workspace目录,并输入make命令以编译insDependDist工具。

  编译完成后,将在obj-intel64(或obj-ia32)目录下生成insDependDist.oinsDependDist.so文件。

  接着,可以在终端中输入如图4-13所示的命令,对/bin/ls进行插桩分析。

a) 默认情况下,最大统计100及以内的依赖距离

b) 通过-s选项设置插桩工具统计的最大依赖距离(如设置为120)

图4-13 使用insDependDist工具对/bin/ls进行插桩分析

  需要注意的是,insDependDist工具默认只统计被插桩可执行文件中不超过100的依赖距离。如果想统计更远的距离,可以使用-s选项来设置,如图4-13 b)所示。此功能得益于insDependDist.cpp中用于设置最大依赖距离的Knob,如图4-14所示。

图4-14 insDependDist工具中,设置最大依赖距离的Knob

  通过编写Knob,可以在调用插桩工具时进行特殊参数的设置。感兴趣的同学可以自行编写新的Knob。

  insDependDist工具运行后,将在当前目录中生成/bin/ls的指令依赖距离信息。此时,在终端中使用python3运行paintInsDependDist.py脚本,即可得到/bin/ls的指令依赖距离分布图,如图4-15所示。

图4-15 /bin/ls的指令依赖距离分布图参考

补充说明 📣

  paintInsDependDist.py默认绘制45以内的依赖距离。若想绘制更多,可在调用脚本时添加参数,如python3 paintInsDependDist.py 100

  感兴趣的同学还可以其他对常用的命令(如pwdclearcat等等),或者自己编写的程序进行插桩分析。

文件备份 💡

  若想将虚拟机中的文件拷贝到PC机,或将PC机的文件拷贝进虚拟机,请参考VirtualBox虚拟机共享文件设置