堆栈溢出引出的一些mark知识点--汇编
程序员文章站
2022-07-02 08:45:13
...
0x01缘由
浏览博客时,发现一篇《CVE-2016-10190 FFmpeg Heap Overflow 漏洞分析及利用》传送:https://security.tencent.com/index.php/blog/msg/116?utm_source=tuicool&utm_medium=referral,因为从事C/C++编程,带着兴趣和疑问阅读了此篇文章。然后阅读这个的过程中,对汇编的理解存在较大的困难,于是带着一些疑问学习了以下相关知识点。
0x02汇编入门
以简单的a + b 程序为例,读懂汇编语言。平台x86_64(注:rsp,esp,sp,前缀:分别代表64bit,32bit,16bit系统的指令)。
#include <stdio.h>
int sum_fun(int a, int b)
{
return a + b;
}
int main(void)
{
int a,b;
int sum = 0;
a = 1;
b = 2;
printf("a + b = %d\n", a + b);
sum = sum_fun(a, b);
printf("a + b = %d\n", sum);
}
利用objdump查看汇编语言信息:
gcc -o test test.c
objdump -d test -M intel
汇编如下:
test: file format elf64-x86-64
Disassembly of section .init:
00000000004003f0 <_init>:
4003f0: 48 83 ec 08 sub rsp,0x8
4003f4: e8 73 00 00 00 call 40046c <call_gmon_start>
4003f9: e8 02 01 00 00 call 400500 <frame_dummy>
4003fe: e8 3d 02 00 00 call 400640 <__do_global_ctors_aux>
400403: 48 83 c4 08 add rsp,0x8
400407: c3 ret
Disassembly of section .plt:
0000000000400408 <[email protected]>:
400408: ff 35 e2 0b 20 00 push QWORD PTR [rip+0x200be2] # 600ff0 <_GLOBAL_OFFSET_TABLE_+0x8>
40040e: ff 25 e4 0b 20 00 jmp QWORD PTR [rip+0x200be4] # 600ff8 <_GLOBAL_OFFSET_TABLE_+0x10>
400414: 0f 1f 40 00 nop DWORD PTR [rax+0x0]
0000000000400418 <[email protected]>:
400418: ff 25 e2 0b 20 00 jmp QWORD PTR [rip+0x200be2] # 601000 <_GLOBAL_OFFSET_TABLE_+0x18>
40041e: 68 00 00 00 00 push 0x0
400423: e9 e0 ff ff ff jmp 400408 <_init+0x18>
0000000000400428 <[email protected]>:
400428: ff 25 da 0b 20 00 jmp QWORD PTR [rip+0x200bda] # 601008 <_GLOBAL_OFFSET_TABLE_+0x20>
40042e: 68 01 00 00 00 push 0x1
400433: e9 d0 ff ff ff jmp 400408 <_init+0x18>
Disassembly of section .text:
0000000000400440 <_start>:
400440: 31 ed xor ebp,ebp
400442: 49 89 d1 mov r9,rdx
400445: 5e pop rsi
400446: 48 89 e2 mov rdx,rsp
400449: 48 83 e4 f0 and rsp,0xfffffffffffffff0
40044d: 50 push rax
40044e: 54 push rsp
40044f: 49 c7 c0 a0 05 40 00 mov r8,0x4005a0
400456: 48 c7 c1 b0 05 40 00 mov rcx,0x4005b0
40045d: 48 c7 c7 39 05 40 00 mov rdi,0x400539
400464: e8 bf ff ff ff call 400428 <[email protected]>
400469: f4 hlt
40046a: 90 nop
40046b: 90 nop
000000000040046c <call_gmon_start>:
40046c: 48 83 ec 08 sub rsp,0x8
400470: 48 8b 05 69 0b 20 00 mov rax,QWORD PTR [rip+0x200b69] # 600fe0 <_DYNAMIC+0x1a0>
400477: 48 85 c0 test rax,rax
40047a: 74 02 je 40047e <call_gmon_start+0x12>
40047c: ff d0 call rax
40047e: 48 83 c4 08 add rsp,0x8
400482: c3 ret
400483: 90 nop
400484: 90 nop
400485: 90 nop
400486: 90 nop
400487: 90 nop
400488: 90 nop
400489: 90 nop
40048a: 90 nop
40048b: 90 nop
40048c: 90 nop
40048d: 90 nop
40048e: 90 nop
40048f: 90 nop
0000000000400490 <__do_global_dtors_aux>:
400490: 55 push rbp
400491: 48 89 e5 mov rbp,rsp
400494: 53 push rbx
400495: 48 83 ec 08 sub rsp,0x8
400499: 80 3d 80 0b 20 00 00 cmp BYTE PTR [rip+0x200b80],0x0 # 601020 <__bss_start>
4004a0: 75 4b jne 4004ed <__do_global_dtors_aux+0x5d>
4004a2: bb 30 0e 60 00 mov ebx,0x600e30
4004a7: 48 8b 05 7a 0b 20 00 mov rax,QWORD PTR [rip+0x200b7a] # 601028 <dtor_idx.7384>
4004ae: 48 81 eb 28 0e 60 00 sub rbx,0x600e28
4004b5: 48 c1 fb 03 sar rbx,0x3
4004b9: 48 83 eb 01 sub rbx,0x1
4004bd: 48 39 d8 cmp rax,rbx
4004c0: 73 24 jae 4004e6 <__do_global_dtors_aux+0x56>
4004c2: 66 0f 1f 44 00 00 nop WORD PTR [rax+rax*1+0x0]
4004c8: 48 83 c0 01 add rax,0x1
4004cc: 48 89 05 55 0b 20 00 mov QWORD PTR [rip+0x200b55],rax # 601028 <dtor_idx.7384>
4004d3: ff 14 c5 28 0e 60 00 call QWORD PTR [rax*8+0x600e28]
4004da: 48 8b 05 47 0b 20 00 mov rax,QWORD PTR [rip+0x200b47] # 601028 <dtor_idx.7384>
4004e1: 48 39 d8 cmp rax,rbx
4004e4: 72 e2 jb 4004c8 <__do_global_dtors_aux+0x38>
4004e6: c6 05 33 0b 20 00 01 mov BYTE PTR [rip+0x200b33],0x1 # 601020 <__bss_start>
4004ed: 48 83 c4 08 add rsp,0x8
4004f1: 5b pop rbx
4004f2: c9 leave
4004f3: c3 ret
4004f4: 66 66 66 2e 0f 1f 84 nop WORD PTR cs:[rax+rax*1+0x0]
4004fb: 00 00 00 00 00
0000000000400500 <frame_dummy>:
400500: 55 push rbp
400501: 48 83 3d 2f 09 20 00 cmp QWORD PTR [rip+0x20092f],0x0 # 600e38 <__JCR_END__>
400508: 00
400509: 48 89 e5 mov rbp,rsp
40050c: 74 12 je 400520 <frame_dummy+0x20>
40050e: b8 00 00 00 00 mov eax,0x0
400513: 48 85 c0 test rax,rax
400516: 74 08 je 400520 <frame_dummy+0x20>
400518: bf 38 0e 60 00 mov edi,0x600e38
40051d: c9 leave
40051e: ff e0 jmp rax
400520: c9 leave
400521: c3 ret
400522: 90 nop
400523: 90 nop
0000000000400524 <sum_fun>:
400524: 55 push rbp
400525: 48 89 e5 mov rbp,rsp
400528: 89 7d fc mov DWORD PTR [rbp-0x4],edi
40052b: 89 75 f8 mov DWORD PTR [rbp-0x8],esi
40052e: 8b 45 f8 mov eax,DWORD PTR [rbp-0x8]
400531: 8b 55 fc mov edx,DWORD PTR [rbp-0x4]
400534: 8d 04 02 lea eax,[rdx+rax*1]
400537: c9 leave
400538: c3 ret
0000000000400539 <main>:
400539: 55 push rbp
40053a: 48 89 e5 mov rbp,rsp
40053d: 48 83 ec 10 sub rsp,0x10
400541: c7 45 f4 00 00 00 00 mov DWORD PTR [rbp-0xc],0x0
400548: c7 45 fc 01 00 00 00 mov DWORD PTR [rbp-0x4],0x1
40054f: c7 45 f8 02 00 00 00 mov DWORD PTR [rbp-0x8],0x2
400556: 8b 45 f8 mov eax,DWORD PTR [rbp-0x8]
400559: 8b 55 fc mov edx,DWORD PTR [rbp-0x4]
40055c: 01 c2 add edx,eax
40055e: b8 8c 06 40 00 mov eax,0x40068c
400563: 89 d6 mov esi,edx
400565: 48 89 c7 mov rdi,rax
400568: b8 00 00 00 00 mov eax,0x0
40056d: e8 a6 fe ff ff call 400418 <[email protected]>
400572: 8b 55 f8 mov edx,DWORD PTR [rbp-0x8]
400575: 8b 45 fc mov eax,DWORD PTR [rbp-0x4]
400578: 89 d6 mov esi,edx
40057a: 89 c7 mov edi,eax
40057c: e8 a3 ff ff ff call 400524 <sum_fun>
400581: 89 45 f4 mov DWORD PTR [rbp-0xc],eax
400584: b8 8c 06 40 00 mov eax,0x40068c
400589: 8b 55 f4 mov edx,DWORD PTR [rbp-0xc]
40058c: 89 d6 mov esi,edx
40058e: 48 89 c7 mov rdi,rax
400591: b8 00 00 00 00 mov eax,0x0
400596: e8 7d fe ff ff call 400418 <[email protected]>
40059b: c9 leave
40059c: c3 ret
40059d: 90 nop
40059e: 90 nop
40059f: 90 nop
00000000004005a0 <__libc_csu_fini>:
4005a0: f3 c3 repz ret
4005a2: 66 66 66 66 66 2e 0f nop WORD PTR cs:[rax+rax*1+0x0]
4005a9: 1f 84 00 00 00 00 00
00000000004005b0 <__libc_csu_init>:
4005b0: 48 89 6c 24 d8 mov QWORD PTR [rsp-0x28],rbp
4005b5: 4c 89 64 24 e0 mov QWORD PTR [rsp-0x20],r12
4005ba: 48 8d 2d 53 08 20 00 lea rbp,[rip+0x200853] # 600e14 <__init_array_end>
4005c1: 4c 8d 25 4c 08 20 00 lea r12,[rip+0x20084c] # 600e14 <__init_array_end>
4005c8: 4c 89 6c 24 e8 mov QWORD PTR [rsp-0x18],r13
4005cd: 4c 89 74 24 f0 mov QWORD PTR [rsp-0x10],r14
4005d2: 4c 89 7c 24 f8 mov QWORD PTR [rsp-0x8],r15
4005d7: 48 89 5c 24 d0 mov QWORD PTR [rsp-0x30],rbx
4005dc: 48 83 ec 38 sub rsp,0x38
4005e0: 4c 29 e5 sub rbp,r12
4005e3: 41 89 fd mov r13d,edi
4005e6: 49 89 f6 mov r14,rsi
4005e9: 48 c1 fd 03 sar rbp,0x3
4005ed: 49 89 d7 mov r15,rdx
4005f0: e8 fb fd ff ff call 4003f0 <_init>
4005f5: 48 85 ed test rbp,rbp
4005f8: 74 1c je 400616 <__libc_csu_init+0x66>
4005fa: 31 db xor ebx,ebx
4005fc: 0f 1f 40 00 nop DWORD PTR [rax+0x0]
400600: 4c 89 fa mov rdx,r15
400603: 4c 89 f6 mov rsi,r14
400606: 44 89 ef mov edi,r13d
400609: 41 ff 14 dc call QWORD PTR [r12+rbx*8]
40060d: 48 83 c3 01 add rbx,0x1
400611: 48 39 eb cmp rbx,rbp
400614: 72 ea jb 400600 <__libc_csu_init+0x50>
400616: 48 8b 5c 24 08 mov rbx,QWORD PTR [rsp+0x8]
40061b: 48 8b 6c 24 10 mov rbp,QWORD PTR [rsp+0x10]
400620: 4c 8b 64 24 18 mov r12,QWORD PTR [rsp+0x18]
400625: 4c 8b 6c 24 20 mov r13,QWORD PTR [rsp+0x20]
40062a: 4c 8b 74 24 28 mov r14,QWORD PTR [rsp+0x28]
40062f: 4c 8b 7c 24 30 mov r15,QWORD PTR [rsp+0x30]
400634: 48 83 c4 38 add rsp,0x38
400638: c3 ret
400639: 90 nop
40063a: 90 nop
40063b: 90 nop
40063c: 90 nop
40063d: 90 nop
40063e: 90 nop
40063f: 90 nop
0000000000400640 <__do_global_ctors_aux>:
400640: 55 push rbp
400641: 48 89 e5 mov rbp,rsp
400644: 53 push rbx
400645: 48 83 ec 08 sub rsp,0x8
400649: 48 8b 05 c8 07 20 00 mov rax,QWORD PTR [rip+0x2007c8] # 600e18 <__CTOR_LIST__>
400650: 48 83 f8 ff cmp rax,0xffffffffffffffff
400654: 74 19 je 40066f <__do_global_ctors_aux+0x2f>
400656: bb 18 0e 60 00 mov ebx,0x600e18
40065b: 0f 1f 44 00 00 nop DWORD PTR [rax+rax*1+0x0]
400660: 48 83 eb 08 sub rbx,0x8
400664: ff d0 call rax
400666: 48 8b 03 mov rax,QWORD PTR [rbx]
400669: 48 83 f8 ff cmp rax,0xffffffffffffffff
40066d: 75 f1 jne 400660 <__do_global_ctors_aux+0x20>
40066f: 48 83 c4 08 add rsp,0x8
400673: 5b pop rbx
400674: c9 leave
400675: c3 ret
400676: 90 nop
400677: 90 nop
Disassembly of section .fini:
0000000000400678 <_fini>:
400678: 48 83 ec 08 sub rsp,0x8
40067c: e8 0f fe ff ff call 400490 <__do_global_dtors_aux>
400681: 48 83 c4 08 add rsp,0x8
400685: c3 ret
学习如上片段代码,引出对ELF文件的学习,传送:http://www.cnblogs.com/sayhellowen/p/802b5b0ad648e1a343dcd0f85513065f.html:
关键读懂:
0000000000400524 <sum_fun>:
400524: 55 push rbp //保存完rbp之后,函数将rsp存到了rbp里
400525: 48 89 e5 mov rbp,rsp
400528: 89 7d fc mov DWORD PTR [rbp-0x4],edi //edi存入栈的地址,edi和esi是在
40052b: 89 75 f8 mov DWORD PTR [rbp-0x8],esi //main函数时保存
40052e: 8b 45 f8 mov eax,DWORD PTR [rbp-0x8]
400531: 8b 55 fc mov edx,DWORD PTR [rbp-0x4]
400534: 8d 04 02 lea eax,[rdx+rax*1] //偏移量可以是立即数,也可以是经过四则运算的结果
,更省空间,更有效率
400537: c9 leave
400538: c3 ret
0000000000400539 <main>:
400539: 55 push rbp //将rbp寄存器的值入栈
40053a: 48 89 e5 mov rbp,rsp //栈指针寄存机保存到rbp基指针寄存器中,后面使用
40053d: 48 83 ec 10 sub rsp,0x10 //sub减指令,栈的增长方向是从高地址到低地址,为了
存放a,b,sum两个局部int型变量,地址加12个字节
400541: c7 45 f4 00 00 00 00 mov DWORD PTR [rbp-0xc],0x0 //sum
400548: c7 45 fc 01 00 00 00 mov DWORD PTR [rbp-0x4],0x1 //a
40054f: c7 45 f8 02 00 00 00 mov DWORD PTR [rbp-0x8],0x2 //b
400556: 8b 45 f8 mov eax,DWORD PTR [rbp-0x8]
400559: 8b 55 fc mov edx,DWORD PTR [rbp-0x4]
40055c: 01 c2 add edx,eax //相加,结果保存在edx寄存器
40055e: b8 8c 06 40 00 mov eax,0x40068c //?难道是用完EAX做还原?
400563: 89 d6 mov esi,edx // 将结果放入esi
400565: 48 89 c7 mov rdi,rax
400568: b8 00 00 00 00 mov eax,0x0 //eax存放0
40056d: e8 a6 fe ff ff call 400418 <[email protected]> //调用printf函数
400572: 8b 55 f8 mov edx,DWORD PTR [rbp-0x8] //edx保存 a
400575: 8b 45 fc mov eax,DWORD PTR [rbp-0x4] //eax保存 b
400578: 89 d6 mov esi,edx
40057a: 89 c7 mov edi,eax //分别存入esi,edi寄存器
40057c: e8 a3 ff ff ff call 400524 <sum_fun> //调用sum_fun函数
400581: 89 45 f4 mov DWORD PTR [rbp-0xc],eax //sum_fun函数执行结果存入sum
400584: b8 8c 06 40 00 mov eax,0x40068c //? ?难道是用完EAX做还原?
400589: 8b 55 f4 mov edx,DWORD PTR [rbp-0xc] //为printf准备参数,传入值
40058c: 89 d6 mov esi,edx
40058e: 48 89 c7 mov rdi,rax
400591: b8 00 00 00 00 mov eax,0x0
400596: e8 7d fe ff ff call 400418 <[email protected]>
40059b: c9 leave
40059c: c3 ret
40059d: 90 nop
40059e: 90 nop
40059f: 90 nop
感觉汇编的关键是使用好8个寄存器,每个地方保留上下文信息,方便退栈后信息的还原;
0x03 堆栈溢出
先传送一个地址,先了解,他是在32bit机器上测试。传送:http://blog.csdn.net/heiyeshuwu/article/details/50455236
堆栈溢出,简单理解为把函数栈写超,写超后覆盖某个地址,使其走另外的流程。
今天先到这,感觉汇编还不熟悉,栈的地址分配还不熟练,先练习了,完成后续文章的理解。
上一篇: 地图经纬度坐标系
下一篇: Nginx 之HTTP-FLV解析
推荐阅读