__libc_csu_init函式的通用gadget

Ox9A82發表於2016-05-12
 1 .text:0000000000400840 ; =============== S U B R O U T I N E =======================================
 2 .text:0000000000400840
 3 .text:0000000000400840
 4 .text:0000000000400840                 public __libc_csu_init
 5 .text:0000000000400840 __libc_csu_init proc near               ; DATA XREF: _start+16o
 6 .text:0000000000400840                 push    r15
 7 .text:0000000000400842                 mov     r15d, edi
 8 .text:0000000000400845                 push    r14
 9 .text:0000000000400847                 mov     r14, rsi
10 .text:000000000040084A                 push    r13
11 .text:000000000040084C                 mov     r13, rdx
12 .text:000000000040084F                 push    r12
13 .text:0000000000400851                 lea     r12, __frame_dummy_init_array_entry
14 .text:0000000000400858                 push    rbp
15 .text:0000000000400859                 lea     rbp, __do_global_dtors_aux_fini_array_entry
16 .text:0000000000400860                 push    rbx
17 .text:0000000000400861                 sub     rbp, r12
18 .text:0000000000400864                 xor     ebx, ebx
19 .text:0000000000400866                 sar     rbp, 3
20 .text:000000000040086A                 sub     rsp, 8
21 .text:000000000040086E                 call    _init_proc
22 .text:0000000000400873                 test    rbp, rbp
23 .text:0000000000400876                 jz      short loc_400896
24 .text:0000000000400878                 nop     dword ptr [rax+rax+00000000h]
25 .text:0000000000400880
26 .text:0000000000400880 loc_400880:                             ; CODE XREF: __libc_csu_init+54j
27 .text:0000000000400880                 mov     rdx, r13
28 .text:0000000000400883                 mov     rsi, r14
29 .text:0000000000400886                 mov     edi, r15d
30 .text:0000000000400889                 call    qword ptr [r12+rbx*8]
31 .text:000000000040088D                 add     rbx, 1
32 .text:0000000000400891                 cmp     rbx, rbp
33 .text:0000000000400894                 jnz     short loc_400880
34 .text:0000000000400896
35 .text:0000000000400896 loc_400896:                             ; CODE XREF: __libc_csu_init+36j
36 .text:0000000000400896                 add     rsp, 8
37 .text:000000000040089A                 pop     rbx
38 .text:000000000040089B                 pop     rbp
39 .text:000000000040089C                 pop     r12
40 .text:000000000040089E                 pop     r13
41 .text:00000000004008A0                 pop     r14
42 .text:00000000004008A2                 pop     r15
43 .text:00000000004008A4                 retn
44 .text:00000000004008A4 __libc_csu_init endp
45 .text:00000000004008A4
46 .text:00000000004008A4 ; ---------------------------------------------------------------------------

 x64中的前六個引數依次儲存在RDI, RSI, RDX, RCX, R8和 R9中

r13   =rdx=arg3

r14   =rsi=arg2

r15d=edi=arg1

r12= call address

這段gadgets用於在X64下進行rop,根本原因是X64使用暫存器傳參無法直接用棧進行rop。具體用法如下:

分為兩部分使用

1.執行gad1

.text:000000000040089A                 pop     rbx  必須為0
.text:000000000040089B                 pop     rbp  必須為1
.text:000000000040089C                 pop     r12  call!!!!
.text:000000000040089E                
pop     r13  arg3
.text:00000000004008A0               
  pop     r14  arg2
.text:00000000004008A2                 pop     r15  arg1
.text:00000000004008A4                 retn  ——> to gad2

 

2.再執行gad2

.text:0000000000400880                 mov     rdx, r13
.text:0000000000400883                 mov     rsi, r14
.text:0000000000400886                 mov     edi, r15d
.text:0000000000400889                 call    qword ptr [r12+rbx*8] call!!!
.text:000000000040088D                 add     rbx, 1
.text:0000000000400891                 cmp     rbx, rbp
.text:0000000000400894                 jnz     short loc_400880
.text:0000000000400896                 add     rsp, 8
.text:000000000040089A                 pop     rbx
.text:000000000040089B                 pop     rbp
.text:000000000040089C                 pop     r12
.text:000000000040089E                 pop     r13
.text:00000000004008A0                 pop     r14
.text:00000000004008A2                 pop     r15
.text:00000000004008A4                 retn ——> 構造一些墊板(7*8=56byte)就返回了

 

此外還有一個老司機才知道的x64 gadgets,就是 pop rdi,ret的gadgets。這個gadgets還是在這裡,但是是由opcode錯位產生的。

如上的例子中4008A2、4008A4兩句的位元組碼如下

0x41 0x5f 0xc3

意思是pop r15,ret,但是恰好pop rdi,ret的opcode如下

0x5f 0xc3

因此如果我們指向0x4008A3就可以獲得pop rdi,ret的opcode,從而對於單引數函式可以直接獲得執行

 

與此類似的,還有0x4008A1處的 pop rsi,pop r15,ret

那麼這個有什麼用呢?我們知道x64傳參順序是rdi,rsi,rdx,rcx。

所以rsi是第二個引數,我們可以在rop中配合pop rdi,ret來使用pop rsi,pop r15,ret,這樣就可以輕鬆的呼叫2個引數的函式。

 

綜上,我們介紹了x64下利用通用gadgets呼叫一個引數、兩個引數、三個引數函式的方法。

 

相關文章