Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么我不能使用内存地址设置断点_C_Gcc_Assembly_Compilation_X86 64 - Fatal编程技术网

C 为什么我不能使用内存地址设置断点

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

我正在学习汇编处理器体系结构和利用开发,当我遇到这个关于x68_64缓冲区溢出的教程时,我复制了vuln代码并使用gcc编译了它。我编译的二进制文件不允许我设置断点,但当我从网站下载二进制文件(“我不想这样做”)时,它工作正常,内存地址正常

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

当我尝试在scanf函数后设置断点时: (gdb)中断*0x000000000000085e 0x85e处的断点1 (gdb)运行
#包括
#包括
#包括
无效验证(字符*通过){
如果(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;
}