關於 .init .fini .init_array .fini_array 日誌 2019.7.16 pwn
查詢資料的高效性
retn 返回到棧頂地址
關於 .init .fini .init_array .fini_array
其中存放著的是在main函式執行前執行的程式碼,由__libc_start_main呼叫,(__libc_start_main在libc.so上,所以先有start()呼叫__libc_start_main,再呼叫init段的程式碼)在這段程式碼中就有我們經常使用的libc_csu的gadget
.init段:
.text:0000000000400CB0 ; __unwind { .text:0000000000400CB0 push r15 .text:0000000000400CB2 mov r15d, edi .text:0000000000400CB5 push r14 .text:0000000000400CB7 mov r14, rsi .text:0000000000400CBA push r13 .text:0000000000400CBC mov r13, rdx .text:0000000000400CBF push r12 .text:0000000000400CC1 lea r12, off_6011B0 //此處將init_array(0x6011B0)上的值給r12 .text:0000000000400CC8 push rbp .text:0000000000400CC9 lea rbp, off_6011B8 //此處將fini_array(0x6011B8)上的值給rbp .text:0000000000400CD0 push rbx .text:0000000000400CD1 sub rbp, r12 //rbp為init_array和fini_array的差 .text:0000000000400CD4 xor ebx, ebx //rbx清零 .text:0000000000400CD6 sar rbp, 3 //rbp算術右移3位(地址大小),即變成init_array中有多少個地址 .text:0000000000400CDA sub rsp, 8 .text:0000000000400CDE call _init_proc .text:0000000000400CE3 test rbp, rbp .text:0000000000400CE6 jz short loc_400D06 .text:0000000000400CE8 nop dword ptr [rax+rax+00000000h] .text:0000000000400CF0 .text:0000000000400CF0 loc_400CF0: ; CODE XREF: init+54↓j .text:0000000000400CF0 mov rdx, r13 //這裡到0x400D14就是我們常用的gadget .text:0000000000400CF3 mov rsi, r14 .text:0000000000400CF6 mov edi, r15d .text:0000000000400CF9 call qword ptr [r12+rbx*8] //call r12+rbx*8,正常執行情況下是執行init_array 中的函式 .text:0000000000400CFD add rbx, 1 //rbx算是array中的偏移 .text:0000000000400D01 cmp rbx, rbp //直到array中的所用函式執行完,才能往下走 .text:0000000000400D04 jnz short loc_400CF0 //沒執行完所用函式返回0x400CF0繼續執行 .text:0000000000400D06 .text:0000000000400D06 loc_400D06: ; CODE XREF: init+36↑j .text:0000000000400D06 add rsp, 8 .text:0000000000400D0A pop rbx .text:0000000000400D0B pop rbp .text:0000000000400D0C pop r12 .text:0000000000400D0E pop r13 .text:0000000000400D10 pop r14 .text:0000000000400D12 pop r15 .text:0000000000400D14 retn .text:0000000000400D14 ; } // starts at 400CB0 .text:0000000000400D14 init endp
.init_array
.init_array:00000000006011B0 ; Segment type: Pure data .init_array:00000000006011B0 ; Segment permissions: Read/Write .init_array:00000000006011B0 ; Segment alignment 'qword' can not be represented in assembly .init_array:00000000006011B0 _init_array segment para public 'DATA' use64 .init_array:00000000006011B0 assume cs:_init_array .init_array:00000000006011B0 ;org 6011B0h .init_array:00000000006011B0 off_6011B0 dq offset sub_400850 ; DATA XREF: LOAD:00000000004000F8↑o .init_array:00000000006011B0 ; init+11↑o .init_array:00000000006011B0 _init_array ends
關於.fini段
我的檔案中的.fini只有已經一句程式碼:retn
.text:0000000000400D20 ; void fini(void)
.text:0000000000400D20 fini proc near ; DATA XREF: start+F↑o
.text:0000000000400D20 ; __unwind {
.text:0000000000400D20 rep retn //返回到棧頂地址
.text:0000000000400D20 ; } // starts at 400D20
.text:0000000000400D20 fini endp
而.fini_array中的有一個函式需要執行
.fini_array:00000000006011B8 ; Segment type: Pure data .fini_array:00000000006011B8 ; Segment permissions: Read/Write .fini_array:00000000006011B8 ; Segment alignment 'qword' can not be represented in assembly .fini_array:00000000006011B8 _fini_array segment para public 'DATA' use64 .fini_array:00000000006011B8 assume cs:_fini_array .fini_array:00000000006011B8 ;org 6011B8h .fini_array:00000000006011B8 qword_6011B8 dq 400830h ; DATA XREF: init+19↑o //0x400830需要執行 .fini_array:00000000006011B8 _fini_array ends
所以我猜想:會不會在__libc_start_main()中,在呼叫.fini段前,.fini_array中的函式就已經入棧了?這個猜想也和前面題目在棧中一個情況(在棧上修改.fini_array push在棧上的地址為 main的地址,從而實現在程式main結束之後可以再執行一次的效果)相符合。
問題是:不知道怎麼找到這個.fini_array在棧上的值
彙編
LEA
LEA r16,m
8D /r 不影響標誌位
將源運算元的有效地址送 r16
LEA r32,m
將源運算元的有效地址送 r32
c語言
atol(): 把字串轉換成長整型數用 法: long atol(const char *nptr); 返回長整型
atoll(): 把字串轉換成長長整型數用 法: long long atol(const char *nptr); 返回長長整型
size_t fread ( void *buffer, size_t size, size_t count, FILE *stream) ; 返回真實讀取的項數,count是最多讀取的項數
大多數題目的setbuf()/setvbuf()函式的作用是用來關閉I/O緩衝區,本題沒有關閉緩衝區,函式執行開始階段在fgets()函式以及printf()函式執行的時候,會malloc()兩塊記憶體區域。
震驚!
ida pro居然把我一個全域性變數識別成了區域性變數
然後在函式中將原本應該是全域性變數的s
,寫成了 ::s
,我佛了