3

我一直很好奇

  1. 该过程在内存中的外观如何?
  2. 它有哪些不同的部分(部分)?
  3. 程序(在磁盘上)和进程(在内存中)究竟是如何相关的?

我以前的问题:有关可执行程序(进程)的内存布局的更多信息

在我的探索中,我终于找到了答案。我发现这篇出色的文章清除了我的大部分疑问:http ://www.linuxforums.org/articles/understanding-elf-using-readelf-and-objdump_125.html

在上面的文章中,作者展示了如何获取进程的不同段(LINUX)并将其与相应的 ELF 文件进行比较。我在这里引用本节:

想看看流程段的真实布局吗?我们可以使用 /proc//maps 文件来显示它。是我们要观察的进程的PID。在我们继续之前,我们有一个小问题。我们的测试程序运行得如此之快,以至于在我们转储相关的 /proc 条目之前它就结束了。我使用 gdb 来解决这个问题。您可以使用另一种技巧,例如在调用 return() 之前插入 sleep()。

在控制台(或终端模拟器,如 xterm)中:

$ gdb test
(gdb) b main
Breakpoint 1 at 0x8048376
(gdb) r
Breakpoint 1, 0x08048376 in main ()

按住这里,打开另一个控制台,找出程序“test”的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 文件格式。

  1. 任何用于获取 Windows 中运行进程的布局(段)的工具?
  2. 任何其他好的资源来学习更多关于这个主题?

编辑:

有没有好的文章显示 PE 文件sections和 VA之间的映射segments

4

3 回答 3

5

Sysinternals VMMap也是可视化进程 VA 空间的绝佳工具:

VMMap 截图
(来源:microsoft.com

于 2010-01-25T22:20:14.967 回答
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"
于 2010-01-25T18:27:42.227 回答
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 的Inside Microsoft Windows 2000(第 3 版)(编写 VMMap 的人在不同的答案中提到)。这本书有关于内存管理的部分,从页表布局到更宏观的内存管理,还有一章关于与进程、线程和相关数据结构有关的各种问题。

关于 PE 布局和虚拟地址布局,DLL 被加载到由 VirtualAlloc() 分配的段落边界(x86 上为 64K)上的内存区域中。这里面的各个页面的内存保护(x86上4K,x64上8K)是根据PE文件中每个部分的描述方式(只读,读/执行,读/写)等设置的。由此知道PE文件布局很有用,这就是我提到它的原因。

如果您计划尝试修改 DLL 或执行检测,那么拥有一个可以让您轻松查看 DLL 内容的工具非常有用。因此链接到 PE 文件格式 DLL。对于您自己的特定要求,它也是一个很好的基础。

于 2010-03-31T12:18:54.773 回答