【笔记】恶意代码分析实战-18(加壳与脱壳)

加壳与脱壳

加壳可执行文件的两个主要目的是缩减程序的大小阻碍对加壳程序的探测与分析。虽然加壳器的种类繁多,但是它们都遵循相似的模式:将一个可执行文件转换创建一个新的可执行文件,被转换的可执行文件在这个新的可执行文件中作为数据存储,另外新的可执行文件还包括一个供操作系统调用的脱壳存根(stub)

基础概念

多数加壳器用压缩算法压缩原始文件,加壳器既可以打包整个可执行文件,包括所有的数据和资源节,也可以打包代码节和数据节。

【1】脱壳存根stub

操作系统加载被加壳程序的stub,stub加载原始程序。可执行程序入口点指向stub。原始程序通常存储在加壳程序的一个或多个附加的节中。
stub功能:脱壳原始程序。
stub执行步骤:

  1. 将原始程序脱壳到内存中。
  2. 解析原始可执行程序的所有导入函数。
  3. 将可执行程序转移到原始的程序入口点(oep)。

【2】解析导入函数表

未加壳程序中有一个节段告诉加载器需要导入哪些函数,同时还有一个节存储需要导入的函数名字和地址。

  1. stub最常使用LoadLibrary和GetProcAddress函数,在stub脱壳出原始可执行文件后,stub调用LoadLibrary导入每个库,GetProcAddress获取每个函数的内存地址。
  2. 保持原始导入函数表的完整,让windows加载器能够加载所有dll和导入函数,缺乏隐蔽性、压缩性也不理想。
  3. 为原始导入表的每个DLL保留一个导入函数,分析时仍能够看到原始可执行文件所有的导入库。stub不需要在加载导入库,但是仍需要解析大部分导入函数。
  4. 不导入任何函数。加壳程序自己从库中找到所有需要的函数或者先找到LoadLibrary和GetProcAddress函数,然后定位其他的库。

【3】尾部跳转

尾部跳转详细
5. jmp
6. ret/call
7. NtContiue/ZwContinue

	加壳程序可以用熵值计算的技术探测,加壳程序熵值高,未加壳熵值低。

【4】脱壳方法

  1. 自动静态脱壳:不运行可执行文件,仅仅针对某个壳,并且对那些用来阻碍分析的壳无效。
  2. 自动动态脱壳:自动的动态脱壳程序运行可执行文件、并让脱壳存根脱出原始的可执行文件。一旦原始的可执行文件被脱壳,它将被写入硬盘,然后脱壳程序重构原始的导入表。自动的脱壳程序必须确定脱壳存根的结束位置,原始可执行文件的开始位置,但这非常困难。当脱壳程序不能正确识别脱壳存根的结束位置时,脱壳就会生败。
  3. 手动脱壳

【5】 手动脱壳

(1)查找oep
  1. 可以通过检测从一个节到另一个节的跳转检测oep,或者通过call没有返回定位oep。
  2. 查找尾部跳转指令(一串无效字节指令前的最后一条有效指令,填充这些字节为了保证节的字节对齐)。
  3. 通过esp定律(必由于OllyDbg的界面不允许在栈窗口中设置断点,所以需要在内存转储窗口中查看栈的地址,然后在窗口中设置断点。)。
  4. 在GetProcAddress下断点,再向后找oep。
  5. 查找OEP的最后一个策略是使用OllyDbg的Run Trace选项。Run Trace提供一些额外的断点选项,这使得你能够在较大范围的内存地址上设置断点。例如,很多加壳程序都会留下原始文件的.text节。通常,硬盘上的.text节没有任何东西,但是这个节被保留在PE文件头部,使得加载器能够在内存中为它创建空间。OEP总是位于原始文件的.text节中,通常它是这个节中第一条被调用的指令。Run Trace选项可以让你设置这样一个断点,无论何时执行.text节中的指令,此断点都能被触发。一旦断点被触发,也就找到了OEP。
(2)手动修复导入表

[6]不完全脱壳情况下分析

由于不能完全修复导入表和PE头部,从而导致一个脱壳应用程序无法正常运行。这种情况下,将程序转储到硬盘,使用IDA Pro分析特定的某个节,首先导航一个内存地址,然后将这个段记为代码。也可以在程序上运行Strings,可能会发现导入函数和其他一些导入信息。

[6]加壳dll

DLL的导出表指向导出函数地址,如果DLL被加壳,那么导出函数也会被加壳。加壳程序必须考虑到这一点,确保DLL正常运行。

脱壳DLL与脱壳EXE没有明显的不同。关键要记住与可执行文件一样,DLL也有一个OEP。所有DLL都有一个叫作DllMain的函数,当DLL加载时它会被调用。DLL中的OEP是D11Main原始函数的开始地址,加壳DLL列出的开始地址是脱壳存根中的一个地址,它位于DllMain中而不是主方法中。OllyDbg可以加载DLL,并且OllyDbg有一个叫作LoadDll.exe的工具,利用这个工具可以加载或者调试DLL。问题在于DllMain方法在OllyDbg中断它运行之前被调用。中断发生时,脱壳存根已经运行,这将很难找到OEP。

为了解决这个问题,打开PE文件,定位到IMAGE_FILE_HEADER节的特征标志域,如果IMAGE_FILE_HEADER节Ox2000处的比特位为1,则表示这个PE文件是DLL。如果这个标志位为0,则这个文件被解释为一个可执行文件。OllyDbg像打开EXE文件一样打开这个程序,然后采用我们本章讨论的任何一种策略。当你找到OEP后,改回比特的标志,以确保这个程序被当作DLL对待。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值