Linux:在glibc中的LEA指令中使用RIP进行非法指令

时间:2018-04-13 10:29:36

标签: linux assembly x86 x86-64 crash-dumps

在redhat7.2中,由于信号4,非法指令,我的程序在popen函数中得到了核心转储。但是当我调试核心文件时,我发现rip寄存器中的Illegal指令不存在。调试信息如下:

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寄存器中加载了不存在的指令?

1 个答案:

答案 0 :(得分:1)

在奇怪地址执行的最常见方法是使用一个函数来覆盖其堆栈上保存的%rip - 类似缓冲区溢出的功能可以很好地完成,但是野外或未初始化的指针也是如此。当函数'返回'时,它会进入除预期之外的某个位置。有目的的版本是基本的缓冲区溢出&amp; |面向回归的编程攻击。但要保持偏执,直到它被证明是合理的。

要诊断这一点,您应该仔细分析发生的堆栈帧。调试器能否恢复有意义的堆栈跟踪?堆栈是否包含图案化数据(例如ascii字符串)?

即使调试器不能,通常也值得尝试反汇编堆栈上的值;例如,如果堆栈上有0x123400,请尝试查看0x1233f5 - 如果它反汇编成一个调用指令,您可能会遇到某些问题。打破英特尔参考,有太多的通话格式。通过一些努力,您可以编写一个gdb脚本来自动执行此操作,或者至少确定候选项。

同样看起来在堆栈下方,因为通常会保留一些完整的调用帧,这可能暗示它正在执行的位置。