相关疑难解决方法(0)

x86-64 Linux中不再允许32位绝对地址?

64位Linux默认使用小内存模型,它将所有代码和静态数据置于2GB地址限制之下.这可确保您可以使用32位绝对地址.较旧版本的gcc使用静态数组的32位绝对地址,以便为相对地址计算保存额外的指令.但是,这不再有效.如果我尝试在汇编中创建一个32位的绝对地址,我会收到链接器错误:"在创建共享对象时,不能使用".data"重定位R_X86_64_32S;使用-fPIC重新编译".当然,此错误消息具有误导性,因为我没有创建共享对象,-fPIC也没有帮助.到目前为止我发现的是:gcc版本4.8.5对静态数组使用32位绝对地址,gcc版本6.3.0不使用.版本5可能也没有.binutils 2.24中的链接器允许32位绝对地址,而2.28则不允许.

这种变化的后果是必须重新编译旧库并破坏传统汇编代码.

现在我想问一下:这个改变是什么时候做的?它在某处记录了吗?是否有一个链接器选项,使其接受32位绝对地址?

linux gcc x86-64 linker-errors relocation

21
推荐指数
1
解决办法
5787
查看次数

如何将函数或标签的地址加载到寄存器中

我正在尝试将“main”的地址加载到 GNU 汇编器中的寄存器 (R10) 中。我没办法。在这里,我有什么和我收到的错误消息。

main:
   lea main, %r10
Run Code Online (Sandbox Code Playgroud)

我还尝试了以下语法(这次使用 mov)

main:
   movq $main, %r10
Run Code Online (Sandbox Code Playgroud)

使用以上两种方法,我都会收到以下错误:

/usr/bin/ld: /tmp/ccxZ8pWr.o: relocation R_X86_64_32S against symbol `main' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

使用 -fPIC 编译不能解决问题,只会给我同样的错误。

assembly gcc x86-64 att addressing-mode

10
推荐指数
1
解决办法
5302
查看次数

为什么静态变量的地址相对于指令指针?

我正在按照本教程关于装配.

根据教程(我也在本地尝试,并得到类似的结果),以下源代码:

int natural_generator()
{
        int a = 1;
        static int b = -1;
        b += 1;              /* (1, 2) */
        return a + b;
}
Run Code Online (Sandbox Code Playgroud)

编译到这些汇编指令:

$ gdb static
(gdb) break natural_generator
(gdb) run
(gdb) disassemble
Dump of assembler code for function natural_generator:
push   %rbp
mov    %rsp,%rbp
movl   $0x1,-0x4(%rbp)
mov    0x177(%rip),%eax        # (1)
add    $0x1,%eax
mov    %eax,0x16c(%rip)        # (2)
mov    -0x4(%rbp),%eax
add    0x163(%rip),%eax        # 0x100001018 <natural_generator.b>
pop    %rbp
retq   
End of assembler dump.
Run Code Online (Sandbox Code Playgroud)

(行号的意见(1),(2) …

c assembly gcc cpu-registers

6
推荐指数
1
解决办法
1295
查看次数

"mov offset(%rip),%rax"是做什么的?

是否rax得到偏移加上该指令的地址,或下一个?从微码的角度来看,如果答案是下一条指令可能会更容易.

x86 assembly att

4
推荐指数
2
解决办法
2442
查看次数

如果全局变量的地址被硬编码在 ELF 中,它们如何随机化?

我在几个地方读到过,.data每次程序运行时,ASLR 应该以随机地址加载该部分,这意味着全局变量的地址应该不同。但是,如果我有以下代码:

int global_var = 42;

int main()
{
    global_var = 10;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我用 编译它gcc -fpie -o global global.cobjdump -d -M intel显示以下内容:

  4004ed:   55                      push   rbp
  4004ee:   48 89 e5                mov    rbp,rsp
  4004f1:   c7 05 3d 0b 20 00 0a    mov    DWORD PTR [rip+0x200b3d],0xa        # 601038 <global_var>
Run Code Online (Sandbox Code Playgroud)

它似乎global_var总是被放置在 601038。事实上,如果我用调试符号编译,global_var的 DIE 会硬编码该地址:

$ gcc -ggdb3 -fpie -o global global.c
$ objdump --dwarf=info global
...
<1><55>: Abbrev Number: 4 (DW_TAG_variable) …
Run Code Online (Sandbox Code Playgroud)

c elf dwarf aslr

4
推荐指数
2
解决办法
939
查看次数

功能地址在nm输出和gdb中不同

让我们只关注Rect_IsEmpty()功能.

nm命令为我提供了这个输出:

(...)    
00021af0 T Rect_IsEmpty
(...)
Run Code Online (Sandbox Code Playgroud)

另一方面,当我启动gdb并查看此功能的地址时,我得到:

(gdb) info address Rect_IsEmpty
Symbol "Rect_IsEmpty" is at 0x8057c84 in a file compiled without debugging.
Run Code Online (Sandbox Code Playgroud)

请问任何人解释为什么这些地址不一样?gdb从哪里获取此地址?

c linux gdb nm

3
推荐指数
1
解决办法
1391
查看次数

为什么在NASM中使用相对RIP寻址?

我有一个适用于Mac OS X的程序集hello world程序,如下所示:

global _main


section .text

_main:
    mov rax, 0x2000004
    mov rdi, 1
    lea rsi, [rel msg]
    mov rdx, msg.len
    syscall

    mov rax, 0x2000001
    mov rdi, 0
    syscall


section .data

msg:    db  "Hello, World!", 10
.len:   equ $ - msg
Run Code Online (Sandbox Code Playgroud)

我想知道这条线lea rsi, [rel msg]。为什么NA​​SM强迫我这样做?据我了解,它msg只是指向可执行文件中某些数据的指针,这样做mov rsi, msg会将地址放入rsi。但是,如果我将替换为lea rsi, [rel msg],则NASM会引发此错误(注意:我使用的是命令nasm -f macho64 hello.asm):

hello.asm:9: fatal: No section for index 2 offset 0 found
Run Code Online (Sandbox Code Playgroud)

为什么会这样?有什么特别之处leamov …

assembly nasm cpu-registers memory-address mov

2
推荐指数
2
解决办法
3874
查看次数

为什么此MOVSS指令使用相对RIP寻址?

我在反汇编程序(浮点逻辑c ++)中找到了以下汇编代码。

  842: movss  0x21a(%rip),%xmm0 
Run Code Online (Sandbox Code Playgroud)

我知道,当进程rip将一直为842且此0x21a(%rip)将为const。使用该寄存器似乎有些奇怪。

我想知道使用rip相对地址代替其他寻址有什么好处。

x86 assembly x86-64 disassembly addressing-mode

2
推荐指数
1
解决办法
1378
查看次数

CS:覆盖对 IDA 输出中全局变量的访问,如 mov eax、cs:x?

我正在编写简单的程序然后分析它们。今天我写了这个:

#include <stdio.h>
 
int x;
 
int main(void){
    printf("Enter X:\n");
 
    scanf("%d",&x);
 
    printf("You enter %d...\n",x);
 
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它被编译成这样:

push    rbp
mov     rbp, rsp
lea     rdi, s          ; "Enter X:"
call    _puts
lea     rsi, x
lea     rdi, aD         ; "%d"
mov     eax, 0
call    ___isoc99_scanf
mov     eax, cs:x   <- don't understand this
mov     esi, eax
lea     rdi, format     ; "You enter %d...\n"
mov     eax, 0
call    _printf
mov     eax, 0
pop     rbp
retn
Run Code Online (Sandbox Code Playgroud)

我不明白什么cs:x意思。
我使用 Ubuntu x64、GCC 10.3.0 和 IDA …

assembly x86-64 ida disassembly addressing-mode

2
推荐指数
1
解决办法
65
查看次数

为什么 lea 将明显随机的地址移动到 rdi?

我有以下一段C代码:

#include <stdio.h>

int main()
{
    int i;
    for(i=0; i<10; i++)
        puts("hello, friend");

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我这样编译的:gcc firstprog.c -o firstprog

然后,当使用gdb拆卸它时,我看到:

(gdb) disassemble 
Dump of assembler code for function main:
=> 0x0000555555555149 <+0>: endbr64 
   0x000055555555514d <+4>: push   rbp
   0x000055555555514e <+5>: mov    rbp,rsp
   0x0000555555555151 <+8>: sub    rsp,0x10
   0x0000555555555155 <+12>:    mov    DWORD PTR [rbp-0x4],0x0
   0x000055555555515c <+19>:    jmp    0x55555555516e <main+37>
   0x000055555555515e <+21>:    lea    rdi,[rip+0xe9f]        # 0x555555556004
   0x0000555555555165 <+28>:    call   0x555555555050 <puts@plt>
   0x000055555555516a <+33>:    add    DWORD PTR [rbp-0x4],0x1
   0x000055555555516e <+37>:    cmp …
Run Code Online (Sandbox Code Playgroud)

assembly x86-64 objdump string-literals

1
推荐指数
1
解决办法
1030
查看次数