我今天写了这个小程序,我对结果感到震惊.这是程序
int main(int argc, char **argv)
{
int a;
printf("\n\tMain is located at: %p and the variable a is located at address: %p",main,&a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在我的机器上,主函数总是加载在地址"0x80483d4"并且变量的地址保持不变这是怎么发生的?我在操作系统中读到,作为虚拟化方案的一部分,操作系统不断重新定位指令地址.那么为什么每次我运行这个程序时主要加载到同一个地址呢?
先谢谢你们.
我正在 ARM64 M1 Pro 笔记本电脑上使用 clang 13.1.6 和 MacOS Monterey 12.5 进行汇编编写。
如果我尝试在以标签地址作为其值的部分中使用.dword
/ ,我的程序会在启动时崩溃,并带有..xword
.text
bus error
最小可重现示例:
.text
.balign 4
.global _main
_main:
// accepted method to load from static address
adrp x1, vector@GOTPAGE
ldr x1, [x1, #vector@GOTPAGEOFF]
// now x1 contains the address of vector
ldr x2, [x1]
// now x2 should contain the address of dest
br x2
dest:
mov x0, #0
ret
vector:
.xword dest
Run Code Online (Sandbox Code Playgroud)
使用 进行汇编和链接时不会出现错误或警告cc reloc.s -o reloc
,但在运行时会立即出现总线错误,显然是在到达我的实际代码之前。回溯lldb …
鉴于我编译的一些unix程序,我需要做些什么才能将它重新定位到不同的目录并让它继续正确运行.
我正在考虑Perl,但是会对像Apache这样的其他系统感兴趣,这些系统在完成后似乎也会失败.为了激发这个问题,在将其他系统捆绑为产品安装的一部分时,能够执行此类重定位非常有用.
对于它的价值,ActivePerl的安装过程似乎包含了一些在安装过程中执行重定位的魔法.
Installing ActivePerl...
Copying files to /opt/ActivePerl-5.8...done
Relocating...done (164 files relocated)
Generating HTML documentation...done
Syncing perl PPM database with .packlists...done
ActivePerl has been successfully installed at /opt/ActivePerl-5.8.
Run Code Online (Sandbox Code Playgroud)
任何人都可以告诉我"重新安置......"背后发生了什么?
elf 格式的可执行文件包含各种段,如代码、数据、bss、堆栈等。如果我们说段 xyz 是静态重定位的,那意味着什么?
elf 格式的二进制文件包含每个段的相对地址。当我们说静态重定位时,是否意味着相对地址实际上是物理地址?
我知道现代操作系统(例如 Linux)并不总是在最初链接的同一地址执行应用程序。然而,当调试器开始环顾四周时,它需要知道原始链接地址和最终执行地址之间的关系。GDB如何计算偏移量?
澄清:我不是在谈论虚拟内存。也就是说,我(我认为是)对虚拟内存的工作原理有一个合理的理解,并且完全在该地址空间中运行。当我从 ELF 转储符号表时,我的符号位于一个位置,但当我从内存中获取它们的地址时,符号位于另一个位置。
在这种特殊情况下,我有一个字符串,它在链接的可执行文件中的地址为 0x0E984141。在该进程的内存转储中,它位于地址 0x0E3F2781。.rodata 部分中的所有内容至少都已移动了 0x5919C0。它似乎类似于地址空间布局随机化。
我试图nm
在 C 中重新创建该命令的行为,尽管我成功获取了符号和部分的名称,但我发现我的版本中出现了一些额外的名称。
$> ./my_nm -a obj.o
0000000000000000 b .bss
0000000000000000 n .comment
0000000000000000 d .data
0000000000000000 r .eh_frame
0000000000000000 n .note.GNU-stack
0000000000000000 r .note.gnu.property
0000000000000000 d .rela.eh_frame
0000000000000000 d .rela.text
0000000000000000 t .text
U _GLOBAL_OFFSET_TABLE_
0000000000000000 T elf64_syms
0000000000000000 a elf64_syms.c
U malloc
Run Code Online (Sandbox Code Playgroud)
$> nm -a obj.o
0000000000000000 b .bss
0000000000000000 n .comment
0000000000000000 d .data
0000000000000000 r .eh_frame
0000000000000000 n .note.GNU-stack
0000000000000000 r .note.gnu.property
0000000000000000 t .text
U _GLOBAL_OFFSET_TABLE_
0000000000000000 T elf64_syms
0000000000000000 a elf64_syms.c
U …
Run Code Online (Sandbox Code Playgroud) 我正在exercism.org 上浏览 x86-64 教程。我在 Linux 上使用 NASM,生成 ELF 二进制文件。只有一点 C 代码可以在测试工具中调用我的汇编代码。他们的构建系统-pie
在 LDFLAGS 和-fPIE
CFLAGS 中指定(除其他外,但我认为这些是最相关的)。因此,我需要(并且想了解)一个使用 PIC 的解决方案,它需要 RIP 相对寻址。
我有一个rdi
名为 的 8 字节 (qword) 值数组的索引 (in ) values
。我只想获取偏移量处的地址,以便将mov
其指向的值存入寄存器。或者我会接受mov
直接接受该值。
我试过这个:
lea rbx, [rel values + rdi * 8]
Run Code Online (Sandbox Code Playgroud)
我的理解是,这将查看该部分中rip
的地址(相对于 ),然后它将添加正确的偏移量()并将其放入 中。values
data
rdi * 8
rbx
但这会产生下一个错误:
Run Code Online (Sandbox Code Playgroud)/usr/bin/ld: space_age.o: relocation R_X86_64_32S against `.data' can not be used when making a PIE object; recompile with -fPIE
我理解这 …
我想修改一些已编译的dll的基地址,用于将它们移出虚拟空间的中间并帮助进行大量分配.有谁知道这样做的工具?如果它在加载器中可行,似乎可以在dll文件中永久地执行它.
我只是用来objdump -x ...
检查PE文件的各个部分.
大约有90,000行reloc条目:
reloc 92 offset bc0 [524bc0] HIGHLOW
reloc 93 offset bc4 [524bc4] HIGHLOW
....
Run Code Online (Sandbox Code Playgroud)
大多数PE文件的大部分空间是否都是由上面的reloc条目组成的?
那些条目是什么?
UPDATE
任何人都可以解释重定位条目如何像上面那样工作?
您好,我一直在尝试用汇编语言编写一个简单的 hello world 程序,并将其编译为 .o 文件,然后将其与标准 C 库链接以创建 .exe,以便我可以在我的计算机上查看“puts”的反汇编结果。系统使用gdb -tui
. 我正在将 Cygwin 与以下实用程序版本一起使用(使用 获得这些版本as --version && ld --version
)。我正在尝试在 Windows 8 x64 上完成这一切。
作为版本 2.25
LD版本2.25
测试.asm
我在学习 x86 汇编时在互联网上看到了几种汇编标准。我想我在这里写的是GAS。
.extern puts
_start:
mov $msg, %rdi
call puts
xor %rax, %rax
ret
msg:
.ascii "hello world"
Run Code Online (Sandbox Code Playgroud)
汇编器
我可以毫无问题地组装上述文件,该as
实用程序不会给我警告或任何错误,这是我调用该as
实用程序的方式。
as test.asm -o test.o
连接器
这就是我遇到麻烦的地方,下面的命令是我认为应该如何将目标文件与标准 c 库链接起来。
ld test.o -o test.exe -lc
该命令会产生以下错误,我对此感到困惑。我试图在其他帖子和通过谷歌找到答案,但也许我错过了一些东西。
test.o:fake:(.text+0x3): relocation truncated to fit: R_X86_64_32S against `.text`
/usr/lib/libc.a(t-d000957.o):fake:(.text+0x2): undefined reference …
Run Code Online (Sandbox Code Playgroud)