C 为什么我不能使用内存地址设置断点
我正在学习汇编处理器体系结构和利用开发,当我遇到这个关于x68_64缓冲区溢出的教程时,我复制了vuln代码并使用gcc编译了它。我编译的二进制文件不允许我设置断点,但当我从网站下载二进制文件(“我不想这样做”)时,它工作正常,内存地址正常 但当我用gdb在编译程序中转储main时,我的内存地址如下所示: 0x000000000000085e:lea-0xd0(%rbp),%rax 当我尝试在scanf函数后设置断点时: (gdb)中断*0x000000000000085e 0x85e处的断点1 (gdb)运行C 为什么我不能使用内存地址设置断点,c,gcc,assembly,compilation,x86-64,C,Gcc,Assembly,Compilation,X86 64,我正在学习汇编处理器体系结构和利用开发,当我遇到这个关于x68_64缓冲区溢出的教程时,我复制了vuln代码并使用gcc编译了它。我编译的二进制文件不允许我设置断点,但当我从网站下载二进制文件(“我不想这样做”)时,它工作正常,内存地址正常 但当我用gdb在编译程序中转储main时,我的内存地址如下所示: 0x000000000000085e:lea-0xd0(%rbp),%rax 当我尝试在scanf函数后设置断点时: (gdb)中断*0x000000000000085e 0x85e处的断点1
#包括
#包括
#包括
无效验证(字符*通过){
如果(strcmp(通过,“[修订]”)==0){
printf(“已授予访问权限!”);
printf(“哦,那只是白痴……哦,我的上帝!\n”);
}否则{
printf(“该死的,我有这个东西…\n”);
}
}
int main(int argc,字符**argv){
字符密码[200];
printf(“C:/输入密码:”);
scanf(“%s”,密码);
验证(密码);
返回0;
}
您可以在虚拟地址上设置断点,但是objdump
不知道PIE可执行文件将映射到内存的位置,因此它使用0
作为基址。要使事情更简单,请禁用PIE()。大概你的教程是在这之前写的使用gcc-fno pie-no pie-g foo.c-o foo
。然后您在objdump-drwC-Mintel
中看到的地址将与运行时地址匹配
但是IDK为什么需要数字地址;使用b main
并从那里开始单步执行。即使省略了-g
,函数仍然有符号名
要按要求解决问题,请参见和
一旦可执行文件中有一个正在运行的进程,您就可以
p&main
或disas main
来查找main
的实际运行时地址。但请注意,gdb禁用了ASLR,因此,如果您在针对PIE可执行文件的攻击中使用gdb的代码地址,则它们只有在gdb下运行时才起作用。“正常”运行它将随机化映射可执行文件的虚拟地址。(这就是为什么我建议构建一个位置相关的可执行文件)。但更可能的情况是,您只想返回到可执行堆栈上的可执行代码,在这种情况下,堆栈ASLR才是重要的,堆栈ASLR仍然发生在普通的依赖位置的可执行文件中(除非您也像gdb一样禁用它)。关于:scanf(“%s”,密码)代码>,1)始终检查返回值(而不是参数值),以确保操作成功。在当前场景中,除1之外的任何返回值都表示发生了错误。2) 使用输入格式说明符“%s”和/或“%[…]”时,请始终包含一个小于输入缓冲区长度的最大字符修饰符,以避免缓冲区溢出和由此产生的未定义行为。建议:如果(1!=scanf(“%199s”,password)){fprintf(stderr,“scanf for password failed”);退出(exit_faile)}
当函数的参数:main()
不使用时,建议使用签名:int main(void)
好的,谢谢,这个程序应该是脆弱的,虽然我只是一个初学者。基本上,我复制并粘贴了这个,然后用gcc编译,我的内存地址显示得很奇怪,我不知道从哪里开始寻找这个答案或单词,我的内存地址看起来很奇怪,缺少一个数字。同样,当我从教程网站加载程序并检查地址时,他的地址显示为0x6A84,谢谢这听起来很可靠,我会试试。100%有效0x0000000000400792
End of assembler dump.
#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;
}