我一直很好奇
我之前的问题:more info on Memory layout of an executable program (process)
在我的追求中,我终于找到了答案。我发现这篇优秀文章清除了我的大部分疑问:http://www.linuxforums.org/articles/understanding-elf-using-readelf-and-objdump_125.html
在上面的文章中,作者展示了如何获得流程的不同部分(LINUX)&他将其与相应的ELF文件进行比较。我在这里引用这一部分:
勇敢地看到真正的布局 流程细分?我们可以用 / proc //映射文件以显示它。 是我们过程的PID 想观察。在我们继续之前,我们 这里有一个小问题。我们的测试 程序运行得如此之快以至于结束 在我们甚至可以转储相关之前 / proc条目。我用gdb来解决这个问题。 您可以使用其他技巧,例如 在调用之前插入sleep() 返回()。
在控制台(或终端模拟器中) 比如xterm):
$ gdb test
(gdb) b main
Breakpoint 1 at 0x8048376
(gdb) r
Breakpoint 1, 0x08048376 in main ()
按住这里,打开另一个控制台 并找出程序的PID “测试”。如果你想快速的方式, 类型:
$ cat /proc/`pgrep test`/maps
你会看到如下的输出(你 可能得到不同的输出):
[1] 0039d000-003b2000 r-xp 00000000 16:41 1080084 /lib/ld-2.3.3.so
[2] 003b2000-003b3000 r--p 00014000 16:41 1080084 /lib/ld-2.3.3.so
[3] 003b3000-003b4000 rw-p 00015000 16:41 1080084 /lib/ld-2.3.3.so
[4] 003b6000-004cb000 r-xp 00000000 16:41 1080085 /lib/tls/libc-2.3.3.so
[5] 004cb000-004cd000 r--p 00115000 16:41 1080085 /lib/tls/libc-2.3.3.so
[6] 004cd000-004cf000 rw-p 00117000 16:41 1080085 /lib/tls/libc-2.3.3.so
[7] 004cf000-004d1000 rw-p 004cf000 00:00 0
[8] 08048000-08049000 r-xp 00000000 16:06 66970 /tmp/test
[9] 08049000-0804a000 rw-p 00000000 16:06 66970 /tmp/test
[10] b7fec000-b7fed000 rw-p b7fec000 00:00 0
[11] bffeb000-c0000000 rw-p bffeb000 00:00 0
[12] ffffe000-fffff000 ---p 00000000 00:00 0
注意:我在每行添加数字作为参考。
返回gdb,输入:
(gdb)q
因此,总的来说,我们看到12段(也称为虚拟内存区 - VMA)。
但我想了解Windows Process& PE文件格式。
修改
是否有任何好的文章显示PE文件sections
和&之间的映射。 VA segments
?
答案 0 :(得分:5)
Sysinternals VMMap也是可视化过程VA空间的绝佳工具:
VMMap Screenshot http://i.technet.microsoft.com/dd535533.vmmapScreen(en-us,MSDN.10).jpg
答案 1 :(得分:2)
在正在运行的进程中运行WinDbg中的“!address”。您将看到流程中的每个虚拟内存段都有一些分类 - 映像,内存映射文件,堆栈,堆,PEB,TEB等。
对于像这样的事情,Windows Internals总是很好的参考。
这是记事本的前几个条目:
BaseAddress EndAddress+1 RegionSize Type State Protect Usage
----------------------------------------------------------------------------------------------------------------------
* 0`00000000 0`00be0000 0`00be0000 MEM_FREE PAGE_NOACCESS Free
* 0`00be0000 0`00bf0000 0`00010000 MEM_MAPPED MEM_COMMIT PAGE_READWRITE MemoryMappedFile "PageFile"
* 0`00bf0000 0`00bf7000 0`00007000 MEM_MAPPED MEM_COMMIT PAGE_READONLY MemoryMappedFile "PageFile"
* 0`00bf7000 0`00c00000 0`00009000 MEM_FREE PAGE_NOACCESS Free
* 0`00c00000 0`00c03000 0`00003000 MEM_MAPPED MEM_COMMIT PAGE_READONLY MemoryMappedFile "PageFile"
* 0`00c03000 0`00c10000 0`0000d000 MEM_FREE PAGE_NOACCESS Free
* 0`00c10000 0`00c12000 0`00002000 MEM_MAPPED MEM_COMMIT PAGE_READONLY MemoryMappedFile "PageFile"
* 0`00c12000 0`00c20000 0`0000e000 MEM_FREE PAGE_NOACCESS Free
* 0`00c20000 0`00c21000 0`00001000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE <unclassified>
* 0`00c21000 0`00c30000 0`0000f000 MEM_FREE PAGE_NOACCESS Free
* 0`00c30000 0`00c97000 0`00067000 MEM_MAPPED MEM_COMMIT PAGE_READONLY MemoryMappedFile "\Device\HarddiskVolume2\Windows\System32\locale.nls"
答案 2 :(得分:1)
另一个虚拟内存查看器是VMValidator。内存布局的可视数据,以及内存页和内存段落的数据。
至于PE文件的布局,我推荐书Expert .Net 2.0 IL Assembler,第4章。它主要针对托管(.Net)PE文件而不是本地文件,但它确实描述了它的全部布局
然后,如果你想看一些读取PE文件的源代码(C ++),你应该看一下PE File Format DLL。还有一个GUI,向您展示如何使用DLL。源的许可证是开源的,不受GPL的限制。
编辑:David A Solomon和Mark E Russinovitch(编写VMMap的人在另一个答案中提到)的另一本书推荐是Inside Microsoft Windows 2000 (3rd Edition)。本书有关于内存管理的部分,从页面表布局到更多宏规模内存管理,以及另外一章,涉及与进程,线程和相关数据结构有关的各种问题。关于PE布局和虚拟地址布局,DLL被加载到由VirtualAlloc()分配的段落边界(x86上为64K)的内存区域中。根据PE文件中的每个部分的描述(只读,读/执行,读/写)等,设置各个页面的内存保护(x86上的4K,x64上的8K)。因此了解PE文件布局很有用,这就是我提到的原因。
如果您计划尝试修改DLL或执行检测,那么使用允许您轻松查看DLL内容的工具非常有用。因此,链接到PE文件格式DLL。它也是从您自己的特定要求开始的良好基础。