手动脱壳进阶第三篇PEncrypt V4.0

ZDNet 安全频道频道 更新时间:2008-06-13 作者: 来源:SohuIT

本文关键词:dword Od Notepad

  PEncrypt简介:



  Multi Layer Encryptor for the Decryptor. SoftICE, ICEDump Detection code. Crashes the OS in case it is found in memory. Anti ICEDump’s /TRACEX command. Win9x compatible. Includes anti-debugging, anti-tracing routines



  软件后用Fi测NOTEPAD.EXE的壳为PEncrypt 4.0 Gamma / 4.0 Phi -> junkcode [重叠]



  如何分辨加密壳和压缩壳,通用特点,Od载入时有入口警告或询问是压缩程序吗?普通压缩壳Od调试时候没有异常,加密壳全部有反跟踪代码,会有许多SEH陷阱使OD调试时产生异常。



  找OEP的一般思路如下:



  先看壳是加密壳还是压缩壳,压缩壳相对来说容易些,一般是没有异常。



  外壳解压代码起始点如果是



  pushfd



  pushad



  跟踪时如果有发现



  popad



  popfd



  对应



  有些壳只有



  pushad



  和



  popad



  相对应



  附近还有



  retn



  jmp



  等指令,发生跨断跳跃一般就到了OEP处。



  当然也有其他的,如 je OEP等等,一般都是段之间的大跳转,OD的反汇编窗口里都是同一个段的内容,所以更好区别是否是段间跳转。



  找Oep时注意两点。



  1、单步往前走,不要回头。



  2、观察。注意poshad、poshfd,popad、popfd等,和外壳代码处对应,注意地址发生大的变化。单步跟踪什 么时候F8走,F7,F4步过?



  这里我说说关于F8(Step Over)和F7(Step in)的一般方法,粗跟的时候一般都是常用F8走,但是有些call是变形的Jmp,此时就需要F7代过,区别是否是变形Jmp的一个简单方法是比较call的目标地址和当前地址,如果两者离的很近,一般就是变形Jmp了,用F7走。对于Call的距离很远,可以放心用F8步过,如果你再用F7步过,只是浪费时间而已。F8步过对压缩壳用的很多,F7步过加密壳用的很多,如果用F8一不小心就跑飞(程序运行),跟踪失败。



  加密壳找Oep



  对于加密壳,我的方法一般是用OD载入,钩掉所有异常(不忽略任何异常,除了忽略在KERNEL32 中的内存访问异常打勾。有时由于异常过多可以适当忽略一些异常),运行,数着用了多少次Shift+F9程序运行,显然最后一次异常后,程序会从壳跳到OEP开始执行,这就是我们寻找OEP的一个关键,如果程序 Shift+F9后直接退出,很明显加密壳检测调试器,最简单的应付方法就是用OD插件隐藏OD。



  单步异常是防止我们一步步跟踪程序,即F8,F7,F4等,Int3中断是检测调试器用的,仅在Win9x系统中有效,2000/XP就会出现断点异常,其它的异常主要是干扰调试。这一系列的异常虽然干扰我们调试,但也给我们指明了一条通路,就是Shift+F9略过所有异常,然后找到最后一处异常,再它的恢复异常处下断点,跟踪到脱壳入口点。



  确定从所有Seh异常中走出来,如果前面有大量循环,逐段解压。



  当然你也可以用另一个好东西——Trace,在Command里来个tc eip<42b000 (42b000是当前段的起始位置,滚动条拖到最上面就能看到了,一般程序编译的基地址为400000),42b000只是例子,如果你的下模拟跟踪时机很准,确定没有Seh异常,稍等一会我们就会停在OEP处(对特别加密壳需要大量时间跟踪,因为它的循环极多,但比手动跟踪快,大部分时候是的。)详细跟踪情况可以点运行跟踪看OD跟踪记录。



  我们来实际体会一下。



  我们把Od中的选项-调试选项-异常选项卡中



  除了忽略在KERNEL32 中的内存访问异常打勾,其余一个勾都不打,请检查自己的Od设置。



  用OD载入程序后。



  Od提示程序加壳,选不继续分析。



  00401000 > FC CLD 停在这里。



  00401001 FC CLD



  00401002 FC CLD



  00401003 90 NOP



  00401004 - E9 BDBA0000 JMP NOTEPAD.0040CAC6



  00401009 - E3 D5 JECXZ SHORT NOTEPAD.00400FE0



  0040100B 04 4F ADD AL,4F



  0040100D - 74 A4 JE SHORT NOTEPAD.00400FB3



  ..................................................................



  F9运行。



  Od提示内存异常,Shift+F9继续运行。



  0040CC9E 8618 XCHG BYTE PTR DS:[EAX],BL



  0040CCA0 ^ EB FA JMP SHORT NOTEPAD.0040CC9C



  0040CCA2 4A DEC EDX



  0040CCA3 75 6E JNZ SHORT NOTEPAD.0040CD13



  Od提示调试的程序无法处理异常,按Shift+F9程序退出。



  0040CC9E 8618 XCHG BYTE PTR DS:[EAX],BL



  0040CCA0 ^ EB FA JMP SHORT NOTEPAD.0040CC9C



  很明显加密壳检测出OD调试器,最简单的应付方法就是用OD插件隐藏OD。



  用插件隐藏Od后。



  我们Shift+F9忽略第一次异常到了这里。



  单步异常,再次Shift+F9程序就运行了。停,看堆栈吧。



  0040CCD2 4B DEC EBX



  0040CCD3 6F OUTS DX,DWORD PTR ES:[EDI] ; I/O 命令



  0040CCD4 6368 69 ARPL DWORD PTR DS:[EAX+69],EBP



  堆栈内容。



  0012FFBC 0012FFE0 指针到下一个 SEH 记录



  0012FFC0 0040CCD7 SE 句柄 呵,这里表示Od的最后一个异常处理出口就是0040CCD7,会在0040CCD7处的代码处继续正常运行。



  0012FFC4 77E67903 返回到 KERNEL32.77E67903



  哪我们就Ctrl+G,填入0040CCD7,回车,F2下断点,Shift+F9中断在这里。



  顺利运行到这里,再没有Seh陷阱,可以单步跟踪去Oep处了。



  0040CCD7 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4]



  0040CCDB 8B00 MOV EAX,DWORD PTR DS:[EAX]



  0040CCDD 3D 04000080 CMP EAX,80000004



  0040CCE2 74 06 JE SHORT NOTEPAD.0040CCEA



  0040CCE4 4B DEC EBX



  0040CCE5 65:72 61 JB SHORT NOTEPAD.0040CD49 ; 多余的前缀



  0040CCE8 6C INS BYTE PTR ES:[EDI],DX ; I/O 命令



  0040CCE9 61 POPAD



  0040CCEA EB 02 JMP SHORT NOTEPAD.0040CCEE



  ................................................................



  去Oep出的过程我们先想象一下。



  0040CCD7 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4]



  0040CCDB 8B00 MOV EAX,DWORD PTR DS:[EAX]



  0040CCDD 3D 04000080 CMP EAX,80000004



  0040CCE2 74 06 JE SHORT NOTEPAD.0040CCEA



  0040CCE4 4B DEC EBX



  0040CCE5 65:72 61 JB SHORT NOTEPAD.0040CD49 ; 多余的前缀



  0040CCE8 6C INS BYTE PTR ES:[EDI],DX ; I/O 命令



  0040CCE9 61 POPAD



  0040CCEA EB 02 JMP SHORT NOTEPAD.0040CCEE



  ...........................................................



  经过中间过程。



  Call XXXXX



  循环..............



  popad



  jmp XXXXXX



  或



  ret



  入口点,代码跨段。



  那我们滚动条向上面看,当前段起始位置是40c000



  跨段入口点的地址必须是小于40c000



  那我们可以下条件断点了。



  命令行下命令



  tc eip<40c000



  呵呵,我们熟悉的记事本入口,关键它已经跨段,换个程序通样处理,我们已经学会方法。



  004010CC 55 PUSH EBP 跨段来到这里,我们再这里用Od的Dump插件直接脱壳。



  004010CD 8BEC MOV EBP,ESP



  004010CF 83EC 44 SUB ESP,44



  004010D2 56 PUSH ESI



  004010D3 FF15 E4634000 CALL DWORD PTR DS:[<&KERNEL32.GetCommand>; KERNEL32.GetCommandLineA



  004010D9 8BF0 MOV ESI,EAX



  004010DB 8A00 MOV AL,BYTE PTR DS:[EAX]



  004010DD 3C 22 CMP AL,22



  004010DF 75 1B JNZ SHORT NOTEPAD.004010FC



  004010E1 56 PUSH ESI



  004010E2 FF15 F4644000 CALL DWORD PTR DS:[<&USER32.CharNextA>] ; USER32.CharNextA



  脱壳后发现程序不能运行,这时需要用Imprec修复引入函数表(Import Table)



  在Oep处填10cc,点IT自动搜索,然后点获输入信息,看到输入表全部有效,点修复抓取文件按钮,选择Dump的文件,修复它,运行后仍然不能运行。



  呵,我们还有Lordpe重建PE的功能,用上吧。



  运行Lordpe重建Pe,选择Imprec修复的文件,修复后正常运行。

安全频道 dword 最新报道

安全频道 Notepad 最新报道

[an error occurred while processing this directive]