我正在拆解可执行文件:
(gdb) disas main
Dump of assembler code for function main:
0x004012d0 <main+0>: push %ebp
0x004012d1 <main+1>: mov %esp,%ebp
...
每次内存地址相同时:0x004012d0
。
操作系统不是要动态分配内存地址吗?
更新
现在我看到它的虚拟空间,它可以在某些平台上随机化。
有人可以发布更改的gdb转储吗?
答案 0 :(得分:3)
这取决于操作系统。大多数情况下,二进制文件的地址保持不变。这对于利用内存处理错误非常重要,例如缓冲区溢出。由于ASLR,Linux下链接库的地址总是不同的。在Windows Vista和Windows 7下,二进制文件的虚拟内存空间在每次执行时也会随机化,因此每次运行时函数地址都会不同。
答案 1 :(得分:3)
我认为这里的问题(至少在Linux上)可能是gdb试图帮助,来自文档:
设置禁用随机化
在
上设置禁用随机化此选项(默认情况下在gdb中启用)将关闭本机随机化 已启动程序的虚拟地址空间。此选项对于多个调试很有用 会话使得执行更好的可重现性和内存地址可重用 调试会话。
此功能仅在gnu / Linux上实现。您可以使用
获得相同的行为(gdb) set exec-wrapper setarch `uname -m` -R
http://sourceware.org/gdb/current/onlinedocs/gdb/Starting.html
更新:我现在已经检查了这一点,对我来说似乎就是这种情况(运行Linux 2.6.28)。编译一个简单的Hello World程序并启动没有命令行参数的gdb(我们不想在覆盖disable-randomization设置之前加载程序)然后输入:
(gdb) set disable-randomization off
(gdb) file ./a.out
(gdb) break main
(gdb) run
(gdb) disas printf
每次运行程序时,printf的地址都不同。
答案 2 :(得分:2)
是和否。物理内存由操作系统分配,只有操作系统知道程序在物理RAM中的位置。您的程序只能看到虚拟地址,如果所有内容都以相同的顺序加载,则该地址将始终相同。
答案 3 :(得分:2)
设置了一些可执行文件,以便始终在同一地址加载它们。有些被设置为“可重定位”。在Visual Studio链接器中控制此选项的选项称为/ FIXED。即使是这样的可执行文件也经常在首选地址加载。较新的操作系统(Win7,Vista)随机化一些可执行文件的加载地址以提高安全性(在未知地址加载的攻击过程更难) - 这称为ASLR。注意:即使标记为/ FIXED:NO的可执行文件也不适用于ASLR。开发人员需要allow ASLR explicitly来获取可执行文件。
注意:了解流程拥有整个地址空间非常重要。多个进程都有自己的每个地址空间,因此如果多次启动相同的可执行文件,则没有理由每次都无法在同一地址加载它。
答案 4 :(得分:1)
这是一个虚拟地址。物理地址是OS已知的,但每个进程都有自己的虚拟地址空间。可重定位映像可能每次都获得相同的映射,尤其是主可执行文件。但它不能保证。一个例子是DLL。 DLL可能以不同的顺序加载,导致运行之间的虚拟地址不同,因为当加载DLL 1时,DLL 2无法加载到该virtualaddress中并且必须获得自己的地址。
答案 5 :(得分:0)
这取决于操作系统。在具有虚拟内存的大多数现代操作系统中,不需要可重新定位的可执行代码,但是在较旧的操作系统中,并且在一些专用操作系统(例如,实时,嵌入式)中,代码覆盖可以与位置无关地结合使用。代码和跳转表。在这种情况下,函数的地址可能会改变,例如如果它的代码段被换出然后换回另一个地址。
答案 6 :(得分:0)
这些是计算机安全性的术语。在过去,它是固定地址(&lt; 1996,根据LKML,但直到最近才开始将可执行文件编译为可重定位,以便实现ASLR。(但是更久以前,所有库都已编译为可重定位,因此可以在必要时将库重新加载到不同的地址 - 阅读dynamic relocation但由于加载顺序,这些主系统调用API通常会加载到固定地址。)即使在今天,
执行gdb / bin / ls并执行“run”后,您将发现默认地址未更改:
(gdb)反汇编__open 函数打开的汇编代码转储: 0xb7f017f0&lt; + 0&gt;:cmpl $ 0x0,%gs:0xc 0xb7f017f8&lt; + 8&gt;:jne 0xb7f0181c
无论如何,ASLR起源于PaX - 阅读wiki,它涵盖了实施ASLR的要求。
为什么选择ASLR?为了防止两种类型的攻击:http://en.wikipedia.org/wiki/Return-to-libc_attack和http://en.wikipedia.org/wiki/Return-oriented_programming,因为如果在内存中修复了攻击,则两种攻击都会占用您的代码区域。
答案 7 :(得分:-3)
为什么操作系统会选择不同的地址?
当OS执行进程时,它会将可执行文件加载到虚拟内存空间中。在此过程中,它将解析任何相对和/或符号引用。假设您具有相同的可执行文件和相同的共享库,并以与上次相同的方式启动它,操作系统决定在不同的方式。