首页
社区
课程
招聘
[分享]那两个PE笔记的附件好像看不了我在从新发一遍吧(都是干活啊老铁们哈哈)
2021-10-3 21:07 5507

[分享]那两个PE笔记的附件好像看不了我在从新发一遍吧(都是干活啊老铁们哈哈)

2021-10-3 21:07
5507

!!!!图片穿不上去啊呜呜呜呜 需要的老铁私信我吧
!!!!图片穿不上去啊呜呜呜呜 需要的老铁私信我吧
!!!!图片穿不上去啊呜呜呜呜 需要的老铁私信我吧

 

从ifanew 定位到的地址 再往后偏移4个字节 才是PE标志

 

Map文件里存的是所有函数的声明 便于加壳
Dos头和标准PE头的大小是确定的 可选PE头的大小是不确定的

 

程序加载进入OD之后会停在 imagebase+addressofentrypoint(oep)的位置
代码开始和程序入口 是不一样的

 

基地址+OEP就是代码在内存中开始的地方
一个exe文件有很多的PE文件组成的
OD加载的文件是内存中的地址 不是文件中的地址
每一个exe文件执行时都有自己独立的4gb的空间 所以内存镜像地址不会重复
找到的地址 一般要加上imagebase才有意义
用指针时有的时候会报错

 

NULL相当于地址为0的地方 程序中认为 要是访问0附近的地址 程序就会报错 内存保护区域

 

程序中的每一个dll都相当于一个模块

 

可选PE头下面是节表

 

Filebuffer是从硬盘中copy到内存中的 但是不能执行

 

程序只有经过拉伸后才能跑 原因是地址的问题
程序真正的入口点是img+oep 拉伸后的内存镜像的地址是从imagebase开始的 但是imagebase还不是程序的入口点 程序开始执行的位置
Oep是main函数上层的那个函数

 

在UE中打开的相当于在内存中的地址 相当于filebuffer

 

Imagebuffer上面的是对齐用的 也是用于指针保护的

 

最后执行的时候windows替编译器将虚拟地址转化成为物理地址 程序才能执行

 

OEP可以位于(代码段)的任意一个位置 也就是说程序可以从任意一个位置开始执行
138d7是编译器算出来的地址 用的时候直接找

 

程序的入口点随便改 但是不一定能执行 修改可选PE头里面的address of entry point(oep)


 

这里我联想到了之前学习的脱壳
既然可以修改程序的OEP 然后给他加一个节 然后在节的最后又必须加上程序真正的OEP
那么直接找到那个节的最后的位置 在修改程序的OEP为真正程序开始执行的OEP 就可以完成脱壳了

 

要修改汇编语句既可以通过正向的高级语言进行修改
同样也可以通过逆向的方法通过修改硬编码进行修改

 

为什么要用imagebase+oep的方法:
一个exe有很多的PE 这样能方便查找

 

文件映像才是真正可以执行的文件

 

节表在可选PE头下面的 但是它也属于各种头

 

只有给windows能直接运行的程序才有PE结构
Ifanew偏移之后得到的地址是四个字节的PE 再往后才是machine

 

Int类型的变量往内存中村的时候0X12345678 78 56 34 12
联合体的成员共用一片内存空间

 

PE的大小是确定的 可选PE头的大小是不确定的 32位程序上可选PE头的大小是E0
64位程序上可选PE头的大小是F0

 

节表确定节存储的位置和大小

 

程序刚加载进去的时候就是dos头 然后通过dos头最后的东西找到标准PE头
Size of optionheader中存储的是可选PE头的大小 、
在往后就是节表了

 

在标准PE头中由number of sections 决定一共有几个节表

 

BYTE占用8个字节

 

这个是节的属性表

 

PE标志之后紧跟的20个就是标准PE头

 

在往后查找E0个就是可选PE头的大小接下来就是节表了
每一个节表中存储的数据都是在节表属性的那个在内存中的偏移找到的
现在分析的就是节表

 

每个节表的大小是确定的 所以也就是说找完第一个节表就是第二个节表
表中存贮的数据有表中的属性 在内存中的偏移就可以找到

 

PE标记之后的第二个成员就是节表的总数 00 04 所以一共有4个节表

 

往后查找了 第一个成员是节的名字 一共有8个字节

 

第二个成员就是表的没有对齐前的真实的尺寸(misc) 00 01 97 22 可以随便修改 修改之后程序可以正常使用
节表中的第三个成员:

 

imagebase存储在可选PE头中 UE中加载的不是真正的可以执行的PE文件的结构

 

绿色大括号的长度就是virtualaddress的大小
第四个成员:

 

黄色的东西不用看 字节数目位4 4 2 2 一共是12个字节 直接跳过就行

 

第五个节的成员

 

Pointer to raw data 是看文件中的偏移
VirtualAddress是看内存中的偏移 记得加上iamge base
什么时候处理什么时候有用
以上都是研究的节的属性
手动解表:

 

第一个属性8个字节,是表的名字

 

第二个属性是misc没有对齐前的真实的尺寸 共4个字节 (可以随便修改)

 

第三个属性是virtual address 在内存中的起始偏移地址 共4个字节 在内存中应该加上可选PE头中的imagebase属性

 

第四个属性是在内存中对齐后的大小 size of raw data 共四个字节

 

第五个属性是在文件中的偏移 共4个字节 存储的是1000

 

这就是这个节指向的数据
节表的最后一个属性 也是4个字节:

 

意思是说

 

这个节可读可执行里里面有代码 所以说里面一定是代码段 名字可以随边修改 所以判断节的属性的时候要根据节的属性这个来判断

 

Misc可能大于size of raw data misc里存的是内存里的大小 不是文件中的大小
Cahr a【1000】 在文件中没分配空间 但是在内存中分配了空间
virtual address 在内存中的起始地址
在内存中应该加上可选PE头中的imagebase属性
Filebuffer 和文件的大小是一样的
在内存中的大小 存储在可选PE头里的size of iamge属性里
Copy第一步的时候直接把size of headers整个copy过来

 

第二步就是要copy每一个节表
Pointer to raw data 决定从哪里copy
Virtual Address 决定copy到哪里
大小有由misc决定
但是从内存中copy的时候直接copy size of raw data就可以了
在内存中可能misc比size of raw data大 但是在内存中初始化和未初化的经过拉伸后一定小于那一块的大小
Virtual size可能会很大就是显示是在内存中的大小
size of raw data就是在文件中对齐后的大小
按照Virtual size所显示的大小copy可能会把下一个节的信息也copy了
总的来说copy时就是找大小 找位置

 

Image buffer的开始地址是自己动态申请的 和image base 没有任何关系 是在内存中随机分配的地址 和程序真正执行时的地址不一样

 

Pointer to raw data是在文件中的偏移地址
Virtual address是在内存中的偏移地址
这里能更充分的理解为什么节表中存储的是偏移地址 因为只有这样才能找到
Image buffer开始的地址是随机分配的

 

内存中的大小仅仅通过iamgebuffer来判断是不确定的 必须要通过节表来查询
节表在文件中的大小是可以找到的 这样就可以找到在内存中的大小了

 

要想注入一段PE文件 首先要找到程序的OEP
思路就是修改程序的OEP 让程序从修改的OEP开始执行 然后JMP到程序最初的OEP
先用OD打开程序 输入bp MessageBoxA 查看调用堆栈窗口

 

发现call的硬编码是E8 jmp的硬编码是E9

 

找到地址是761539A0
Call 0X761539A0

 

用VC6查看MessageBox函数

 

所以要注入的硬编码是6A 6A 6A 6A E8 00 00 00 00 E9 00 00 00 00

 

因为计算E8的时候是在内存中计算的 所以最后加代码的时候也要在ImageBuffer中加入

 

先用PEtools查看字节数目是否够插入
文件对齐后的大小减去内存中的大小

 

现在要从1000开始找 然后加在19722的后面 这样加入的代码才不会影响拉伸后的程序
第一个节从1000开始 到46000结束 因为45000表示的是节的大小

 

这一串都是代码区的空闲区域 可以随便加入代码

 

Messagebox找到地址是761539A0
最后加入E8的下一行的地址是内存中的偏移 现在是在文件中加入 所以要算偏移地址

 

现在E8下一行的地址是450bd 要跳转的地址是761539A0
就是要找到在内存中的E8的下一行地址:
Imagebase+450bd(表示的是在内存中的偏移)在飞鸽中成立 是因为飞鸽传书在文件中和内存中的偏移是一样的 file buffer和image buffer是一样的
要是不一样得先算出在 文件中的偏移值:用这个地址-该节表的首地址(找到在表中的偏移),得到偏移值 ,然后在加上在内存中节表的首地址得到在内存中的在表中的偏移, 再加上imagebase就是E8的下一行的地址
也就是要找E8在两个表中的偏移值 先找到在filebuffer里的偏移值A 然后再找在imagebuffer中的E8的下一行的地址 :也就是imagebuffer中的第一个节表的首地址+A
然后在加上imagebase就是真正要跳转的地址
最后需要计算的是拉伸后的偏移是多少

 

Imagebase就是400000
450bd
4450BD
761539A0
相减之后得到75D0E8E3
填入E3 E8 D0 75
入口点是441EC+400000=4441EC 要跳转的地址
450C2+400000=4450C2 e9的下一行地址
得到FFFFF12A
所以填入 2A F1 FF FF
然后找到原来的OEP更改为450B0
在可选PE头里面找 OEP 000441EC

 

000450B0
更改为 B0 50 04 00

 

注入成功!

 

!!!!图片穿不上去啊呜呜呜呜 需要的老铁私信我吧


[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

最后于 2021-10-3 21:10 被wx_s_471编辑 ,原因:
收藏
点赞0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回