再上一次学习栈溢出ret2syscall
方法时,我们会发现有些gadget
不存在,我们只能借用read
遗留下来的ebx寄存机调用,这时就可以使用万能gadget
,这个万能的gadget
存在__libc_csu_init
中,由于每个动态链接的程序就有有libc
,并且__libc_csu_init
用于初始化,所以说几乎每个程序都含有__libc_csu_init
,我们使用里面的万能gadget
够着ROP Chain
上述中的代码就是万能gadget
分步骤的话代码流程如下
第一步
.text:0000000000400716 loc_400716: ; CODE XREF: __libc_csu_init+34↑j
.text:0000000000400716 48 83 C4 08 add rsp, 8
.text:000000000040071A 5B pop rbx
.text:000000000040071B 5D pop rbp
.text:000000000040071C 41 5C pop r12
.text:000000000040071E 41 5D pop r13
.text:0000000000400720 41 5E pop r14
.text:0000000000400722 41 5F pop r15
.text:0000000000400724 C3 retn
第二步
.text:0000000000400700 loc_400700: ; CODE XREF: __libc_csu_init+54↓j
.text:0000000000400700 4C 89 EA mov rdx, r13
.text:0000000000400703 4C 89 F6 mov rsi, r14
.text:0000000000400706 44 89 FF mov edi, r15d
.text:0000000000400709 41 FF 14 DC call ds:(__frame_dummy_init_array_entry - 600E10h)[r12+rbx*8]
第三步
.text:000000000040070D 48 83 C3 01 add rbx, 1
.text:0000000000400711 48 39 EB cmp rbx, rbp
.text:0000000000400714 75 EA jnz short loc_400700
具体第一步每个参数的值如下
寄存器 | 值 |
---|---|
rbx | 0 |
rbp | 1 |
r12 | 对应rdx,调用函数的第三个参数 |
r13 | 对应rsi,调用函数的第二个参数 |
r14 | 对应rdi,调用函数的第一个参数 |
我们需要设置rbx为0,rbp为1,然后rdx,rsi,rdi为需要的参数,通过栈溢出成功执行函数后,我们需要传入第二个gadget
,就是上述步骤中的第二步和第三步,他会调用我们的想执行的函数,然后将rbx的值加1,将rbx - rbp
的值计算,通过结果判断是否跳转到