【发布时间】:2018-04-13 10:29:36
【问题描述】:
在redhat7.2中,由于信号4,非法指令,我的程序在popen函数中得到了核心转储。但是当我调试核心文件时,我发现 rip 寄存器中的非法指令不存在。调试信息如下:
Program terminated with signal 4, Illegal instruction.
#0 0x00007fb2f217b1f4 in popen@@GLIBC_2.2.5 () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.17-105.el7.x86_64 libgcc-4.8.5-4.el7.x86_64 libstdc++-4.8.5-4.el7.x86_64 zlib-1.2.7-15.el7.x86_64
(gdb) disas
Dump of assembler code for function popen@@GLIBC_2.2.5:
0x00007fb2f217b1d0 <+0>: push %r12
0x00007fb2f217b1d2 <+2>: mov %rsi,%r12
0x00007fb2f217b1d5 <+5>: push %rbp
0x00007fb2f217b1d6 <+6>: mov %rdi,%rbp
0x00007fb2f217b1d9 <+9>: mov $0x100,%edi
0x00007fb2f217b1de <+14>: push %rbx
0x00007fb2f217b1df <+15>: sub $0x10,%rsp
0x00007fb2f217b1e3 <+19>: callq 0x7fb2f212d340 <memalign@plt>
0x00007fb2f217b1e8 <+24>: test %rax,%rax
0x00007fb2f217b1eb <+27>: mov %rax,%rbx
0x00007fb2f217b1ee <+30>: je 0x7fb2f217b240 <popen@@GLIBC_2.2.5+112>
0x00007fb2f217b1f0 <+32>: lea 0xf0(%rax),%rax
0x00007fb2f217b1f7 <+39>: xor %esi,%esi
看最新的两行,0x00007fb2f217b1f4 应该在它们之间,但是它不存在!为什么 rip 寄存器中加载了不存在的指令?
【问题讨论】:
-
遇到非法指令的地址是
0x00007fb2f217b1f4。这正好在lea 0xf0(%rax),%rax指令的中间,让我觉得是某些东西导致处理器进入随机地址。 -
也许有人试图通过 ret2reg 或 ret2code 攻击来攻击您的系统。也许他们正在寻找
jmp %rsp2 字节序列或类似的序列,但您的 glibc 的机器代码与他们开发攻击的系统不同。 -
您的措辞在技术上是错误的。地址0x00007fb2f217b1f4确实存在,如果你将那里的内存内容反汇编为x86_64指令,它可能会形成一个(或非法操作码),但它不像CPU理解原始指令边界,有
lea开始的线索在..f0和xor..f7,每条x86指令都有一定的“操作码”,由1-15个字节组成,如果你将CPU指向中间的字节,它会将它们解释为其他操作码,甚至可能(很可能)不小心形成了有效的指令。lea有 7B 操作码。 -
即CPU 确实只看到内存中的正常字节(在开始/结束操作码处没有特殊标记),并且 fetch/decode 单元将推进
rip其最后一次解码当前指令所使用的数量,因此 CPU 将正确推进“每条指令”一旦它确实从有意义的一个开始,但某些机器代码可能会在某个偏移开始处隐藏不同的指令序列,这有时甚至可能被漏洞利用编写者(ROP)滥用,或者在混淆你的代码时,或者当某些错误使您的代码跳转到计划外的地址时。
标签: linux assembly x86 x86-64 crash-dumps