吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1501|回复: 14
收起左侧

[已解决] 求助熟悉PE结构的大佬解惑

[复制链接]
朱朱你堕落了 发表于 2023-10-27 09:20
789吾爱币
本帖最后由 朱朱你堕落了 于 2023-10-27 09:24 编辑

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

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



1
可以看到.rsrc区段的Virtual size大小是00008304,而下图中是书中.rsrc在
内存中的大小却是8314,所以这应该是书中错了吧,或是印刷错误吧?


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
书中习题,计算转换。如下图


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


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

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

最佳答案

查看完整内容

可以参考:https://bytepointer.com/resources/pietrek_peering_inside_pe.htm 的 Table 6. IMAGE_SECTION_HEADER Formats 部分 该字段在 EXE 或 OBJ 中具有不同的含义,对于 EXE 文件是 VirtualSize,对于 OBJ 文件 是 PhysicalAddress 两句话都没错,官方翻译指的是实际有效的那部分:没有经过内存对齐填充多余 0 的那部分 也就是实例中的意思 没对齐前的真实尺寸

免费评分

参与人数 1吾爱币 +1 收起 理由
netspirit + 1 你之前cb不是都没了吗,怎么又突然发出来了高价悬赏呀

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

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 的那部分
也就是实例中的意思 没对齐前的真实尺寸

点评

又重新理解了一遍,对Misc.VirtualSize还是有些不太明白。还得麻烦lyl610abc大佬解惑。 Misc 官方翻译 Misc 双字,该字段是一个union型的数据,这是该节在没有对齐前的真实尺寸,该值可以不准确。 1 针对这  详情 回复 发表于 2023-10-28 22:39
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 了

点评

Misc.VirtualSize 节加载到内存时的总大小,以字节为单位。如果该值大于SizeOfRawData成员,则该section将被0填充。此字段仅对可执行Image有效,对于object files应设置为0 SizeOfRawData 官方翻译 磁盘上初始化  详情 回复 发表于 2023-10-27 14:57

免费评分

参与人数 3吾爱币 +2 热心值 +2 收起 理由
雪流星 + 1 + 1 看这个大佬的pe,他的写的非常清晰,逻辑完整
董督秀 + 1 我很赞同!
yuxuan1311 + 1 热心回复!

查看全部评分

无闻无问 发表于 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有点区别)
[C] 纯文本查看 复制代码
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;
}

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
bester + 1 + 1 我很赞同!

查看全部评分

lyl610abc 发表于 2023-10-27 15:15
本帖最后由 lyl610abc 于 2023-10-27 15:18 编辑
朱朱你堕落了 发表于 2023-10-27 14:57
Misc.VirtualSize
节加载到内存时的总大小,以字节为单位。如果该值大于SizeOfRawData成员,则该section ...

我帖子里分析的案例是 SizeOfRawData > VirtualSize 的情况
麻烦看看帖子吧
https://www.52pojie.cn/thread-14 ... 8%E5%88%86%E6%9E%90

R.Size = 199200 > V.Address = 1990a9
缺的部分补 0

点评

别的字段我基本上明白,但是关于 union { DWORD PhysicalAddress; DWORD VirtualSize; } Misc; 这个我彻底懵逼了,为什么,因为官方的解释和实例中的解释不怎么对应呢? 贴子中  详情 回复 发表于 2023-10-28 10:59
 楼主| 朱朱你堕落了 发表于 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是“该节在没有对齐前的真实尺寸”,而官方翻译即是“节加载到内存时的总大小”......
也不知道到底哪句说的对,我彻底疯了。

点评

根据文件类型:EXE 或 OBJ 时不同,EXE 对应 VirtualSize ,OBJ 对应 PhysicalAddress 官方翻译和实例都没错,只不过描述方式不一样  发表于 2023-10-28 13:59
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-23 01:17

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表