PE速查

RVA的含义:相对虚拟地址 = 该数据的虚拟地址 - 映象的装载基址的虚拟地址.

IMAGE_DOS_HEADER ;DOS头:
00000000: DB e_magic   "MZ"
0000003C: DD e_lfanew ;PE头基址,最后一个字段

IMAGE_NT_HEADERS ;PE头:
00000000: DB Signature "PE",0,0

IMAGE_FILE_HEADER ;文件头
00000004: DW Machine    ;运行平台(1)
00000006: DW NumberOfSection   ;文件节数目
00000008: DD TimeDateStamp   ;创建文件的时间   (usually usless)
0000000c: DD PointerToSymbolTable ;指向符号表   (usless)
00000010: DD NumberOfSymbols   ;符号表中符号的数量 (usless)
00000014: DW SizeOfOptionalHeader ;可选头大小,一般为E0h
00000016: DW Characteristics   ;文件属性(2)

IMAGE_OPTIONAL_HEADER32 ;可选头(其实是必须的)
00000018: DW Magic    ;107h=ROM Image,10bh=exe Image
0000001a: DB MajorLinkerVersion ;连接器主版本号    (usless)
0000001b: DB MinorLinkerVersion ;连接器次版本号    (usless)
0000001c: DD SizeOfCode   ;所有含代码的节的总大小   (usless)
00000020: DD SizeOfInitializedData ;所有含已初始化节的总大小 (usless)
00000024: DD SizeOfUninitializedData ;所有含未初始化节的总大小 (usless)
00000028: DD AddressOfEntryPoint ;程序执行入口RVA
0000002c: DD BaseOfCode   ;代码节起始RVA    (usless)
00000030: DD BaseOfData   ;数据节起始RVA    (usless)
00000034: DD ImageBase   ;程序建议装载地址(虚拟地址)
00000038: DD SectionAlignment ;内存中节对齐粒度,一般是4KB,64位系统是8KB
0000003c: DD FileAlignment   ;文件中节对齐粒度,一般是200h
00000040: DW MajorOperatingSystemVersion ;操作系统主版本号 (usless)
00000042: DW MinorOperatingSystemVersion ;操作系统次版本号 (usless)
00000044: DW MajorImageVersion ;可运行的操作系统的最小版本号,主版本号 (usless)
00000046: DW MinorImageVersion ;可运行的操作系统的最小版本号,次版本号 (usless)
00000048: DW MajorSubsystemVersion ;可运行的操作系统的最小子系统主版本号 (usless)
0000004a: DW MinorSubsystemVersion ;可运行的操作系统的最小子系统次版本号 (usless)
0000004c: DD Win32VersionValue ;未用,Win32VersionValue   (usless)
00000050: DD SizeOfImage   ;内存中整个PE映象的大小
00000054: DD SizeOfHeaders   ;所有头+节表的大小
00000058: DD CheckSum   ;checksum,在可执行文件中为0,系统DLL和驱动中为校验和,就是将文件的所有内容按单字大小带进位累加,最后去掉进位加上文件大小.就是校验和
0000005c: DW Subsystem   ;文件的子系统(3)
0000005e: DW DllCharacteristics
00000060: DD SizeOfStackReserve ;初始化时堆栈大小
00000064: DD SizeOfStackCommit ;初始化时实际提交的堆栈大小
00000068: DD SizeOfHeapReserve ;初始化时堆大小
0000006c: DD SizeOfHeapCommit ;初始化时实际提交的堆大小
00000070: DD LoaderFlags
00000074: DD NumberOfRvaAndSizes ;数据目录的大小
00000078: QD DataDirectory   ;数据目录,一般是16个目录项,每个目录项8字节(4)
000000f0: QD     ;最后一个目录项

IMAGE_DATA_DIRECTORY ;数据目录结构
00000000: DD VirtualAddress   ;数据起始RVA
00000004: DD isize    ;数据块长度

IMAGE_SECTION_HEADER ;节表
00000000: DB 8 DUP (?) Name1    ;节名称
00000008: DD   VirtualSize   ;节未对齐时的大小
0000000c: DD   VirtualAddress   ;节在内存中的RVA
00000010: DD   SizeOfRawData   ;节在文件中对齐后的大小
00000014: DD   PointerToRawData ;节在文件中的偏移
00000018: DD   PointerToRelocations ;usless
0000001c: DD   PointerToLinenumbers ;usless
00000020: DW   NumberOfRelocations ;usless
00000022: DW   NumberOfLinenumbers ;usless
00000024: DD   Characteristics   ;节属性(5)

每个节被加载到内存后,节基址是按页对齐的,因为系统管理内存数据是以页为单位,而节保存在磁盘中时,节基址是以扇区为对齐单位的,这是系统管理磁盘数据的普遍规定.
往往一个页要大于一个扇区的大小,又有在内存中节基址偏移是相对于映象基址的,在磁盘中节基址的偏移是相对于文件基址的.
所以为了避免当节被加载到内存时要进行对齐转换,在节表中加入了该节被实际加载到内存后相对于映象基址的按页对齐的偏移,同时保留该节在磁盘上相对于文件基址的按扇区对齐的偏移.
这样既方便加载又节省磁盘空间.

虽然方便了加载,但是通过数据的RVA来得到数据在磁盘文件基址的偏移就比较麻烦.
方法是:
先通过该数据的RVA比较各节基址的RVA和各节的大小,看该数据是否落在某个节中,如果落在某个节中,则算出数据相对于节基址的偏移(数据的RVA-节基址RVA)
然后,因为该数据相对于节基址的偏移在内存中和在文件中都是相同的,所以找到该数据所处的节在文件中的基址,
然后用算出的偏移加上该节在文件中的节基址,就是该数据在文件中的偏移.

节表紧靠在可选头后面.

;导入表
00000000: DD   ;指向一个双字的RVA,该双字描述一个导入函数.若指向的双字的最高位为1,则指向的双字的剩余数据是该函数的导出编号,否则是一个RVA,这个RVA 指向一个结构,该结构最低字是一个编号,然后是一个以0结尾的字符串,该字符串是导入的函数名.
00000004: DD   ;创建时间,dump一下一般都是0?
00000008: DD   ;dump了一下都是0?
0000000c: DD   ;指向导入库文件名称字符串的RVA,该字符串以0结尾.
00000010: DD   ;指向一个双字的RVA,当映象被加载后,该字段指向的双字被加载器动态修改为对应的导入函数首指令所在字节地址.当在程序中动态加载函数后,在调用的时候是通过call,最后转到一个jmp dword ptr [xxxxxxxx]间接寻址的指令所在的位置,而这个间接地址xxxxxxxx=该RVA+映象基址.

导入表最后要有一个全0表项,指示导入表的结束,00000000指向的偏移处的结构也需要一个全0双字表示结束.

;导出表
00000000: DD   ;全0
00000004: DD   ;文件产生时间
00000008: DD   ;全0
0000000c: DD   ;指向文件名字符串的RVA,该字符串以0结尾.
00000010: DD   ;导出函数的起始序号
00000014: DD   ;导出函数的总数
00000018: DD   ;以名称导出的函数的总数
0000001c: DD   ;指向导出函数地址表的RVA,指向的是一个双字表,该双字表每个双字保存函数入口RVA.个数由00000014字段指定
00000020: DD   ;指向导出函数名地址表的RVA,指向的是一个双字表,该双字表每个双字保存函数名字符串.个数由00000018字段指定
00000024: DD   ;指向对照表的RVA,指向的是一个单字表,该单字表每个单字的索引对应导出函数名表,每个单字的值对应导出函数表的索引.个数由00000018字段指定,该表将导出函数表和导出函数名表对应起来.

函数的导出序号等于该函数所在的导出函数表索引加00000010字段.
索引都是从0记数.

;重定位表
重定位只是对直接寻址指令进行重定位,积存器寻址不需要.只有在映象基址和建议加载不符时才需要重定位,而实际加载地址是加载时动态确定的,所以重定位表只需保存需要重定位的数值地址.
重定位表是按页分块的,这样不用保存高端地址,只保存页偏移,当页内有多个重定位地址时节省空间.
00000000: DD   ;页起始RVA.
00000004: DD   ;重定位块长度
通过重定位长度算出该页内重定位个数,每个重定位项用一个字表示,该字的低12位指定页内偏移,高4位含义如下:
0:该双字地址不重定位
1:该双字地址高16位重定位
2:该双字地址低16位重定位
3:该双字地址全部重定位
其他值含义不详
最后以一个全0的8字节结束

;资源

;调试信息

注释:
1.运行平台(WORD):
0 未知平台
14ch Intel 386
14dh Intel 486
14eh Intel 586
160h R3000 大尾方式
162h R3000 小尾方式
166h R4000 小尾方式
168h R10000 小尾方式
184h Dec Alpha AXP
1f0h IBM Power PC 小尾方式
284h Dec Alpha AXP64

2.文件属性(WORD):
位数 含义
0 文件中不存在重定位信息
1 文件是可执行的
2 不存在行信息(?)
3 不存在符号信息
7 小尾方式
8 只在32位平台运行
9 不包含调试信息
10 不能从可移动盘(如软盘,光盘)运行
11 不能从网络运行
12 系统文件,不能直接运行
13 这是一个DLL文件
14 文件不能在多处理器机上运行
15 大尾方式

3.使用界面的子系统(WORD):
0 未知子系统
1 不需要子系统(?)
2 Windows图形界面
3 Windows控制台界面
5 OS2控制台界面
7 POSIX控制台界面
8 不需要子系统(?)
9 WinCE图形界面

4.数据目录项的含义:(每个表项占8字节,低双字是一个实际数据的RVA,高双字是实际数据的大小)
0 导出表
1 导入表
2 资源
3 异常(?)
4 安全(?)
5 重定位表
6 调试信息(?)
7 0
8 全局指针(?)
9 Thread Local Storage(?)
10 加载配置表(?)
11 绑定输入表(?)
12 IAT,导入函数地址表
13 延迟加载的输入表(?)
14 CLR运行时头地址
15 0

5.节属性(DWORD):
位 含义
5 (00000020h)节中包含代码
6 (00000040h)节中包含已初始化的数据
7 (00000080h)节中包含未初始化的数据
25 (02000000h)节在初始化以后将被丢弃,如重定位节
26 (04000000h)节中的数据不会经过缓存
27 (08000000h)节中的数据不会交到磁盘
28 (10000000h)节中的数据将被不同进程共享
29 (20000000h)映射到内存中页面包含可执行属性
30 (40000000h)映射到内存中页面包含可读属性
31 (80000000h)映射到内存中页面包含可写属性

### 回答1: exeinfope是一款用于查找和识别PE文件的工具,它可以帮助我们分析二进制文件以及了解其内部结构和特征。虽然它本身不是用来对抗或解除壳的工具,但可以在确定文件的保护机制和使用的安全措施后,为我们寻找更好的解决办法提供指导。 首先,我们需要下载和安装exeinfope工具。一些版本的exeinfope可以在其官方网站或其他可信源进行下载。 安装完成后,我们可以打开工具并选择我们想要分析的PE文件。在文件菜单中,选择"Open"选项并浏览到要分析的文件路径。另一种方法是将PE文件拖放到exeinfope窗口中。 一旦PE文件加载完成,exeinfope会显示有关该文件的基本信息,如文件大小、入口点、反汇编代码等。接下来,我们可以在工具栏中点击"PE Section"选项卡来查看有关文件节的详细信息,以及它们的属性和特征。 要查找和识别壳,我们可以使用工具栏中的"QuickScan"选项卡。在这个选项卡中,我们可以看到有关文件的一些重要信息,如文件标志、导入表、资源、加密段等。 在"QuickScan"选项卡下方,我们可以找到一些按钮,如"Search"和"Scan"。这些按钮可以帮助我们在已加载的PE文件中搜索和扫描特定的特征和字符串,可能与壳相关。我们可以使用这些功能来探查文件的保护机制以及识别是否使用了壳。 exeinfope还提供了一些其他功能和选项,如PE编辑器、加密解密工具等。这些工具可以进一步协助我们分析和解决与壳有关的问题。 需要注意的是,exeinfope仅用于查找和识别PE文件的特征和保护机制,不提供直接的壳解决方案。为了有效地解决壳相关的问题,我们可能需要进一步的研究和使用其他高级工具,如IDA Pro或OllyDbg,以获得更深入的分析和操作能力。 ### 回答2: exeinfope是一款常用的PE文件信息分析工具,可以用于查看和判断一个可执行文件是否被壳包裹。下面是一个关于如何使用exeinfope来查壳的简单教程: 步骤一:下载并安装exeinfope工具。可以在官方网站或一些软件下载网站上找到并下载exeinfope,然后按照提示完成安装过程。 步骤二:打开exeinfope工具。启动exeinfope,并点击打开按钮选择需要分析的可执行文件。 步骤三:进行壳检测。在exeinfope工具的界面中,可以看到文件的各种信息。查找到"Packers Detected"或者"Protection Detected"的选项,并查看是否有壳的信息。如果有壳的信息显示出来,说明该可执行文件被壳包裹。 步骤四:查看壳的详细信息。如果exeinfope检测到壳,可以进一步点击壳的名称或者"Plugins"选项来查看具体的壳信息。这些信息可以帮助你了解所用壳的功能和特点。 步骤五:根据具体情况进行解壳。根据exeinfope工具所显示的壳的信息,可以针对性地选择相应的解壳工具进行解壳操作。不同的壳使用不同的解壳方法和工具,需要根据具体情况进行处理。 需要注意的是,exeinfope工具是一款查壳工具,主要用于分析PE文件是否被壳,而不是提供具体的解壳方法。对于复杂的壳,可能需要使用其他专门的解壳工具,或者进行进一步的逆向分析。在进行壳分析和解壳操作时,务必遵守相关法律法规,以及遵循道德和伦理规范。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值