脱壳以及简单练习
脱壳以及简单练习
Muzjili脱壳以及简单练习
一 、壳概述
1、壳的概念
正常的软件开发者不对开发的软件进行保护的话,会导致开发的软件源代码很容易的被心怀不轨的人窃取到,而程序的壳便是抵抗第一过程的手段,就如自然界中的昆虫壳的作用一样,程序壳便是保护程序不被非法分子获取甚至破坏的。
2、壳的工作过程
加壳过程是用加壳程序对源程序进行压缩、加密、转换指令等操作,然后一般是在程序的开头加上一段壳程序。当加壳程序运行时,在程序开头的壳程序会对加壳程序进行解压缩、解密代码或者数据、解释执行相应代码等过程,壳程序运行完之后一般会将加壳程序恢复成源程序,加壳程序便依旧可以执行相应的功能。
3、壳的几种分类
压缩壳:UPX 、 ASPack
压缩壳主要是为了让程序文件占用更小的体积,对于程序的加密保护方面侧重性不是很强。
加密壳 : ASProtect 、Armadillo 、EXECryptor 、Themida
加密壳的功能更加侧重安全性,对于加壳后程序的体积大小并不是十分关注,它能够将程序的重要代码、数据等进行加密,甚至可以提供额外的功能,比如注册机制、使用次数、时间限制等。有的加密壳也涉及到了虚拟机保护技术。
二、脱壳技术
1、壳的加载过程
保存入口参数(pushad/popad pushfd/popfd)
获取壳本身使用的API地址
关键函数:
LoadLibraryA(W)、LoadLibraryExA(W) : 将制定的DLL文件映射进内存,返回模块的句柄
GetmoduleHandle: 获取已经映射进内存的dll文件的句柄,返回值句柄
GetProcAddress : 获取dll内制定的函数地址,返回函数地址
解密源程序的各个区块的数据
IAT的初始化
重定位项的处理(DLL文件脱壳)
HOOK API
跳转到OEP
2、脱壳三部曲
三、脱壳方法
1、单步跟踪法
我们完整运行脱壳程序,跳过循环恢复代码的片段,边调试边观察,确保程序不会略过OEP,让软件实现自动脱壳
要点:
- 跟踪过程是不修改任何代码的
- 使用F7[单步步入]、F8[单步步过]、F4[直接执行到指定位置]等功能完整的进行自脱壳的过程
- 大循环用f4跳过,尽量实现向下jmp
- 函数载入不远处的call一般选择f7步入
- 一般如果jmp到很远的地址,那极有可能就是跳到原程序入口(EOP)
练习1:UPX加壳程序
程序导入OllyDbg,我们开始单步跟踪程序
循环跳过案例:
当我们F8运行至
0x00409CA1初,我们发现程序会回跳至0x00409C90分析这段代码,发现
0x00409C98处还有一处跳转因此对于这种情况,我们就可以直接在
0x00409CA3处F4当F8指定到
0x00409D45处JMP 00409C96指令时,我们则可以点击其下一条指令,我们可以看到有跳转语句会跳转至0x00409D4A我们继续F4使得程序执行到
0x00409D4A处的POP ESI我们继续分析,分析看到
POPAD和JMP 00401000,我们已经解压成功F8执行,到达OEP
2、ESP定律法
堆栈平衡概念
我们知道在执行函数时会涉及到堆栈
对于汇编程序:在函数执行时一般要包含和恢复被执行过程修改的寄存器。
- 在开始时将寄存器入栈
- 在返回前将寄存器出栈
函数执行过程:
函数参数入栈
函数的参数按照特定的顺序(通常是从右向左的顺序)入栈,
函数调用指令执行
将返回地址(也就是跳回调用者的地址)压入栈中
将EIP跳转至函数段首
函数执行结束:
计算结果(如果有的话)在寄存器或是某个特定的内存位置中。
函数参数出栈
函数调用而压入栈的参数将会从栈中弹出。这个过程有时被称为“清理堆栈”。
返回地址出栈并跳转,回到调用者的代码中。
ESP定律原理
ESP定律的原理在于程序中堆栈平衡的合理利用。
压缩/加密壳:
- 将当前寄存器内容压栈,如使用PUSHAD
- 在解压结束后,会将之前的寄存器值出栈,如使用POPAD,
因此我们可以在这些地址设置硬件访问断点,F9运行,当程序中断时,则距离OEP就很近了
记录系统加载时的ESP值,对其设置硬件断点
- OllyDbg硬件断点快捷命令HW 内存地址
- 数据窗口区 –>转到内存地址 –>选取 –>右键 –>断点 –>硬件访问–>双字。
练习2:UPX加壳程序
(未完待续)







