0%

逆向工程核心原理PE文件格式部分总结

UPX部分

众所周知,UPX是一种较为常见的压缩壳。(除压缩壳外,还有加密壳)

先对壳做个基本的了解:壳的初始作用是保护软件,但后来发展的方向不一就出现了各种各样的壳,大致有压缩壳、加密壳、VM 壳的分类。压缩壳故名思意,主要作用是用于压缩方面,可以有效的减小软件的大小;加密壳,其主要作用是保护软件;VM 壳是一种很特殊的壳,它利用了虚拟机技术,可以很有效的保护指定地址代码,但很大的牺牲了效率,所以一般只在关键代码处使用。(其实就是隐藏函数的OEP–主要入口点)

压缩和压缩方式

  1. 压缩又分为无损压缩和有损压缩。

    两种压缩都是为了能节省一定的空间,只是无损不会使数据不完整(如各种压缩包);而有损有时会通过压缩文件(数据)损失一定的信息,来提高压缩率(如mp3、mp4和jpg文件,这也是为什么前两个有音质和画质之分的根源所在吧)。

  2. 压缩方式大体分为两种:普通压缩和运行时压缩。一张图说明二者区别

image-20211224113639435

运行时压缩(也叫PE压缩器)是针对PE文件的。PE文件内部含有解压缩代码,运行瞬间于内存中解压然后执行。

上文说过,压缩可以节约内存空间,还有一点,能够隐藏PE文件的内部代码和资源。

  1. 既然压缩的目的是为了防止内部代码资源泄露,那么为了对PE文件提供更强的保护,PE保护器就存在了。

image-20211224114154673

  1. 压缩文件和正常文件的PE结构的区别(感觉这一块书上已经将的很清楚了,就放原图吧。)
    image-20211224114504354

image-20211224120500126

image-20211224120527464

脱UPX壳

32位的就没啥说的了拖进OD找到PUSH ad和POP ad就行了或者能用ESP定律就更好

64位就需要单步跟踪了,具体情况具体分析(推介X64dbg)。

关于重定位

前面浅谈PE文件的时候,简单说过重定位。

这里再贴一下吧

image-20211224121526295

本次我们注重关注在重定位的原理。

PE文件重定位的原理

image-20211224122210645

查值通过基址重定位表完成,基址定位表地址如下:

image-20211224123046202

基址定位表是IMAGE_BASE_RELOCATION结构体数组

该结构体含有两个成员:1. 基准地址virtualaddrss—RVA值(DWORD型);2.SizeOfBlock—重定位块的大小(DWORD型)还有一个被注释的Typeoffset—表示该结构体下会出现WORD型的数组,该数组元素的值就是硬编码在程序中的地址偏移。

此处易将VA和RVA混淆,贴一个。

image-20211224152619953

通过找到基址重定位表的RVA的值,我们在.reloc节区可以发现

image-20211224151613796

image-20211224151859721

该重定位节区在2AE00开始,那根据其结构体成员可知,RVA的值位1000,重定位块的大小为150(都是小端序标识法。)

image-20211224152136922

我们已经知道Typeoffset(它的低12位是真正的基于VirtualSize位置的偏移。)是WORD型(两字节,16位)的,其由4位的Type和12位的offset合成的。

比如第一个3420,其Type为3,offset为420。

程序中硬编码地址的偏移用如下等式换算:

VirtualSize+Offsize=RVA(该等式中,VirtualSize和RVA易混淆,见上文所贴的图。)

image-20211224155355494

可以看到图片下方的ds里有IAT的地址VA,C010C4(不同设备运行,值不一样。)

使用上述偏移值可以查找硬编码地址值,将该值减去ImageBase,再加上实际加载地址,即可得到VA,完成重定位。

对于程序内硬编码的地址,PE装载器都做如上的处理,根据实际加载的内存地址修正后,将得到的值覆盖到同一位置上。对一个IMAGE_BASE_RELOCATION结构体的所有TypeOffset都做如上处理,且对RVA 1000~2000地址区域对应的所有硬编码地址都要进行PE重定位处理。如果TypeOffset值为0,说明一个IMAGE_BASE_RELOCATION结构体结束。至此,完成重定位流程。

删除重定位节区.reloc

由于该节区对程序正常运行没有影响,且删除后文件大小将缩减。故试着删除:

image-20211224161108321

可以看到,该节区区域为270-297,用00填充该区域;接着删除该节区,根据该节区的其起始偏移位置C000,一直到末尾,删除即可(因为.reloc为最后一个节区,所以直接到拉到文件末尾进行删除);然后修改节区数,该文件原有5个节区,现在删了一个,将其改为4个,在文件头里面修改number os sections

image-20211224161900975

下图为已经更改过的image-20211224161923290

最后就是修改可选头的文件(映像)大小,size of image。

同样的的方法

image-20211224162116107

该重定位节区的大小为E40

这里还需要用到如下知识。(选自加密与解密第四版)

image-20211224162435728

在可选头中,我们找到了两种对齐值

image-20211224162757991

故,E40需对齐到1000.再用原本的size of image将其减去,则为10000,做出修改。

至此,重定位节区算是删除完成了。

UPack PE文件头分析及查找OEP

感觉没啥好说的,对着书看吧…

内嵌补丁(内嵌代码补丁)

先上一张概念图:

image-20211224164128856

整个过程中,值得注意的点:

  1. 程序运行的逻辑
  2. 代码整体结构(借用一下书上的图)image-20211224164351755
  3. 补丁代码设置的位置
    • 设置到文件的空白区域
    • 扩展最后节区后设置
    • 添加新节区后设置
  4. 异或操作和加密区域的查找—(涉及RVA to RAW的转化。)

对该练习有疑惑可以参考一下文章:

内嵌补丁练习_Mi1k7ea-CSDN博客

总结

注重实操。