宝峰科技

 找回密码
 注册

QQ登录

只需一步,快速开始

智能终端设备维修查询系统注册会员邮箱认证须知!
查看: 2521|回复: 0

UltraProtect 1.x 的脱壳与修复

[复制链接]

该用户从未签到

破解狼人 发表于 2010-10-31 21:01:14 | 显示全部楼层 |阅读模式

欢迎您注册加入!这里有您将更精采!

您需要 登录 才可以下载或查看,没有账号?注册

x
本帖最后由 破解狼人 于 2010-10-31 21:03 编辑

UltraProtect 1.x 的脱壳与修复 - 雪狐提醒簿 V3.0
软件名称:雪狐提醒簿 V3.0
软件大小:4644KB
软件语言:简体中文
软件类别:国产软件/免费版/闹铃时钟
运行环境:Win9x/Me/NT/2000/XP
调试环境:Win2000, Ollydbg1.10, LordPE, ImportREC 1.6.2, PEid v0.93
文章作者:blackeyes
作者声明:初学Crack,只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!


1. Dump文件,寻找OEP

首先用PEiD v0.93:
UltraProtect 1.x -> RISCO Software Inc.

打开OllyDbg,载入 RemindBook.exe
  1. 009A6000 >  60              PUSHAD                                   ; 壳入口
  2. 009A6001    EB 01           JMP SHORT RemindBo.009A6004
  3. 009A6003    7B 66           JPO SHORT RemindBo.009A606B
  4. 009A6005    BD A98966C1     MOV EBP,C16689A9
复制代码
按F9运行,有 INT3, 停在009B799F
  1. 009B799B    64:8920         MOV DWORD PTR FS:[EAX],ESP
  2. 009B799E    CC              INT3
  3. 009B799F    90              NOP                                      ; 停在这
  4. 009B79A0    64:67:8F06 0000 POP DWORD PTR FS:[0]
  5. 009B79A6    83C4 04         ADD ESP,4
复制代码
按1次Shift+F9, 程序运行

Ctrl+F2 重来, CODE段下f2断点, F9运行, Shift+F9 通过INT3, 停在 OEP
  1. 00729280 >  55              PUSH EBP                                 ; 程序 OEP
  2. 00729281    8BEC            MOV EBP,ESP
  3. 00729283    B9 05000000     MOV ECX,5
  4. 00729288    6A 00           PUSH 0
  5. 0072928A    6A 00           PUSH 0
复制代码
F7 单步 跟一下, 很快找到IAT

IAT:  0074F26C-0074FD6B
size: 0B00

这时打开 ImportREC, 选 Process RemindBook.exe
填上下列信息,
    OEP:  329280
    RVA:  0034F26C, Size:0B00
按 Get Imports, 很多无效的, 直接用 ImportREC 修复不了,
随便选一个, 右键==>Disassemble/HexView
  1. 009A6010    68 8DF3FB5A     PUSH 5AFBF38D
  2. 009A6015    813424 D8A5032D XOR DWORD PTR SS:[ESP],2D03A5D8
  3. 009A601C    C3              RETN
复制代码
这几行等于
  1. jmp far 77F85655,     // 5AFBF38D XOR 2D03A5D8 = 77F85655
复制代码
变形的跳转.

从 009A6010 到 009A67FB, 全是这样, ImportREC 不能处理,
要将它们变成 jmp xxxx,


Ctrl+F2 重来, 到 OEP 后, 在CODE段找一段空白地方, 写上一段代码修复
  1. 00729F00    60              PUSHAD
  2. 00729F01    BF 10609A00     MOV EDI,RemindBo.009A6010                ; 起始地址
  3. 00729F06    B9 EC070000     MOV ECX,7EC                              ; Size
  4. 00729F0B    33C0            XOR EAX,EAX
  5. 00729F0D    B0 68           MOV AL,68                                ; 先找 68
  6. 00729F0F    F2:AE           REPNE SCAS BYTE PTR ES:[EDI]
  7. 00729F11    83F9 00         CMP ECX,0
  8. 00729F14    74 2C           JE SHORT RemindBo.00729F42
  9. 00729F16    8B1F            MOV EBX,DWORD PTR DS:[EDI]               ; push XXXX
  10. 00729F18    8B47 04         MOV EAX,DWORD PTR DS:[EDI+4]
  11. 00729F1B    25 FFFFFF00     AND EAX,0FFFFFF
  12. 00729F20    3D 81342400     CMP EAX,243481                           ; 再找 813424
  13. 00729F25  ^ 75 E4           JNZ SHORT RemindBo.00729F0B
  14. 00729F27    8B57 07         MOV EDX,DWORD PTR DS:[EDI+7]             ; xor [esp], YYYY
  15. 00729F2A    33DA            XOR EBX,EDX
  16. 00729F2C    8A47 0B         MOV AL,BYTE PTR DS:[EDI+B]
  17. 00729F2F    3C C3           CMP AL,0C3                               ; 是 C3 吗?, RETN
  18. 00729F31  ^ 75 D8           JNZ SHORT RemindBo.00729F0B
  19. 00729F33    C647 FF E9      MOV BYTE PTR DS:[EDI-1],0E9              ; 修改成 JMP FAR ZZZZ
  20. 00729F37    83EB 04         SUB EBX,4
  21. 00729F3A    2BDF            SUB EBX,EDI
  22. 00729F3C    891F            MOV DWORD PTR DS:[EDI],EBX
  23. 00729F3E  ^ EB CB           JMP SHORT RemindBo.00729F0B
  24. 00729F40    90              NOP
  25. 00729F41    90              NOP
  26. 00729F42    61              POPAD
  27. 00729F43    90              NOP
复制代码
上面代码的Binary Format, 在OLLYDBG 中, 可在CPU的数据窗直接用 Binary Copy/Binary Paste, 挺方便的.
  1. 60 BF 10 60 9A 00 B9 EC 07 00 00 33 C0 B0 68 F2 AE 83 F9 00 74 2C 8B 1F 8B 47 04 25 FF FF FF 00
  2. 3D 81 34 24 00 75 E4 8B 57 07 33 DA 8A 47 0B 3C C3 75 D8 C6 47 FF E9 83 EB 04 2B DF 89 1F EB CB
  3. 90 90 61 90 00 00 00 00 00 00 00 00 00 00 00 00
复制代码
写完代码后, 让这段代码运行一遍, 再回到OEP, 用OllyDump 插件 Dump

这时打开ImportREC, 再进行IAT修复, 用Level 1后, 只有3个不能修复, 并且指向壳中
  1. 0  0034F330  ?  0000  009A6280
  2. 0  0034F844  ?  0000  009B4E31
  3. 0  0034F878  ?  0000  009B4E4B
复制代码
2. Debug, 修复IAT

Ctrl+F2 重来, 到 OEP 后, 直接转到 009A6280/009B4E31, 然后 F7 单步跟踪


先跟 009B4E31
  1. 009B4E31    837C24 04 FF             CMP DWORD PTR SS:[ESP+4],-1
  2. 009B4E36    74 13                    JE SHORT RemindBo.009B4E4B
  3. 009B4E38    90                       NOP
  4. 009B4E39    90                       NOP
  5. 009B4E3A    90                       NOP
  6. 009B4E3B    90                       NOP
  7. 009B4E3C    55                       PUSH EBP
  8. 009B4E3D    E8 BE120000              CALL RemindBo.009B6100                   ; EBP = 005A5000
  9. 009B4E42    8BC5                     MOV EAX,EBP
  10. 009B4E44    5D                       POP EBP
  11. 009B4E45  - FFA0 C4FD4000            JMP DWORD PTR DS:[EAX+40FDC4]            ; user32.RegisterHotKey
复制代码
所以 009B4E31 实际上就是 user32.RegisterHotKey,

再跟009A6280, 实际上与009B4E4B一样了
  1. 009A6280   /E9 C6EB0000              JMP RemindBo.009B4E4B
复制代码
从现在起, 下面有很多的花指令, 以及很多的垃圾指令, 来干扰跟踪, 而且其中最主要的 CODE 还是
加密的, 总是先解密, 然后执行, 接着又加密回去, 下面只将有用的指令列出:
  1. 009B4E4B    60                       PUSHAD
  2. 009B4E4C    FC                       CLD
  3. 009B4E4D    78 03                    JS SHORT RemindBo.009B4E52
  4. 009B4E4F    79 01                    JNS SHORT RemindBo.009B4E52
  5. ...

  6. 009B4F13    68 F64F9B00              PUSH RemindBo.009B4FF6                   ; 解密的起始地址

  7. 009B4F1F    5B                       POP EBX                                  ; RemindBo.009B4FF6

  8. 009B4F31    BF 535ED47F              MOV EDI,7FD45E53                         ; 解密的 Key

  9. 009B4F40    B9 691549E2              MOV ECX,E2491569
  10. 009B4F45    03EF                     ADD EBP,EDI
  11. 009B4F47    81C1 D6EAB61D            ADD ECX,1DB6EAD6                         ; ECX = 3F, 解密的长度, DWORD

  12. 009B4F56    8B03                     MOV EAX,DWORD PTR DS:[EBX]               ; 读出加密的CODE, 一个 DWORD

  13. 009B4F5D    33C7                     XOR EAX,EDI                              ; 变换

  14. 009B4F6D    C1C0 11                  ROL EAX,11                               ; 变换

  15. 009B4F76    2B43 04                  SUB EAX,DWORD PTR DS:[EBX+4]             ; 变换

  16. 009B4F91    8903                     MOV DWORD PTR DS:[EBX],EAX               ; 写回解密后的CODE, 一个 DWORD

  17. 009B4FA5    81C7 DBF7E8FD            ADD EDI,FDE8F7DB                         ; Key变换

  18. 009B4FDA    83E9 01                  SUB ECX,1
  19. 009B4FDD  ^ 0F85 73FFFFFF            JNZ RemindBo.009B4F56                    ; 循环
  20. ...
复制代码
下面是解密后的CODE, 没有花指令, 没有垃圾指令, 看起来舒服多了
  1. 009B4FF6    61                       POPAD
  2. 009B4FF7    55                       PUSH EBP
  3. 009B4FF8    E8 03110000              CALL RemindBo.009B6100
  4. 009B4FFD    8BC5                     MOV EAX,EBP                              ; EAX = RemindBo.005A5000
  5. 009B4FFF    5D                       POP EBP
  6. 009B5000    837C24 04 FF             CMP DWORD PTR SS:[ESP+4],-1
  7. 009B5005    74 25                    JE SHORT RemindBo.009B502C
  8. 009B5007   |90                       NOP
  9. 009B5008   |90                       NOP
  10. 009B5009   |90                       NOP
  11. 009B500A   |90                       NOP
  12. 009B500B   |8B98 2C854100            MOV EBX,DWORD PTR DS:[EAX+41852C]        ; user32.MessageBoxA
复制代码
到这已经得到了API, 可以修复IAT 了

再跟一跟这段代码
  1. 009B5011    803B CC                  CMP BYTE PTR DS:[EBX],0CC                ; MessageBoxA 上有断点吗?
  2. 009B5014    0F84 DE000000            JE RemindBo.009B50F8                     ; 有就跳, 最后会到005A5000
  3. 009B501A    807B 01 CC               CMP BYTE PTR DS:[EBX+1],0CC              ; MessageBoxA+1 上有断点吗?
  4. 009B501E    0F84 D4000000            JE RemindBo.009B50F8                     ; 有就跳, 最后会到005A5000
  5. 009B5024    8BC3                     MOV EAX,EBX                              ; EAX <== API Address
  6. 009B5026    60                       PUSHAD
  7. 009B5027    E9 CC000000              JMP RemindBo.009B50F8
  8. ...
复制代码
如果跟踪原程序, 假如在MessageBoxA, 或者MessageBoxA+1上下断点, 壳会检测到的!!


下面这段CODE 就是把 009B4FF6-009B50F1 再加密回去
  1. 009B50F8    60                       PUSHAD
  2. 009B50F9    E8 00000000              CALL RemindBo.009B50FE
  3. 009B50FE    5E                       POP ESI
  4. 009B50FF    83EE 06                  SUB ESI,6
  5. 009B5102    B9 02010000              MOV ECX,102
  6. 009B5107    29CE                     SUB ESI,ECX
  7. 009B5109    BA 5D6540FE              MOV EDX,FE40655D
  8. 009B510E    C1E9 02                  SHR ECX,2
  9. 009B5111    83E9 02                  SUB ECX,2
  10. 009B5114    83F9 00                  CMP ECX,0
  11. 009B5117    7C 1A                    JL SHORT RemindBo.009B5133
  12. 009B5119    8B048E                   MOV EAX,DWORD PTR DS:[ESI+ECX*4]
  13. 009B511C    8B5C8E 04                MOV EBX,DWORD PTR DS:[ESI+ECX*4+4]
  14. 009B5120    03C3                     ADD EAX,EBX
  15. 009B5122    C1C8 11                  ROR EAX,11
  16. 009B5125    33C2                     XOR EAX,EDX
  17. 009B5127    81EA DBF7E8FD            SUB EDX,FDE8F7DB
  18. 009B512D    89048E                   MOV DWORD PTR DS:[ESI+ECX*4],EAX
  19. 009B5130    49                       DEC ECX
  20. 009B5131  ^ EB E1                    JMP SHORT RemindBo.009B5114
  21. 009B5133    61                       POPAD

  22. 009B5134    61                       POPAD                                    ; 对应009B5026 的PUSHAD
  23. 009B5135    837C24 04 FF             CMP DWORD PTR SS:[ESP+4],-1
  24. 009B513A    74 06                    JE SHORT RemindBo.009B5142
  25. 009B513C    90                       NOP
  26. 009B513D    90                       NOP
  27. 009B513E    90                       NOP
  28. 009B513F    90                       NOP
  29. 009B5140  - FFE0                     JMP EAX                                  ; user32.MessageBoxA
  30. 009B5142    C2 1000                  RETN 10
复制代码
从 009B5140 跳到API 中执行.

跟踪结果:
  1. 0  0034F330  ?  0000  009A6280      // user32.MessageBoxA
  2. 0  0034F844  ?  0000  009B4E31      // user32.RegisterHotKey
  3. 0  0034F878  ?  0000  009B4E4B      // user32.MessageBoxA
复制代码
3. 脱壳后的再修复

脱壳, IAT修复后,再运行, 还是有错

用 OLLYDBG 载入dumped_.exe

Ctrl+F2 重来, 在壳的CODE段下f2断点, F9运行, 断在下面, 说明脱壳后, CODE 与壳还有联系.

下面的CODE, 要用F7跟踪, 有很多的花指令, 很多的垃圾指令, 来干扰跟踪, 而且其中主要的 CODE 还是
加密的, 总是先解密, 然后执行, 接着又加密回去,与上面的MessageBoxA 那段CODE很象,

下面只将有用的指令列出, 花指令/垃圾指令 都略过.
  1. 009A702E    60                       PUSHAD
  2. 009A702F    F9                       STC
  3. 009A7030    87C8                     XCHG EAX,ECX
  4. ...
  5. 009A70D5    BB D9719A00              MOV EBX,RemindBo.009A71D9                ; 解密的起始地址
  6. ...
  7. 009A70F1    BE B0E08A2A              MOV ESI,2A8AE0B0
  8. 009A70F6    C1EA C4                  SHR EDX,0C4                              ; Shift constant out of range 1..31
  9. 009A70F9    81C6 073A95D0            ADD ESI,D0953A07                         ; ESI = FB201AB7

  10. 009A710F    BF 39CECA88              MOV EDI,88CACE39
  11. 009A7114    8BC6                     MOV EAX,ESI
  12. 009A7116    81F7 12CECA88            XOR EDI,88CACE12                         ; EDI = 002B, 解密的长度, DWORD

  13. 009A712E    8B2B                     MOV EBP,DWORD PTR DS:[EBX]               ; 读出加密的 DWORD
  14. ...
  15. 009A7140    03EE                     ADD EBP,ESI                              ; 变换
  16. ...
  17. 009A7155    C1C5 10                  ROL EBP,10                               ; 变换
  18. ...
  19. 009A7166    036B 04                  ADD EBP,DWORD PTR DS:[EBX+4]             ; 变换
  20. ...
  21. 009A7179    892B                     MOV DWORD PTR DS:[EBX],EBP               ; 写回解密后的DWORD
  22. ...
  23. 009A7189    81F6 3D309808            XOR ESI,898303D
  24. ...
  25. 009A71A7    81EB FCFFFFFF            SUB EBX,-4
  26. ...
  27. 009A71C3    83EF 01                  SUB EDI,1
  28. 009A71C6  ^ 0F85 62FFFFFF            JNZ RemindBo.009A712E                    ; 循环
  29. 009A71CC   /7E 03                    JLE SHORT RemindBo.009A71D1
  30. 009A71CE   |7F 01                    JG SHORT RemindBo.009A71D1

  31. 009A71D1   /E9 03000000              JMP RemindBo.009A71D9
复制代码
从009A71D9到009A7284为解密的CODE
  1. 009A71D9    E8 22EF0000              CALL RemindBo.009B6100                    ; 壳用来重定位的一个地址 EBP=005A5000
  2. 009A71DE    8B4424 20                MOV EAX,DWORD PTR SS:[ESP+20]             ; 返回地址 404FB0 ==> EAX
  3. 009A71E2    33C9                     XOR ECX,ECX                               ; ECX = 0, index
  4. 009A71E4    8B9C8D 812E4000          MOV EBX,DWORD PTR SS:[EBP+ECX*4+402E81]   ; Offset 保存在从009A7E81开始的地址
  5. 009A71EB    039D 46F84000            ADD EBX,DWORD PTR SS:[EBP+40F846]         ; 加上 Module Base 00400000
  6. 009A71F1    3BC3                     CMP EAX,EBX                               ; 与返回地址比较
  7. 009A71F3    74 07                    JE SHORT RemindBo.009A71FC                ; 相等吗?
  8. 009A71F5    90                       NOP
  9. 009A71F6    90                       NOP
  10. 009A71F7    90                       NOP
  11. 009A71F8    90                       NOP
  12. 009A71F9    41                       INC ECX                                   ; index 加 1
  13. 009A71FA  ^ EB E8                    JMP SHORT RemindBo.009A71E4               ; 循环

  14. 009A71FC    8DB5 615D4000            LEA ESI,DWORD PTR SS:[EBP+405D61]         ; ESI=009AAD61, 被抽掉的 Code 保存的

  15. 起始地址
  16. 009A7202    B8 0A000000              MOV EAX,0A                                ; 每块被抽掉的 Code 保存为 0x0a bytes
  17. 009A7207    F7E1                     MUL ECX                                   ; index
  18. 009A7209    03F0                     ADD ESI,EAX                               ; 对应于返回地址的 被抽Code的保存起始,
复制代码
源地址
009A720B    8DBD 07184000            LEA EDI,DWORD PTR SS:[EBP+401807]         ; EDI = 009A6807, 目的地址, 共用的,

与index无关
009A7211    0FB6840D C9224000        MOVZX EAX,BYTE PTR SS:[EBP+ECX+4022C9]    ; 从地址009A72C9开始记录各处CALL到壳

中的次数
  1. 009A7219    FEC0                     INC AL                                    ; 次数加 1
  2. 009A721B    88840D C9224000          MOV BYTE PTR SS:[EBP+ECX+4022C9],AL       ; 保存次数
  3. 009A7222    3C 20                    CMP AL,20                                 ; 已经 0x20 次了吗?
  4. 009A7224    75 13                    JNZ SHORT RemindBo.009A7239               ; 不够 0x20 次, 跳到009A7239
  5. 009A7226    90                       NOP
  6. 009A7227    90                       NOP
  7. 009A7228    90                       NOP
  8. 009A7229    90                       NOP

  9. 009A722A    8BBD 4AF84000            MOV EDI,DWORD PTR SS:[EBP+40F84A]         ; 如果已经0x20 次, 目的地址从

  10. [009B484A]中取出
  11.                                                                                ; 为00134938
  12. 009A7230    B8 0A000000              MOV EAX,0A
  13. 009A7235    F7E1                     MUL ECX
  14. 009A7237    03F8                     ADD EDI,EAX                               ; 再加上偏移量, 0x0a * index, 与

  15. index相关, 不重叠
  16. 009A7239    8A9D 1E204000            MOV BL,BYTE PTR SS:[EBP+40201E]           ; SS:[009A701E]=BA, 解密的Key
  17. 009A723F    B9 0A000000              MOV ECX,0A                                ; 0x0a bytes
  18. 009A7244    AC                       LODS BYTE PTR DS:[ESI]                    ; 从源地址取一byte
  19. 009A7245    32C3                     XOR AL,BL                                 ; 变换
  20. 009A7247    AA                       STOS BYTE PTR ES:[EDI]                    ; 保存到目的地址
  21. 009A7248  ^ E2 FA                    LOOPD SHORT RemindBo.009A7244             ; 循环 0x0a 次
  22. 009A724A    83EF 0A                  SUB EDI,0A                                ; 目的地址
  23. 009A724D    57                       PUSH EDI                                  ; 目的地址入栈
  24. 009A724E    8DB5 07184000            LEA ESI,DWORD PTR SS:[EBP+401807]         ; ESI = 009A6807, 共用的目的地址
  25. 009A7254    33F7                     XOR ESI,EDI
  26. 009A7256    74 19                    JE SHORT RemindBo.009A7271                ; 目的地址 是 009A6807? 是就跳
  27. 009A7258    90                       NOP
  28. 009A7259    90                       NOP
  29. 009A725A    90                       NOP
  30. 009A725B    90                       NOP
复制代码
下面的几行, 把程序中的 CALL 009A702E, 改成 CALL ( 00134938 + 0x0a * index )
可能主要是为了提高速度, 因为 CALL 到 009A702E, 要执行这么多的指令, 而实际上的指令只有 0x0a byte
  1. 009A725C    8B7424 24                MOV ESI,DWORD PTR SS:[ESP+24]
  2. 009A7260    83EE 04                  SUB ESI,4
  3. 009A7263    AD                       LODS DWORD PTR DS:[ESI]
  4. 009A7264    81EF 2E204000            SUB EDI,RemindBo.0040202E
  5. 009A726A    2BFD                     SUB EDI,EBP
  6. 009A726C    03C7                     ADD EAX,EDI
  7. 009A726E    8946 FC                  MOV DWORD PTR DS:[ESI-4],EAX

  8. 009A7271    5F                       POP EDI
  9. 009A7272    57                       PUSH EDI
  10. 009A7273    33C9                     XOR ECX,ECX
  11. 009A7275    83F9 08                  CMP ECX,8                                 ; 循环 8 次, 将目的地址挪到 PUSHAD 进

  12. 栈的8个DWORD 下面
  13. 009A7278    74 0E                    JE SHORT RemindBo.009A7288
  14. 009A727A    90                       NOP
  15. 009A727B    90                       NOP
  16. 009A727C    90                       NOP
  17. 009A727D    90                       NOP
  18. 009A727E    8B448C 04                MOV EAX,DWORD PTR SS:[ESP+ECX*4+4]
  19. 009A7282    89048C                   MOV DWORD PTR SS:[ESP+ECX*4],EAX
  20. 009A7285    41                       INC ECX
  21. 009A7286  ^ EB ED                    JMP SHORT RemindBo.009A7275
  22. 009A7288    893C8C                   MOV DWORD PTR SS:[ESP+ECX*4],EDI

  23. 009A728B    60                       PUSHAD                                   ; 重新加密 009A71D9-009A7284
  24. 009A728C    E8 00000000              CALL RemindBo.009A7291
  25. 009A7291    5E                       POP ESI
  26. 009A7292    83EE 06                  SUB ESI,6
  27. 009A7295    B9 B2000000              MOV ECX,0B2
  28. 009A729A    29CE                     SUB ESI,ECX
  29. 009A729C    BA B71A20FB              MOV EDX,FB201AB7
  30. 009A72A1    C1E9 02                  SHR ECX,2
  31. 009A72A4    83E9 02                  SUB ECX,2
  32. 009A72A7    83F9 00                  CMP ECX,0
  33. 009A72AA    7C 1A                    JL SHORT RemindBo.009A72C6
  34. 009A72AC    8B048E                   MOV EAX,DWORD PTR DS:[ESI+ECX*4]
  35. 009A72AF    8B5C8E 04                MOV EBX,DWORD PTR DS:[ESI+ECX*4+4]
  36. 009A72B3    2BC3                     SUB EAX,EBX
  37. 009A72B5    C1C8 10                  ROR EAX,10
  38. 009A72B8    2BC2                     SUB EAX,EDX
  39. 009A72BA    81F2 3D309808            XOR EDX,898303D
  40. 009A72C0    89048E                   MOV DWORD PTR DS:[ESI+ECX*4],EAX
  41. 009A72C3    49                       DEC ECX
  42. 009A72C4  ^ EB E1                    JMP SHORT RemindBo.009A72A7
  43. 009A72C6    61                       POPAD                                   ; 加密结束

  44. 009A72C7    61                       POPAD
  45. 009A72C8    C3                       RETN                                    ; 返回 目的地址
复制代码
目的地址, 0x0a bytes, 这就是程序 CALL 009A702E 真正要执行的 CODE
  1. 009A6807    33FD                     XOR EDI,EBP                             ; 干扰指令
  2. 009A6809    33DB                     XOR EBX,EBX                             ; 从原程序中抽掉的指令
  3. 009A680B    8B40 04                  MOV EAX,DWORD PTR DS:[EAX+4]            ; 从原程序中抽掉的指令
  4. 009A680E    33FD                     XOR EDI,EBP                             ; 干扰指令
  5. 009A6810    C3                       RETN                                    ; 返回 00404FB0
复制代码
其中有两条干扰指令, 真正起作用的指令只有两条, 为 5 BYTES

壳实际上是把真正的原程序中的
  1.       33DB                     XOR EBX,EBX
  2.           8B40 04                  MOV EAX,DWORD PTR DS:[EAX+4]
复制代码
抽掉, 再加上两条干扰指令, 然后加密保存起来, 再把原程序中被抽掉的地方改成
            CALL 009A702E
从 009A702E 开始的CODE, 就是根据返回地址, 找到保存的加密code, 解密, 然后执行.

看看从原程序中都抽掉了多少CODE

009A72C9 - 009A7E80, 每块为 1 BYTE,   保存次数
009A7E81 - 009AAD60, 每块为 1 DWORD,  保存Offset
009AAD61 - 009B2290, 每块为 10 BYTES, 保存加密的CODE

总共是0BB8块, 用10进制是3000, 够变态的吧?!

而且每块被抽的 5 BYTES, 不仅加密, 还加上两条干扰指令, 搞的不能很简单的自动还原, 脱了壳,
还得带着壳的一些CODE 运行, 够狠的!


先说脱壳后的问题:

脱壳后的程序, 如果运行到 009A722A, 从[009B484A]中取出的地址00134938,

已经不可以使用了, 这时候如果把解密的CODE 放到其中, 不出问题才怪!

[009B484A]的地址00134938, 应该是壳在解码程序, 运行到OEP之前分配的内存, 一脱壳就把这脱没了.


再说一说如何修复吧:

用OLLYDBG 载入dumped_.exe, F2 在009A702E 下断, F9 运行, 停在009A702E

再 F2 在009A728B 下断, F9 运行, 停在009A728B,

这时壳009A71D9-009A7284的CODE 已解密,

然后将下面的三个地方改掉,
  1. 009A702E    60                       PUSHAD
  2. 009A702F    E9 A5010000              JMP RemindBo.009A71D9                  ; 直接 跳过垃圾指令与壳解密的指令

  3. 009A7222    3C 20                    CMP AL,20
  4. 009A7224   /EB 13                    JMP SHORT RemindBo.009A7239            ; 总是使用共用的目的地址

  5. 009A728B   /EB 3A                    JMP SHORT RemindBo.009A72C7            ; 直接 跳过壳加密指令
复制代码
最后将 009A702E - 009A6810 的区域DUMP出来, 再用16进制编辑器, 覆盖 dumped_.exe 的相应地方,

然后运行, 一切正常.
您需要登录后才可以回帖 登录 | 注册

本版积分规则

免责声明

本站中所有被研究的素材与信息全部来源于互联网,版权争议与本站无关。本站所发布的任何软件编程开发或软件的逆向分析文章、逆向分析视频、补丁、注册机和注册信息,仅限用于学习和研究软件安全的目的。全体用户必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。学习编程开发技术或逆向分析技术是为了更好的完善软件可能存在的不安全因素,提升软件安全意识。所以您如果喜欢某程序,请购买注册正版软件,获得正版优质服务!不得将上述内容私自传播、销售或者用于商业用途!否则,一切后果请用户自负!

QQ|Archiver|手机版|小黑屋|联系我们|宝峰科技 ( 滇公网安备 53050202000040号 | 滇ICP备09007156号-2 )

Copyright © 2001-2023 Discuz! Team. GMT+8, 2024-12-22 21:53 , File On Powered by Discuz! X3.49

快速回复 返回顶部 返回列表