【CTF】关于 .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
,我佛了