加壳与脱壳知识点(持续更新)

加壳与脱壳知识点(持续更新)加壳与脱壳知识点1.壳的种类有几种壳分为压缩壳/加密壳/虚拟壳(1.1压缩壳)压缩壳调用压缩引引擎主要目的是对文件进行压缩减小文件大小(1.2)加密壳加密壳主要是保护软件防止被各种反跟踪技术来调试程序(1.3)虚拟壳虚拟技术应用到壳的领域,设计了一套虚拟机引擎,将原始的汇编代码转译成虚拟机指令,要理解原始的汇编代码,就必须对其虚拟机引擎进行研究,而这极大地增加了激活成功教程和逆向的难度及成本。2.常见的壳(2.1)压缩壳UPX、ASPack、PECompact(2.2)加密壳ASProte

加壳与脱壳知识点(持续更新)

QQ:1024275440,如需转载请说明出处!
加壳与脱壳知识点
1.壳的种类有几种
壳分为压缩壳/加密壳/虚拟壳
(1.1压缩壳)
压缩壳调用压缩引引擎主要目的是对文件进行压缩减小文件大小
(1.2)加密壳
加密壳主要是保护软件防止被各种反跟踪技术来调试程序
(1.3)虚拟壳
虚拟技术应用到壳的领域,设计了一套虚拟机引擎,将原始的汇编代码转译成虚拟机指令,要理解原始的汇编代码,就必须对其虚拟机引擎进行研究,而这极大地增加了激活成功教程和逆向的难度及成本。
2.常见的壳
(2.1)压缩壳
UPX、ASPack、PECompact
(2.2)加密壳
ASProtect、Armadillo
(2.3)虚拟壳
EXECryptor、Thrmida、VMProtect
3.壳加载过程
(3.1)保存入口参数
通常用pushad/popad、pushfd/popfd等指令来保存于恢复环境
(3.2)获取壳本身需要使用的API地址
外壳输入表只有GetProceAddress、GetModuleHandle、LoadLibrary这三个API函数
LoadLibrary DLL文件地址
GetModuleHandle 获取模块地址
GetProcAddress获取函数地址
(3.3)解密原程序各个区块的数据
壳一般会加密原程序文件的各个区块,在程序执行时外壳将解密这些区块数据,从而使程序能够正常运行。
(3.4)IAT初始化
IAT的填写原本是由PE装载器实现的,但由于加壳时构造了一个自建输入表,并让PE文件头目录表中的输入表指向自建的输入表,PE装载器会对自建输入表进行填写,程序的原始输入文件被变形后存储,IAT的填写会由外壳程序实现,外壳要做的就是将变形输入表的结构从头到尾扫描一遍,重新获取每一个DLL引入的所有函数地址,并将其填写在IAT中。
(3.5)重定位项的处理
EXE文件不需要重定位,一般加壳软件将直接删除该属性。
DLL文件需要重定位,壳中需要有重定位的代码。
(3.6)Hook API
壳大都在修改原程序文件的输入表后自己模仿Windows操作系统的工作流程,向输入表填充相关数据,在填充过程中,外壳可以填充Hook API代码的地址,从而间接获得程序的控制权。
(3.7)
跳转到程序原入口点(OEP)
从这时候开始壳,就把控制权还给了原程序了,一般壳在这里会有一条明显的分界线,现在越来越多的加密壳先将OEP代码段搬到外壳的地址空间里,再将这段代码清除(这种技术称为 Stolen Bytes)这样,OEP与外壳之间那条明显的分界线就消失了,脱壳难度也就增加了。
4.手动脱壳的三个步骤
(1)查找程序真正的入口点
(2)抓取内存映像文件
(3)重建PE文件
5.寻找OEP技巧
(5.1)根据跨段指令寻找OEP
当外壳程序代码处理完毕就会跳到程序本身代码处,根据跨段的转移指令可能找到真正的程序入口点。
可以利用动态调试工具(OD、XDBG等)使用内存断点寻找OEP,比如在.text节中做段断点
关键点:
这个方法的关键是待代码解压完毕堆代码段设置内存访问断点,如果在之前设置了断点,程序就会不停地对代码进行写入指令中断,解决这个问题有一个好方法,可以先在.rdata、.data等区块处设置内存访问断点,待程序中断,此时text代码段已解压完毕,再对代码段(.text区块),设置内存访问断点来到达OEP。

(5.2)根据栈平衡原理寻找OEP
加壳软件必须保证外壳初始化的现场环境(各寄存器值)与源程序的现场环境是相同的(主要是esp、ebp等重要的寄存器参数),加壳程序在初始化时保存各个寄存器的值,待外壳执行完毕恢复各寄存器的内容,最后跳转到原程序执行,通常是pushad/popad或pushfd/popfd指令对保存与恢复现现场环境。
可以使用动态调试工具在程序在pushad之后在原esp栈地址位置设置断点,在调用popad的时候将会调试软件将自动中断,将有可能在附近或直接找到OEP原入口点。
关键点:可以把整个外壳程序当成一个函数或者子函数理解,这个过程是需要遵循栈平衡原理的,当跳转到OEP时,esp的值不会改变,还有就是程序运行的开始阶段esp的值是由操作系统决定的。

(5.3)根据编译语言特点寻找OEP
各类语言编译的文件入口点都有各自的特点,同一种编译器编译的程序入口代码又很类似,都有一段启动代码,编译器在编译程序时会自动与程序连接,在完成必需的初始化工作之后,调用WinMain函数该函数执行完毕,启动代码将再次获取控制权,进行一次初始化清理工作,比如VS6.0默认有4个入口点,处理ANSI字符的GUI版本,启动函数是WinMainCRTStartup,处理ANSI字符的GUI版本mainCRTSartup、此外还有两个Unicode版本VC6的启动版本部分由GetCommandLine(W),GetModuleHandle(W),GetVersion、GetStartupInfoA(W)等函数,因此可以通过这些函数来设置断点,从而方便定位程序的OEP。
比如OllyDbg在GetVersion函数设置断点两次之后就能回到OEP的附近了。
关键点: 对常见语言的入口点比较熟悉,很容易完成脱壳修复和定位OEP等工作,
由于采用默认的启动代码对软件进行加壳保护不是很有利,一些开发人员对启动源代码进行修改,这时程序的入口点与默认完全不同。
6.抓取内存映像与反Dump技术
抓取内存映像,也称转储(Dump)是指把内存指定的映像文件读出,用文件等形式将其保存出来的过程。
Dump文件有一定技巧,在一般情况下当外壳来到OEP处时进行Dump是正确的,如果等程序真正运行起来Dump由于一些变量的初始化了,不适合进行Dump。
(6.1)Dump原理
常用的Dump软件有LordPE、PETools这类工具一般利用Module32Next来获取Dump进程的基本信息。
LordPE、ProcDump都是先根据此结构中的modBaseSize和modBaseAddr字段获取进程映像大小和基址在调用ReadProcessMemory来读取进程内的数据,如果读取成功,ProcDump会检测IMAGE_DOS_SIGNATURE和IMAGE_NT_SIGNATURE是否完整如果完整,就基本上不会对剩余的大多数字段进行检查,如果不完整会根据szExePath字段打开进程原始文件,读取文件头以取代进程文件头,LordPE则更加简单,根本不使用进程的文件头,而直接读取原始文件的文件头,在读取内存数据后,再把进程中的数据保存到磁盘文件中。
(6.2)反Dump技术
某些加壳软件会使用反Dump技术(Anti-Dump)来防止被脱壳,为了顺利脱壳必须绕过Anti-Dump。
纠正SizeOfimage,在Dump一些关键参数是通过MODULEENTRY32结构的快照获得的,因此可以在modBaseSize和ModBaseAddr字段中填入错误的值,让Dump软件无法正确读取进程中数据,一般修改modBaseAddr的值会使系统出现文件,所以只能修改modBaseSize的值。
通过修改内存属性防止Dump,如果使用VirtualProtect函数将PE文件头设置为不可读,执行dump软件到不可读区域时将会发生错误。
(6.3)绕过Anti-Dump
可以使用LoadPE的correct ImageSize功能处理Anti,原理就是打开磁盘文件,直接读取PE文件头的SizeOfImage来纠正这个错误。
(6.4)修改内存属性绕过Anti-Dump
如果壳程序使用VirtualProtect函数将PE头设置为不可读,可以使用LoadPE的dump Region功能选中进程执行dump region命令查看是否可读,如果不可读可以使用Ollydbg软件加载目标程序进行进程按Alt+M组合键打开内存映像,在该进程的PE头处单击右键,在弹出快菜单中执行Set access -> Full access命令将PE头设置为完整权限,这样在运行LordPE时就可以Dump内存映像。
7.输入表加密概括
(1)完整地保留了原输入表,外壳加载时未对IAT加密
(2)完整地保留了原输入表,当外壳装载时对IAT进行加密处理
(3)加壳时破坏了原输入表,外壳装载时未对IAT进行加密处理
(4)加壳时破坏了原输入表,装载外壳时对IAT进行了加密处理

今天的文章加壳与脱壳知识点(持续更新)分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/33880.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注