设为首页 加入收藏

TOP

【持续更新】C/C++ 踩坑记录(一)(二)
2023-08-06 07:49:43 】 浏览:353
Tags:C/C
at elf64-x86-64 Disassembly of section .text: 0000000000001169 <is_valid>: 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: 48 89 7d e8 mov %rdi,-0x18(%rbp) 1179: 48 8b 45 e8 mov -0x18(%rbp),%rax 117d: 0f b6 00 movzbl (%rax),%eax 1180: 88 45 ff mov %al,-0x1(%rbp) 1183: 48 83 7d e8 00 cmpq $0x0,-0x18(%rbp) 1188: 75 07 jne 1191 <is_valid+0x28> 118a: b8 00 00 00 00 mov $0x0,%eax 118f: eb 1e jmp 11af <is_valid+0x46> 1191: 48 8b 45 e8 mov -0x18(%rbp),%rax 1195: 48 8d 15 68 0e 00 00 lea 0xe68(%rip),%rdx # 2004 <_IO_stdin_used+0x4> 119c: 48 89 d6 mov %rdx,%rsi 119f: 48 89 c7 mov %rax,%rdi 11a2: e8 c9 fe ff ff call 1070 <strcmp@plt> 11a7: 85 c0 test %eax,%eax 11a9: 0f 94 c0 sete %al 11ac: 0f b6 c0 movzbl %al,%eax 11af: c9 leave 11b0: c3 ret

段错误如愿以偿地发生了,且是来自读取 str 处 1 字节并进行零扩展的 movzbl 指令,之前看到的编译期求值没有再次发生。

现在升高优化等级至 Og,编译期求值并优化掉第一个 if 语句的特效回归了:

lyazj@HelloWorld:~$ gcc -Wall -Wshadow -Wextra ub_null.c -o ub_null -Og
ub_null.c: In function ‘is_valid’:
ub_null.c:7:11: warning: comparison is always false due to limited range of data type [-Wtype-limits]
    7 |   if(head == 0x80) return 0;
      |           ^~
lyazj@HelloWorld:~$ ./ub_null
0
lyazj@HelloWorld:~$ objdump --disassemble=is_valid -j.text ub_null

ub_null:     file format elf64-x86-64


Disassembly of section .text:

0000000000001169 <is_valid>:
    1169:	f3 0f 1e fa          	endbr64 
    116d:	48 85 ff             	test   %rdi,%rdi
    1170:	74 1d                	je     118f <is_valid+0x26>
    1172:	48 83 ec 08          	sub    $0x8,%rsp
    1176:	48 8d 35 87 0e 00 00 	lea    0xe87(%rip),%rsi        # 2004 <_IO_stdin_used+0x4>
    117d:	e8 de fe ff ff       	call   1060 <strcmp@plt>
    1182:	85 c0                	test   %eax,%eax
    1184:	0f 94 c0             	sete   %al
    1187:	0f b6 c0             	movzbl %al,%eax
    118a:	48 83 c4 08          	add    $0x8,%rsp
    118e:	c3                   	ret    
    118f:	b8 00 00 00 00       	mov    $0x0,%eax
    1194:	c3                   	ret    

GCC 如何优化,除取决于编译选项外,同样取决于程序员编写什么样的源代码,这一点不足为奇。然而,当优化等级升至 O2 时,更为不好的事情发生了:

lyazj@HelloWorld:~$ gcc -Wall -Wshadow -Wextra ub_null.c -o ub_null -O2
ub_null.c: In function ‘is_valid’:
ub_null.c:7:11: warning: comparison is always false due to limited range of data type [-Wtype-limits]
    7 |   if(head == 0x80) return 0;
      |           ^~
In function ‘is_valid’,
    inlined from ‘main’ at ub_null.c:15:3:
ub_null.c:9:10: warning: argument 1 null where non-null expected [-Wnonnull]
    9 |   return strcmp(str, "expected string") == 0;
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from ub_null.c:2:
ub_null.c: In function ‘main’:
/usr/include/string.h:156:12: note: in a call to function ‘strcmp’ declared ‘nonnull’
  156 | extern int strcmp (const char *__s1, const char *__s2)
      |            ^~~~~~
lyazj@HelloWorld:~$ ./ub_null
Segmentation fault
lyazj@HelloWorld:~$ objdump --disassemble=is_valid -j.text ub_null

ub_null:     file format elf64-x86-64


Disassembly of section .text:

00000000000011b0 <is_valid>:
    11b0:	f3 0f 1e fa          	endbr64 
    11b4:	48 83 ec 08          	sub    $0x8,%rsp
    11b8:	48 8d 35 45 0e 00 00 	lea    0xe45(%rip),%rsi        # 2004 <_IO_stdin_used+0x4>
    11bf:	e8 9c fe ff ff       	call   1060 <strcmp@plt>
    11c4:	85 c0                	test   %eax,%eax
    11c6:	0f 94 c0             	sete   %al
    11c9:	48 83 c4 08          	add    $0x8,%rsp
    11cd:	0f b6 c0             	movzbl %al,%eax
    11d0:	c3                   	ret    

值得注意的是,现在段错误来自 strcmp() 中的 NULL dereference,且 is_valid() 的反汇编出奇地简单,GCC 同时干掉了两个 if 语句!因为我们首先访问了 str 处的 1 字节,由于 NULL dereference 是典型的 UB,编译器便假定了 str != NULL,这样第二个 if 语句也可以被优化掉!现在,我们产生了具有严重漏洞的 is_v

首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C语言中EOF的意义与用法 下一篇操作系统复习 MITS6.1810 lab uti..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目