Nattevak 发表于 2021-12-20 11:41

脱壳之aspack压缩壳

本帖最后由 Nattevak 于 2021-12-21 21:22 编辑

壳代码的基本流程
       ① 保存寄存器环境
       ② 加载一些必要的API
       ③ 解密代码和数据
       ④ 修复重定位
       ⑤ 填充IAT
       ⑥ 恢复寄存器环境

一、ESP定律脱壳
一般再执行Shell部分代码时,会先保存上下文环境,使用push指令(pushad/pushfd),执行Shell部分代码之后,再使用pop指令(popad/popfd)恢复环境,使堆栈平衡,故使用ESP定律进行简单脱壳。
(00.aspack.exe为源程序,ESP_1.exe为Dump文件,ESP_1_.exe为修复后文件)

1.使用OD加载程序,发现pushad指令,判断程序已加壳


2.按下F8单步步过,使得程序走到CALL的位置,然后对ESP下断点,再将程序运行起来



3.程序断下来的地方即为pop的地方


注:smile1110大佬让把OD的自动分析关掉


4.F8单步步过,找到原始OEP


5.在原始OEP处,右键菜单,选择用OllyDump脱壳调试进程


6.点击获取EIP作为OEP按钮,再点击脱壳按钮将文件转存到磁盘中


7.不要关闭OD!使用导入表修复工具(ImpREC)对导入表进行修复


8.选择正在脱壳的进程,不要关闭OD!


9.修改OEP,并自动查找IAT,获取IAT信息后,获取输入表,再转储到文件,选择之前在OD中dump出的文件进行修复




10.使用010Editor关闭随机机制,保存文件


11.完成此次简单脱壳


二、单步跟踪脱壳
当我们单步跟踪时,第一个遇到的函数是GetModuleHandleA,调用此函数获取的信息是kernel32的基地址


继续寻找下一个函数调用GetProcAddress,有了GetModuleHandleA+GetProcAddress两个函数,kernel32模块中的所有函数都可以获取并调用


此处出现了VirtualAlloc函数,此函数一般与解压解密代码有一定的关联


又调用了VirtualAlloc函数,查看内部调用发现很繁琐,先分析参数


分析参数发现这4个参数与我们想要找的解压代码函数类似
有申请的内存地址、代码段大小,步过分析缓冲区,第二个参数中放的就是解压代码


继续向下分析,发现这一段代码在寻找E8、E9,然后修复E8、E9后面的值,也就是说整个代码段CALL和JMP都会被修复


观察修复后的值和未修复的值,发现修复后的值是原先的代码,而未修复的值是经过转换的,这个值看起来是为了迎合压缩算法而进行的转换


经过循环代码进行了解压,并修正了代码,继续向下分析,可以看到这里将解压的代码拷贝到了原始代码段的代码


拷贝完成后,申请的内存就没有用了,也确实在下面发现了释放内存的函数


单步发现此段代码在进行循环解压代码、数据等各区段


继续跟踪发现,代码访问了重定位的区段,分析后发现是在重定位代码


其中这一行代码是清除重定位信息的,正是有了这行代码,我们在脱壳之后才导致随机基址无法支持,所以在脱壳时,我们应该将这一行代码NOP掉


继续跟踪后,发现了GetModuleHandleA函数的调用,而GetModuleHandleA->LoadLibraryA->GetProcAddress三个函数连在一起,比较容易能猜出代码功能,从获取模块基址到加载模块,再到获取函数地址,一般情况下修复IAT才会有这样一组操作


继续分析找到了填充IAT的地方


此处下断点可以看到IAT函数调用都恢复


继续跟踪,最后就是修改各区段的内存属性,填充原始OEP,跳转到原始OEP


在跟踪过程中,我们遇到了重定位相关的代码,并发现有对重定位表清除的操作


在内存中,大片以3开头的word数据,一般都是基址重定位信息,基址的RVA是16000


在清除重定位信息的地方下断点,观察寄存器的值和寄存器指向的内容


可以看出此处在清除重定位表中的数据,将其NOP,此处内容上文已经提到


基址重定位表的RVA为16000,大小为0xC74



将dump出的程序,使用LordPE对数据目录表中基址重定位项进行修改,程序就可以支持随机基址了




脱壳三步法
       1. 寻找原始OEP
       2. dump内存到文件
       3. 修复文件

脱壳三步法-寻找OEP技巧
1. 堆栈平衡法(ESP定律)
       壳代码就像一个函数,进入时会开辟堆栈、保存寄存器环境,退出时会恢复堆栈、恢复
寄存器。所以应该是堆栈平衡的,那我们可以在壳代码操作了堆栈后对堆栈设置访问或
写入断点,然后运行程序,当断点命中的时候,应该就是退出壳代码的时候。在其附近
单步几次,应该就能到达程序的原始OEP。
2. 特征定位法
       在我们熟悉的程序中,我们可以使用特征来定位程序原始OEP。特征有几种:
       ① 二进制特征
            比如release版的VS2013是:
            oep入口特征:E8????????E9
            第一个CALL内的特征:5657BF4EE640BBBE0000FFFF3BC7
            注意:搜索特征应该在程序解密之后再搜索,一般让程序跑起来,在程序代码段开始处
            搜索,使用Ctrl+B搜索二进制
       ② API特征
            比如release版的VS2013的第一个API调用是:
            GetSystemTimeAsFileTime
            比如vc6.0的第一个API调用是:
            GetVersion
            比如Delphi程序第一个API调用是:
            GetModuleHandleA
       ③编译器特征
       IAT调用不同的编译器生成的调用机器码是不一样
       vs -》 call -》 FF15 xx xx xx xx
       delphi -> jmp -》 FF25 xx xx xx xx
3. 单步跟踪法
       这种方法一般使用在练习分析壳时,如二。{:301_1008:}

Nattevak 发表于 2021-12-21 19:56

Anneliese 发表于 2021-12-21 10:48
萌新想问下如何判断当前位置是原始OEP

三个方法
堆栈平衡法(ESP定律)
特征定位法
单步跟踪法

zouhuangfa 发表于 2021-12-20 12:34

使用010Editor关闭随机机制是什么原理呢,是否所有软件都是这样关闭?

cd1234 发表于 2021-12-20 12:12

也许,这就是大佬吧

侃遍天下无二人 发表于 2021-12-20 12:13

这是在脱upx壳吗

Nattevak 发表于 2021-12-20 12:40

zouhuangfa 发表于 2021-12-20 12:34
使用010Editor关闭随机机制是什么原理呢,是否所有软件都是这样关闭?

就是将程序DLL特征值中的随机基址位置0的操作,也可以选择在loadPE中勾选重定位已分离,具体可以参考我的 一个JMP完成WinRAR去广告 文末有贴出方法

CXC303 发表于 2021-12-20 13:06

收藏备用

smile1110 发表于 2021-12-20 13:34

@Nattevak在4寻找oep的过程中,右键菜单中把od的自动分析关闭

bestwars 发表于 2021-12-20 14:06

收藏学习了感谢分享

lianxing11 发表于 2021-12-20 14:30

收藏了,以后看一下

Nattevak 发表于 2021-12-20 14:52

smile1110 发表于 2021-12-20 13:34
@Nattevak在4寻找oep的过程中,右键菜单中把od的自动分析关闭

好的大佬
自动分析后面会影响程序吗{:301_985:}
页: [1] 2 3
查看完整版本: 脱壳之aspack压缩壳