Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.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 为什么我要在printf中获得oveflow?_C_Assembly - Fatal编程技术网

C 为什么我要在printf中获得oveflow?

C 为什么我要在printf中获得oveflow?,c,assembly,C,Assembly,嘿,我必须在汇编中调用glibc的一个函数进行练习。所以我找到了这个调用printf的代码 section .rodata format: db 'Hello %s', 10 name: db 'Conrad' section .text global main extern printf main: ; printf(format, name) mov rdi, format mov

嘿,我必须在汇编中调用glibc的一个函数进行练习。所以我找到了这个调用printf的代码

section .rodata
    format: db 'Hello %s', 10
    name:   db 'Conrad'

section .text
        global main
        extern printf
    main:
        ; printf(format, name)
        mov rdi, format
        mov rsi, name
        call printf
        ; return 0
        mov rax, 0
        ret

但我得到了一个错误:

符号“printf”导致R_X86_64_PC32重定位中溢出

汇编时使用了:

nasm-f elf64-o test.o test.asm

gcc-o测试

执行此操作后会发生错误


/test

您应该编译您的文件,而不使用饼图

解释了这个错误。引用原文:

Debian在64位模式下切换到PIC/PIE二进制文件&在您的例子中,GCC试图将您的对象链接为PIC,但它将在mov$str,%rdi中遇到绝对地址


你应该编译你的文件,而不是派

解释了这个错误。引用原文:

Debian在64位模式下切换到PIC/PIE二进制文件&在您的例子中,GCC试图将您的对象链接为PIC,但它将在mov$str,%rdi中遇到绝对地址

将call printf更改为callprintf@PLT. 前者仅在printf的实际定义包含±2GB的调用指令时有效,如果定义位于共享库中,则无法知道调用指令的大小。但是,如果您使用静态链接,则前者有效。溢出是指相对地址(最多需要64位)在32位调用指令偏移量中溢出

利用printf@PLT,您将获得一个相对地址,该地址在链接时静态解析为PLT中的thunk,加载并跳转到函数定义的地址,在动态链接时解析

正如Maxime B.所指出的,格式和名称地址的负载对于位置独立代码也是不正确的。它们应该用rip相对形式加载,但看起来你在使用奇怪的英特尔asm语法,我不知道如何用这种语法编写。正如Maxime B.所建议的,您可以使用-fno-pie构建,但更好的方法是找到修复代码的方法,这样它就不依赖于特定固定地址的链接。

将call printf更改为callprintf@PLT. 前者仅在printf的实际定义包含±2GB的调用指令时有效,如果定义位于共享库中,则无法知道调用指令的大小。但是,如果您使用静态链接,则前者有效。溢出是指相对地址(最多需要64位)在32位调用指令偏移量中溢出

利用printf@PLT,您将获得一个相对地址,该地址在链接时静态解析为PLT中的thunk,加载并跳转到函数定义的地址,在动态链接时解析



正如Maxime B.所指出的,格式和名称地址的负载对于位置独立代码也是不正确的。它们应该用rip相对形式加载,但看起来你在使用奇怪的英特尔asm语法,我不知道如何用这种语法编写。正如Maxime B.所建议的,你可以用-fno-pie来构建,但更好的办法是找到修复代码的方法,这样它就不依赖于特定固定地址的链接。

Add\0 to format and name。相同mistake@eanmos:这是一个单独的问题。将\0添加到格式和名称。相同mistake@eanmos:那是另一个问题。那么我只有分段fault@JanWolfram这可能是由于eanmos指出字符串末尾缺少“\0”:(否),这不是错误。对不起,我的不好knowledge@JanWolfram:因为在调用printf之前没有对齐堆栈。并且没有设置AL=0,所以它将使用对齐的存储将XMM regs保存到它的寄存器保存区域,所以这个ABI冲突在实践中可能会崩溃fault@JanWolfram这可能是由于eanmos指出的字符串末尾缺少“\0”:“不,这不是错误。对不起,我的不好knowledge@JanWolfram:因为在调用printf之前没有对齐堆栈。并且没有设置AL=0,因此它将使用对齐的存储将XMM REG保存到其寄存器保存区域,因此这种ABI冲突在实践中可能会崩溃undefined@JanWolfram当前位置可能是nasm希望它再次以某种奇怪的方式书写,我不熟悉它使用的语法,也可能只是你在语法中引入了额外的空间或其他错误。呼叫printf@plt将是GNU汇编程序syntaxforme@plt isundefined@JanWolfram当前位置可能是nasm希望它再次以某种奇怪的方式书写,我不熟悉它使用的语法,也可能只是你在语法中引入了额外的空间或其他错误。呼叫printf@plt将是GNU汇编程序语法