偶然发现了这个问题(和答案):https://stackoverflow.com/questions/2170843/va-virtual-adress-rva-relative-virtual-address在我寻求了解Windows PE格式的请求中,我想知道:为什么默认图像库值是0x400000?
为什么我们不能从0开始呢?在所有实际目的中,VA等于RVA。

我显然缺少了一些东西,但是最近40分钟我一直找不到对此的合理解释。

评论

好吧,零将是bios区域...所以没办法...堆栈和堆可以在0x10000左右开始,而其他一些dll等则在那儿(.nls文件等等)在ollydbg中打开一个exe,然后查看内存视图,您将看到那里的内容,通常是其中的一些系统信息,我系统上的至少一个nls文件以及主线程堆栈的开始并且大于0x80000000(无论如何都是32位)用于内存映射文件,驱动程序等

@ evlcrn8等等-操作系统无论如何都会将所有内存引用转换为物理位置,所以我绝对不能访问BIOS内容或几乎所有不属于我的东西...不是吗?

@ evlcrn8:默认情况下,未映射0x00000000的内存;它肯定不是“ BIOS区”。并且从用户模式映射到内存的文件被映射到0x80000000以下。

我只是记得它是旧dos时代的bios区域,它与我息息相关,当我通过测试时,我很确定通过mapviewoffile映射的文件位于> 0x80000000

#1 楼


为什么默认图像库值为0x400000?


来自http://msdn.microsoft.com/zh-cn/library/ms809762.aspx-


在为Windows NT生成的可执行文件中,默认
映像库为0x10000。对于DLL,默认值为0x400000。在Windows
95中,地址0x10000不能用于加载32位EXE,因为它位于所有进程共享的线性地址区域内。因此,Microsoft已将Win32可执行文件的默认基址更改为0x400000。请注意,默认(或“首选”)基址是在构建时由链接器(GCC的ld,Microsoft VC ++的link.exe等)设置; Windows无法确定默认的(或“首选的”)基地址。

评论


微软一个有点奇怪,我上次看它是通过模块的名称来工作的,并从中计算出基数

–evlncrn8
2014年9月15日19:16

@ evlncrn8:根据msdn.microsoft.com/en-us/library/f7f5138s.aspx,即使最新的MS VC ++ link.exe也使用0x400000作为默认基址。

–詹森·格夫纳(Jason Geffner)
2014-09-15 20:00

@ evlncrn8:您可能会看到“加载地址随机化”。

–JDługosz
2014年9月15日在22:08

雷蒙·陈(Raymond Chen)就这个确切的问题发表了详细的文章:blogs.msdn.com/b/oldnewthing/archive/2014/10/03/10562176.aspx

– QAZ
2014年10月3日在14:23

@QAZ:哇,他今天早上发布了。也许这个StackExchange问​​题促使Raymond撰写了该博客文章:)我想说的是,该新博客文章中给出的解释比我上面链接的内容更完整,因此请在此处随意发表作为答案(因此您将获得荣誉),我很乐意将其投票。

–詹森·格夫纳(Jason Geffner)
14-10-3在14:38

#2 楼

如果您希望msvc编译图像基数为0x10000的驱动程序,则可以更改基数。如果是这样,则如何更改用户模式可执行文件,图像基数必须为64k的倍数,如果这样,则msvc编译驱动程序。使用base:0时exe的图像基数为0x10000

:\>kd -c "!dh acpi;q" -z c:\WINDOWS\system32\drivers\acpi.sys | grep -i image
File Type: EXECUTABLE IMAGE
00010000 image base
    5.01 image version
   2DD80 size of image

:\>