正如@IgorSkochinsky建议的那样,您可以使用动态二进制检测 (DBI)。
PIN 的一种替代方法是DynamoRIO。
$ ./drbuild.sh # build script (below)
$ gcc gcd.c -o gcd
# run one
$ $ ./dynamorio/build/bin32/drrun -t drcov -dump_text -- ./gcd 5 10
5
$ ls # so we know which log is from our first run
drbuild.sh drcov.gcd.18958.0000.proc.log dynamorio gcd gcd.c
# run two
$ $ ./dynamorio/build/bin32/drrun -t drcov -dump_text -- ./gcd 128 24
8
现在我们已经用drbuild.sh、编译gcd.c、运行gcd和生成drcov.gcd.18958.0000.proc.log和构建了 DynamoRIO drcov.gcd.18960.0000.proc.log,我们可以比较运行一 (2177) 和运行二 (2183) 的日志之间的“BB 表”字段,以立即看到更多基本块(计算重复性)由于while()in gcd_iter().
基本块按模块分组,并通过它们在该模块中的偏移量来标识。例如,module 0包含gcd二进制中的所有基本块。包含的行module[ 0]: 0x0000043b表示module 0 start (0x08048000) + 0x0000043b遇到了基本块 at 。从这个 cfg,我们可以看到这0x0804843b是gcd_iter()函数中的第一个基本块。
如果 to 的第一个参数gcd_iter()是否定的,则执行将通过 to 0x08048444,从而否定该参数;否则,我们跳转到0x8048447。前两次运行的日志(所有参数均为正)与此预期一致。
$ grep -F 'module[ 0]:' drcov.gcd.18958.0000.proc.log
...
module[ 0]: 0x0000043b, 9
module[ 0]: 0x00000447, 6
...
gcd使用否定的第一个参数运行显示 DynamoRIO 的输出是如何动态的。
$ ./dynamorio/build/bin32/drrun -t drcov -dump_text -- ./gcd -5 10
$ grep -F 'module[ 0]:' drcov.gcd.18970.0000.proc.log
...
module[ 0]: 0x0000043b, 9
module[ 0]: 0x00000444, 9
...