【问题标题】:Why cant i set Breakpoints using the memory addresses为什么我不能使用内存地址设置断点
【发布时间】:2018-01-26 03:38:16
【问题描述】:

当我遇到 x68_64 bufferOverFlows 的本教程时,我正在学习汇编处理器架构和漏洞利用开发,因此我复制了 vuln 代码并使用 gcc 编译它。我编译的二进制文件不允许我设置断点,但是当我从网站下载二进制文件时(“我不想这样做”)它工作正常,内存地址正常

但是当我用 gdb 在我的编译程序中转储 main 时,我的内存地址如下所示: 0x000000000000085e : lea -0xd0(%rbp),%rax

End of assembler dump.

当我尝试在 scanf 函数之后设置中断点时: (gdb) 中断 *0x000000000000085e 0x85e 处的断点 1 (gdb) 运行

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void validate(char *pass) {
   if (strcmp(pass, "[REDACTED]") == 0) {
        printf("ACCESS GRANTED!");
        printf("Oh that's just idio... Oh my god!\n");
    } else {
        printf("Damn it, I had something for this...\n");
    }
}

int main(int argc, char **argv) {
    char password[200];
    printf("C:/ENTER PASSWORD: ");
    scanf("%s", password);
    validate(password);
   return 0;
}

【问题讨论】:

  • 关于:scanf("%s", password);, 1) 始终检查返回值(不是参数值)以确保操作成功。在当前场景中,任何除 1 以外的返回值都表示发生了错误。 2) 使用输入格式说明符 '%s' 和/或 '%[...]' 时,始终包含比输入缓冲区长度小 1 的 MAX CHARACTERS 修饰符,以避免缓冲区溢出和导致的未定义行为。建议:if( 1 != scanf("%199s", password) ) { fprintf( stderr, "scanf for password failed" ); exit( EXIT_FAILURE ); }
  • 当函数的参数:main()不打算使用时,建议使用签名:int main( void )
  • 好的,谢谢,这个程序应该是易受攻击的,我只是一个初学者。基本上我复制并粘贴了这个然后使用 gcc 编译它,我的内存地址很奇怪我不知道从哪里开始寻找这个答案或者说我的内存地址看起来像 0x6c5 奇怪的缺少一个数字。
  • 当我从教程网站下载程序并检查了他出来的地址时,看起来像这样 0x6a84

标签: c gcc assembly compilation x86-64


【解决方案1】:

您可以在虚拟地址上设置断点,但objdump 不知道您的 PIE 可执行文件将映射到内存的何处,因此它使用0 作为基地址。为了使事情更简单,请禁用 PIE (which your distro apparently enables by default)。大概您的教程是在这很常见之前编写的。 使用gcc -fno-pie -no-pie -g foo.c -o foo。然后您在objdump -drwC -Mintel 中看到的地址将匹配运行时地址。

但是 IDK 为什么需要数字地址;使用b main 并从那里单步执行。即使你省略了-g,你仍然会有函数的符号名称。


如需解决问题,请参阅Stopping at the first machine code instruction in GDBSet a breakpoint on GDB entry point for stripped PIE binaries without disabling ASLR

一旦你的可执行文件有一个正在运行的进程,你可以通过p &amp;maindisas main 找到main 的实际运行时地址。但请注意,gdb 禁用了 ASLR,因此如果您在针对 PIE 可执行文件的漏洞利用中使用 GDB 找到的代码地址,它们将在 GDB 下运行时工作。 “正常”运行它将随机化映射可执行文件的虚拟地址。 (这就是为什么我建议构建一个位置相关的可执行文件)。但更有可能您只想返回可执行堆栈上的可执行代码,在这种情况下,堆栈 ASLR 很重要,并且堆栈 ASLR 仍然发生在普通的旧位置相关可执行文件中(除非您也禁用它,就像 gdb 那样)。

【讨论】:

  • 谢谢 这听起来很可靠 我试试看。
  • 工作 100% 0x0000000000400792
猜你喜欢
  • 2014-09-28
  • 2017-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-02
  • 2019-01-23
  • 2011-02-10
相关资源
最近更新 更多