飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 3902|回复: 4

[07版] ASPROTECT 2.x 脱壳系列(1-3)及找OEP篇

[复制链接]
  • TA的每日心情
    开心
    2018-1-9 11:05
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2007-4-5 08:49:21 | 显示全部楼层 |阅读模式
    标 题: ASPROTECT 2.x 脱壳系列(一)
    发帖人:loveboom
    时 间: 2005-10-05 20:36
    原文链接:http://bbs.pediy.com/showthread.php?threadid=17373
    详细信息:


    ASPROTECT 2.x 脱壳系列(一)

    【目    标】:DVD Fab Gold 2.9.4.2
    【工    具】:Olydbg1.1(diy版)、LORDPE、ImportREC1.6F
    【任    务】:简单的脱壳
    【操作平台】:Windows XP sp2
    【作    者】: LOVEBOOM[DFCG][FCG][US]
    【相关链接】: 自己搜索下
    【简要说明】: 时间在不断的减少,人越靠近死亡的边缘.人在死亡的边缘线上挣扎.寻求人间仅有的希望,骤觉得到了,又已失去了:-(.再虚幻的网络都要回到现实,但愿大家的现实比虚幻过的更充实.
      ASPROTECT比起以前的版本可算是进步不少,脱壳难度大了不少,回头看看自己,感觉太失败了,别人进步了这么多,自己却还在原地踏步走:-(

    【详细过程】:
      想脱这个壳的话,建议对他的历史版本有所了解,那样对看起文章来不会那么吃力.asprotect 2.x惯用的伎俩:2.x版本anti-debug方面没有什么新变化,很多人说这是这个壳的失败之外,我倒觉得说其是失败之处,倒不如说是作者别有用心:-).代码混淆处理方面做了很大功夫,变形处理和1.23可以说基本不是一个层次了,新版不再是只抽程序入口代码,程序入口代码那一个段基本上都抽光了,其它地方也是抽的很利害.输入表也处理的很难修复.我这次挑的目标是没有抽入口代码的程序.所以相对简单些.
    用OD载入目标,去除调试标志.打开内存异常项,通过N个异常后到程序的入口:

    00ADAF43    64:8921         MOV     DWORD PTR FS:[ECX], ESP
    00ADAF46    C601 A6         MOV     BYTE PTR DS:[ECX], 0A6           ; 最后一次异常
    00ADAF49    5B              POP     EBX                              ; 00B4AC90
    .......
    00ADB09B    E8 807AFEFF     CALL    00AC2B20
    00ADB0A0    E8 73CAFFFF     CALL    00AD7B18                         ; 直接在这里下断然后直接这里f2断点
    00ADB0A5    83C4 2C         ADD     ESP, 2C
    00ADB0A8    5D              POP     EBP                              ; 00B4AC90

    最后一个异常发生时,在00adb0a0处下f2断点,然后shift+f9,断下后f7进去,进去之后CTRL+F9执行到RETURN
    00D20000    68 1F1C0627     PUSH    27061C1F                         ; 进到这里
    00D20005    66:81C0 96FC    ADD     AX, 0FC96
    .......
    00D2011C   /0F85 0F000000   JNZ     00D20131
    00D20122   |B0 6A           MOV     AL, 6A
    00D20124   |E9 3E000000     JMP     00D20167                         ; f4运行到这里
    00D20129   |40              INC     EAX
    ......
    00D20192    2BC3            SUB     EAX, EBX
    00D20194    5C              POP     ESP                              ; DVDFabGo.00400000
    00D20195  - FFE0            JMP     EAX                              ; 这里跳去OEP
    00D20197    40              INC     EAX


    当然如果你只是想直接到
    oep的话,最后一个异常发生后直接在CODE段下f2断点,再shift+f9就可以了:

    0047572E    55              PUSH    EBP                              ; 程序OEP
    0047572F    8BEC            MOV     EBP, ESP
    00475731    6A FF           PUSH    -1
    00475733    68 80F14700     PUSH    0047F180
    .....
    到了OEP后,我们先定位下IAT,观察后发现相关的API函数并没有什么加密处理,IAT:47A000 SIZE:BC4.


    api没有什么特别处理,并不表示容易的,在程序里随便找一下就会看到call api到壳里去了。

    00475832    E8 C9A78C00     CALL    00D40000

    搜索一下发现很多地方都改成这样子了,一个一个去改??,我以前是试过一个一个去改。但那样效率太低了,且容易出错。跟过aspr 2.x的应该知道壳运行时会改地址的,因此在475832处下写入断点,运行中断:
    00AE6265    8B45 F4         MOV     EAX, DWORD PTR SS:[EBP-C]
    00AE6268    8B40 3C         MOV     EAX, DWORD PTR DS:[EAX+3C]
    00AE626B    8B55 FC         MOV     EDX, DWORD PTR SS:[EBP-4]        ; 传递正确的API到EDX中
    00AE626E    E8 D1130000     CALL    00AE7644                         ; 因是壳会检测相关代码,进去这里面后有地方不会被检测的
    --------------------进入第一层----------------------------
      00AE7644    55              PUSH    EBP
      00AE7645    8BEC            MOV     EBP, ESP
      00AE7647    83C4 E4         ADD     ESP, -1C
      00AE764A    53              PUSH    EBX
      00AE764B    56              PUSH    ESI
      00AE764C    57              PUSH    EDI
      00AE764D    894D F4         MOV     DWORD PTR SS:[EBP-C], ECX
      00AE7650    8955 F8         MOV     DWORD PTR SS:[EBP-8], EDX        ; kernel32.GetModuleHandleA
      00AE7653    8945 FC         MOV     DWORD PTR SS:[EBP-4], EAX
      00AE7656    33C0            XOR     EAX, EAX
      00AE7658    8945 F0         MOV     DWORD PTR SS:[EBP-10], EAX
      00AE765B    B8 00070000     MOV     EAX, 700                         ; 这里还有代码检测的,再次进入
      00AE7660    E8 DFAEFDFF     CALL    00AC2544
      00AE7665    8945 E4         MOV     DWORD PTR SS:[EBP-1C], EAX
      ----------------------------------进入第二层------------------------------------------
        00AC2544    85C0            TEST    EAX, EAX
        00AC2546    74 0A           JE      SHORT 00AC2552                   ; 经跟踪发现这里的条件判断在这个程序里是不会跳转的
        00AC2548    FF15 18A0AE00   CALL    DWORD PTR DS:[AEA018]            ; 这里的代码也不会被检测到,因此我把这里做为我们的突破点
        00AC254E    09C0            OR      EAX, EAX
        00AC2550    74 01           JE      SHORT 00AC2553
        00AC2552    C3              RETN
        00AC2553    B0 01           MOV     AL, 1
      ---------------------------------------------------------------------------------------
    --------------------END----------------------------
    00AE6273    8945 FC         MOV     DWORD PTR SS:[EBP-4], EAX
    00AE6276    8B45 E0         MOV     EAX, DWORD PTR SS:[EBP-20]
    00AE6279    8B00            MOV     EAX, DWORD PTR DS:[EAX]
    00AE627B    E8 D0E6FFFF     CALL    00AE4950
    00AE6280    8BD0            MOV     EDX, EAX
    00AE6282    0255 DF         ADD     DL, BYTE PTR SS:[EBP-21]
    00AE6285    8B4D FC         MOV     ECX, DWORD PTR SS:[EBP-4]
    00AE6288    8B45 F4         MOV     EAX, DWORD PTR SS:[EBP-C]
    00AE628B    E8 80040000     CALL    00AE6710
    00AE6290    8945 FC         MOV     DWORD PTR SS:[EBP-4], EAX
    00AE6293    8B45 F4         MOV     EAX, DWORD PTR SS:[EBP-C]
    00AE6296    8B40 24         MOV     EAX, DWORD PTR DS:[EAX+24]
    00AE6299    8B55 F4         MOV     EDX, DWORD PTR SS:[EBP-C]
    00AE629C    0382 E0000000   ADD     EAX, DWORD PTR DS:[EDX+E0]
    00AE62A2    0145 1C         ADD     DWORD PTR SS:[EBP+1C], EAX
    00AE62A5    8B45 FC         MOV     EAX, DWORD PTR SS:[EBP-4]
    00AE62A8    2B45 1C         SUB     EAX, DWORD PTR SS:[EBP+1C]       ; DVDFabGo.00475832
    00AE62AB    83E8 05         SUB     EAX, 5
    00AE62AE    8B55 1C         MOV     EDX, DWORD PTR SS:[EBP+1C]       ; DVDFabGo.00475832
    00AE62B1    42              INC     EDX                              ; DVDFabGo.00475833
    00AE62B2    8902            MOV     DWORD PTR DS:[EDX], EAX          ; 这里断下,写入call的地址
    00AE62B4    EB 01           JMP     SHORT 00AE62B7
    00AE62B6    E8 8B45F883     CALL    84A6A846

    找到突破点后,再找这段代码的出口,tc command is:POPFD,条件符合后中断:

    00D500B0    9D              POPFD                                    ; 条件中断在这里
    00D500B1    5C              POP     ESP
    00D500B2    F3:             PREFIX REP:                              ; Superfluous prefix
    00D500B3    EB 02           JMP     SHORT 00D500B7
    00D500B5    CD 20           INT     20
    00D500B7    FF6424 FC       JMP     DWORD PTR SS:[ESP-4]             ; 这里跳去执行原程序的call api,注意这里已经处理过了,不再是简单的call api了
    00D500BB    F3:             PREFIX REP:                              ; Superfluous prefix
    00D500BC    EB 02           JMP     SHORT 00D500C0
    00D500BE    CD 20           INT     20

    再找一个空闲的地方写上修复代码,考虑到代码可能会长一点,选择代码后的空白地址479bc0修复代码起始地址。
    总结一下大概为:

    OEP:        47572E
    IAT:        47A000
    SIZE:        BC4

    Patch点一:      00AC2548
    Patch点二:      00D500B7(这个地址每次运行都会改变的)
    Patch起始地址:      479BC0

    现在唯一没有解决的问题就是,都有哪些地方改成了CALL    00D40000,当然,可以通过比较死的方法,直接去搜索,我觉得那样可能没有那么准确,所以我选择了直接记录的方式。
    重新加载,载入后,两次GetModuleHandleA中断后,让壳的代码完全解出来:
    00AF25C2   /75 08           JNZ     SHORT 00AF25CC
    00AF25C4   |B8 01000000     MOV     EAX, 1
    00AF25C9   |C2 0C00         RETN    0C
    00AF25CC   \68 A08FAE00     PUSH    0AE8FA0                          ; 壳的执行代码执行点
    00AF25D1    C3              RETN
    ......
    00AE8FA0    55              PUSH    EBP                              ; 壳的代码
    00AE8FA1    8BEC            MOV     EBP, ESP
    00AE8FA3    83C4 B4         ADD     ESP, -4C

    壳的代码完全解出来后,搜索命令

    MOV [EBP],EAX
    PUSH 0A

    找到相关位置后下硬件执行断点。执行后中断:

    00AE653F    8945 00         MOV     DWORD PTR SS:[EBP], EAX          ; 找到这里,ebp-1就正好是call d40000的地址
    00AE6542    6A 0A           PUSH    0A
    00AE6544    E8 63C4FEFF     CALL    00AD29AC
    00AE6549    8BC8            MOV     ECX, EAX

    现在要要找的就是存放这些地址的空间,ASPR加壳的程序,最后一个段是空的,我们可以利用下,我选择514100开始保存相关数据:
    514100保存将要保存相关call地址的实际地址,514108保存call [address]中的address,514100开始保存相关call 00d40000的实际地址。好了,现在写上一段代码来保存相关数据:
    00AE653F   /EB 43           JMP     SHORT 00AE6584                   ; 跳去执行我们的代码
    00AE6541   |90              NOP
    00AE6542   |6A 0A           PUSH    0A
    00AE6544   |E8 63C4FEFF     CALL    00AD29AC
    00AE6549   |8BC8            MOV     ECX, EAX
    00AE654B   |038B E4000000   ADD     ECX, DWORD PTR DS:[EBX+E4]
    00AE6551   |8BD6            MOV     EDX, ESI
    00AE6553   |8BC3            MOV     EAX, EBX
    00AE6555   |E8 9EE5FFFF     CALL    00AE4AF8
    00AE655A   |FF0C24          DEC     DWORD PTR SS:[ESP]
    00AE655D   |03B3 E4000000   ADD     ESI, DWORD PTR DS:[EBX+E4]
    00AE6563   |833C24 00       CMP     DWORD PTR SS:[ESP], 0
    00AE6567  ^|0F87 55FEFFFF   JA      00AE63C2
    00AE656D   |53              PUSH    EBX                              ; 写好代码后直接在这里F2断点
    00AE656E   |E8 5D000000     CALL    00AE65D0
    00AE6573   |0183 EC000000   ADD     DWORD PTR DS:[EBX+EC], EAX
    00AE6579   |B0 01           MOV     AL, 1
    00AE657B   |83C4 24         ADD     ESP, 24
    00AE657E   |5D              POP     EBP                              ; DVDFabGo.004033AD
    00AE657F   |5F              POP     EDI
    00AE6580   |5E              POP     ESI
    00AE6581   |5B              POP     EBX
    00AE6582   |C3              RETN
    00AE6583   |90              NOP
    00AE6584   \53              PUSH    EBX                              ; 保存堆栈
    00AE6585    51              PUSH    ECX
    00AE6586    B9 00415100     MOV     ECX, 514100                      ; 起始地址
    00AE658B    8339 00         CMP     DWORD PTR DS:[ECX], 0
    00AE658E    75 06           JNZ     SHORT 00AE6596
    00AE6590    C701 10415100   MOV     DWORD PTR DS:[ECX], 514110       ; 如果是第一次则写入相关数据
    00AE6596    8B19            MOV     EBX, DWORD PTR DS:[ECX]
    00AE6598    4D              DEC     EBP                              ; DVDFabGo.004033AD
    00AE6599    892B            MOV     DWORD PTR DS:[EBX], EBP          ; 保存call的地址
    00AE659B    83C3 04         ADD     EBX, 4
    00AE659E    8919            MOV     DWORD PTR DS:[ECX], EBX          ; 保存下次保存数据的地址
    00AE65A0    45              INC     EBP                              ; DVDFabGo.004033AD
    00AE65A1    59              POP     ECX
    00AE65A2    5B              POP     EBX
    00AE65A3    8945 00         MOV     DWORD PTR SS:[EBP], EAX          ; 执行壳原来的代码
    00AE65A6  ^ EB 9A           JMP     SHORT 00AE6542

    写完代码后直接在00AE656D下F2断点,断下后,还原patch代码,514100处的数据保存起来(主要是方便一次操作不成功,第二次不用再写代码获取相关数据,当然其实完全可以一次操作成功的)。

    获取到了相关的数据后,运行到OEP处,然后就可以直接写上完整的修复代码了,在前面总结的479BC0处写上修复代码:


    00479BC0   .  60            PUSHAD                                   ;  保护堆栈,直接定位到这里
    00479BC1   .  B9 10415100   MOV     ECX, 00514110                    ;  把call 00d40000改成call ds:[addr]
    00479BC6   >  8B19          MOV     EBX, DWORD PTR DS:[ECX]          ;  取出相关地址
    00479BC8   .  83FB 00       CMP     EBX, 0                           ;  判断是否处理完了
    00479BCB   .  74 15         JE      SHORT 00479BE2
    00479BCD   .- FFE3          JMP     EBX                              ;  执行原call
    00479BCF   .  8B15 08415100 MOV     EDX, DWORD PTR DS:[514108]       ;  [514108]就是保存call [address] 中的address
    00479BD5   .  66:C703 FF15  MOV     WORD PTR DS:[EBX], 15FF          ;  修复成call ds:[address]
    00479BDA   .  8953 02       MOV     DWORD PTR DS:[EBX+2], EDX        ;  填上实际的address
    00479BDD   .  83C1 04       ADD     ECX, 4
    00479BE0   .^ EB E4         JMP     SHORT 00479BC6
    00479BE2   >  33C0          XOR     EAX, EAX                         ;  这里开始修复call [addr]中实际上是jmp [addr]的部分
    00479BE4   .  B0 E8         MOV     AL, 0E8
    00479BE6   .  BF 00104000   MOV     EDI, <ModuleEntryPoint>          ;  代码段的起始地址
    00479BEB   .  B9 B89B0600   MOV     ECX, 69BB8                       ;  大小
    00479BF0   >  F2:AE         REPNE   SCAS BYTE PTR ES:[EDI]
    00479BF2   .  83F9 00       CMP     ECX, 0
    00479BF5   .  74 3C         JE      SHORT 00479C33                   ;  如果处理完则结束过程
    00479BF7   .  8B1F          MOV     EBX, DWORD PTR DS:[EDI]
    00479BF9   .  8D5C3B 04     LEA     EBX, DWORD PTR DS:[EBX+EDI+4]
    00479BFD   .  81FB 00104000 CMP     EBX, <ModuleEntryPoint>
    00479C03   .^ 72 EB         JB      SHORT 00479BF0
    00479C05   .  81FB BA9B4700 CMP     EBX, 00479BBA
    00479C0B   .^ 77 E3         JA      SHORT 00479BF0
    00479C0D   .  66:813B FF15  CMP     WORD PTR DS:[EBX], 15FF
    00479C12   .^ 75 DC         JNZ     SHORT 00479BF0
    00479C14   .  817B 02 00A04>CMP     DWORD PTR DS:[EBX+2], 0047A000   ;  再次准确的判断是否为真的要修改的代码
    00479C1B   .^ 72 D3         JB      SHORT 00479BF0
    00479C1D   .  817B 02 C0AB4>CMP     DWORD PTR DS:[EBX+2], 0047ABC0
    00479C24   .^ 77 CA         JA      SHORT 00479BF0
    00479C26   .  66:C703 FF25  MOV     WORD PTR DS:[EBX], 25FF
    00479C2B   .  83C7 04       ADD     EDI, 4
    00479C2E   .  83E9 04       SUB     ECX, 4
    00479C31   .^ EB BD         JMP     SHORT 00479BF0
    00479C33   >  61            POPAD                                    ;  还原现场
    00479C34   .  00            DB      00
    00479C35   .  00            DB      00                               ;  因为我是操作边写的,这里留多点空间方便修改代码
    00479C36   .  00            DB      00
    00479C37   .  00            DB      00
    00479C38   .  00            DB      00
    00479C39   .  00            DB      00
    00479C3A   .  00            DB      00
    00479C3B   .  00            DB      00
    00479C3C   .  00            DB      00
    00479C3D   .  00            DB      00
    00479C3E   .  00            DB      00
    00479C3F   .  00            DB      00
    00479C40   .  00            DB      00
    00479C41   .  00            DB      00
    00479C42   .  00            DB      00
    00479C43   .  00            DB      00
    00479C44   .  00            DB      00
    00479C45   .  00            DB      00
    00479C46   .  00            DB      00
    00479C47   .  00            DB      00
    00479C48   .  00            DB      00
    00479C49   .  00            DB      00
    00479C4A   .  00            DB      00
    00479C4B   .  00            DB      00
    00479C4C   .  00            DB      00
    00479C4D   .  00            DB      00
    00479C4E   .  00            DB      00
    00479C4F   .  00            DB      00
    00479C50   .  00            DB      00
    00479C51   .  00            DB      00
    00479C52   .  00            DB      00
    00479C53   .  00            DB      00
    00479C54   .  00            DB      00
    00479C55   .  00            DB      00
    00479C56   .  00            DB      00
    00479C57   .  00            DB      00
    00479C58   .  00            DB      00
    00479C59   .  00            DB      00
    00479C5A   .  00            DB      00
    00479C5B   .  00            DB      00
    00479C5C   .  00            DB      00
    00479C5D   .  00            DB      00
    00479C5E   .  00            DB      00
    00479C5F   .  00            DB      00
    00479C60   .  00            DB      00
    00479C61   .  00            DB      00
    00479C62   .  00            DB      00
    00479C63   .  00            DB      00
    00479C64   .  00            DB      00
    00479C65   .  00            DB      00
    00479C66   .  00            DB      00
    00479C67   .  00            DB      00
    00479C68   .  00            DB      00
    00479C69   .  00            DB      00
    00479C6A   .  00            DB      00
    00479C6B   .  00            DB      00
    00479C6C   .  00            DB      00
    00479C6D   .  00            DB      00
    00479C6E   .  00            DB      00
    00479C6F   .  00            DB      00
    00479C70      789C4700      DD      DVDFabGo.00479C78
    00479C74      00            DB      00
    00479C75      90            NOP
    00479C76      90            NOP
    00479C77      90            NOP
    00479C78   .  60            PUSHAD
    00479C79   .  8BC2          MOV     EAX, EDX
    00479C7B   .  B9 C80B0000   MOV     ECX, 0BC8                        ;  iat大小
    00479C80   .  BF 00A04700   MOV     EDI, 0047A000                    ;  iat起始地址
    00479C85   .  F2:AF         REPNE   SCAS DWORD PTR ES:[EDI]
    00479C87   .  83EF 04       SUB     EDI, 4
    00479C8A   .  893D 08415100 MOV     DWORD PTR DS:[514108], EDI       ;  保存地址
    00479C90   .  61            POPAD
    00479C91   .  FF15 18A0AE00 CALL    DWORD PTR DS:[AEA018]            ;  执行程序的原代码
    00479C97   .  C3            RETN
    00479C98      90            NOP

    再把这里的代码改一下:
    00AC2548    FF15 709C4700   CALL    DWORD PTR DS:[479C70]            ; DVDFabGo.00479C78

    写到这里,完了吗?当然没有了,认真看就会发前的的jmp ebx那里是个call,直接这样操作就回不来了,这也就是为什么前面还用一个patch2,
    直接到00D500B7看看去,看看现在在哪里了。
    00D500E1    9D              POPFD
    00D500E2    5C              POP     ESP                              ; 00A80000
    00D500E3  - FF6424 FC       JMP     DWORD PTR SS:[ESP-4]             ; 这次在这里了
    00D500E7    CC              INT3

    直接在D500E3处下硬件断点,没错了,我想在这里的时候把返回地址改成跳去00479BCF,直接修改代码?当然不行了,壳会检测的,找到地方去除检测?我偷懒处理下,用脚本就很简单的搞定了:
    //fixed aspr 2.x
    var addr


    start:
      run

    l1:
      cmp eip,00D500E3
      jne l2
      mov addr,esp
      sub addr,4
      mov [addr],479bcf
      jmp start

    l2:
      ret

    写好后,记得在479c33处下个f2断,再运行,否则运行脚本后会"飞"的。

    脚本运行完毕,赶快dump完,修复收工吧(做完后要记得把修复代码和保存的数据给清除掉哦,做事要有头有尾才行的).嗯,脱壳完毕,当然这里实际上还是有点小问题的,问题解决方法请参考我的第二篇ASPR文章


    标 题: 答复
    发帖人:wenglingok
    时 间: 2005-10-08 11:01
    详细信息:



    引用:
    --------------------------------------------------------------------------------
    00AE6265    8B45 F4         MOV     EAX, DWORD PTR SS:[EBP-C]
    00AE6268    8B40 3C         MOV     EAX, DWORD PTR DS:[EAX+3C]
    00AE626B    8B55 FC         MOV     EDX, DWORD PTR SS:[EBP-4]        ; 传递正确的API到EDX中
    --------------------------------------------------------------------------------


    我用Aspr2.11加壳的记事本
    第一个Call api 应该是调用 GetCommandLineA
    被改为Call 00D60000
    跟进来到你说的传递正确API到EDX的地方时,竟然变成了GetSartupInfo
    怎么也想不通会这样,正在郁闷中啊!
    (已解决)
    原来修改代码前传递正确的API,随后会传递下一个Api准备调用,下一个Api就是GetSartupInfo,我跟到那里去了。




    ASPROTECT 2.x 脱壳系列(二)
    Submitted by heartnn on 2006, March 14, 6:18 AM. 技术
    【目    标】:DVD Fab Gold 2.9.3.5
    【工    具】:Olydbg1.1(diy版)、LORDPE、ImportREC1.6F
    【任    务】:简单的脱壳
    【操作平台】:Windows XP sp2
    【作    者】:LOVEBOOM[DFCG][FCG][US]
    【相关链接】:自己搜索下
    【简要说明】:其实这个版本的还是更先脱的,只是整理的时候更后整理出来。看这篇文章之前建议先看我的第一篇文章,否则有些过程可能不好理解。

    【详细过程】:
      话也不多说,直接入主题, 载入目标程序,去除调试标志,下断bp GetModuleHandleA,运行中断两次,然后执行到完全解压出壳的代码:
    00AF24AC    85C0            TEST    EAX, EAX                         ; 第二次返回到这里
    00AF24AE    75 07           JNZ     SHORT 00AF24B7
    00AF24B0    53              PUSH    EBX
    00AF24B1    FF95 F0314400   CALL    DWORD PTR SS:[EBP+4431F0]        ; kernel32.LoadLibraryA
    ......
    00AF25BB    8985 112F4400   MOV     DWORD PTR SS:[EBP+442F11], EAX
    00AF25C1    61              POPAD                                    ; 直接f4执行到这里
    00AF25C2    75 08           JNZ     SHORT 00AF25CC
    00AF25C4    B8 01000000     MOV     EAX, 1
    00AF25C9    C2 0C00         RETN    0C
    00AF25CC    68 A08FAE00     PUSH    0AE8FA0                          ; 解压完跳去壳的代码入口点
    00AF25D1    C3              RETN
    00AF25D2    8B85 DC304400   MOV     EAX, DWORD PTR SS:[EBP+4430DC]   ; kernel32.7C800000
    ......
    00AE8FA0    55               PUSH    EBP                              ; 壳代码入口点
    00AE8FA1    8BEC             MOV     EBP, ESP
    00AE8FA3    83C4 B4          ADD     ESP, -4C
    00AE8FA6    B8 988DAE00      MOV     EAX, 0AE8D98

    到了壳的入口点后直接搜索以下命令:
      MOV     DWORD PTR SS:[EBP], EAX
      PUSH    0A
    找到一处:
    00AE653F    8945 00          MOV     DWORD PTR SS:[EBP], EAX          ; 找到这里
    00AE6542    6A 0A            PUSH    0A
    00AE6544    E8 63C4FEFF      CALL    00AD29AC
    00AE6549    8BC8             MOV     ECX, EAX

    找到地址后,在上面的地址处下硬件断点,执行发生中断后取消硬件断点。

    再找一下存放相关数据的地址,我选择的是513100.找到后,写段保存数据代码:
    00AE653F   /EB 43            JMP     SHORT 00AE6584                   ; 找到这里
    00AE6541   |90               NOP
    00AE6542   |6A 0A            PUSH    0A
    00AE6544   |E8 63C4FEFF      CALL    00AD29AC
    00AE6549   |8BC8             MOV     ECX, EAX
    00AE654B   |038B E4000000    ADD     ECX, DWORD PTR DS:[EBX+E4]
    00AE6551   |8BD6             MOV     EDX, ESI
    00AE6553   |8BC3             MOV     EAX, EBX
    00AE6555   |E8 9EE5FFFF      CALL    00AE4AF8
    00AE655A   |FF0C24           DEC     DWORD PTR SS:[ESP]
    00AE655D   |03B3 E4000000    ADD     ESI, DWORD PTR DS:[EBX+E4]
    00AE6563   |833C24 00        CMP     DWORD PTR SS:[ESP], 0
    00AE6567  ^|0F87 55FEFFFF    JA      00AE63C2
    00AE656D   |53               PUSH    EBX                              ; 写好保存相关数据代码后,在这里下F2断点
    00AE656E   |E8 5D000000      CALL    00AE65D0
    00AE6573   |0183 EC000000    ADD     DWORD PTR DS:[EBX+EC], EAX
    00AE6579   |B0 01            MOV     AL, 1
    00AE657B   |83C4 24          ADD     ESP, 24
    00AE657E   |5D               POP     EBP                              ; 00ADBDC8
    00AE657F   |5F               POP     EDI                              ; 00ADBDC8
    00AE6580   |5E               POP     ESI                              ; 00ADBDC8
    00AE6581   |5B               POP     EBX                              ; 00ADBDC8
    00AE6582   |C3               RETN
    00AE6583   |90               NOP
    00AE6584   \53               PUSH    EBX                              ; 保护堆栈
    00AE6585    51               PUSH    ECX
    00AE6586    B9 00315100      MOV     ECX, 513100                      ; 保存相关数据的起始地址
    00AE658B    8339 00          CMP     DWORD PTR DS:[ECX], 0
    00AE658E    75 06            JNZ     SHORT 00AE6596
    00AE6590    C701 10315100    MOV     DWORD PTR DS:[ECX], 513110       ; 如果是第次则初始化,从513110处开始保存相关数据
    00AE6596    8B19             MOV     EBX, DWORD PTR DS:[ECX]          ; wsock32.#1139
    00AE6598    4D               DEC     EBP                              ; DVDFabGo.004EE4A6
    00AE6599    892B             MOV     DWORD PTR DS:[EBX], EBP          ; 保存相关地址
    00AE659B    83C3 04          ADD     EBX, 4
    00AE659E    8919             MOV     DWORD PTR DS:[ECX], EBX
    00AE65A0    45               INC     EBP                              ; DVDFabGo.004EE4A6
    00AE65A1    59               POP     ECX                              ; 00ADBDC8
    00AE65A2    5B               POP     EBX                              ; 00ADBDC8
    00AE65A3    8945 00          MOV     DWORD PTR SS:[EBP], EAX          ; 执行原壳的代码
    00AE65A6  ^ EB 9A            JMP     SHORT 00AE6542
    00AE65A8    C1E3 18          SHL     EBX, 18
    00AE65AB    31D8             XOR     EAX, EBX

    写好代码后在00AE656D处下F2断点,再F9运行,运行中断后,把修复代码还原回去,第三次出现机器码时写上注册信息:

    --------------------第一次----------------------
    0012FF1C   0012FF28  Pointer to next SEH record
    0012FF20   00ADC92E  SE handler
    0012FF24   00000002
    0012FF28   0012FF80  Pointer to next SEH record
    0012FF2C   00ADD739  SE handler
    0012FF30   0012FF78
    0012FF34   00AC0000
    0012FF38   00A80000
    0012FF3C   00ADBDC8
    0012FF40   00000000
    0012FF44   00B59E34  ASCII "6uCokAAAJmg="
    0012FF48   00B59E00  ASCII "2A0FFBAB-CB5A"
    0012FF4C   C5FC9640
    0012FF50   41B05FF0
    0012FF54   F81D0E0A
    ......
    --------------------第二次----------------------
    0012FF1C   0012FF28  Pointer to next SEH record
    0012FF20   00ADCAD5  SE handler
    0012FF24   00B3045C
    0012FF28   0012FF80  Pointer to next SEH record
    0012FF2C   00ADD739  SE handler
    0012FF30   0012FF78
    0012FF34   00AC0000
    0012FF38   00A80000
    0012FF3C   00ADBDC8
    0012FF40   00000000
    0012FF44   00B59E34  ASCII "6uCokAAAJmg="
    0012FF48   00B59E00  ASCII "2A0FFBAB-CB5A"
    0012FF4C   C5FC9640
    0012FF18   0012FF28  Pointer to next SEH record
    0012FF1C   00ADCEE7  SE handler
    0012FF20   00B3045C
    0012FF24   00B59E00  ASCII "2A0FFBAB-CB5A"
    0012FF28   0012FF80  Pointer to next SEH record
    0012FF2C   00ADD739  SE handler
    0012FF30   0012FF78
    0012FF34   00AC0000
    0012FF38   00A80000
    0012FF3C   00ADBDC8
    0012FF40   00000000
    0012FF44   00B59E34  ASCII "6uCokAAAJmg="
    0012FF48   00B59E00  ASCII "2A0FFBAB-CB5A"
    0012FF4C   C5FC9640
    ......
    --------------------第三次----------------------
    0012FF18   0012FF28  Pointer to next SEH record
    0012FF1C   00ADCEE7  SE handler
    0012FF20   00B3045C
    0012FF24   00B59E00  ASCII "2A0FFBAB-CB5A"
    0012FF28   0012FF80  Pointer to next SEH record
    0012FF2C   00ADD739  SE handler
    0012FF30   0012FF78
    0012FF34   00AC0000
    0012FF38   00A80000
    0012FF3C   00ADBDC8
    0012FF40   00000000
    0012FF44   00B59E34  ASCII "6uCokAAAJmg="
    0012FF48   00B59E00  ASCII "2A0FFBAB-CB5A"
    0012FF4C   C5FC9640

    第三次出现机器码后,在code段访问断点,shift+f9后中断在这里:
    00424CD7    8B4424 04        MOV     EAX, DWORD PTR SS:[ESP+4]        ; 中断在这里,[esp+4]保存注册名地址
    00424CDB    81EC 08020000    SUB     ESP, 208
    ......
    0012FF1C   00ADD190  RETURN to 00ADD190
    0012FF20   00AC3A29
    0012FF24   00B59E00  ASCII "2A0FFBAB-CB5A"
    0012FF28   0012FF80  Pointer to next SEH record
    修改为:
    0012FF1C   00ADD190  RETURN to 00ADD190
    0012FF20   00479F70  ASCII "loveboom[DFCG][FCG][US]"
    0012FF24   00B59E00  ASCII "2A0FFBAB-CB5A"
    0012FF28   0012FF80  Pointer to next SEH record

    这样注册块就处理好了,再过几个异常后直接F2断到程序OEP:

    0047550E    55               PUSH    EBP                              ; OEP
    0047550F    8BEC             MOV     EBP, ESP
    00475511    6A FF            PUSH    -1
    ......
    00AC2544    85C0             TEST    EAX, EAX
    00AC2546    74 0A            JE      SHORT 00AC2552
    00AC2548    FF15 18A0AE00    CALL    DWORD PTR DS:[AEA018]
    00AC254E    09C0             OR      EAX, EAX
    00AC2550    74 01            JE      SHORT 00AC2553
    ......
    00D500EB    5C               POP     ESP
    00D500EC  - FF6424 FC        JMP     DWORD PTR SS:[ESP-4]    ;patch
    00D500F0    EB 01            JMP     SHORT 00D500F3



    再找一下找到输入表信息:
    IAT位置:47A000 SIZE:bb0


    PATCH 1:       00ac2548
    PATCH 2:      00D500EC
    PATCH 3:      4799b0(保存修复代码的起始地址)
    修改跳转地址为:      004799BF


    写上全部的修复代码:

    004799B0   .  60            PUSHAD                                   ;  保存堆栈
    004799B1   .  B9 10315100   MOV     ECX, 00513110                    ;  取出相关的地址
    004799B6   >  8B19          MOV     EBX, DWORD PTR DS:[ECX]
    004799B8   .  83FB 00       CMP     EBX, 0
    004799BB   .  74 15         JE      SHORT 004799D2                   ;  如果取完了则跳去修复jmp [addr]
    004799BD   .  FFE3          JMP     EBX                              ;  执行原CALL
    004799BF   .  8B15 08315100 MOV     EDX, DWORD PTR DS:[513108]       ;  取出call [addr]中的addr
    004799C5   .  66:C703 FF15  MOV     WORD PTR DS:[EBX], 15FF          ;  修改成call [addr]
    004799CA   .  8953 02       MOV     DWORD PTR DS:[EBX+2], EDX        ;  <&winmm.PlaySound>
    004799CD   .  83C1 04       ADD     ECX, 4
    004799D0   .^ EB E4         JMP     SHORT 004799B6
    004799D2   >  33C0          XOR     EAX, EAX
    004799D4   .  B0 E8         MOV     AL, 0E8                          ;  修复jmp [addr]
    004799D6   .  BF 00104000   MOV     EDI, 00401000                    ;  code段的起始地址
    004799DB   .  B9 A0990600   MOV     ECX, 699A0                       ;  大小
    004799E0   >  F2:AE         REPNE   SCAS BYTE PTR ES:[EDI]
    004799E2   .  83F9 00       CMP     ECX, 0
    004799E5   .  74 3C         JE      SHORT 00479A23                   ;  处理完则跳
    004799E7   .  8B1F          MOV     EBX, DWORD PTR DS:[EDI]
    004799E9   .  8D5C3B 04     LEA     EBX, DWORD PTR DS:[EBX+EDI+4]
    004799ED   .  81FB 00104000 CMP     EBX, 00401000                    ;  Entry address
    004799F3   .^ 72 EB         JB      SHORT 004799E0
    004799F5   .  81FB 94994700 CMP     EBX, 00479994
    004799FB   .^ 77 E3         JA      SHORT 004799E0
    004799FD   .  66:813B FF15  CMP     WORD PTR DS:[EBX], 15FF
    00479A02   .^ 75 DC         JNZ     SHORT 004799E0
    00479A04   .  817B 02 00A04>CMP     DWORD PTR DS:[EBX+2], <&advapi32>
    00479A0B   .^ 72 D3         JB      SHORT 004799E0
    00479A0D   .  817B 02 C0AB4>CMP     DWORD PTR DS:[EBX+2], 0047ABC0
    00479A14   .^ 77 CA         JA      SHORT 004799E0                   ;  让代码更精确些
    00479A16   .  66:C703 FF25  MOV     WORD PTR DS:[EBX], 25FF
    00479A1B   .  83C7 04       ADD     EDI, 4
    00479A1E   .  83E9 04       SUB     ECX, 4
    00479A21   .^ EB BD         JMP     SHORT 004799E0
    00479A23   >  B9 10315100   MOV     ECX, 00513110                    ;  再次精确些处理jmp [addr] **********这里是上篇中没有注意到的
    00479A28   >  8B19          MOV     EBX, DWORD PTR DS:[ECX]
    00479A2A   .  83FB 00       CMP     EBX, 0
    00479A2D   .  74 2E         JE      SHORT 00479A5D                   ;  操作完则跳
    00479A2F   .  66:8B03       MOV     AX, WORD PTR DS:[EBX]
    00479A32   .  66:3D FF15    CMP     AX, 15FF                         ;  判断是否为call [addr]
    00479A36   .  75 20         JNZ     SHORT 00479A58
    00479A38   .  66:8B43 FA    MOV     AX, WORD PTR DS:[EBX-6]          ;  如果是的话,判断前一句代码是否为jmp [addr]
    00479A3C   .  66:3D FF25    CMP     AX, 25FF
    00479A40   .  75 16         JNZ     SHORT 00479A58
    00479A42   .  8B53 FC       MOV     EDX, DWORD PTR DS:[EBX-4]
    00479A45   .  81FA 00A04700 CMP     EDX, <&advapi32.AdjustTokenPrivi>
    00479A4B   .  72 0B         JB      SHORT 00479A58
    00479A4D   .  81FA C0AB4700 CMP     EDX, 0047ABC0
    00479A53   .  77 03         JA      SHORT 00479A58
    00479A55   .  66:8903       MOV     WORD PTR DS:[EBX], AX            ;  如果是的话则认为这当前句也是jmp [addr]
    00479A58   >  83C1 04       ADD     ECX, 4
    00479A5B   .^ EB CB         JMP     SHORT 00479A28
    00479A5D   >  61            POPAD
    00479A5E   .  00            DB      00
    00479A5F   .  00            DB      00
    00479A60      689A4700      DD      dumped_.00479A68
    00479A64   .  00            DB      00
    00479A65      90            NOP
    00479A66      90            NOP
    00479A67      90            NOP
    00479A68   .  60            PUSHAD
    00479A69   .  8BC2          MOV     EAX, EDX                         ;  保存call [addr]中的addr到 513108处
    00479A6B   .  B9 C80B0000   MOV     ECX, 0BC8
    00479A70   .  BF 00A04700   MOV     EDI, <&advapi32.AdjustTokenPrivi>
    00479A75   .  F2:AF         REPNE   SCAS DWORD PTR ES:[EDI]
    00479A77   .  83EF 04       SUB     EDI, 4
    00479A7A   .  893D 08315100 MOV     DWORD PTR DS:[513108], EDI       ;  ntdll.7C930738
    00479A80   .  61            POPAD
    00479A81      FF15 18A0AE00 CALL    DWORD PTR DS:[AEA018]
    00479A87   .  C3            RETN
    00479A88      90            NOP

    再写上修复脚本:
    //fixed aspr 2.x
    var addr


    start:
      run

    l1:
      cmp eip,00D500EC
      jne l2
      mov addr,esp
      sub addr,4
      mov [addr],004799BF
      jmp start

    l2:
      ret


    写好后在00D500EC下硬件执行断点,在00479A5D下普通F2断点,再执行脚本。脱壳完毕!
    破解就像恋爱,这过程没有什么人能帮到你,什么都得靠自己一步一步的走。愿自己的恋爱能和脱壳一样风雨无阻:-).



    http://www.my.usmanbiz.com/blog/trackback.php?id=321


    标  题】:ASPROTECT 2.x 脱壳系列(三)
    【关键字】:ASPROTECT,2.x
    【来  源】:BLOG.CSDN.NET

    ASPROTECT 2.x 脱壳系列(三)
    ASPROTECT 2.x 脱壳系列(三)

    【目    标】:BeeIcons 4.02.1
    【工    具】:Olydbg1.1(diy版)、LORDPE、ImportREC1.6F
    【任    务】:简单的脱壳
    【操作平台】:Windows XP sp2
    【作    者】:LOVEBOOM[DFCG][FCG][US]
    【相关链接】:自己搜索下
    【简要说明】:继上一篇,这次的目标前两篇的又有所不同了.难度稍微大了点。这次来个一气呵成:-)
    【详细过程】:

    OD设置:忽略除int3之外的其它异常,载入目标:
    00401000 >  68 01706100     PUSH    00617001                         ; 壳EP
    00401005    E8 01000000     CALL    0040100B

    F9运行后中断下来:
    0103700B    90              NOP                                     ; 异常中断
    0103700C    EB 01           JMP     SHORT 0103700F
    0103700E    6966 81 FE47467>IMUL    ESP, DWORD PTR DS:[ESI-7F], 7446>

    异常中断在code段下F2断点,然后shift+f9,中断:
    0102267D    F3:A5           REP     MOVS DWORD PTR ES:[EDI], DWORD P>; 中断这里 
    0102267F    89C1            MOV     ECX, EAX
    01022681    83E1 03         AND     ECX, 3
    01022684    83C6 03         ADD     ESI, 3
    01022687    83C7 03         ADD     EDI, 3
    0102268A    F3:A4           REP     MOVS BYTE PTR ES:[EDI], BYTE PTR>

    断下后,查找相关命令:
    mov [ebp],eax
    push 0a

    找到一处,在找到的位置下硬件执行断点:
    01045F7B    8945 00         MOV     DWORD PTR SS:[EBP], EAX          ; 找到这里,直接在这里下硬件执行断点
    01045F7E    6A 0A           PUSH    0A
    01045F80    E8 8FCEFEFF     CALL    01032E14
    01045F85    8BC8            MOV     ECX, EAX

    和上两篇一样,找到相关地址,然后写上相关代码:
    ___________________________获取CALL 01270000全部地址的修复代码_______________________________

    01045F7B   /EB 43           JMP     SHORT 01045FC0                   ; 找到这里,直接在这里下硬件执行断点
    01045F7D   |90              NOP
    01045F7E   |6A 0A           PUSH    0A
    01045F80   |E8 8FCEFEFF     CALL    01032E14
    01045F85   |8BC8            MOV     ECX, EAX
    01045F87   |038B E4000000   ADD     ECX, DWORD PTR DS:[EBX+E4]
    01045F8D   |8BD6            MOV     EDX, ESI
    01045F8F   |8BC3            MOV     EAX, EBX
    01045F91   |E8 9EE5FFFF     CALL    01044534
    01045F96   |FF0C24          DEC     DWORD PTR SS:[ESP]
    01045F99   |03B3 E4000000   ADD     ESI, DWORD PTR DS:[EBX+E4]
    01045F9F   |833C24 00       CMP     DWORD PTR SS:[ESP], 0
    01045FA3  ^|0F87 55FEFFFF   JA      01045DFE
    01045FA9   |53              PUSH    EBX                              ; 这里F2断点
    01045FAA   |E8 5D000000     CALL    0104600C
    01045FAF   |0183 EC000000   ADD     DWORD PTR DS:[EBX+EC], EAX
    01045FB5   |B0 01           MOV     AL, 1
    01045FB7   |83C4 24         ADD     ESP, 24
    01045FBA   |5D              POP     EBP                              ; BeeIcons.0040129D
    01045FBB   |5F              POP     EDI
    01045FBC   |5E              POP     ESI
    01045FBD   |5B              POP     EBX
    01045FBE   |C3              RETN
    01045FBF   |90              NOP
    01045FC0   \53              PUSH    EBX
    01045FC1    51              PUSH    ECX
    01045FC2    B9 00916400     MOV     ECX, 649100
    01045FC7    8339 00         CMP     DWORD PTR DS:[ECX], 0
    01045FCA    75 06           JNZ     SHORT 01045FD2
    01045FCC    C701 10916400   MOV     DWORD PTR DS:[ECX], 649110       ; 保存相关地址数据的起始地址
    01045FD2    8B19            MOV     EBX, DWORD PTR DS:[ECX]
    01045FD4    4D              DEC     EBP                              ; BeeIcons.0040129D
    01045FD5    892B            MOV     DWORD PTR DS:[EBX], EBP          ; BeeIcons.0040129D
    01045FD7    83C3 04         ADD     EBX, 4
    01045FDA    8919            MOV     DWORD PTR DS:[ECX], EBX
    01045FDC    45              INC     EBP                              ; BeeIcons.0040129D
    01045FDD    59              POP     ECX
    01045FDE    5B              POP     EBX
    01045FDF    8945 00         MOV     DWORD PTR SS:[EBP], EAX
    01045FE2  ^ EB 9A           JMP     SHORT 01045F7E

    _______________________________END___________________________________________

    保存好全部数据后,F9再次发生INT3异常中断:
    0103700B    90              NOP                                      ; INT 3异常中断
    0103700C    EB 01           JMP     SHORT 0103700F
    0103700E    6966 81 FE47467>IMUL    ESP, DWORD PTR DS:[ESI-7F], 7446>
    01037015    05 31C040EB     ADD     EAX, EB40C031
    0103701A    0231            ADD     DH, BYTE PTR DS:[ECX]
    0103701C    C031 DB         SAL     BYTE PTR DS:[ECX], 0DB           ; Shift constant out of range 1..31
    0103701F    64:8F03         POP     DWORD PTR FS:[EBX]               ; 0012FF20
    01037022    83C4 04         ADD     ESP, 4
    01037025    EB 01           JMP     SHORT 01037028
    01037027    E8 5F5E5BC3     CALL    C45ECE8B
    0103702C    51              PUSH    ECX
    0103702D    52              PUSH    EDX
    0103702E    53              PUSH    EBX
    0103702F    56              PUSH    ESI
    01037030    57              PUSH    EDI
    01037031    E8 01000000     CALL    01037037
    01037036  - E9 5831C031     JMP     32C3A193
    0103703B    D2B9 03000000   SAR     BYTE PTR DS:[ECX+3], CL
    01037041    BE 8F700301     MOV     ESI, 103708F                     ; ASCII " \\.\SICE"
    01037046    EB 01           JMP     SHORT 01037049
    01037048    69AC50 516A0068>IMUL    EBP, DWORD PTR DS:[EAX+EDX*2+680>
    01037053    6A 03           PUSH    3
    01037055    6A 00           PUSH    0
    01037057    6A 01           PUSH    1
    01037059    EB 01           JMP     SHORT 0103705C
    0103705B    E8 68000000     CALL    010370C8
    01037060    8056 E8 A5      ADC     BYTE PTR DS:[ESI-18], 0A5
    01037064    E6 FE           OUT     0FE, AL                          ; I/O command
    01037066    FF59 5A         CALL    FAR FWORD PTR DS:[ECX+5A]        ; Far call
    01037069    40              INC     EAX
    0103706A    75 0C           JNZ     SHORT 01037078
    0103706C    01D6            ADD     ESI, EDX
    0103706E    EB 02           JMP     SHORT 01037072
    01037070    CD 20           INT     20
    01037072  ^ E2 D2           LOOPD   SHORT 01037046
    01037074    31C0            XOR     EAX, EAX
    01037076    EB 0D           JMP     SHORT 01037085
    01037078    48              DEC     EAX
    01037079    50              PUSH    EAX
    0103707A    E8 85E6FEFF     CALL    01025704                         ; JMP to kernel32.CloseHandle
    0103707F    EB 01           JMP     SHORT 01037082
    01037081    0F31            RDTSC
    01037083    C040 5F 5E      ROL     BYTE PTR DS:[EAX+5F], 5E         ; Shift constant out of range 1..31
    01037087    EB 01           JMP     SHORT 0103708A
    01037089    C7              ???                                      ; Unknown command
    0103708A    5B              POP     EBX                              ; 0012FF20
    0103708B    5A              POP     EDX                              ; 0012FF20
    0103708C    59              POP     ECX                              ; 直接在这里下F2断点
    0103708D    C3              RETN
    0103708E    9A 095C5C2E 5C5>CALL    FAR 535C:2E5C5C09                ; Far call
    01037095    49              DEC     ECX
    01037096    43              INC     EBX
    01037097    45              INC     EBP

    在0103708C处下断,shift+f9一次中断,断下后在code段下断,断下后可以看到OEP了:

    00569594    55              PUSH    EBP                              ; OEP
    00569595    8BEC            MOV     EBP, ESP
    00569597    83C4 F0         ADD     ESP, -10


    到了OEP处后,像前面的文章一样,找到保存相关地方:

    01022544    85C0            TEST    EAX, EAX
    01022546 >  74 0A           JE      SHORT 01022552
    01022548    FF15 18900401   CALL    DWORD PTR DS:[1049018]  ;这里改成我们自己的代码
    0102254E    09C0            OR      EAX, EAX
    01022550    74 01           JE      SHORT 01022553
    ......

    012800A0    9D              POPFD
    012800A1    5C              POP     ESP
    012800A2    FF6424 FC       JMP     DWORD PTR SS:[ESP-4]  ;这里设置硬件断点用于写上我们自己的代码
    012800A6    54              PUSH    ESP

    因为这个程序里的IAT是部分加密处理过的,所以相对来说处理会麻烦一点,这个要靠自己去想怎么去解决,我的处理方法比较麻烦。可能有更好的方法,我现在还没有想到:-(.再写上一段代码和一段脚本,然后运行脚本就可以了:
    ________________________-相关代码_________________________________

    005695D0   .  60            PUSHAD
    005695D1   .  B9 10916400   MOV     ECX, 00649110                    ;  调用call address的位置
    005695D6   >  8339 00       CMP     DWORD PTR DS:[ECX], 0
    005695D9   .  74 17         JE      SHORT 005695F2
    005695DB   .  8B19          MOV     EBX, DWORD PTR DS:[ECX]          ;  ntdll.7C92E64E
    005695DD   .- FFE3          JMP     EBX                              ;  跳去执行原call
    005695DF   .  66:C703 FF15  MOV     WORD PTR DS:[EBX], 15FF          ;  改写成call [addr]
    005695E4   .  8B15 08916400 MOV     EDX, DWORD PTR DS:[649108]       ;  <&comdlg32.ChooseColorA>
    005695EA   .  8953 02       MOV     DWORD PTR DS:[EBX+2], EDX        ;  ntdll.KiFastSystemCallRet
    005695ED   .  83C1 04       ADD     ECX, 4
    005695F0   .^ EB E4         JMP     SHORT 005695D6
    005695F2   >  33C0          XOR     EAX, EAX                         ;  修复为jmp [addr]的部分
    005695F4   .  B9 CC951600   MOV     ECX, 1695CC
    005695F9   .  BF 00104000   MOV     EDI, 00401000
    005695FE   >  B0 E8         MOV     AL, 0E8
    00569600   >  F2:AE         REPNE   SCAS BYTE PTR ES:[EDI]
    00569602   .  83F9 00       CMP     ECX, 0
    00569605   .  74 2C         JE      SHORT 00569633
    00569607   .  8B1F          MOV     EBX, DWORD PTR DS:[EDI]
    00569609   .  8D5C3B 04     LEA     EBX, DWORD PTR DS:[EBX+EDI+4]
    0056960D   .  81FB 00104000 CMP     EBX, 00401000
    00569613   .^ 72 EB         JB      SHORT 00569600
    00569615   .  81FB C7955600 CMP     EBX, 005695C7                    ;  判断是否符合修复条件
    0056961B   .^ 77 E3         JA      SHORT 00569600
    0056961D   .  66:8B03       MOV     AX, WORD PTR DS:[EBX]
    00569620   .  66:3D FF15    CMP     AX, 15FF
    00569624   .  75 0B         JNZ     SHORT 00569631
    00569626   .  66:C703 FF25  MOV     WORD PTR DS:[EBX], 25FF
    0056962B   .  83C7 04       ADD     EDI, 4
    0056962E   .  83E9 04       SUB     ECX, 4
    00569631   >^ EB CB         JMP     SHORT 005695FE
    00569633   >  61            POPAD
    00569634   .  90            NOP
    00569635   .  90            NOP
    00569636   .  90            NOP
    00569637   .  90            NOP
    00569638   .  90            NOP
    00569639   .  90            NOP
    0056963A   .  90            NOP
    0056963B   .  90            NOP
    0056963C   .  90            NOP
    0056963D   .  90            NOP
    0056963E   .  90            NOP
    0056963F   .  90            NOP
    00569640   .  48965600      DD      dumped_.00569648
    00569644      00            DB      00
    00569645      00            DB      00
    00569646      00            DB      00
    00569647      00            DB      00
    00569648      90            NOP
    00569649   .  60            PUSHAD
    0056964A   .  BD 00916400   MOV     EBP, 00649100
    0056964F   .  90            NOP
    00569650   .  8B4D 04       MOV     ECX, DWORD PTR SS:[EBP+4]
    00569653   .  0BC9          OR      ECX, ECX
    00569655   .  75 18         JNZ     SHORT 0056966F                   ;  这里修复和上两篇有所不同,这篇里的iat是加密处理过的
    00569657   .  B9 C4E05700   MOV     ECX, <&kernel32.GetFileType>     ;  对于修复加密的输入表,我采用脚本+代码的方式
    0056965C   .  8911          MOV     DWORD PTR DS:[ECX], EDX          ;  来修复输入表
    0056965E   .  894D 08       MOV     DWORD PTR SS:[EBP+8], ECX
    00569661   .  83C1 04       ADD     ECX, 4
    00569664   .  894D 04       MOV     DWORD PTR SS:[EBP+4], ECX
    00569667   .  90            NOP
    00569668   .  90            NOP
    00569669   .  90            NOP
    0056966A   .  90            NOP
    0056966B   .  90            NOP
    0056966C   .  90            NOP
    0056966D   .  EB 45         JMP     SHORT 005696B4
    0056966F   >  8BF1          MOV     ESI, ECX
    00569671   .  81E9 C4E05700 SUB     ECX, <&kernel32.GetFileType>
    00569677   .  C1E9 02       SHR     ECX, 2
    0056967A   .  8BC2          MOV     EAX, EDX                         ;  ntdll.KiFastSystemCallRet
    0056967C   .  BF C4E05700   MOV     EDI, <&kernel32.GetFileType>
    00569681   .  F2:AF         REPNE   SCAS DWORD PTR ES:[EDI]
    00569683   .  0BC9          OR      ECX, ECX
    00569685   .  74 08         JE      SHORT 0056968F
    00569687   .  83EF 04       SUB     EDI, 4
    0056968A   .  897D 08       MOV     DWORD PTR SS:[EBP+8], EDI        ;  ntdll.7C930738
    0056968D   .  EB 25         JMP     SHORT 005696B4
    0056968F   >  90            NOP
    00569690      90            NOP                                      ;  写好脚本和这里的代码后,先在这里下f2断
    00569691   .  90            NOP                                      ;  用于脚本判断是否为相同的DLL
    00569692   .  90            NOP
    00569693   .  90            NOP
    00569694   .  90            NOP
    00569695   .  0BD2          OR      EDX, EDX                         ;  通过脚本判断是否为相同的DLL,如果相同edx=0不同edx=1
    00569697   .  75 0D         JNZ     SHORT 005696A6
    00569699   .  8906          MOV     DWORD PTR DS:[ESI], EAX
    0056969B   .  8975 08       MOV     DWORD PTR SS:[EBP+8], ESI
    0056969E   .  83C6 04       ADD     ESI, 4
    005696A1   .  8975 04       MOV     DWORD PTR SS:[EBP+4], ESI
    005696A4   .  EB 0E         JMP     SHORT 005696B4
    005696A6   >  83C6 04       ADD     ESI, 4
    005696A9   .  8906          MOV     DWORD PTR DS:[ESI], EAX
    005696AB   .  8975 08       MOV     DWORD PTR SS:[EBP+8], ESI
    005696AE   .  83C6 04       ADD     ESI, 4
    005696B1   .  8975 04       MOV     DWORD PTR SS:[EBP+4], ESI
    005696B4   >  61            POPAD
    005696B5   .  FF15 18900401 CALL    DWORD PTR DS:[1049018]           ;  执行原壳的代码
    005696BB   .  C3            RETN

    _____________________END_____________________________________


    ____________________相关脚本_________________________________

    //fix1
    var dll1
    var dllnow
    var addr

    start:
       run

    l1:
    cmp eip,569690   //跳去处理是否为同一DLL
    je l2
    cmp eip,0012800c5  //判断是否为jmp [esp-4]处
    je l6

      ret


    l2:
    gn edx
    mov dllnow,$RESULT_1
    cmp dll1,0
    jne l3
    mov dll1,dllnow

    l3:
    cmp dll1,dllnow
    jne l4
    mov edx,0
    jmp l5

    l4:
    mov dll1,dllnow
    mov edx,1


    l5:
    sto
    jmp start


    l6:
    mov addr,esp
    sub addr,4
    mov [addr],5695df   //修改eip
    jmp start
    _____________________END_____________________________________

    写好了上面的东西,运行脚本,用importrec修复输入表时,有一个是GetProcAddress:
    00407784  - FF25 28B45700   JMP     DWORD PTR DS:[57B428]
    把这个API修复好,其它无效的直接cut掉,分两次就可以把iat获取并修复好。

    修复好程序并不能够运行的。通过运行发现下面的地方,就是检测是否被壳的相关地址:

    0055B03B   .  E8 7498FDFF   CALL    005348B4                         ;  CreateFileA
    0055B040      3D A66D0D00   CMP     EAX, 0D6DA6                      ;  判断文件大小?
    0055B045      0F8E 8B000000 JLE     0055B0D6                         ;  如果小于或等于则跳,正常这里是跳的

    因为考虑到处理反脱壳检测可能会比较麻烦,所以我直接改CreateFileA为原来没有脱壳的文件名,这样就可以通过检测,操作好后,还有一个段被抽在程序里,直接用lordpe添加段进去。这样子程序就可以运行了,不过可惜的,按菜单功能的时间还是会异常退出:-(,唉不脱了,再脱真的是脱皮而不是脱壳了。


    ASProtect SKE 2.X +代码变形 (實例)

    【破解作者】 SYSCOM
    【使用工具】 Ollydbg1.10, LordPE,ImportREC1.65,PEid 0.93
    【破解平台】 Windows XP SP1
    【软件名称】 BetterJPEG 1, 4, 4, 0
    【下载地址】 http://www.betterjpeg.com/
    【软件简介】 Edit JPEG photos
    【加壳方式】 ASProtect SKE 2.X
    【破解声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享:)
    --------------------------------------------------------------------------------
    (1) 用ollydbg 载入BetterJPEG.exe ,设置忽略所有异常。
    在命令栏输入
    BP GetVersion ,按 F9,看 STACK 返回 431EE4 ,在按 ALT+F9
    返回,主程式 ,往上看.....不远地方

    431EB8-PUSH EBP <======= OEP 进入点
    431EB9-MOV EBP,ESP
    431EBB-PUSH -1
    .....
    .....


    (2)修正 Import Table and .CODE 写入补丁 PATCH(1)
    先修正 9F4387-PUSH 9F43A4==>PUSH PATCH(1)+0x29 Offset Address

    //********************** Start of Code in Object BinaryCode **************
    :00000000 mov edx, 00401000 ;主程式 Start address
    :00000005 cmp byte ptr [edx], E8 ;判断是否为 call 指令
    :00000008 jne 0000001E
    :0000000A mov eax, dword ptr [edx+01]
    :0000000D add eax, edx
    :0000000F add eax, 00000005
    :00000014 cmp eax, 00CD0000 ;判断是否为 call API 加密,进入点
    :00000019 jne 0000001E
    :0000001B pushad ;保存所有暂存器
    :0000001C jmp edx
    :0000001E inc edx
    :0000001F cmp edx, 00461000 ;主程式 end address
    :00000025 jbe 00000005
    :00000027 jmp 00000027 ;PATCH END
    :00000029 mov ecx, 00461000 ;IAT start address (解码返回进入点)
    :0000002E mov edx, dword ptr [ebp-0C]
    :00000031 cmp dword ptr [ecx], edx
    :00000033 jne 00000052
    :00000035 mov dword ptr [00460800], ecx ;暂存 Import Address
    :0000003B add esp, 0000023C
    :00000041 popad ;取回所有暂存器
    :00000042 mov ebx, dword ptr [00460800] ;取出 Import Address
    :00000048 mov dword ptr [edx+02], ebx ;修正 Import Address
    :0000004B mov word ptr [edx], 15FF ;修正 CALL
    :00000050 jmp 0000001E
    :00000052 add ecx, 00000004
    :00000055 cmp ecx, 004616AC ;IAT End address
    :0000005B jl 00000031
    :0000005D jmp 0000005D


    (3)写入补丁 PATCH(2)

    //********************** Start of Code in Object BinaryCode **************
    :00000000 mov edx, 00401000 ;主程式 Start address
    :00000005 cmp byte ptr [edx], E8 ;判断是否为 call 指令
    :00000008 jne 00000030
    :0000000A mov eax, dword ptr [edx+01]
    :0000000D add eax, edx
    :0000000F add eax, 00000005
    :00000014 cmp eax, 00401000 ;判断是否为 > 401000
    :00000019 jb 00000030
    :0000001B cmp eax, 00461000 ;判断是否为 < 461000
    :00000020 ja 00000030
    :00000022 mov bx, word ptr [eax]
    :00000025 cmp bx, 15FF ;判断是否为 call 指令
    :0000002A jne 00000030
    :0000002C mov [eax+01], 25 ;修正 CALL =>JMP
    :00000030 inc edx
    :00000031 cmp edx, 00461000 ;主程式 End address
    :00000037 jne 00000005
    :00000039 jmp 00000039

    (4) PATCH 完后,Dump BetterJPEG_dump.exe

    (5)run BetterJPEG.exe 在用 ImportREC 抓出 Import
    并修复 kernel32,中一个无效指针,改为 GetProcAddress
    再修正,RestoreLastError ==>SetLastError (98/XP/NT4/2003 相容)

    (6)使用 lordPE DUMP 变形程式,MEMORY 区块
    并附加在 BetterJPEG_dump.exe,的后面

    ADDRESS: SIZE SET
    -----------------------------------
    9D0000 32000 RWE
    A64000 10000 RWE
    C80000 1000 RWE
    D10000 1000 RWE
    D30000 2000 RWE
    D40000 2000 RWE
    D50000 1000 RWE
    D60000 1000 RWE
    -----------------------------------

    (7)修正 Route CHECK

    9F70CE-MOV EAX,[EAX+34] => 9F70CE-NOP
    9F70D1-CALL EAX => 9F70CF-NOP
    9FD0D3-SUB [EBP+C],EAX => 9F70D0-MOV EAX,[ESP+58]
    9FD0D6-MOV EAX,[ENP+C] => 9F70D4-SUB EAX,5

    (9)OK->TEST->RUN BetterJPEG_dump.exe


    总结:

    找oep很简单的,直接到最后一个异常后找到离返回处最近的那个call进去-->执行一次到返回(ctrl+f9),
    如果没有抽代码,进去后jmp eax就是跳去oep,如果抽代码ctrl+f9后就是stolen code的开始处

    剛剛試了一個軟件結果出現一個ERROR視窗內容如下:
    OS: Windows XP Professional, SP2
    CPU: AuthenticAMD, AMD AMD Athlon(tm) , MMX @ 2480 MHz

    Application data:
    VmVyc2lvbjogVWtSdWJXUmtZWFlwSlZCamRYUmhaMmNFQURnbE95eHV
    lR1JpYWk4L0lUNGdJakpBZG45eGRXWndPQT09DQpJbWFnZUJhc2U6ID
    AwNDAwMDAwDQpFaXA6IDE2N0U5MDYNCkVheDogRTg1MUQ4QkYNCkVje
    DogMA0KRWR4OiAxM0ZGODANCkVieDogRTg1MUQ4QkYNCkVzaTogMTZC
    MDc0Qw0KRWRpOiAxNjUwMDAwDQpFYnA6IDEzRkY5OA0KRXNwOiAxM0Z
    GMzgNCkVycm9yQ29kZTogDQo4MyxDNCw0LDhELEMsNyw1OSxBMSw0OC
    w0OCw2OCwxLDhCLDAsOEIsNjgsMUMsQTEsNDgsNDgsNjgsMSw4QiwwL
    DhCLDAsODksNDQsMjQsNCxBMSw0OCw0OCw2OCwxLDhCLDAsOEQsNzgs
    MTgsQTEsQjgsNDcsNjgsMSw4OCw1OCw4LDgzLDNGLDAsMC4uLg0KQ29
    kZSA9IFsyMzddDQotIDIwDQotIDIwOA0KLSAwDQotIDANCi0gW10NCj
    4gRDpcVzgwMElcYWFhXGNsaWVudFxjbGllbnQxNC5leGUNCj4gQzpcV

    會出現這個訊息,就是你被 aspr 偵測發現,使用 debug
    不可亂下 BP ,會被發現的...............


    我沒有下bp呀~~
    只是照著loveboom大大說的方法到了最後一次異常處,找到离返回处最近的那个call进去
    ,從異常那個位置要到call的地方就過不去了,在od左下角提示shift+f7 f8 f9
    按了shift+f7就會跑到地址7c92eaf0去,這是正常的嗎?

    以上問題已解決!
    只要再离返回处最近的那个call先下F2斷點,在SHIFT+F9,就會停在那了,然後再F7進去!

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?加入我们

    x
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2007-4-5 12:18:39 | 显示全部楼层
    loveboom斑斑的文章 转载的东西 我正在考虑如何处理版权问题
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2007-4-6 21:55:36 | 显示全部楼层
    最好不要转载别人的文章,除非斑斑亲自来发个帖子/:13

    PYG教程应该全部为本PYG会员的原创文章/:16
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2007-4-6 22:18:59 | 显示全部楼层
    原帖由 tigerisme 于 2007-4-6 21:55 发表
    最好不要转载别人的文章,除非斑斑亲自来发个帖子/:13

    PYG教程应该全部为本PYG会员的原创文章/:16



    至少应该本人有在PYG注册过 如果我们贸然引用对方的帖子 不太合适啊
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2018-1-9 11:05
  • 签到天数: 2 天

    [LV.1]初来乍到

     楼主| 发表于 2007-4-9 21:01:36 | 显示全部楼层
    楼主说的有道理,不过,我觉得这个脱的壳很有些代表性.
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

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