栈粉碎原理分析

栈粉碎原理分析

源代码如下

#include <stdio.h>

void function(int a, int b) {
	char buffer[12];
	gets(buffer);

	//long* ret = (long *) ((long)buffer+28);
	//*ret = *ret + 7;

	return;
}

void main() {
	 int x;
	 x = 0;
	 function(1,2);
	 x = 1;
	 printf("%d\n",x);
} 
  1. 由解注释前的源代码生成二进制,分析其汇编程序,画出栈操作过程。
    Makefile
cc=gcc

all: stack_smashing stack_smashing.asm

.PHONY : clean

stack_smashing: stack_smashing.o
	cc -o stack_smashing stack_smashing.o

stack_smashing.o: stack_smashing.s
	cc -c -o stack_smashing.o stack_smashing.s

stack_smashing.s: stack_smashing.c
	cc -S -O0 -fno-stack-protector -o stack_smashing.s stack_smashing.c

stack_smashing.asm: stack_smashing
	objdump -d stack_smashing > stack_smashing.asm

clean:
	rm *.s
	rm *.o

由于存在Makefile是来编译stack_smashing.c,因此直接输入命令进行编译

make 

stack_smashing:     文件格式 elf64-x86-64


Disassembly of section .init:

0000000000001000 <_init>:
    1000:	f3 0f 1e fa          	endbr64 
    1004:	48 83 ec 08          	sub    $0x8,%rsp
    1008:	48 8b 05 d9 2f 00 00 	mov    0x2fd9(%rip),%rax        # 3fe8 <__gmon_start__@Base>
    100f:	48 85 c0             	test   %rax,%rax
    1012:	74 02                	je     1016 <_init+0x16>
    1014:	ff d0                	call   *%rax
    1016:	48 83 c4 08          	add    $0x8,%rsp
    101a:	c3                   	ret    

Disassembly of section .plt:

0000000000001020 <.plt>:
    1020:	ff 35 92 2f 00 00    	push   0x2f92(%rip)        # 3fb8 <_GLOBAL_OFFSET_TABLE_+0x8>
    1026:	f2 ff 25 93 2f 00 00 	bnd jmp *0x2f93(%rip)        # 3fc0 <_GLOBAL_OFFSET_TABLE_+0x10>
    102d:	0f 1f 00             	nopl   (%rax)
    1030:	f3 0f 1e fa          	endbr64 
    1034:	68 00 00 00 00       	push   $0x0
    1039:	f2 e9 e1 ff ff ff    	bnd jmp 1020 <_init+0x20>
    103f:	90                   	nop
    1040:	f3 0f 1e fa          	endbr64 
    1044:	68 01 00 00 00       	push   $0x1
    1049:	f2 e9 d1 ff ff ff    	bnd jmp 1020 <_init+0x20>
    104f:	90                   	nop

Disassembly of section .plt.got:

0000000000001050 <__cxa_finalize@plt>:
    1050:	f3 0f 1e fa          	endbr64 
    1054:	f2 ff 25 9d 2f 00 00 	bnd jmp *0x2f9d(%rip)        # 3ff8 <__cxa_finalize@GLIBC_2.2.5>
    105b:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)

Disassembly of section .plt.sec:

0000000000001060 <printf@plt>:
    1060:	f3 0f 1e fa          	endbr64 
    1064:	f2 ff 25 5d 2f 00 00 	bnd jmp *0x2f5d(%rip)        # 3fc8 <printf@GLIBC_2.2.5>
    106b:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)

0000000000001070 <gets@plt>:
    1070:	f3 0f 1e fa          	endbr64 
    1074:	f2 ff 25 55 2f 00 00 	bnd jmp *0x2f55(%rip)        # 3fd0 <gets@GLIBC_2.2.5>
    107b:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)

Disassembly of section .text:

0000000000001080 <_start>:
    1080:	f3 0f 1e fa          	endbr64 
    1084:	31 ed                	xor    %ebp,%ebp
    1086:	49 89 d1             	mov    %rdx,%r9
    1089:	5e                   	pop    %rsi
    108a:	48 89 e2             	mov    %rsp,%rdx
    108d:	48 83 e4 f0          	and    $0xfffffffffffffff0,%rsp
    1091:	50                   	push   %rax
    1092:	54                   	push   %rsp
    1093:	45 31 c0             	xor    %r8d,%r8d
    1096:	31 c9                	xor    %ecx,%ecx
    1098:	48 8d 3d f0 00 00 00 	lea    0xf0(%rip),%rdi        # 118f <main>
    109f:	ff 15 33 2f 00 00    	call   *0x2f33(%rip)        # 3fd8 <__libc_start_main@GLIBC_2.34>
    10a5:	f4                   	hlt    
    10a6:	66 2e 0f 1f 84 00 00 	cs nopw 0x0(%rax,%rax,1)
    10ad:	00 00 00 

00000000000010b0 <deregister_tm_clones>:
    10b0:	48 8d 3d 59 2f 00 00 	lea    0x2f59(%rip),%rdi        # 4010 <__TMC_END__>
    10b7:	48 8d 05 52 2f 00 00 	lea    0x2f52(%rip),%rax        # 4010 <__TMC_END__>
    10be:	48 39 f8             	cmp    %rdi,%rax
    10c1:	74 15                	je     10d8 <deregister_tm_clones+0x28>
    10c3:	48 8b 05 16 2f 00 00 	mov    0x2f16(%rip),%rax        # 3fe0 <_ITM_deregisterTMCloneTable@Base>
    10ca:	48 85 c0             	test   %rax,%rax
    10cd:	74 09                	je     10d8 <deregister_tm_clones+0x28>
    10cf:	ff e0                	jmp    *%rax
    10d1:	0f 1f 80 00 00 00 00 	nopl   0x0(%rax)
    10d8:	c3                   	ret    
    10d9:	0f 1f 80 00 00 00 00 	nopl   0x0(%rax)

00000000000010e0 <register_tm_clones>:
    10e0:	48 8d 3d 29 2f 00 00 	lea    0x2f29(%rip),%rdi        # 4010 <__TMC_END__>
    10e7:	48 8d 35 22 2f 00 00 	lea    0x2f22(%rip),%rsi        # 4010 <__TMC_END__>
    10ee:	48 29 fe             	sub    %rdi,%rsi
    10f1:	48 89 f0             	mov    %rsi,%rax
    10f4:	48 c1 ee 3f          	shr    $0x3f,%rsi
    10f8:	48 c1 f8 03          	sar    $0x3,%rax
    10fc:	48 01 c6             	add    %rax,%rsi
    10ff:	48 d1 fe             	sar    %rsi
    1102:	74 14                	je     1118 <register_tm_clones+0x38>
    1104:	48 8b 05 e5 2e 00 00 	mov    0x2ee5(%rip),%rax        # 3ff0 <_ITM_registerTMCloneTable@Base>
    110b:	48 85 c0             	test   %rax,%rax
    110e:	74 08                	je     1118 <register_tm_clones+0x38>
    1110:	ff e0                	jmp    *%rax
    1112:	66 0f 1f 44 00 00    	nopw   0x0(%rax,%rax,1)
    1118:	c3                   	ret    
    1119:	0f 1f 80 00 00 00 00 	nopl   0x0(%rax)

0000000000001120 <__do_global_dtors_aux>:
    1120:	f3 0f 1e fa          	endbr64 
    1124:	80 3d e5 2e 00 00 00 	cmpb   $0x0,0x2ee5(%rip)        # 4010 <__TMC_END__>
    112b:	75 2b                	jne    1158 <__do_global_dtors_aux+0x38>
    112d:	55                   	push   %rbp
    112e:	48 83 3d c2 2e 00 00 	cmpq   $0x0,0x2ec2(%rip)        # 3ff8 <__cxa_finalize@GLIBC_2.2.5>
    1135:	00 
    1136:	48 89 e5             	mov    %rsp,%rbp
    1139:	74 0c                	je     1147 <__do_global_dtors_aux+0x27>
    113b:	48 8b 3d c6 2e 00 00 	mov    0x2ec6(%rip),%rdi        # 4008 <__dso_handle>
    1142:	e8 09 ff ff ff       	call   1050 <__cxa_finalize@plt>
    1147:	e8 64 ff ff ff       	call   10b0 <deregister_tm_clones>
    114c:	c6 05 bd 2e 00 00 01 	movb   $0x1,0x2ebd(%rip)        # 4010 <__TMC_END__>
    1153:	5d                   	pop    %rbp
    1154:	c3                   	ret    
    1155:	0f 1f 00             	nopl   (%rax)
    1158:	c3                   	ret    
    1159:	0f 1f 80 00 00 00 00 	nopl   0x0(%rax)

0000000000001160 <frame_dummy>:
    1160:	f3 0f 1e fa          	endbr64 
    1164:	e9 77 ff ff ff       	jmp    10e0 <register_tm_clones>

0000000000001169 <function>:
    1169:	f3 0f 1e fa          	endbr64 
    116d:	55                   	push   %rbp
    116e:	48 89 e5             	mov    %rsp,%rbp
    1171:	48 83 ec 20          	sub    $0x20,%rsp
    1175:	89 7d ec             	mov    %edi,-0x14(%rbp)
    1178:	89 75 e8             	mov    %esi,-0x18(%rbp)
    117b:	48 8d 45 f4          	lea    -0xc(%rbp),%rax
    117f:	48 89 c7             	mov    %rax,%rdi
    1182:	b8 00 00 00 00       	mov    $0x0,%eax
    1187:	e8 e4 fe ff ff       	call   1070 <gets@plt>
    118c:	90                   	nop
    118d:	c9                   	leave  
    118e:	c3                   	ret    

000000000000118f <main>:
    118f:	f3 0f 1e fa          	endbr64 
    1193:	55                   	push   %rbp
    1194:	48 89 e5             	mov    %rsp,%rbp
    1197:	48 83 ec 10          	sub    $0x10,%rsp
    119b:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%rbp)
    11a2:	be 02 00 00 00       	mov    $0x2,%esi
    11a7:	bf 01 00 00 00       	mov    $0x1,%edi
    11ac:	e8 b8 ff ff ff       	call   1169 <function>
    11b1:	c7 45 fc 01 00 00 00 	movl   $0x1,-0x4(%rbp)
    11b8:	8b 45 fc             	mov    -0x4(%rbp),%eax
    11bb:	89 c6                	mov    %eax,%esi
    11bd:	48 8d 05 40 0e 00 00 	lea    0xe40(%rip),%rax        # 2004 <_IO_stdin_used+0x4>
    11c4:	48 89 c7             	mov    %rax,%rdi
    11c7:	b8 00 00 00 00       	mov    $0x0,%eax
    11cc:	e8 8f fe ff ff       	call   1060 <printf@plt>
    11d1:	90                   	nop
    11d2:	c9                   	leave  
    11d3:	c3                   	ret    

Disassembly of section .fini:

00000000000011d4 <_fini>:
    11d4:	f3 0f 1e fa          	endbr64 
    11d8:	48 83 ec 08          	sub    $0x8,%rsp
    11dc:	48 83 c4 08          	add    $0x8,%rsp
    11e0:	c3                   	ret    

这个asm汇编程序的主要涉及到栈操作的为functionmain函数

main函数

0000000000001169 <function>:
    1169:	f3 0f 1e fa          	endbr64         # 将64位模式下的栈对齐到16字节
    116d:	55                   	push   %rbp      #保存调用该函数前的栈基指针。
    116e:	48 89 e5             	mov    %rsp,%rbp # 将rsp寄存器的值赋给rbp寄存器
    1171:	48 83 ec 20          	sub    $0x20,%rsp # 在栈中为局部变量分配空间,将rsp寄存器的值减去0x20,即开辟栈空间0x20
    1175:	89 7d ec             	mov    %edi,-0x14(%rbp) # 将edi寄存器的值赋给局部变量-0x14(%rbp)
    1178:	89 75 e8             	mov    %esi,-0x18(%rbp) # 将esi寄存器的值赋给局部变量-0x18(%rbp)
    117b:	48 8d 45 f4          	lea    -0xc(%rbp),%rax  # 将局部变量-0xc(%rbp)的地址赋给rax寄存器
    117f:	48 89 c7             	mov    %rax,%rdi        # 将rax寄存器的值赋给rdi寄存器
    1182:	b8 00 00 00 00       	mov    $0x0,%eax      # 将0x0赋给eax寄存器目的是为了调用printf函数
    1187:	e8 e4 fe ff ff       	call   1070 <gets@plt> # 调用gets函数
    118c:	90                   	nop                    # 无操作,目的是为了填充字节,使得函数的长度为16的倍数
    118d:	c9                   	leave                 # 恢复rbp寄存器的值
    118e:	c3                   	ret                 # 函数返回
000000000000118f <main>:
    118f:	f3 0f 1e fa          	endbr64           # 将64位模式下的栈对齐到16字节
    1193:	55                   	push   %rbp           # 保存调用该函数前的栈基指针
    1194:	48 89 e5             	mov    %rsp,%rbp     # 将rsp寄存器的值赋给rbp寄存器
    1197:	48 83 ec 10          	sub    $0x10,%rsp    # 在栈中为局部变量分配空间,将rsp寄存器的值减去0x10,即开辟栈空间0x10
    119b:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%rbp)   # 将0x0赋给局部变量-0x4(%rbp)
    11a2:	be 02 00 00 00       	mov    $0x2,%esi       # 将0x2赋给esi寄存器
    11a7:	bf 01 00 00 00       	mov    $0x1,%edi       # 将0x1赋给edi寄存器
    11ac:	e8 b8 ff ff ff       	call   1169 <function> # 调用function函数
    11b1:	c7 45 fc 01 00 00 00 	movl   $0x1,-0x4(%rbp)  # 将0x1赋给局部变量-0x4(%rbp)
    11b8:	8b 45 fc             	mov    -0x4(%rbp),%eax  # 将局部变量-0x4(%rbp)的值赋给eax寄存器
    11bb:	89 c6                	mov    %eax,%esi          # 将eax寄存器的值赋给esi寄存器
    11bd:	48 8d 05 40 0e 00 00 	lea    0xe40(%rip),%rax        # 2004 <_IO_stdin_used+0x4> # 将字符串的地址赋给rax寄存器
    11c4:	48 89 c7             	mov    %rax,%rdi            # 将rax寄存器的值赋给rdi寄存器
    11c7:	b8 00 00 00 00       	mov    $0x0,%eax             # 将0x0赋给eax寄存器目的是为了调用printf函数
    11cc:	e8 8f fe ff ff       	call   1060 <printf@plt>       # 调用printf函数
    11d1:	90                   	nop                            # 无操作,目的是为了填充字节,使得函数的长度为16的倍数
    11d2:	c9                   	leave                     # 恢复rbp寄存器的值
    11d3:	c3                   	ret                    # 函数返回

0x1193-0x1194 push %rbp 将栈顶指针向下移动 8 字节,并将rbp中的值压入栈中。mov %rsp,%rbprsp的值复制到rbp中,这样就建立了一个新的基址指针,用于指向当前函数的栈帧。

0x1197 sub $0x10,%rsp 将栈顶指针向下移动了0x10个字节,给当前函数分配了16个字节的栈空间。这些空间用于存储本地变量和函数调用时需要保存的寄存器。

0x119b movl $0x0,-0x4(%rbp) 将变量x初始化为 0

在这里插入图片描述

0x11a2-0x11a7 mov $0x2,%esimov $0x1,%edi 分别将值2和1存储到 %esi%edi 中。

0x11ac call 1169 <function> 调用function(1,2) 在调用函数之前,当前函数的返回地址%rip被压入栈中,同时 %rsp 指针向下移动了8个字节

在这里插入图片描述

0x116d-0x116epush %rbp 将栈顶指针向下移动 8 字节,并将 %rbp 中的值压入栈中。 mov %rsp,%rbp%rsp 的值复制到 %rbp 中,建立一个新的基址指针,用于指向当前函数的栈帧。

0x1171 sub $0x20,%rsp 将栈顶指针向下移动了0x20个字节,给当前函数分配了32个字节的栈空间。

0x1175-0x1178mov %edi,-0x14(%rbp)mov %esi,-0x18(%rbp) 分别将 %edi%esi 寄存器中的值存储到当前栈帧中的相对偏移量为 -0x14 和 -0x18 的位置中。这两个值分别是函数 function 的形参a,b

在这里插入图片描述

接下来调用 gets(buffer)

lea -0xc(%rbp),%rax
mov %rax,%rdi
mov $0x0,%eax 将 buffer 地址传给寄存器 rdi
call 1070 <gets@plt> 调用 gets(buffer)

nop; leave; ret 返回到 ret_function(0x11b1) 中

movl $0x1,-0x4(%rbp) # 将0x1赋给局部变量-0x4(%rbp) 将 x 设为 1

在这里插入图片描述

接下来调用 printf("%d\n", x)

mov -0x4(%rbp),%eax 将局部变量-0x4(%rbp)的值赋给eax寄存
mov %eax,%esi 将eax寄存器的值赋给esi寄存器,将 x 值传给寄存器 esi
lea 0xe40(%rip),%rax 将字符串的地址赋给rax寄存器
mov %rax,%rdi
mov $0x0,%eax 将 “%d\n” 字符串地址传给寄存器 rdi
call 1060 <printf@plt> 调用 printf(“%d\n”, x)

nop; leave; ret

  1. 将源代码中的语句解注释,再生成二进制,分析其汇编程序,画出栈操作过程。

将源代码解注释的汇编代码


stack_smashing:     文件格式 elf64-x86-64


Disassembly of section .init:

0000000000001000 <_init>:
    1000:	f3 0f 1e fa          	endbr64 
    1004:	48 83 ec 08          	sub    $0x8,%rsp
    1008:	48 8b 05 d9 2f 00 00 	mov    0x2fd9(%rip),%rax        # 3fe8 <__gmon_start__@Base>
    100f:	48 85 c0             	test   %rax,%rax
    1012:	74 02                	je     1016 <_init+0x16>
    1014:	ff d0                	call   *%rax
    1016:	48 83 c4 08          	add    $0x8,%rsp
    101a:	c3                   	ret    

Disassembly of section .plt:

0000000000001020 <.plt>:
    1020:	ff 35 92 2f 00 00    	push   0x2f92(%rip)        # 3fb8 <_GLOBAL_OFFSET_TABLE_+0x8>
    1026:	f2 ff 25 93 2f 00 00 	bnd jmp *0x2f93(%rip)        # 3fc0 <_GLOBAL_OFFSET_TABLE_+0x10>
    102d:	0f 1f 00             	nopl   (%rax)
    1030:	f3 0f 1e fa          	endbr64 
    1034:	68 00 00 00 00       	push   $0x0
    1039:	f2 e9 e1 ff ff ff    	bnd jmp 1020 <_init+0x20>
    103f:	90                   	nop
    1040:	f3 0f 1e fa          	endbr64 
    1044:	68 01 00 00 00       	push   $0x1
    1049:	f2 e9 d1 ff ff ff    	bnd jmp 1020 <_init+0x20>
    104f:	90                   	nop

Disassembly of section .plt.got:

0000000000001050 <__cxa_finalize@plt>:
    1050:	f3 0f 1e fa          	endbr64 
    1054:	f2 ff 25 9d 2f 00 00 	bnd jmp *0x2f9d(%rip)        # 3ff8 <__cxa_finalize@GLIBC_2.2.5>
    105b:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)

Disassembly of section .plt.sec:

0000000000001060 <printf@plt>:
    1060:	f3 0f 1e fa          	endbr64 
    1064:	f2 ff 25 5d 2f 00 00 	bnd jmp *0x2f5d(%rip)        # 3fc8 <printf@GLIBC_2.2.5>
    106b:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)

0000000000001070 <gets@plt>:
    1070:	f3 0f 1e fa          	endbr64 
    1074:	f2 ff 25 55 2f 00 00 	bnd jmp *0x2f55(%rip)        # 3fd0 <gets@GLIBC_2.2.5>
    107b:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)

Disassembly of section .text:

0000000000001080 <_start>:
    1080:	f3 0f 1e fa          	endbr64 
    1084:	31 ed                	xor    %ebp,%ebp
    1086:	49 89 d1             	mov    %rdx,%r9
    1089:	5e                   	pop    %rsi
    108a:	48 89 e2             	mov    %rsp,%rdx
    108d:	48 83 e4 f0          	and    $0xfffffffffffffff0,%rsp
    1091:	50                   	push   %rax
    1092:	54                   	push   %rsp
    1093:	45 31 c0             	xor    %r8d,%r8d
    1096:	31 c9                	xor    %ecx,%ecx
    1098:	48 8d 3d 0e 01 00 00 	lea    0x10e(%rip),%rdi        # 11ad <main>
    109f:	ff 15 33 2f 00 00    	call   *0x2f33(%rip)        # 3fd8 <__libc_start_main@GLIBC_2.34>
    10a5:	f4                   	hlt    
    10a6:	66 2e 0f 1f 84 00 00 	cs nopw 0x0(%rax,%rax,1)
    10ad:	00 00 00 

00000000000010b0 <deregister_tm_clones>:
    10b0:	48 8d 3d 59 2f 00 00 	lea    0x2f59(%rip),%rdi        # 4010 <__TMC_END__>
    10b7:	48 8d 05 52 2f 00 00 	lea    0x2f52(%rip),%rax        # 4010 <__TMC_END__>
    10be:	48 39 f8             	cmp    %rdi,%rax
    10c1:	74 15                	je     10d8 <deregister_tm_clones+0x28>
    10c3:	48 8b 05 16 2f 00 00 	mov    0x2f16(%rip),%rax        # 3fe0 <_ITM_deregisterTMCloneTable@Base>
    10ca:	48 85 c0             	test   %rax,%rax
    10cd:	74 09                	je     10d8 <deregister_tm_clones+0x28>
    10cf:	ff e0                	jmp    *%rax
    10d1:	0f 1f 80 00 00 00 00 	nopl   0x0(%rax)
    10d8:	c3                   	ret    
    10d9:	0f 1f 80 00 00 00 00 	nopl   0x0(%rax)

00000000000010e0 <register_tm_clones>:
    10e0:	48 8d 3d 29 2f 00 00 	lea    0x2f29(%rip),%rdi        # 4010 <__TMC_END__>
    10e7:	48 8d 35 22 2f 00 00 	lea    0x2f22(%rip),%rsi        # 4010 <__TMC_END__>
    10ee:	48 29 fe             	sub    %rdi,%rsi
    10f1:	48 89 f0             	mov    %rsi,%rax
    10f4:	48 c1 ee 3f          	shr    $0x3f,%rsi
    10f8:	48 c1 f8 03          	sar    $0x3,%rax
    10fc:	48 01 c6             	add    %rax,%rsi
    10ff:	48 d1 fe             	sar    %rsi
    1102:	74 14                	je     1118 <register_tm_clones+0x38>
    1104:	48 8b 05 e5 2e 00 00 	mov    0x2ee5(%rip),%rax        # 3ff0 <_ITM_registerTMCloneTable@Base>
    110b:	48 85 c0             	test   %rax,%rax
    110e:	74 08                	je     1118 <register_tm_clones+0x38>
    1110:	ff e0                	jmp    *%rax
    1112:	66 0f 1f 44 00 00    	nopw   0x0(%rax,%rax,1)
    1118:	c3                   	ret    
    1119:	0f 1f 80 00 00 00 00 	nopl   0x0(%rax)

0000000000001120 <__do_global_dtors_aux>:
    1120:	f3 0f 1e fa          	endbr64 
    1124:	80 3d e5 2e 00 00 00 	cmpb   $0x0,0x2ee5(%rip)        # 4010 <__TMC_END__>
    112b:	75 2b                	jne    1158 <__do_global_dtors_aux+0x38>
    112d:	55                   	push   %rbp
    112e:	48 83 3d c2 2e 00 00 	cmpq   $0x0,0x2ec2(%rip)        # 3ff8 <__cxa_finalize@GLIBC_2.2.5>
    1135:	00 
    1136:	48 89 e5             	mov    %rsp,%rbp
    1139:	74 0c                	je     1147 <__do_global_dtors_aux+0x27>
    113b:	48 8b 3d c6 2e 00 00 	mov    0x2ec6(%rip),%rdi        # 4008 <__dso_handle>
    1142:	e8 09 ff ff ff       	call   1050 <__cxa_finalize@plt>
    1147:	e8 64 ff ff ff       	call   10b0 <deregister_tm_clones>
    114c:	c6 05 bd 2e 00 00 01 	movb   $0x1,0x2ebd(%rip)        # 4010 <__TMC_END__>
    1153:	5d                   	pop    %rbp
    1154:	c3                   	ret    
    1155:	0f 1f 00             	nopl   (%rax)
    1158:	c3                   	ret    
    1159:	0f 1f 80 00 00 00 00 	nopl   0x0(%rax)

0000000000001160 <frame_dummy>:
    1160:	f3 0f 1e fa          	endbr64 
    1164:	e9 77 ff ff ff       	jmp    10e0 <register_tm_clones>

0000000000001169 <function>:
    1169:	f3 0f 1e fa          	endbr64 
    116d:	55                   	push   %rbp
    116e:	48 89 e5             	mov    %rsp,%rbp
    1171:	48 83 ec 30          	sub    $0x30,%rsp
    1175:	89 7d dc             	mov    %edi,-0x24(%rbp)
    1178:	89 75 d8             	mov    %esi,-0x28(%rbp)
    117b:	48 8d 45 ec          	lea    -0x14(%rbp),%rax
    117f:	48 89 c7             	mov    %rax,%rdi
    1182:	b8 00 00 00 00       	mov    $0x0,%eax
    1187:	e8 e4 fe ff ff       	call   1070 <gets@plt>
    118c:	48 8d 45 ec          	lea    -0x14(%rbp),%rax
    1190:	48 83 c0 1c          	add    $0x1c,%rax
    1194:	48 89 45 f8          	mov    %rax,-0x8(%rbp)
    1198:	48 8b 45 f8          	mov    -0x8(%rbp),%rax
    119c:	48 8b 00             	mov    (%rax),%rax
    119f:	48 8d 50 07          	lea    0x7(%rax),%rdx
    11a3:	48 8b 45 f8          	mov    -0x8(%rbp),%rax
    11a7:	48 89 10             	mov    %rdx,(%rax)
    11aa:	90                   	nop
    11ab:	c9                   	leave  
    11ac:	c3                   	ret    

00000000000011ad <main>:
    11ad:	f3 0f 1e fa          	endbr64 
    11b1:	55                   	push   %rbp
    11b2:	48 89 e5             	mov    %rsp,%rbp
    11b5:	48 83 ec 10          	sub    $0x10,%rsp
    11b9:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%rbp)
    11c0:	be 02 00 00 00       	mov    $0x2,%esi
    11c5:	bf 01 00 00 00       	mov    $0x1,%edi
    11ca:	e8 9a ff ff ff       	call   1169 <function>
    11cf:	c7 45 fc 01 00 00 00 	movl   $0x1,-0x4(%rbp)
    11d6:	8b 45 fc             	mov    -0x4(%rbp),%eax
    11d9:	89 c6                	mov    %eax,%esi
    11db:	48 8d 05 22 0e 00 00 	lea    0xe22(%rip),%rax        # 2004 <_IO_stdin_used+0x4>
    11e2:	48 89 c7             	mov    %rax,%rdi
    11e5:	b8 00 00 00 00       	mov    $0x0,%eax
    11ea:	e8 71 fe ff ff       	call   1060 <printf@plt>
    11ef:	90                   	nop
    11f0:	c9                   	leave  
    11f1:	c3                   	ret    

Disassembly of section .fini:

00000000000011f4 <_fini>:
    11f4:	f3 0f 1e fa          	endbr64 
    11f8:	48 83 ec 08          	sub    $0x8,%rsp
    11fc:	48 83 c4 08          	add    $0x8,%rsp
    1200:	c3                   	ret    

这个asm汇编程序的同样主要涉及到栈操作的为functionmain函数,这里就不再重复上述的注释过程

main函数的栈帧变化与上面的相同

lea -0x14(%rbp),%rax
mov %rax,%rdi
mov $0x0,%eax 将 buffer 地址传给寄存器 rdi
call 1070 <gets@plt> 调用 gets(buffer)

gets函数结束时

在这里插入图片描述

那么我们来分析解注释及在调用gets函数后的变化

lea -0x14(%rbp),%rax 计算距离当前 %rbp 20 个字节的地址,并将其存储到 %rax 中。

add $0x1c,%rax 指令将 %rax中的值加上 0x1c,执行(long *) ((long)buffer+28),此时rsp指向rbp+8即ret_function位置

mov %rax,-0x8(%rbp)%rax的值存储到距离当前%rbp8个字节的位置,即将ret_function的地址传给ret
在这里插入图片描述

mov -0x8(%rbp),%rax 将ret值传给rax

mov (%rax),%rax
lea 0x7(%rax),%rdx将 rax + 0x7的地址传给rdx
mov -0x8(%rbp),%rax将ret值传给rax
mov %rdx,(%rax) 将 rax + 0x7 的值传给 ret_function

在这里插入图片描述

nop; leave; ret 返回到 ret_function(0x11cf+0x7=0x11d6) 中

因此返回main函数时不会执行0x11d6的命令即movl $0x1,-0x4(%rbp)作用为将x=1

因此最终程序会输出0

  1. 思考注释的源码语句,在你的系统环境和编译器设置下,是否偏移量28和7能够实现跳过main函数中“x=1;”语句的功能?如果不能,在你的系统/编译器设置下,这两个偏移量应设置为多少?

根据上述分析和测试结果能

在这里插入图片描述

  1. 解释被注释的源码语句,是如何在源码层面实现修改返回指令指针的?

%rax lea 0x7(%rax),%rdx将 rax + 0x7的地址传给rdx mov -0x8(%rbp),%rax将ret值传给rax mov %rdx,(%rax)` 将 rax + 0x7 的值传给 ret_function

[外链图片转存中…(img-71yUOgqP-1690513044497)]

nop; leave; ret 返回到 ret_function(0x11cf+0x7=0x11d6) 中

因此返回main函数时不会执行0x11d6的命令即movl $0x1,-0x4(%rbp)作用为将x=1

因此最终程序会输出0

  1. 思考注释的源码语句,在你的系统环境和编译器设置下,是否偏移量28和7能够实现跳过main函数中“x=1;”语句的功能?如果不能,在你的系统/编译器设置下,这两个偏移量应设置为多少?

根据上述分析和测试结果能
在这里插入图片描述

  1. 解释被注释的源码语句,是如何在源码层面实现修改返回指令指针的?

根据 function函数栈帧的排列分布,该代码中ret获取buffer数组的地址后,再加上28(0x1c),便获取到了function函数返回地址所在的空间,将该值加上 7(0x7)后,在函数返回main 函数时,便会跳过x=1的执行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/48165.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

windows C++多线程同步<3>-互斥量

windows C多线程同步&#xff1c;3&#xff1e;-互斥量 概念&#xff0c;如下图&#xff1a; 另外就是互斥对象谁拥有&#xff0c;谁释放 那么一个线程允许多次获取互斥对象吗&#xff1f; 答案是允许&#xff0c;但是申请多次就要释放多次&#xff0c;否则其他线程获取不到互…

「分享」Word文档被锁定无法编辑怎么办?4种方法解决

有没有遇到这种情况&#xff1f;打开Word文档后&#xff0c;发现文档被锁定了&#xff0c;无法输入内容&#xff0c;也无法修改&#xff0c;这很大可能是Word文档被设置了“限制编辑”。 如果Word文档被设置了“限制编辑”&#xff0c;而我们又需要编辑文档&#xff0c;可以用…

等分切割图片的方法

在做数据集的过程中&#xff0c;有时候需要将大图进行切分成小图片&#xff0c;一方面是为了满足训练需要&#xff0c;一方面是为了扩增数据集。 如下图的尺寸为5472x3648,但是我用不着这么大的图片&#xff0c;需要将图9等分 市面上也有等分切割图片的软件或者网站&#xff…

tensorRT多batch动态推理

tensorRT的多batch推理&#xff0c;导出的onnx模型必须是动态batch&#xff0c;只需在导出的时候&#xff0c;设置一个dynamic_axis参数即可。 torch.onnx.export(hybrik_model, dummy_input, "./best_model.onnx", verboseTrue, input_namesinput_names, \output_…

19 QListWidget控件

Tips: 对于列表式数据可以使用QStringList进行左移一块输入。 代码&#xff1a; //listWidget使用 // QListWidgetItem * item new QListWidgetItem("锄禾日当午"); // QListWidgetItem * item2 new QListWidgetItem("汗滴禾下土"); // ui->…

树状数组1

五分钟丝滑动画讲解 | 树状数组_哔哩哔哩_bilibili (23条消息) 树状数组(详细分析应用)&#xff0c;看不懂打死我!_树形数组_鲜果维他命的博客-CSDN博客 注意&#xff1a; 1、树状数组一般的数组一般从下标1开始赋值0作为一个边界 &#xff0c;lowbit&#xff08;0&#…

apple pencil值不值得购买?便宜的电容笔推荐

如今&#xff0c;对ipad使用者而言&#xff0c;苹果原装的Pencil系列无疑是最佳的电容笔。只是不过这款电容笔的售价&#xff0c;实在是太高了&#xff0c;一般的用户都无法入手。因此&#xff0c;在具体的使用过程中&#xff0c;如何选用一种性能优良、价格低廉的电容笔是非常…

Python数据可视化工具——Pyecharts

目录 1 简介绘图前先导包 2 折线图3 饼图4 柱状图/条形图5 散点图6 箱线图7 热力图8 漏斗图9 3D柱状图10 其他&#xff1a;配置项 1 简介 Pyecharts是一款将python与echarts结合的强大的数据可视化工具 Pyecharts是一个用于生成echarts图表的类库。echarts是百度开源的一个数据…

以智慧监测模式守护燃气安全 ,汉威科技“传感芯”凸显智慧力

城市燃气工程作为城市基建的重要组成部分&#xff0c;与城市居民生活、工业生产紧密相关。提升城市燃气服务质量和安全水平&#xff0c;也一直是政府和民众关注的大事。然而&#xff0c;近年来居民住宅、餐饮等工商业场所燃气事故频发&#xff0c;时刻敲响的警钟也折射出我国在…

大数据课程D1——hadoop的初识

文章作者邮箱&#xff1a;yugongshiyesina.cn 地址&#xff1a;广东惠州 ▲ 本章节目的 ⚪ 了解大数据的概念&#xff1b; ⚪ 了解大数据的部门结构&#xff1b; ⚪ 了解hadoop的定义&#xff1b; ⚪ 了解hadoop的发展史&#xff1b; 一、大数据简介 1. 概述…

简要介绍 | 自回归生成:探索序列的未来之旅

注1&#xff1a;本文系“简要介绍”系列之一&#xff0c;仅从概念上对Autoregressive Generation进行非常简要的介绍&#xff0c;不适合用于深入和详细的了解。 自回归生成&#xff1a;探索序列的未来之旅 Approach - Autoregressive Conditional Generation using Transformer…

【Ajax】笔记-jsonp实现原理

JSONP JSONP是什么 JSONP(JSON With Padding),是一个非官方的跨域解决方案&#xff0c;纯粹凭借程序员的聪明才智开发出来的&#xff0c;只支持get请求。JSONP 怎么工作的&#xff1f; 在网页有一些标签天生具有跨域能力&#xff0c;比如&#xff1a;img link iframe script. …

启用、禁用员工账号

接口相关信息 controller层 /** 启用禁用员工账号* */PostMapping("/status/{status}")ApiOperation("启用禁用员工账号")public Result startOrStop(PathVariable Integer status, Long id) {log.info("启用禁用员工{}&#xff0c;{}",status,i…

Docker网络与Docker Compose服务编排

docker网络 docker是以镜像一层一层构建的&#xff0c;而基础镜像是linux内核&#xff0c;因此docker之间也需要通讯&#xff0c;那么就需要有自己的网络。就像windows都有自己的内网地址一样&#xff0c;每个docker容器也是有自己的私有地址的。 docker inspect [docker_ID]…

flask中的常用装饰器

flask中的常用装饰器 Flask 框架中提供了一些内置的装饰器&#xff0c;这些装饰器可以帮助我们更方便地开发 Web 应用。以下是一些常用的 Flask 装饰器&#xff1a; app.route()&#xff1a;这可能是 Flask 中最常用的装饰器。它用于将 URL 路由绑定到一个 Python 函数&#x…

【C++初阶】C++基础(上)——C++关键字、命名空间、C++输入输出、缺省参数、函数重载

目录 1. C关键字 2. 命名空间 2.1 命名空间的定义 2.2 命名空间的使用 3. C输入&输出 4. 缺省参数 4.1 缺省参数概念 4.2 缺省参数分类 5. 函数重载 5.1 函数重载概念 5.2 C支持函数重载的原理——名字修饰&#xff08;name Mingling&#xff09; 5.3 extern &…

【Nodejs】接口规范和业务分层

1.接口规范-RESTful架构 1.1 什么是REST REST全称是Representational State Transfer&#xff0c;中文意思是表述&#xff08;编者注&#xff1a;通常译为表征&#xff09;性状态转移。 它首次出现在2000年Roy Fielding的博士论文中&#xff0c;Roy Fielding是HTTP规范的主要编…

图像 检测 - FCOS: Fully Convolutional One-Stage Object Detection (ICCV 2019)

FCOS: Fully Convolutional One-Stage Object Detection - 全卷积一阶段目标检测&#xff08;ICCV 2019&#xff09; 摘要1. 引言2. 相关工作3. 我们的方法3.1 全卷积一阶目标检测器3.2 FCOS的FPN多级预测3.3 FCOS中心度 4. 实验4.1 消融研究4.1.1 FPN多级预测4.1.2 有无中心度…

HighTec 工程配置详解1

目录 HighTec 工程配置详解编译配置构建配置管理器编译属性编译步骤编译环境变量编译日志编译配置TriCore C CompilerTriCore C LinkerHighTec 工程配置详解 编译配置 构建配置管理器 管理器内,可以创建各种不同用途的配置项。例如用于生产工程的 ROM 配置,用于调试工程的…

神经网络的初始化方法

文章目录 1、随机初始化2、Xavier初始化3、He初始化4、权重预训练初始化5、零初始化 对于神经网络的训练过程中&#xff0c;合适的参数初始化方法有助于更好的处理梯度消失和梯度爆炸问题。通常有以下几种初始化方法&#xff1a; 1、随机初始化 随机初始化&#xff08;Random…