Den*_*eno 1 c memory-management elf objdump memory-address
通过使用该命令,我发现内存中的objdump
地址包含 start the path ,并且由于 C 标准,该路径以一个字节结束。0x02a8
/lib64/ld-linux-x86-64.so.2
0x00
因此,我尝试编写一个简单的 C 程序来打印这一行(我使用了 Denis Yurichev 所著的《RE for Beginners》一书中的示例 - 第 24 页):
#include <stdio.h>
int main(){
printf(0x02a8);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但我很失望地得到了分段错误而不是预期的/lib64/ld-linux-x86-64.so.2
输出。
我发现使用这样一个printf
不带说明符或至少不带指针转换的“快速”调用很奇怪,所以我尝试使代码更自然:
#include <stdio.h>
int main(){
char *p = (char*)0x02a8;
printf(p);
printf("\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
运行后我仍然遇到分段错误。
我不相信这是因为内存区域受限而发生的,因为在书中,第一次尝试一切都很顺利。我不确定,也许还有那本书中没有提到的事情。
因此,需要一些清晰的解释来解释为什么每次我尝试运行程序时都会发生分段错误。
我正在使用最新的完全升级的 Kali Linux 版本。
令人失望的是,你的“RE for初学者”书没有首先深入基础知识,并且吐出这些废话。尽管如此,你所做的显然是错误的,让我解释一下原因。
通常在 Linux 上,GCC 生成位置无关的ELF 可执行文件。这样做是出于安全目的。当程序运行时,操作系统能够将其放置在内存中的任何位置(任何地址),并且程序将正常工作。这种技术称为地址空间布局随机化,是目前默认启用的操作系统的一项功能。
通常,ELF 程序会有一个“基地址”,并且会准确地加载到该地址才能工作。然而,在位置无关的 ELF 的情况下,“基地址”设置为0x0
,操作系统和解释器决定在运行时将程序放在哪里。
当objdump
在位置无关的可执行文件上使用时,您看到的每个地址都不是真正的地址,而是相对于程序基址的偏移量(仅在运行时才知道)。因此,只能在运行时知道这样的字符串(或任何其他变量)的位置。
如果你想让上面的代码起作用,你就必须编译一个不与位置无关的 ELF。你可以这样做:
gcc -no-pie -fno-pie prog.c -o prog
Run Code Online (Sandbox Code Playgroud)