Win32 PE文件格式简要总结

PE文件的内容分为不同的块/节(Section),块中包含代码或数据,各个块按页边界对齐,块没有大小限制,是一个连续结构。
PE文件不是作为一个整体被载入内存的而是分节加载的。PE装载器不会对PE文件头作特殊处理,但装载各个块的时候会根据块的属性做不同的处理:
1. 内存页的属性
对于磁盘来说,所有的页都是按照磁盘映射文件函数指定的属性设置的,但是在装载可执行文件的时候,与块对应的内存页属性要按照块的属性来设置,所以,在同属于一个模块的内存页中,从不同块映射过来的内存页的属性是不同的。
2. 块的偏移地址
块的起始地址在磁盘文件中是按照IMAGE_OPTIONAL_HEADER32结构的 FileAlignment 字段的值进行对齐的,而当被加载道内存中时是按照同一结构中的SectionAlignment字段的值设置对齐的,两者的值可能不同。所以一个块表被装载到内存后相对于文件头的偏移地址和磁盘中的偏移地址可能是不同的。(块表事实上就是相同属性数据的组合,当块表再入到内存中的时候,相同一个快比爱所对应的内存页都将被赋予相同的页属性,事实上Windows 系统对内存属性的设置是以页为单位的进行的,块表在内存的对齐的单位必须是一个页的大小或者是一个页的正整数倍)。在磁盘中没有这个限制,因为磁盘中排放的是以空间为主导,在磁盘知识存放,不是使用,所以不用设置那么详细的属性。
3. 块表的尺寸
主要有2个方面:
对齐:磁盘映像和内存映像中块表对齐存储单位的不同而导致了长度不同;
初始化:某些数据没有初始化,那么没有必要为其在磁盘中浪费空间资源,但是在内存中不同,程序一旦运行,之前没有初始化的数据便有可能要被赋值初始化,那么就必须为他们留下空间。
4. 不进行映射的块表
有些块表并不需要映射到内存中,例如 .reloc 块表,重定位数据对于文件的执行代码是透明的,它只是提供Windows装载器使用执行代码根本不会去访问他们,所以没有必要将他们映射到物理内存中。

各种地址概念

虚拟地址(VA):
每个进程都有自己独立的4G虚拟内存空间,对应的地址为VA
基址:
PE映象文件被装入内存的地址,在windows中也就是hModule的值,同时也指向PE头
相对虚拟地址 RVA(Relative Virtual Addresses):
PE文件可以被加载到进程地址空间的任何位置;RVA是相对于基址的偏移,即VA=基址+RVA
文件偏移地址:
和内存无关,指距离文件头的偏移

重定位

1.每个PE文件可以定义一个默认的基址,但当它被装载时该基址有可能已经被其他模块占用
2.链接器生成PE文件时会假设指令中用到的地址都基于默认的基地址
3.假如该模块被迫加载到非默认的基址上,此时就需要根据重定位表进行地址的修复
*.由于一般exe是第一个加载的,所以一般exe不需要重定位表,但不代表所有exe都没有重定位表

常见section

.text:虽然叫text,但实际上它主要保存编译后的源码指令,是只读字段
.data:保存数据,对应初始化后的非const的全局变量变量或者局部static变量
.rdata:保存只读数据,对应C语言中的const变量
.bss:未初始化的非const全局变量和局部static变量
.reloc:重定位段。如果加载PE文件失败,将基于此段进行重新调整
.rsrc:资源

PE头

通过GetModuleHandle得到的HMODULE实际上就指向IMAGE_DOS_HEADER,也就是PE文件头的特殊标记MZ。通过IMAGE_DOS_HEADER可以进一步获取到IMAGE_FILE_HEADER,并依此访问各个节的数据。相关代码网上一搜就有,不过要注意32位与64位平台的差异。

导入表, 导出表

导入表记录一个exe/dll所用到的其他模块导出的函数;导出表则记录了导出符号的信息;日常开发中常用的工具exescope/dumpbin/depends等就是从导入表/导出表中获取的相应信息。
exe很少有导出表;大多数dll都有导出表;某些仅用于存放资源的dll可以没有导出表;
可以根据PE结构解析出已经被加载到内存中的某个模块的导出表的地址并对其进行修改以达到hook某个函数的目的,这就是IAT Hook。

应用

为什么要学习PE格式,学了这个可以做什么?列举几个例子:

  1. IAT hook
  2. chrome_elf
    chrome_elf模块为chrome浏览器提供以下支持:初始化crashpad(dump抓取);拦截第三方模块注入;
    为了确保抓取到某些早期逻辑导致的崩溃,也为了拦住在早期就注入到进程里的第三方模块,chrome_elf的执行非常早,早于一般程序的入口点winMain,也早于全局对象的初始化,它基于隐式链接动态库的DllMain函数来实现。为了确保它在程序启动的最早时机被执行,编译chrome.exe之后会由某个脚本修改chrome.exe的导入表,将chrome_elf.dll置于第一个,因为隐式加载dll的顺序是按导入表的顺序执行的,这样就可以确保chrome_elf.dll被第一个加载到进程里,并首先运行chrome_elf.dll里的DllMain。
  3. 注入exe
    这个主要为某些病毒程序所用,将其源码插入到正常程序中,或者将其dll插入到exe导入表中,达到跟随正常程序启动的目的;
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,444评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,421评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,363评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,460评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,502评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,511评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,280评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,736评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,014评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,190评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,848评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,531评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,159评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,411评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,067评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,078评论 2 352

推荐阅读更多精彩内容