前言:之前我们有说到,upack压缩过后的文件的文件头部发生了变化,同时正常文件的第一,第三节区也被压缩到了notepad的第二个节区(第一,第三节区的部分空间已经映射了文件的头部)像麻花一样。
我们知道正常的PE文件,文件的第一节区应该是代码段,第二节区是数据段。upack压缩后的数据挤在第二节区,UPack解码需要将该节区的部分数据解密到第一节区。
接下来还是以notepad_upack.exe为例来调试一下看看。

解码函数

使用OD打开notepad_upack.exe文件时,会弹出错误消息对话框(因为UPack将IMAGE_OPTIONAL_HEADER当中的NumberOfRvaAndSize的值从10设置成A,但这不影响,点“确认”就关闭对话框了)
UPack调试笔记
来到EP处,我们知道,所有的压缩器都存在由许多条件分支语句和循环语句组成的解码循环。大体思路是有的,UPack将压缩过后的数据放到第二节区,再运行解码循环将其放回第一节区,现在我们来看看:
UPack调试笔记
前两条指令是将0x100739D压入堆栈,该地址属于第一节区,这些将第一节区的一个地址压栈,很可能将来第二节区数据解密数据被解密到第一个节区的该地址,也就是说,该地址很可能就是OEP。
单步跟踪几步后可以发现,LoadlibraryA,GetProcAddress函数会入栈,两个函数的作用是在文件解密完成后对原始文件重建IAT表。
UPack调试笔记
继续单步跟踪一段后,会执行到如下指令,从10010EB跳到101EC57,这是个大跳转,也就是从这里直接跳到第二节区

UPack调试笔记

解密函数

跳转过后,单步跟踪几步就会到达解密函数
UPack调试笔记
可以进去看看,单步跟踪几步就会发现许多条件分支和跳转语句
UPack调试笔记
这个解密函数具体原理就太复杂了,我们直接ctrl+f9出来

重建IAT表

执行完解密函数后,会根据原文件重建IAT表,UPack使用导入的2个函数LoadLibraryA和GetProcAddress,边执行边循环构建原本notepad的IAT。
UPack调试笔记
0x1013004是刚解密后还未重建IAT表时,库模块和函数的符号地址,如下图
UPack调试笔记

地址10012c4是重建IAT表后,IAT表的地址,通过函数LoadLibraryA加载dll,GetProcAddress将函数对应的地址写入0x10012c4,IAT表重建完成后如下图
UPack调试笔记

OPE

IAT表重建完成后,直接到了地址0x100739D,这个地址很熟悉,这个是最开始第三条指令压栈的一个地址,前面说这个地址很可能就是OEP的入口地址,如下图所示
UPack调试笔记

相关文章: