|
|
1
3
这取决于操作系统。大多数情况下,二进制文件的地址保持不变。这对于利用内存操作错误非常重要,例如 缓冲区溢出 .由于ASLR,Linux下链接库的地址将始终不同。在Windows Vista和Windows 7下,二进制文件的虚拟内存空间也会在每次执行时随机化,因此每次运行的函数地址都会不同。 |
|
|
2
3
我认为这里的问题(至少在Linux上)可能是gdb试图从文档中提供帮助:
http://sourceware.org/gdb/current/onlinedocs/gdb/Starting.html 更新:我现在已经检查过了,对我来说似乎确实如此(运行Linux 2.6.28)。编译一个简单的Hello World程序,在没有命令行参数的情况下启动gdb(我们不希望在覆盖禁用随机化设置之前加载该程序),然后输入:
每次运行程序时,printf的地址都不同。 |
|
|
3
2
是和否。物理内存由操作系统分配,只有操作系统知道程序在物理RAM中的位置。您的程序只会看到虚拟地址,如果所有内容都以相同的顺序加载,则虚拟地址将始终相同。 |
|
|
4
2
可执行重定位一些可执行文件被设置为总是在同一地址加载。有些设置为“可重新定位”。在VisualStudio链接器中控制此操作的选项称为/FIXED。即使是这样的可执行文件,也通常在首选地址加载。较新的操作系统(Win7,Vista)将一些可执行文件的加载地址随机化,以提高安全性(攻击未知地址加载的进程比较困难)——这称为 ASLR 注:即使标记为/FIXED:NO的可执行文件也不适用于ASLR。开发者需要 allow ASLR explicitly 对于可执行文件。 虚拟地址空间注意:了解进程拥有整个地址空间是很重要的。多个进程都有各自的地址空间,因此如果多次启动同一个可执行文件,没有理由每次都不能在同一地址加载。 |
|
5
1
这是一个虚拟地址。操作系统知道物理地址,但每个进程都有自己的虚拟地址空间。可重新定位的映像可能每次都会得到相同的映射,尤其是主可执行文件。但这并不能保证。DLL就是一个例子。DLL可能以不同的顺序加载,导致运行之间的虚拟地址不同,因为加载DLL 1时,DLL 2无法加载到该虚拟地址中,必须获得自己的地址。 |
|
|
6
0
这取决于操作系统。在大多数具有虚拟内存的现代操作系统中,不需要重新定位可执行代码,但在较旧的操作系统中,以及在一些专门的操作系统(例如实时嵌入式)中,代码覆盖可以与位置无关的代码和跳转表结合使用。在这种情况下,函数的地址可能会发生变化,例如,如果它的代码段被调出,然后在不同的地址被调回。 |
|
|
7
0
这些是来自计算机安全的术语。在过去,它是固定地址(根据《纽约时报》报道,是1996年) LKML ,但直到最近,Executable才开始被编译为可重新定位的,以便实现 ASLR (但在很久以前,所有库都被编译为可重新定位的,这样库就可以在必要时重新加载到不同的地址——读取) dynamic relocation 但由于加载顺序,这些主系统调用API通常加载到固定地址。)即使在今天, 做一个gdb/bin/ls,然后按“run”,你会发现默认地址没有改变: (gdb)拆开 函数open的汇编程序代码转储: 0xb7f017f0<+0>:cmpl$0x0,%gs:0xc 0xb7f017f8<+8>:jne 0xb7f0181c 总之,ASLR起源于 PaX -阅读维基,它涵盖了很多关于实现ASLR的需求。 为什么是ASLR?要防止两种类型的攻击: http://en.wikipedia.org/wiki/Return-to-libc_attack 和 http://en.wikipedia.org/wiki/Return-oriented_programming ,因为如果在内存中修复,这两种攻击都会占用您的代码区域。 |
|
|
8
-3
为什么操作系统会选择不同的地址? 当操作系统执行一个进程时,它会将一个可执行文件加载到虚拟内存空间中。在此过程中,它将解析任何相对和/或符号引用。假设您有相同的可执行文件和相同的共享库,并以与上次相同的方式启动它,那么操作系统决定在 不同的 方法 |