【问题标题】:I can't modify RIP register on 64-bit linux我无法在 64 位 linux 上修改 RIP 寄存器
【发布时间】:2014-01-03 17:00:45
【问题描述】:

我正在尝试了解堆栈溢出,但我读到的都是关于 32 位的。我的处理器是 64 位的,我遇到了以下问题:

C 代码:

#include <stdio.h>
#include <string.h>
void return_input (void)
{ 
char array[30]; 
gets (array); 
printf("%s\n", array); 
}
int main() 
{ 
return_input(); 
return 0; 

}

GDB 拒绝:

Dump of assembler code for function main:
   0x000000000040055f <+0>: push   %rbp
   0x0000000000400560 <+1>: mov    %rsp,%rbp
   0x0000000000400563 <+4>: callq  0x40053d <return_input>
   0x0000000000400568 <+9>: mov    $0x0,%eax
   0x000000000040056d <+14>:    pop    %rbp
   0x000000000040056e <+15>:    retq   
End of assembler dump.

GDB 不作为返回输入:

   Dump of assembler code for function return_input:
   0x000000000040053d <+0>: push   %rbp
   0x000000000040053e <+1>: mov    %rsp,%rbp
   0x0000000000400541 <+4>: sub    $0x20,%rsp
   0x0000000000400545 <+8>: lea    -0x20(%rbp),%rax
   0x0000000000400549 <+12>:    mov    %rax,%rdi
   0x000000000040054c <+15>:    callq  0x400440 <gets@plt>
   0x0000000000400551 <+20>:    lea    -0x20(%rbp),%rax
   0x0000000000400555 <+24>:    mov    %rax,%rdi
   0x0000000000400558 <+27>:    callq  0x400410 <puts@plt>
   0x000000000040055d <+32>:    leaveq 
   0x000000000040055e <+33>:    retq 

编译说明:

cc -mpreferred-stack-boundary=4 -ggdb overflow.c -o overflow
or
cc -mpreferred-stack-boundary=4 -ggdb -fno-stack-protector -z execstack overflow.c -o overflow

好吧,我正在尝试将 RIP 修改为 0x0000000000400563,并使代码要求输入两次,但它不起作用。

我发现输入 40 个字符时代码会崩溃。所以我尝试了以下输入:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x63\x05\x40\x00

break *0x000000000040055

(gdb) x/12x $rsp
0x7fffffffe280: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffe290: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffe2a0: 0x41414141  0x41414141  0x3336785c  0x3530785c
(gdb) 

正常输入无崩溃:

AAAAAAAAAAAAAAAAAAAAAAAAA

break *0x000000000040055

(gdb) x/12x $rsp
0x7fffffffe280: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffe290: 0x41414141  0x41414141  0x00400041  0x00000000
0x7fffffffe2a0: 0xffffe2b0  0x00007fff  0x00400568  0x00000000
(gdb) 

如您所见,这里的堆栈指向 0x00400568,但控制输入的 RIP 指向 0x3336785c。为什么?我无法以正确的方式注入地址。

感谢您的宝贵时间。我真的很感激任何答案。

【问题讨论】:

  • GDB disas return_input:...这里也是main的反汇编
  • @user2529583 已编辑。谢谢。

标签: gcc assembly gdb 64-bit stack-overflow


【解决方案1】:

所以我尝试了以下输入:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x63\x05\x40\x00

您正在将文字字符 '\\', '6', '3', '\\', '0', '5' 等(即它们的 ASCII 代码)放入缓冲区。但是您应该将实际数字 0x400563 放在那里,而不是 '4', '0' 等的 ASCII 码。

通常的方法是通过管道输出例如

perl -e 'print "A" x 20, "\x63", "\x05", "\x40", "\x00"'

到你的程序的输入。

更新:

但是我是怎么装上 gdb "perl -e ..."

实现这一点的常用方法是将所需的输出放入文件中:

printf "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x63\x05\x40\x00" > /tmp/t

然后使用 GDB 输入重定向:

(gdb) run < /tmp/t

【讨论】:

  • 当我执行"printf"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x63\x05\x40\x00" | ./overflow" 时,它会打印两次。但是我如何使用 gdb "perl -e 'print "A" x 20、"\x63"、"\x05"、"\x40"、"\x00"'"。我是说什么时候?
猜你喜欢
  • 1970-01-01
  • 2022-01-15
  • 2021-08-17
  • 1970-01-01
  • 1970-01-01
  • 2019-04-21
  • 2013-11-29
  • 1970-01-01
  • 2011-10-26
相关资源
最近更新 更多