Triton学习笔记(三)
Triton我看重的就两点,一是可以让我不用写C/C++, 另一点就是本篇要开始讲的重点,符号执行,这篇先介绍符号执行
首先看官方给的例子:
1 | # src/examples/python/ir.py |
1 | $ python src/examples/python/ir.py |
输出结果的第一行是汇编代码,下面的几行就是符号表达式了
符号表达式说简单点就是把一个变量的变化用表达式表示出来
其实只要理解了每个符号所代表的意义,还是很容易理解的,末尾也有注释
比如:
ref!1 = ((_ zero_extend 0) (_ bv4194311 64)) ; Program Counter
后面的注释很明显,程序指针,也就是eip
, 其中(_ bv4194311 64)
表示一个64bit的数,值的十进制表示为4194311
,转成十六进制就是0x400007
, (_ zero_extend 0)
表示剩余为用0
填充,4194311
是不够64bit的,所以前面要用0
到64bit
所以这个符号表达式翻译成简单的表达式就是eip = 0x400007
, 很好理解的,执行完这句指令后,下句指令的地址就是0x400007
为啥要用这么复杂的一个符号表达式来表示这么简单的一句指令呢? 我认为应该是涉及到污点染色,会在之后的篇章中介绍
ref!0 = ((_ zero_extend 0) (concat ((_ extract 7 0) (_ bv0 8)) ((_ extract 7 0) (_ bv0 8)) ((_ extract 7 0) (_ bv0 8)) ((_ extract 7 0) (_ bv0 8)) ((_ extract 7 0) (_ bv0 8)) ((_ extract 7 0) (_ bv0 8)) ((_ extract 7 0) (_ bv0 8)) ((_ extract 7 0) (_ bv0 8)))) ; MOV operation
看注释就知道,这句表达式是mov
操作的表达式,处于学习阶段我们就耐心的慢慢读表达式,等都理解之后可以使用专门的模块进行处理.
((_ extract 7 0) (_ bv0 8))
这句很简单,一个8bit的数0,取0-7
bit的数,来举一个特例来解释下把,比如((_ extract 4 1) (_ bv93 8))
的值是14
化简后就是: ((_ zero_extend 0) (concat 0 0 0 0 0 0 0 0))
, concat
的作用就是把后面8个8bit的0连接起来,因为赋值给rax, 用了qword指针,所以是64位
因为示例不是实际代码, [eip+0x13b8]
指向的地址值未知,所以这里是0
我们继续往底下看,下一句指令是lea rsi, qword ptr [rbx + rax*8]
符号表达式是:
ref!2 = ((_ zero_extend 0) (bvadd (_ bv0 64) (bvadd (_ bv67890 64) (bvmul ((_ extract 63 0) ref!0) (_ bv8 64))))) ; LEA operation
其中ref!0
从上面我们可以看出表示的是rax
, 所以((_ extract 63 0) ref!0)
表示的就是rax
,如果改成((_ extract 31 0) ref!0)
则表示的就是32为的rax
也就是eax
我们对表达式进行化简: (bvadd 0 (bvadd 67890 (bvmul rax 8)))
(bvmul rax 8)
也就是rax*8
bvadd
表示加法
剩下看的就简单了: rax*8 + 67890 + 0
我们在python代码中初始化过rbx
的值:
inst.updateContext(Register(REG.RBX, 67890));
所以67890
表示的就是rbx
这句表达式就容易理解了,rsi = rax*8 + rbx
总结
介绍暂时就介绍这些,Triton的符号表达式引擎用的是SMT2-LIB
, 所以要知道某句表达式的意思可以去参考官方文档
Triton学习笔记(三)