Board logo

标题: 菜鸟也脱未知加密壳诀窍 [打印本页]

作者: dsa3027235    时间: 2009-5-24 19:35     标题: 菜鸟也脱未知加密壳诀窍

【背景介绍】
  一个加密保护壳,用PEID未查出壳类型,《加密与解密》二版上的东西,说是因为篇幅没有贴教程,但附有脱壳要点,然而本人太菜,看不懂要点,也不知道要点怎么去操作,只得自己摸索,结果三弄两弄,竟然成功脱了,一看文件8M多,心想发了,可惜脱出来的既不是黄金也不是裸女
  【详尽步骤】(限于篇幅就不贴代码了)
  1。OD载入,选否,按F9运行,按3次SHIFT+F9(第4次就运行了!);
  2。ALT+M,在00401000 code 在这行按F2下断,按SHIFT+F9断下;
  3。然后小心而使用大胆的使用F7,F8,F4,直到来到004010CC这行;
  4。用LordPE dump出来(如果用OD dump会提示出错);
  5。关闭OD,运行未脱壳的文件,用IMPROTREC载入进程;(不关OD importrec修复时没反应);
  6。OEP处填000010CC,点IAT AUTOSEARCH, 再点 GET Imports;
  7。点 Show Invalid ,在选中的函数上点右键,点 Trace Level3(Trap Flag),等待一会;
  8。看到全部都是Valid:YES了,点Fix Dump修复脱出来的文件吧!
  【个人心得】
  1.高手们的经验是菜鸟们进步的财富;
  2.不断更新的工具是成功当然也是偷懒的捷径;
  3.其实我早该会的,只是……(我的意思是新手尽量不要花太长的不必要的时间在一些基本的简单问题上)
  【转载自原文的脱壳要点】(供深入研究者参考,我本人是没有看的)
  1、找OEP大概11个SEH调用后,再跟几步就能找到。
  2、DUMP取数据
  由于UnpackMe.exe内存映像有9M之多,因此Dump后必须将其减肥。将Dump取的境像文件最后两个区块删除(即
  偏移地址为0xd000后的数据全删)
  或直接抓取前0xD000大小的数据:PAGEIN D 400000 D000 \??\C:\dump.exe
  3、输入表
  外壳模拟Windows装载器填充IAT时,会对IAT成员加密(即Hook API),此时IAT的成员指向的是外壳代码。
  由于加入了许多垃圾代码干扰,此时用ImportREC是不能重建得到输入表的。
  所以第一步就是要得到没加密的IAT。
  方法如下:
  bpm 4062E4(记事本程序的IAT位置是4062E4)
  同时观察数据窗口DD 4062E4 变化
  或用这个断点:bpx getprocadress
  会来到如下代码处:
  001B:0040D2A9  46                  INC       ESI
  001B:0040D2AA  8A0E                MOV       CL,[ESI]
  001B:0040D2AC  0AC9                OR        CL,CL
  001B:0040D2AE  750A                JNZ       0040D2BA
  001B:0040D2B0  8A4E03              MOV       CL,[ESI+03]
  001B:0040D2B3  80F980              CMP       CL,80
  001B:0040D2B6  7402                JZ        0040D2BA
  001B:0040D2B8  EB4C                JMP       0040D306
  001B:0040D2BA  8B06                MOV       EAX,[ESI]
  001B:0040D2BC  3D00000080          CMP       EAX,80000000
  001B:0040D2C1  760B                JBE       0040D2CE
  001B:0040D2C3  25FFFFFF0F          AND       EAX,0FFFFFFF
  001B:0040D2C8  50                  PUSH      EAX
  001B:0040D2C9  83C604              ADD       ESI,04
  001B:0040D2CC  EB08                JMP       0040D2D6
  001B:0040D2CE  56                  PUSH      ESI
  001B:0040D2CF  46                  INC       ESI
  001B:0040D2D0  8A0E                MOV       CL,[ESI]
  001B:0040D2D2  84C9                TEST      CL,CL
  001B:0040D2D4  75F9                JNZ       0040D2CF
  001B:0040D2D6  FFB585040000        PUSH      DWORD PTR [EBP+00000485]
  001B:0040D2DC  FF9534060000        CALL      [EBP+00000634]
  001B:0040D2E2  8B8D89040000        MOV       ECX,[EBP+00000489]
  001B:0040D2E8  890F                MOV       [EDI],ECX              // 此行,下A命令改成mov [edi],eax
  001B:0040D2EA  C601B8              MOV       BYTE PTR [ECX],B8
  001B:0040D2ED  41                  INC       ECX
  001B:0040D2EE  8901                MOV       [ECX],EAX
  001B:0040D2F0  83C104              ADD       ECX,04
  001B:0040D2F3  66C701FFE0          MOV       WORD PTR [ECX],E0FF
  001B:0040D2F8  83C102              ADD       ECX,02
  001B:0040D2FB  898D89040000        MOV       [EBP+00000489],ECX
  001B:0040D301  83C704              ADD       EDI,04
  001B:0040D304  EBA3                JMP       0040D2A9
  在001B:0040D2E8一行,此时EAX中是getprocadress返回的函数地址,EDI指向的IAT,因此将代码改成mov [edi],eax,这样外壳会将正确
  的函数地址填充到IAT结构中。程序运行后,再用ImportREC重建输入表。
  今天无意中发现了这个东东,试了一下很简单的,适合我等新手练习练习。
  点击浏览该文件
  第一步:寻找OEP
  用IsDebug 1.4插件去掉Ollydbg的调试器标志,设置Ollydbg忽略除了“内存访问异常”之外的所有异常选项。
  F9运行,程序中断在异常处,然后按4次Shift+F9跳过异常
  003C2727    8B00            MOV EAX,DWORD PTR DS:[EAX]          //第一次异常
  003C14BC   /7C 03           JL SHORT 003C14C1                   //第二次异常
  003C2AF3    6285 F4290000   BOUND EAX,QWORD PTR SS:[EBP+29F4]   //第三次异常
  0040D46F    8700            XCHG DWORD PTR DS:[EAX],EAX         //第四次异常,够了,再按一次程序就运行了!
  这是看看堆栈的内容
  0012FF94   00000206  指针到下一个 SEH 记录
  0012FF98   0040D06E  SE 句柄             //不用说了吧,就去这里下断吧。
  0012FF9C   0040F41C  UnpackMe.0040F41C
  在0040D06E处下断,Shift+F9来到此处
  0040D06E    8B5C24 0C       MOV EBX,DWORD PTR SS:[ESP+C]
  0040D072    81AB B8000000 2>SUB DWORD PTR DS:[EBX+B8],24  //Context.eip-24,此时堆栈值0040D46F-24=0040D44B
  0040D07C    33C0            XOR EAX,EAX   //表示已修复,可以从异常处继续执行
  0040D07E    C3              RETN       //系统取Context内容,下一步将从Context.eip处执行。
  0040D072    81AB B8000000 2>SUB DWORD PTR DS:[EBX+B8],24    //减法指令
  运行到这一行,你就可以看到DS:[EBX+B8]的值为0040D46F,执行这条指令后,不就是0040D46F-24=0040D44B
  注意这里千万不能返回,因为这个RET并非是一个CALL的结束,它的作用是返回系统异常执行处理程序里,系统取堆栈里的
  Context环境结构内容,使线程继续执行。
  好了,剩下的内容大家都知道怎么做了吧。
  去往0040D44B处断,F9运行
  不用慢慢手动步过,命令行下命令
  Tc eip<40D000
  呵,停在Oep处。
  0040D44B    B8 55010000     MOV EAX,155
  0040D450    56              PUSH ESI
  0040D451    8DB5 80000000   LEA ESI,DWORD PTR SS:[EBP+80]
  0040D457    B9 CB030000     MOV ECX,3CB
  0040D45C    3006            XOR BYTE PTR DS:[ESI],AL
  0040D45E    46              INC ESI
  0040D45F  ^ E2 FB           LOOPD SHORT UnpackMe.0040D45C
  0040D461    5E              POP ESI
  0040D462  ^ E9 19FCFFFF     JMP UnpackMe.0040D080  //往上跳
  0040D080    64:8F05 0000000>POP DWORD PTR FS:[0]   //条到这里,以下全用F8带过
  0040D087    83C4 04         ADD ESP,4
  0040D08A    8DB5 50060000   LEA ESI,DWORD PTR SS:[EBP+650]
  0040D090    56              PUSH ESI
  0040D091    FF95 38060000   CALL DWORD PTR SS:[EBP+638]
  0040D097    0BC0            or EAX,EAX
  0040D099    75 07           JNZ SHORT UnpackMe.0040D0A2
  0040D09B    56              PUSH ESI
  0040D09C    FF95 3C060000   CALL DWORD PTR SS:[EBP+63C]
  0040D0A2    50              PUSH EAX
  0040D0A3    8D9D B8040000   LEA EBX,DWORD PTR SS:[EBP+4B8]
  0040D0A9    53              PUSH EBX
  0040D0AA    50              PUSH EAX
  0040D0AB    FF95 34060000   CALL DWORD PTR SS:[EBP+634]
  0040D0B1    8985 C6040000   MOV DWORD PTR SS:[EBP+4C6],EAX
  0040D0B7    58              POP EAX
  0040D0B8    50              PUSH EAX
  0040D0B9    8D9D CA040000   LEA EBX,DWORD PTR SS:[EBP+4CA]
  0040D0BF    53              PUSH EBX
  0040D0C0    50              PUSH EAX
  0040D0C1    FF95 34060000   CALL DWORD PTR SS:[EBP+634]
  0040D0C7    8985 E0040000   MOV DWORD PTR SS:[EBP+4E0],EAX
  0040D0CD    58              POP EAX
  0040D0CE    50              PUSH EAX
  0040D0CF    8D9D E4040000   LEA EBX,DWORD PTR SS:[EBP+4E4]
  0040D0D5    53              PUSH EBX
  0040D0D6    50              PUSH EAX
  0040D0D7    FF95 34060000   CALL DWORD PTR SS:[EBP+634]
  0040D0DD    8985 F0040000   MOV DWORD PTR SS:[EBP+4F0],EAX
  0040D0E3    58              POP EAX
  0040D0E4    50              PUSH EAX
  0040D0E5    8D9D F4040000   LEA EBX,DWORD PTR SS:[EBP+4F4]
  0040D0EB    53              PUSH EBX
  0040D0EC    50              PUSH EAX
  0040D0ED    FF95 34060000   CALL DWORD PTR SS:[EBP+634]
  0040D0F3    8985 FD040000   MOV DWORD PTR SS:[EBP+4FD],EAX
  0040D0F9    58              POP EAX
  0040D0FA    8D9D 11050000   LEA EBX,DWORD PTR SS:[EBP+511]
  0040D100    53              PUSH EBX
  0040D101    50              PUSH EAX
  0040D102    FF95 34060000   CALL DWORD PTR SS:[EBP+634]
  0040D108    8985 20050000   MOV DWORD PTR SS:[EBP+520],EAX
  0040D10E    8DB5 AD040000   LEA ESI,DWORD PTR SS:[EBP+4AD]
  0040D114    56              PUSH ESI
  0040D115    FF95 38060000   CALL DWORD PTR SS:[EBP+638]
  0040D11B    0BC0            or EAX,EAX
  0040D11D    75 07           JNZ SHORT UnpackMe.0040D126
  0040D11F    56              PUSH ESI
  0040D120    FF95 3C060000   CALL DWORD PTR SS:[EBP+63C]
  0040D126    8D9D 01050000   LEA EBX,DWORD PTR SS:[EBP+501]
  0040D12C    53              PUSH EBX
  0040D12D    50              PUSH EAX
  0040D12E    FF95 34060000   CALL DWORD PTR SS:[EBP+634]
  0040D134    8985 0D050000   MOV DWORD PTR SS:[EBP+50D],EAX
  0040D13A    8D9D 4C050000   LEA EBX,DWORD PTR SS:[EBP+54C]
  0040D140    53              PUSH EBX
  0040D141    FF95 C6040000   CALL DWORD PTR SS:[EBP+4C6]
  0040D147    8B85 91040000   MOV EAX,DWORD PTR SS:[EBP+491]
  0040D14D    83F8 01         CMP EAX,1
  0040D150    0F85 D7000000   JNZ UnpackMe.0040D22D    //跳了
  0040D22D    33C0            XOR EAX,EAX  //跳到这里,继续按F8带过
  0040D22F    8B8D 74050000   MOV ECX,DWORD PTR SS:[EBP+574]
  0040D235    8BB5 70050000   MOV ESI,DWORD PTR SS:[EBP+570]
  0040D23B    03B5 71040000   ADD ESI,DWORD PTR SS:[EBP+471]
  0040D241    8D4481 43       LEA EAX,DWORD PTR DS:[ECX+EAX*4+43]
  0040D245    3006            XOR BYTE PTR DS:[ESI],AL
  0040D247    D40A            AAM
  0040D249    46              INC ESI
  0040D24A  ^ E2 F5           LOOPD SHORT UnpackMe.0040D241 //循环
  0040D24C    E8 F9000000     CALL UnpackMe.0040D34A   //按F4来到这里
  0040D251    6A 04           PUSH 4
  0040D253    68 00100000     PUSH 1000
  0040D258    68 00100000     PUSH 1000
  0040D25D    6A 00           PUSH 0
  0040D25F    FF95 44060000   CALL DWORD PTR SS:[EBP+644]
  0040D265    8985 89040000   MOV DWORD PTR SS:[EBP+489],EAX
  0040D26B    8BB5 79040000   MOV ESI,DWORD PTR SS:[EBP+479]
  0040D271    03B5 71040000   ADD ESI,DWORD PTR SS:[EBP+471]
  0040D277    8B3E            MOV EDI,DWORD PTR DS:[ESI]
  0040D279    85FF            TEST EDI,EDI
  0040D27B    0F84 8B000000   JE UnpackMe.0040D30C
  0040D281    03BD 71040000   ADD EDI,DWORD PTR SS:[EBP+471]
  0040D287    83C6 05         ADD ESI,5
  0040D28A    56              PUSH ESI
  0040D28B    FF95 38060000   CALL DWORD PTR SS:[EBP+638]
  0040D291    85C0            TEST EAX,EAX
  0040D293    75 07           JNZ SHORT UnpackMe.0040D29C
  0040D295    56              PUSH ESI
  0040D296    FF95 3C060000   CALL DWORD PTR SS:[EBP+63C]
  0040D29C    8985 85040000   MOV DWORD PTR SS:[EBP+485],EAX
  0040D2A2    46              INC ESI
  0040D2A3    8A0E            MOV CL,BYTE PTR DS:[ESI]
  0040D2A5    84C9            TEST CL,CL
  0040D2A7  ^ 75 F9           JNZ SHORT UnpackMe.0040D2A2  //循环
  0040D2A9    46              INC ESI    //按F4下来
  0040D2AA    8A0E            MOV CL,BYTE PTR DS:[ESI]
  0040D2AC    0AC9            or CL,CL
  0040D2AE    75 0A           JNZ SHORT UnpackMe.0040D2BA
  0040D2B0    8A4E 03         MOV CL,BYTE PTR DS:[ESI+3]
  0040D2B3    80F9 80         CMP CL,80
  0040D2B6    74 02           JE SHORT UnpackMe.0040D2BA
  0040D2B8    EB 4C           JMP SHORT UnpackMe.0040D306
  0040D2BA    8B06            MOV EAX,DWORD PTR DS:[ESI]
  0040D2BC    3D 00000080     CMP EAX,80000000
  0040D2C1    76 0B           JBE SHORT UnpackMe.0040D2CE
  0040D2C3    25 FFFFFF0F     AND EAX,0FFFFFFF
  0040D2C8    50              PUSH EAX
  0040D2C9    83C6 04         ADD ESI,4
  0040D2CC    EB 08           JMP SHORT UnpackMe.0040D2D6
  0040D2CE    56              PUSH ESI
  0040D2CF    46              INC ESI
  0040D2D0    8A0E            MOV CL,BYTE PTR DS:[ESI]
  0040D2D2    84C9            TEST CL,CL
  0040D2D4  ^ 75 F9           JNZ SHORT UnpackMe.0040D2CF    //循环
  0040D2D6    FFB5 85040000   PUSH DWORD PTR SS:[EBP+485]   //按F4下来
  0040D2DC    FF95 34060000   CALL DWORD PTR SS:[EBP+634]
  0040D2E2    8B8D 89040000   MOV ECX,DWORD PTR SS:[EBP+489]
  0040D2E8    890F            MOV DWORD PTR DS:[EDI],ECX
  0040D2EA    C601 B8         MOV BYTE PTR DS:[ECX],0B8
  0040D2ED    41              INC ECX
  0040D2EE    8901            MOV DWORD PTR DS:[ECX],EAX
  0040D2F0    83C1 04         ADD ECX,4
  0040D2F3    66:C701 FFE0    MOV WORD PTR DS:[ECX],0E0FF
  0040D2F8    83C1 02         ADD ECX,2
  0040D2FB    898D 89040000   MOV DWORD PTR SS:[EBP+489],ECX
  0040D301    83C7 04         ADD EDI,4
  0040D304  ^ EB A3           JMP SHORT UnpackMe.0040D2A9   //向上跳,又是一个大循环,仔细观察发现0040D2B8处可
  跳出这个循环
  0040D306    46              INC ESI     //按F4下来
  0040D307  ^ E9 6BFFFFFF     JMP UnpackMe.0040D277    //继续循环,发现0040D27B处可跳出此循环
  0040D30C    6A 00           PUSH 0   //按F4下来
  0040D30E    54              PUSH ESP
  0040D30F    6A 04           PUSH 4
  0040D311    68 00100000     PUSH 1000
  0040D316    FFB5 71040000   PUSH DWORD PTR SS:[EBP+471]
  0040D31C    FF95 20050000   CALL DWORD PTR SS:[EBP+520]
  0040D322    83C4 04         ADD ESP,4
  0040D325    8B85 71040000   MOV EAX,DWORD PTR SS:[EBP+471]
  0040D32B    8B58 3C         MOV EBX,DWORD PTR DS:[EAX+3C]
  0040D32E    03D8            ADD EBX,EAX
  0040D330    83C3 16         ADD EBX,16
  0040D333    66:810B 0020    or WORD PTR DS:[EBX],2000
  0040D338    61              POPAD     //哈哈,见到阳光了
  0040D339    8B85 75040000   MOV EAX,DWORD PTR SS:[EBP+475]
  0040D33F    5D              POP EBP
  0040D340    50              PUSH EAX
  0040D341    C3              RETN    //返回004010CC
  004010CC    55              PUSH EBP    //这里就是OEP了。因为这个壳会修改PE头,只好用LordPE DUMP了
  004010CD    8BEC            MOV EBP,ESP
  004010CF    83EC 44         SUB ESP,44
  004010D2    56              PUSH ESI
  004010D3    FF15 E4634000   CALL DWORD PTR DS:[4063E4]
  004010D9    8BF0            MOV ESI,EAX
  004010DB    8A00            MOV AL,BYTE PTR DS:[EAX]
  004010DD    3C 22           CMP AL,22
  004010DF    75 1B           JNZ SHORT UnpackMe.004010FC
  004010E1    56              PUSH ESI
  004010E2    FF15 F4644000   CALL DWORD PTR DS:[4064F4]
  004010E8    8BF0            MOV ESI,EAX
  第二步:修复
  至于修复最简单的就是用ImporREC了,用追踪层次3可以全部修复指针。
  当然也可以手动修复,下断
  bp GetProcAddress
  慢慢往下跟就会发现MOV [EDI],ECX等这几行代码,此时EAX中是GetProcAddress返回地址,EDI是指向IAT,将其改为MOV
  [EDI],EAX,这样外壳就会将正确的地址填充到IAT结构中。
  脱壳后的程序过大,用FileScan优化一下就行了。




欢迎光临 【3.A.S.T】网络安全爱好者 (http://3ast.com/) Powered by Discuz! 7.2