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位绝对地址?
我正在尝试将“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 编译不能解决问题,只会给我同样的错误。
我正在按照本教程关于装配.
根据教程(我也在本地尝试,并得到类似的结果),以下源代码:
Run Code Online (Sandbox Code Playgroud)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.
(行号的意见(1),(2) …
是否rax得到偏移加上该指令的地址,或下一个?从微码的角度来看,如果答案是下一条指令可能会更容易.
我在几个地方读到过,.data每次程序运行时,ASLR 应该以随机地址加载该部分,这意味着全局变量的地址应该不同。但是,如果我有以下代码:
int global_var = 42;
int main()
{
global_var = 10;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我用 编译它gcc -fpie -o global global.c,objdump -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) 让我们只关注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从哪里获取此地址?
我有一个适用于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]。为什么NASM强迫我这样做?据我了解,它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)
为什么会这样?有什么特别之处lea是mov …
我在反汇编程序(浮点逻辑c ++)中找到了以下汇编代码。
842: movss 0x21a(%rip),%xmm0
Run Code Online (Sandbox Code Playgroud)
我知道,当进程rip将一直为842且此0x21a(%rip)将为const。使用该寄存器似乎有些奇怪。
我想知道使用rip相对地址代替其他寻址有什么好处。
我正在编写简单的程序然后分析它们。今天我写了这个:
#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 …
我有以下一段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)