Pwn学习随笔( 十 )

x86-64 , 通常可以通过从指令字节序指令的其他部分提取出我们想要的指令 。

Pwn学习随笔

文章插图
下面举个例子来详细说明ROP与之前的Buffer overflow有什么区别 , 我们不关心栈地址在哪 , 只需要看有没有可以利用的指令
我们可以在程序的汇编代码中找到这样的代码:
0000000000400f15 <setval_210>:400f15: c7 07 d4 48 89 c7 movl $0xc78948d4,(%rdi)400f1b: c3 retq这段代码的本意是
void setval_210(unsigned *p){*p = 3347663060U;}这样一个函数 , 但是通过观察我们可以发现 , 汇编代码的最后部分:48 89 c7 c3又可以代表
movq %rax, %rdiret这两条指令(指令的编码可以见讲义中的附录) 。
第1行的movq指令可以作为攻击代码的一部分来使用 , 那么我们怎么去执行这个代码呢?我们知道这个函数的入口地址是0x400f15 , 这个地址也是这条指令的地址 。我们可以通过计算得出48 89 c7 c3这条指令的首地址是0x400f18 , 我们只要把这个地址存放在栈中 , 在执行ret指令的时候就会跳转到这个地址 , 执行48 89 c7 c3编码的指令 。同时 , 我们可以注意到这个指令的最后是c3编码的是ret指令 , 利用这一点 , 我们就可以把多个这样的指令地址依次放在栈中 , 每次ret之后就会去执行栈中存放的下一个地址指向的指令 , 只要合理地放置这些地址 , 我们就可以执行我们想要执行的命令从而达到攻击的目的 。
下面是一些常见指令的指令码
  • movq : The codes for these are shown in Figure 3A.
  • popq : The codes for these are shown in Figure 3B.
  • ret : This instruction is encoded by the single byte 0xc3.
  • nop : This instruction (pronounced “no op,” which is short for “no operation”) is encoded by the single byte 0x90. Its only effect is to cause the program counter to be incremented by 1
一些常见指令对应的机器码 , movqpopqmovlnop(2 Bytes)、可以参考CSAPPAttackLab
Pwn学习随笔

文章插图

Pwn学习随笔

文章插图

Pwn学习随笔

文章插图

Pwn学习随笔

文章插图
寻找 gadget理论上 , ROP是图灵完备的 。在漏洞利用过程中 , 比较常用的gadget有以下类型: