每一个程序都有一个符号表,angr 可以确保从每个导入符号都可以解析出地址,可以使用 angr 提供的 Project.hook_symbol
API 来通过符号名来 Hook 函数所有的调用地址,这意味着可以用自己的代码替换函数,一个简单的例子:
运行一下查看结果
这里前面的部分都可以直接照抄上面一题的代码,关键是定义一个继承 angr.SimProcedure 的类,以利用 Angr 的 SimProcedures。
SimProcedure 用 Python 编写的我们自己的函数代替了原来函数。 除了用 Python 编写之外,该函数的行为与用 C 编写的任何函数基本相同。self
之后的任何参数都将被视为要替换的函数的参数, 参数将是符号位向量。 另外,Python 可以以常用的 Python 方式返回,Angr 将以与原来函数相同的方式对待它
我们先来看一下函数原型:
不难发现函数的第一个参数是待检测字符串首地址指针,然后就是字符串的长度,接下来我们就可以开始书写我们的模拟函数
Hook 上 check_equals 函数, angr 会自动查找与该函数符号关联的地址
对于 scanf 的 hook
运行一下查看结果
之前的步骤很多都和上一题一样,只不过在编写模拟的 scanf 函数的时候有一些不太一样
还记得之前在 05_angr_symbolic_memory
我们学会的如何符号化内存吗?因为我们这里 Scanf 是要向内存写入数据的,于是我们利用使用 state.memory
的 .store(addr, val)
接口将符号位向量写入两个字符串的内存区域
globals
这里的关键我们都知道 Python 的变量生存周期,在这里 scanf0
和 scanf1
是函数 ReplacementScanf
的局部变量,为了让函数外部也能获得我们输入的符号位向量,从而调用求解器获得答案,需要将这两个符号位向量变为全局变量,这里我们需要调用带有全局状态的 globals 插件中“保存”对我们的符号值的引用。globals 插件允许使用列表,元组或多个键的字典来存储多个位向量