朱朱你堕落了 发表于 2023-10-27 09:20

求助熟悉PE结构的大佬解惑

本帖最后由 朱朱你堕落了 于 2023-10-27 09:24 编辑

很基础的问题,求助各位大佬。

以某书中的例子讲PE结构notepad为例说明,用exeinfo查看区段信息如下:

https://im.gurl.eu.org/file/5701369e951ffc91329da.png

1
可以看到.rsrc区段的Virtual size大小是00008304,而下图中是书中.rsrc在
内存中的大小却是8314,所以这应该是书中错了吧,或是印刷错误吧?
https://im.gurl.eu.org/file/2b816ef780c419a85b14d.png

2
先看text区段,它的Virtual size大小为7748,而RAW size大小是7800,就是说物理磁盘中区段
大小却大于加载到内存中,这就说明物理磁盘中的有7800-7748=0xB8大小的数据没有被加载???这不可能
吧?不合逻辑啊。到底要如何理解。

再看data区段,RAW size大小为800, Virtual size大小为1BA8,我总是感觉这种RAW size小于Virtual size才
是合理的,因为物理磁盘中的数据拉伸到内存中,1BA8-800=0x13A8大小的空间在内存中用0填充的空间,
这才符合逻辑,而text区段想不通。

请问,到底怎么回事?

3
书中习题,计算转换。如下图
https://im.gurl.eu.org/file/2072fbd52a64a6c22060d.png

计算公式和原理是明白的,但是它的解释不明白啥意思,但是书中并没有说具体应该要如何计算。
请问,到底这个File Offset到底是多少,具体怎么计算才是正确的?请不要直接使用工具转化啥的,
我想知道如何手工计算。


麻烦大佬耐心讲详细些,希望这次能彻底明白,以后不再问这个问题。

书中例子:
https://cowtransfer.com/s/d2ace83a9b5544

lyl610abc 发表于 2023-10-27 09:20

朱朱你堕落了 发表于 2023-10-28 10:59
别的字段我基本上明白,但是关于
union {
      DWORD   PhysicalAddress;

可以参考:https://bytepointer.com/resources/pietrek_peering_inside_pe.htm 的 Table 6. IMAGE_SECTION_HEADER Formats 部分
该字段在 EXE 或 OBJ 中具有不同的含义,对于 EXE 文件是 VirtualSize,对于 OBJ 文件 是 PhysicalAddress

两句话都没错,官方翻译指的是实际有效的那部分:没有经过内存对齐填充多余 0 的那部分
也就是实例中的意思 没对齐前的真实尺寸

lyl610abc 发表于 2023-10-27 10:06

本帖最后由 lyl610abc 于 2023-10-27 10:10 编辑

1.应该是印刷错误
2.可以参考我的帖子:https://www.52pojie.cn/thread-1407996-1-1.html
Misc.VirtualSize
节加载到内存时的总大小,以字节为单位。如果该值大于SizeOfRawData成员,则该section将被0填充。此字段仅对可执行Image有效,对于object files应设置为0
SizeOfRawData
官方翻译
磁盘上初始化数据的大小,以字节为单位。这个值必须是IMAGE_OPTIONAL_HEADER结构文件对齐FileAlignment成员的倍数。如果该值小于VirtualSize成员,则节的其余部分将被填充为0。如果该节只包含未初始化的数据,则该成员为零

内存对齐后的大小 = (Max{Misc,SizeOfRawData} ÷ SectionAlignment) 向上取整 × SectionAlignment
详细实际案例看我帖子

通俗版
节在文件中对齐后的尺寸
3.参考我的帖子:
https://www.52pojie.cn/thread-1408576-1-1.html
PS:帖子无人问津 EMO 了{:301_999:}

无闻无问 发表于 2023-10-27 11:11

加壳的吧,如果加壳了,对不上正常,因为壳干的事情…

bester 发表于 2023-10-27 11:23

lyl610abc 发表于 2023-10-27 10:06
1.应该是印刷错误
2.可以参考我的帖子:https://www.52pojie.cn/thread-1407996-1-1.html
Misc.VirtualSi ...

是真的难得见到你,还想再看看你的佳作

JuncoJet 发表于 2023-10-27 11:46

楼主的理解没错,就是没加载

朱朱你堕落了 发表于 2023-10-27 14:57

lyl610abc 发表于 2023-10-27 10:06
1.应该是印刷错误
2.可以参考我的帖子:https://www.52pojie.cn/thread-1407996-1-1.html
Misc.VirtualSi ...
Misc.VirtualSize
节加载到内存时的总大小,以字节为单位。如果该值大于SizeOfRawData成员,则该section将被0填充。此字段仅对可执行Image有效,对于object files应设置为0
SizeOfRawData
官方翻译
磁盘上初始化数据的大小,以字节为单位。这个值必须是IMAGE_OPTIONAL_HEADER结构文件对齐FileAlignment成员的倍数。如果该值小于VirtualSize成员,则节的其余部分将被填充为0。如果该节只包含未初始化的数据,则该成员为零

大佬,你回复的这两个,都是VirtualSize>SizeOfRawData的情况,并没有说到VirtualSize<SizeOfRawData的情况,VirtualSize<SizeOfRawData的情况到底是什么样的?

MJ_B 发表于 2023-10-27 15:14

1、写错了或者印错了
2、Raw size是对齐后的大小。
   Virtual size还没有对齐,所以一般看起来都比Raw size小,对齐之后就是0x8000
3、RVA和FOA转换的关键问题就是找到地址在节中的偏移。
   一个RVA地址radd,去节表中找radd属于哪个节中记作X,找到之后再用radd减去X节的内存地址(VirtualAddress),结果就是偏移,最后加上PointerToRawData就是最终结果。
   一个FOA地址fadd,去节表中找fadd属于哪个节中记作X,找到之后再用radd减去X节的文件地址(PointerToRawData),结果就是偏移,最后加上VirtualAddress就是最终结果。
代码:(注意:RVAToFOA和FOAToRVA有点区别)
DWORD RVAToFOA(const char *fileBuff, DWORD addr) {
    PIMAGE_NT_HEADERS32 nt = copyNTHead(fileBuff);
    PIMAGE_SECTION_HEADER sec =
      copySecHead(fileBuff) + nt->FileHeader.NumberOfSections;

    for (size_t i = nt->FileHeader.NumberOfSections; i > 0; i--) {
      sec--;
      if (addr >= sec->VirtualAddress)
            return addr - sec->VirtualAddress + sec->PointerToRawData;
    }

    return addr;
}

DWORD FOAToRVA(const char *fileBuff, DWORD addr) {
    PIMAGE_NT_HEADERS32 nt = copyNTHead(fileBuff);
    PIMAGE_SECTION_HEADER sec = copySecHead(fileBuff);
    DWORD rra = 0, rva = 0;

    for (size_t i = 0; i < nt->FileHeader.NumberOfSections; i++) {
      if (addr < sec->PointerToRawData) {
            if (i == 0) return addr;
            return addr - rra + rva;
      }
      rra = sec->PointerToRawData;
      rva = sec->VirtualAddress;
      sec++;
    }

    return addr;
}

lyl610abc 发表于 2023-10-27 15:15

本帖最后由 lyl610abc 于 2023-10-27 15:18 编辑

朱朱你堕落了 发表于 2023-10-27 14:57
Misc.VirtualSize
节加载到内存时的总大小,以字节为单位。如果该值大于SizeOfRawData成员,则该section ...
我帖子里分析的案例是 SizeOfRawData > VirtualSize 的情况
麻烦看看帖子吧{:301_977:}
https://www.52pojie.cn/thread-14 ... 8%E5%88%86%E6%9E%90
https://610-pic-bed.oss-cn-shenzhen.aliyuncs.com/image-20210404131821611.png
R.Size = 199200 > V.Address = 1990a9
缺的部分补 0

朱朱你堕落了 发表于 2023-10-28 10:59

lyl610abc 发表于 2023-10-27 15:15
我帖子里分析的案例是 SizeOfRawData > VirtualSize 的情况
麻烦看看帖子吧
https://www.52 ...
别的字段我基本上明白,但是关于
union {
      DWORD   PhysicalAddress;
      DWORD   VirtualSize;
       } Misc;
这个我彻底懵逼了,为什么,因为官方的解释和实例中的解释不怎么对应呢?

贴子中官方翻译如下:

Misc
官方翻译
Misc 双字,该字段是一个union型的数据,这是该节在没有对齐前的真实尺寸,该值可以不准确

通俗版
这是一个联合结构,可以使用下面两个值其中的任何一个,一般是取Misc.VirtualSize

Misc.PhysicalAddress
文件地址

Misc.VirtualSize
节加载到内存时的总大小,以字节为单位。如果该值大于SizeOfRawData成员,则该section将被0填充。此字段仅对可执行Image有效,对于object files应设置为0

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

既然是联合结构,可以使用两个值中的一个,一般是取Misc.VirtualSize
问:
那么什么情况下使用PhysicalAddress?什么情况下使用VirtualSize?
是由什么决定的?

3
Misc.VirtualSize
节加载到内存时的总大小,以字节为单位。如果该值大于SizeOfRawData成员,则该section将被0填充。此字段仅对可执行Image有效,对于object files应设置为0

问:
实例中说Misc.VirtualSize是“该节在没有对齐前的真实尺寸”,而官方翻译即是“节加载到内存时的总大小”......
也不知道到底哪句说的对,我彻底疯了。
页: [1] 2
查看完整版本: 求助熟悉PE结构的大佬解惑