- UID
 - 11574
 
 注册时间2006-4-30
阅读权限10
最后登录1970-1-1
周游历练 
  
 
 
 
该用户从未签到  
 | 
 
 
 楼主 |
发表于 2007-3-4 17:12:04
|
显示全部楼层
 
 
 
标 题: ASPROTECT 2.0脱壳示例 
作 者: loveboom 
时 间: 2004-10-28,23:05 
链 接: http://bbs.pediy.com/showthread.php?threadid=6320 
 
ASPROTECT  2.0 脱壳示例 
【目    标】:Win98’s notepad 
【工    具】:Olydbg1.1(diy版)、LORDPE、ImportREC1.6F 
【任    务】:简单的脱一下asprotect的壳 
【操作平台】:Windows Xp sp2 
【作    者】:loveboom[DFCG][FCG][US] 
【简要说明】:有一段时间没写文章了,这篇文章本来是想在奥运会那时写出来,因为公事比较多,有空的时候心情不好等原因,所以一直放到现在才写. 
【详细过程】: 
设置忽略全部异常,去掉调试标志。 
- 载入后到这里:
 
 - 00401000 >  68 01D040>PUSH 0040D001                            ; EP壳的入口
 
 - 00401005    E8 010000>CALL 0040100B
 
 - 载入后,直接g LoadLibraryA运行到LoadLibraryA这个API处.
 
 - 7C801D77 >  8BFF      MOV EDI,EDI                              ; LoadLibraryA
 
 - 7C801D79    55        PUSH EBP
 
 - 到了后,ALT+F9执行到返回:
 
 - 009884B7    8985 4D29>MOV DWORD PTR SS:[EBP+44294D],EAX        ; 返回到这里
 
 - 009884BD    C785 5129>MOV DWORD PTR SS:[EBP+442951],0
 
 - ……
 
 - 009885C1    61        POPAD
 
 - 009885C2    75 08     JNZ SHORT 009885CC                       ; 看到这里,跟过Aspack的朋友就是知道这里是什么了
 
 - 009885C4    B8 010000>MOV EAX,1
 
 - 009885C9    C2 0C00   RETN 0C
 
 - 009885CC    68 000000>PUSH 0                                   ; 如果解压完壳代码这里会push 一个返回的地址
 
 - 009885D1    C3        RETN
 
 - 返回到009884B7处后,右键查找全部字符串,然后在字符串窗中查找250这样就会看到这些东西:
 
 -  
 
 -  
 
 - 双击10那里到了cpu窗口处:
 
 - 0096CD66   /75 0A     JNZ SHORT 0096CD72
 
 - 0096CD68   |68 C8D096>PUSH 96D0C8                              ; 双击到这里,这里向上找到代码开始处
 
 - 0096CD6D   |E8 BE6DFF>CALL 00963B30
 
 - 向上找到这里:
 
 - 0096CC70   /EB 01     JMP SHORT 0096CC73
 
 - 0096CC72   |90        NOP
 
 - 0096CC73   \8B43 08   MOV EAX,DWORD PTR DS:[EBX+8]             ; 这里开始对IAT进行处理
 
 - 0096CC76    8B30      MOV ESI,DWORD PTR DS:[EAX]
 
 - 0096CC78    8343 08 0>ADD DWORD PTR DS:[EBX+8],4
 
 - 0096CC7C    8B43 08   MOV EAX,DWORD PTR DS:[EBX+8]
 
 - 0096CC7F    8A00      MOV AL,BYTE PTR DS:[EAX]
 
 - 0096CC81    884424 07 MOV BYTE PTR SS:[ESP+7],AL
 
 - 0096CC85    FF43 08   INC DWORD PTR DS:[EBX+8]
 
 - 0096CC88    85F6      TEST ESI,ESI
 
 - 0096CC8A    75 1A     JNZ SHORT 0096CCA6                       ; 这里比较输入表是否处理完毕,如果没有就跳下去
 
 - 0096CC8C    EB 01     JMP SHORT 0096CC8F
 
 - ……
 
 - 0096CCC9    FF43 08   INC DWORD PTR DS:[EBX+8]
 
 - 0096CCCC    84C0      TEST AL,AL                               ; 这里开始对AL的值的不同而进行相关的处理
 
 - 0096CCCE    75 20     JNZ SHORT 0096CCF0
 
 - ……
 
 - 0096CD59    8B4424 14 MOV EAX,DWORD PTR SS:[ESP+14]
 
 - 0096CD5D    E8 DEECFF>CALL 0096BA40                            ; GetProcAddress
 
 - 0096CD62    8BE8      MOV EBP,EAX
 
 - 0096CD64    85ED      TEST EBP,EBP
 
 - 0096CD66    75 0A     JNZ SHORT 0096CD72                       ; 判断获取API是否成功
 
 - 0096CD68    68 C8D096>PUSH 96D0C8                              ; 双击到这里,这里向上找到代码开始处
 
 - 0096CD6D    E8 BE6DFF>CALL 00963B30
 
 - 0096CD72    837C24 20>CMP DWORD PTR SS:[ESP+20],0
 
 - ……
 
 - 0096CDF7    E8 8469FF>CALL 00963780                            ; 当AL为2时对IAT的处理,跟进去
 
 - 0096CDFC  ^ E9 72FEFF>JMP 0096CC73                             ; 处理完跳回去
 
 - ……
 
 - 跟进看看:
 
 - 00963756    8BC0      MOV EAX,EAX
 
 - 00963758    55        PUSH EBP
 
 - 00963759    8BEC      MOV EBP,ESP
 
 - 0096375B    53        PUSH EBX
 
 - 0096375C    8BD8      MOV EBX,EAX
 
 - 0096375E    8BC2      MOV EAX,EDX
 
 - 00963760    8BD1      MOV EDX,ECX
 
 - 00963762    E8 79FFFF>CALL 009636E0
 
 - 00963767    C603 E9   MOV BYTE PTR DS:[EBX],0E9                ; 先在这里也下个断,因为这里就是程序的OEP
 
 - 0096376A    8D53 01   LEA EDX,DWORD PTR DS:[EBX+1]             ; 这里原程跳就是壳抽程序代码的开始地方
 
 - 0096376D    8902      MOV DWORD PTR DS:[EDX],EAX
 
 - 0096376F    8B45 08   MOV EAX,DWORD PTR SS:[EBP+8]
 
 - 00963772    8910      MOV DWORD PTR DS:[EAX],EDX
 
 - 00963774    B8 050000>MOV EAX,5
 
 - 00963779    5B        POP EBX
 
 - 0096377A    5D        POP EBP
 
 - 0096377B    C2 0400   RETN 4
 
 - 0096377E    8BC0      MOV EAX,EAX
 
 - 00963780    53        PUSH EBX                                 ; 进到这里
 
 - 00963781    8BD8      MOV EBX,EAX
 
 - 00963783    8BC3      MOV EAX,EBX
 
 - 00963785    E8 56FFFF>CALL 009636E0
 
 - 0096378A    C603 E8   MOV BYTE PTR DS:[EBX],0E8                ; 这里把IAT的改成call xxxxxx的样式,所以我们这里要进去处理
 
 - 0096378D    43        INC EBX
 
 - 0096378E    8903      MOV DWORD PTR DS:[EBX],EAX
 
 - 00963790    5B        POP EBX
 
 - 00963791    C3        RETN
 
 - 现在这里我们来修复一下:
 
 - 先自己申请两块空间,当然你也可以直接找空闲的地方来写代码,我分别申请了00B90000和00BA0000这个块内存空间,00b90000这块是用来写patch代码,00ba0000是用来保存临时要存放的数据。
 
 - 00BA0000用来保存DLL的基址,00BA0010用来保存要存放IAT的地址。
 
 - 搞清这些东西后,我们开始写代码:
 
 - 00963781    8BD8      MOV EBX,EAX
 
 - 00963783    8BC3      MOV EAX,EBX
 
 - 00963785    E8 56FFFF>CALL 009636E0
 
 - 0096378A    E8 71C822>CALL 00B90000                            ; 调用我们改的代码处
 
 - 0096378F    90        NOP
 
 - 00963790    5B        POP EBX
 
 - 00963791    C3        RETN
 
  
- 00B90000用来写我们自己的修复代码:
 
 - 00B90000    51        PUSH ECX                                 ; 保护现场
 
 - 00B90001    52        PUSH EDX
 
 - 00B90002    8B5424 28 MOV EDX,DWORD PTR SS:[ESP+28]            ; 取出基址到EDX中
 
 - 00B90006    3B15 0000>CMP EDX,DWORD PTR DS:[BA0000]            ; 比较基址是否相同
 
 - 00B9000C    74 0D     JE SHORT 00B9001B
 
 - 00B9000E    8915 0000>MOV DWORD PTR DS:[BA0000],EDX            ; 如果不同就写入新的基址
 
 - 00B90014    8305 1000>ADD DWORD PTR DS:[BA0010],4              ; 并把填入IAT的地址再加上4
 
 - 00B9001B    8B0D 1000>MOV ECX,DWORD PTR DS:[BA0010]            ; 如果是第一次我们要手工写一下保存IAT的地址,我选择的是40C000
 
 - 00B90021    8929      MOV DWORD PTR DS:[ECX],EBP               ; 写入正确的函数
 
 - 00B90023    66:C703 F>MOV WORD PTR DS:[EBX],15FF               ; 这里要看程序的情况而定,如果是DELPHI之类的,这果就可能是FF25了,因为是C的,所以这里是ff15
 
 - 00B90028    890E      MOV DWORD PTR DS:[ESI],ECX               ; 把存放IAT的地址放到程序里
 
 - 00B9002A    8305 1000>ADD DWORD PTR DS:[BA0010],4              ; 保存IAT的地址+4
 
 - 00B90031    5A        POP EDX                                  ; 还原现场
 
 - 00B90032    59        POP ECX
 
 - 00B90033    C3        RETN                                     ; 返回到壳那边继续
 
  
- 继续到AL=1时的处理:
 
 - 0096CE07  ^\E9 67FEFF>JMP 0096CC73
 
 - 0096CE0C    3C 01     CMP AL,1                                 ; 当AL=1的处理
 
 - 0096CE0E    0F85 B200>JNZ 0096CEC6
 
 - ……
 
 - 0096CE7E    A1 B8A697>MOV EAX,DWORD PTR DS:[97A6B8]
 
 - 0096CE83    8B00      MOV EAX,DWORD PTR DS:[EAX]
 
 - 0096CE85    FFD0      CALL EAX                                 ; GetProcAddress
 
 - 0096CE87    8BE8      MOV EBP,EAX
 
 - 0096CE89    85ED      TEST EBP,EBP
 
 - 0096CE8B    75 0A     JNZ SHORT 0096CE97                       ; 如果获取成功就跳
 
 - 0096CE8D    68 D8D096>PUSH 96D0D8                              ; ASCII "11
 
 - "
 
 - 0096CE92    E8 996CFF>CALL 00963B30
 
 - 0096CE97    8B0424    MOV EAX,DWORD PTR SS:[ESP]
 
 - 0096CE9A    50        PUSH EAX
 
 - 0096CE9B    68 08BC96>PUSH 96BC08
 
 - 0096CEA0    8D4C24 20 LEA ECX,DWORD PTR SS:[ESP+20]
 
 - 0096CEA4    8BD5      MOV EDX,EBP
 
 - 0096CEA6    8BC3      MOV EAX,EBX
 
 - 0096CEA8    E8 BFF4FF>CALL 0096C36C
 
 - 0096CEAD    8B5424 0C MOV EDX,DWORD PTR SS:[ESP+C]             ; 这里壳又要对IAT破坏处理,我们这里又要自己修复一下
 
 - 0096CEB1    8902      MOV DWORD PTR DS:[EDX],EAX               ; 这里写上我们自己的代码
 
 - 0096CEB3    8B4424 0C MOV EAX,DWORD PTR SS:[ESP+C]
 
 - 0096CEB7    8906      MOV DWORD PTR DS:[ESI],EAX
 
 - 0096CEB9    0FB74424 >MOVZX EAX,WORD PTR SS:[ESP+4]
 
 - 0096CEBE    0143 08   ADD DWORD PTR DS:[EBX+8],EAX
 
 - 0096CEC1  ^ E9 ADFDFF>JMP 0096CC73                             ; 处理完就跳回去
 
 - 当AL=1时的修复代码:
 
 - 0096CEA8    E8 BFF4FF>CALL 0096C36C
 
 - 0096CEAD    E8 8E3122>CALL 00B90040
 
 - 0096CEB2    90        NOP
 
 - 0096CEB3    90        NOP
 
 - 0096CEB4    90        NOP
 
 - 0096CEB5    90        NOP
 
 - 0096CEB6    90        NOP
 
 - 0096CEB7    90        NOP
 
 - 0096CEB8    90        NOP
 
 - 0096CEB9    0FB74424 >MOVZX EAX,WORD PTR SS:[ESP+4]
 
 - 0096CEBE    0143 08   ADD DWORD PTR DS:[EBX+8],EAX
 
 - 0096CEC1  ^ E9 ADFDFF>JMP 0096CC73
 
  
- 00B90040处的修复代码:
 
 - 00B90040    51        PUSH ECX                                 ; 保护现场
 
 - 00B90041    52        PUSH EDX
 
 - 00B90042    8B5424 20 MOV EDX,DWORD PTR SS:[ESP+20]            ; 取出当然要处理DLL的基址
 
 - 00B90046    3B15 0000>CMP EDX,DWORD PTR DS:[BA0000]            ; 比较基址是否相同
 
 - 00B9004C    74 0D     JE SHORT 00B9005B
 
 - 00B9004E    8915 0000>MOV DWORD PTR DS:[BA0000],EDX
 
 - 00B90054    8305 1000>ADD DWORD PTR DS:[BA0010],4
 
 - 00B9005B    8B0D 1000>MOV ECX,DWORD PTR DS:[BA0010]            ; 1.0040C004
 
 - 00B90061    8929      MOV DWORD PTR DS:[ECX],EBP               ; 把IAT写到我们要指定的地址去也就是40c000那个段里
 
 - 00B90063    890E      MOV DWORD PTR DS:[ESI],ECX               ; 那保存函数的地址写入程序中
 
 - 00B90065    8305 1000>ADD DWORD PTR DS:[BA0010],4
 
 - 00B9006C    5A        POP EDX
 
 - 00B9006D    59        POP ECX                                  ; 还原现场
 
 - 00B9006E    C3        RETN                                     ; 执行到返回
 
 - 到了AL=4的处理了:
 
 - 0096CEC6    3C 04     CMP AL,4                                 ; 当AL为4有两个分支
 
 - 0096CEC8    0F85 F400>JNZ 0096CFC2
 
 - 0096CECE    EB 01     JMP SHORT 0096CED1
 
 - 0096CED0    90        NOP
 
 - 0096CED1    8B43 08   MOV EAX,DWORD PTR DS:[EBX+8]
 
 - 0096CED4    8A00      MOV AL,BYTE PTR DS:[EAX]
 
 - 0096CED6    FF43 08   INC DWORD PTR DS:[EBX+8]
 
 - 0096CED9    84C0      TEST AL,AL
 
 - 0096CEDB    75 5B     JNZ SHORT 0096CF38                       ; 这里跳的话就和AL=1时的处理一样
 
 - 0096CEDD    8B43 08   MOV EAX,DWORD PTR DS:[EBX+8]             ; 这里是AL=4时的第一个分支
 
 - 0096CEE0    8B30      MOV ESI,DWORD PTR DS:[EAX]
 
 - 0096CEE2    8343 08 0>ADD DWORD PTR DS:[EBX+8],4
 
 - 0096CEE6    8B43 08   MOV EAX,DWORD PTR DS:[EBX+8]
 
 - 0096CEE9    8B28      MOV EBP,DWORD PTR DS:[EAX]
 
 - 0096CEEB    8343 08 0>ADD DWORD PTR DS:[EBX+8],4
 
 - 0096CEEF    8B43 08   MOV EAX,DWORD PTR DS:[EBX+8]
 
 - 0096CEF2    8B00      MOV EAX,DWORD PTR DS:[EAX]
 
 - 0096CEF4    894424 2C MOV DWORD PTR SS:[ESP+2C],EAX
 
 - 0096CEF8    8343 08 0>ADD DWORD PTR DS:[EBX+8],4
 
 - 0096CEFC    837B 30 0>CMP DWORD PTR DS:[EBX+30],0
 
 - 0096CF00    75 0A     JNZ SHORT 0096CF0C
 
 - 0096CF02    68 E8D096>PUSH 96D0E8                              ; ASCII "81
 
 - "
 
 - 0096CF07    E8 246CFF>CALL 00963B30
 
 - 0096CF0C    8D5424 30 LEA EDX,DWORD PTR SS:[ESP+30]
 
 - 0096CF10    8BC3      MOV EAX,EBX
 
 - 0096CF12    E8 8DF8FF>CALL 0096C7A4                            ; 这个CALL要进去,因为这里面就是计算将要保存IAT的地址
 
 - 进去看看先:
 
 - 0096C7A4    53        PUSH EBX
 
 - 0096C7A5    56        PUSH ESI
 
 - 0096C7A6    8BF2      MOV ESI,EDX
 
 - 0096C7A8    8BD8      MOV EBX,EAX
 
 - 0096C7AA    B8 040000>MOV EAX,4
 
 - 0096C7AF    E8 985DFE>CALL 0095254C
 
 - 0096C7B4    8906      MOV DWORD PTR DS:[ESI],EAX               ; 这里把计算出来的地址填入[esi]中
 
 - 0096C7B6    8B43 40   MOV EAX,DWORD PTR DS:[EBX+40]
 
 - 0096C7B9    8946 04   MOV DWORD PTR DS:[ESI+4],EAX
 
 - 0096C7BC    5E        POP ESI
 
 - 0096C7BD    5B        POP EBX
 
 - 0096C7BE    C3        RETN
 
 - 这里处理第一个分支先,第二个分支我们可以完全调用AL=1时的代码,AL=4第一个分支的修复代码:
 
 - 0096C7A4    53        PUSH EBX
 
 - 0096C7A5    56        PUSH ESI
 
 - 0096C7A6    8BF2      MOV ESI,EDX
 
 - 0096C7A8    8BD8      MOV EBX,EAX
 
 - 0096C7AA    B8 040000>MOV EAX,4
 
 - 0096C7AF    E8 985DFE>CALL 0095254C
 
 - 0096C7B4    E8 C13822>CALL 00B9007A
 
 - 0096C7B9    8946 04   MOV DWORD PTR DS:[ESI+4],EAX
 
 - 0096C7BC    5E        POP ESI
 
 - 0096C7BD    5B        POP EBX
 
 - 0096C7BE    C3        RETN
 
  
- 00B9007A的修复代码:
 
 - 00B9007A    51        PUSH ECX                                 ; 保护现场
 
 - 00B9007B    52        PUSH EDX
 
 - 00B9007C    8B5424 2C MOV EDX,DWORD PTR SS:[ESP+2C]            ; 取出当然要处理DLL的基址
 
 - 00B90080    3B15 0000>CMP EDX,DWORD PTR DS:[BA0000]            ; kernel32.7C800000
 
 - 00B90086    74 0D     JE SHORT 00B90095
 
 - 00B90088    8915 0000>MOV DWORD PTR DS:[BA0000],EDX
 
 - 00B9008E    8305 1000>ADD DWORD PTR DS:[BA0010],4
 
 - 00B90095    8B0D 1000>MOV ECX,DWORD PTR DS:[BA0010]            ; 1.0040C020
 
 - 00B9009B    890E      MOV DWORD PTR DS:[ESI],ECX               ; 取出我们要保存IAT的址址到[ESI]中
 
 - 00B9009D    8305 1000>ADD DWORD PTR DS:[BA0010],4
 
 - 00B900A4    5A        POP EDX
 
 - 00B900A5    59        POP ECX                                  ; 还原现场
 
 - 00B900A6    8B43 40   MOV EAX,DWORD PTR DS:[EBX+40]            ; 执行我们前面所"吃"掉一行代码
 
 - 00B900A9    C3        RETN                                ;执行到返回
 
 - ……
 
 - 0096CF17    8B4424 2C MOV EAX,DWORD PTR SS:[ESP+2C]
 
 - 0096CF1B    50        PUSH EAX
 
 - 0096CF1C    8D4424 34 LEA EAX,DWORD PTR SS:[ESP+34]
 
 - 0096CF20    50        PUSH EAX
 
 - 0096CF21    55        PUSH EBP
 
 - 0096CF22    A1 70A597>MOV EAX,DWORD PTR DS:[97A570]
 
 - 0096CF27    8B00      MOV EAX,DWORD PTR DS:[EAX]
 
 - 0096CF29    50        PUSH EAX
 
 - 0096CF2A    56        PUSH ESI
 
 - 0096CF2B    8B4424 28 MOV EAX,DWORD PTR SS:[ESP+28]
 
 - 0096CF2F    50        PUSH EAX
 
 - 0096CF30    FF53 30   CALL DWORD PTR DS:[EBX+30]               ; 这里计算函数并写入地址
 
 - 0096CF33  ^ E9 3BFDFF>JMP 0096CC73
 
 - 0096CF38    8B43 08   MOV EAX,DWORD PTR DS:[EBX+8]
 
 - 0096CF3B    8B00      MOV EAX,DWORD PTR DS:[EAX]
 
 - 0096CF3D    890424    MOV DWORD PTR SS:[ESP],EAX
 
 - 0096CF40    8343 08 0>ADD DWORD PTR DS:[EBX+8],4
 
 - 0096CF44    8B43 08   MOV EAX,DWORD PTR DS:[EBX+8]
 
 - 0096CF47    66:8B00   MOV AX,WORD PTR DS:[EAX]
 
 - 0096CF4A    66:894424>MOV WORD PTR SS:[ESP+4],AX
 
 - 0096CF4F    8343 08 0>ADD DWORD PTR DS:[EBX+8],2
 
 - 0096CF53    8B0C24    MOV ECX,DWORD PTR SS:[ESP]
 
 - 0096CF56    66:8B5424>MOV DX,WORD PTR SS:[ESP+4]
 
 - 0096CF5B    8B43 08   MOV EAX,DWORD PTR DS:[EBX+8]
 
 - 0096CF5E    E8 91ABFF>CALL 00967AF4
 
 - 0096CF63    8B4424 10 MOV EAX,DWORD PTR SS:[ESP+10]
 
 - 0096CF67    E8 E055FE>CALL 0095254C
 
 - 0096CF6C    894424 0C MOV DWORD PTR SS:[ESP+C],EAX
 
 - 0096CF70    8B43 08   MOV EAX,DWORD PTR DS:[EBX+8]
 
 - 0096CF73    50        PUSH EAX
 
 - 0096CF74    8B4424 18 MOV EAX,DWORD PTR SS:[ESP+18]
 
 - 0096CF78    50        PUSH EAX
 
 - 0096CF79    A1 B8A697>MOV EAX,DWORD PTR DS:[97A6B8]
 
 - 0096CF7E    8B00      MOV EAX,DWORD PTR DS:[EAX]
 
 - 0096CF80    FFD0      CALL EAX                                 ; GetProcAddress
 
 - 0096CF82    8BE8      MOV EBP,EAX
 
 - 0096CF84    85ED      TEST EBP,EBP
 
 - 0096CF86    75 0C     JNZ SHORT 0096CF94                       ; 如果获取成功就跳
 
 - 0096CF88    68 F8D096>PUSH 96D0F8                              ; ASCII "250
 
 - "
 
 - 0096CF8D    E8 9E6BFF>CALL 00963B30
 
 - 0096CF92    EB 15     JMP SHORT 0096CFA9
 
 - 0096CF94    A1 ECA597>MOV EAX,DWORD PTR DS:[97A5EC]
 
 - 0096CF99    3B28      CMP EBP,DWORD PTR DS:[EAX]
 
 - 0096CF9B    75 0C     JNZ SHORT 0096CFA9
 
 - 0096CF9D    837B 34 0>CMP DWORD PTR DS:[EBX+34],0
 
 - 0096CFA1    74 06     JE SHORT 0096CFA9
 
 - 0096CFA3    8B6B 34   MOV EBP,DWORD PTR DS:[EBX+34]
 
 - 0096CFA6    036B 40   ADD EBP,DWORD PTR DS:[EBX+40]
 
 - 0096CFA9    8B4424 0C MOV EAX,DWORD PTR SS:[ESP+C]             ; 到这里就是和AL=1的处理一样,这里就是第二个分支
 
 - 0096CFAD    8928      MOV DWORD PTR DS:[EAX],EBP
 
 - 0096CFAF    8B4424 0C MOV EAX,DWORD PTR SS:[ESP+C]
 
 - 0096CFB3    8906      MOV DWORD PTR DS:[ESI],EAX
 
 - 0096CFB5    0FB74424 >MOVZX EAX,WORD PTR SS:[ESP+4]
 
 - 0096CFBA    0143 08   ADD DWORD PTR DS:[EBX+8],EAX
 
 - 0096CFBD  ^ E9 B1FCFF>JMP 0096CC73
 
 - ……
 
 - 第二个分支的处理,这里很简单我们只改几行代码就行了,改成这样子:
 
 - 0096CFA9    E8 923022>CALL 00B90040                        ;和AL=1一样的处理
 
 - 0096CFAE    90        NOP
 
 - 0096CFAF    90        NOP
 
 - 0096CFB0    90        NOP
 
 - 0096CFB1    90        NOP
 
 - 0096CFB2    90        NOP
 
 - 0096CFB3    90        NOP
 
 - 0096CFB4    90        NOP
 
 - 这个程序里没有AL=3和AL=5的情况,所以我也就不多说了.
 
 - 好了,处理完IAT后我们记住这里:
 
 - 00963767    C603 E9   MOV BYTE PTR DS:[EBX],0E9
 
 - 直接在这00963767处下断,然后运行,中断在这里后,我们就知道这里的[EBX]就是保存我们的目标程序的OEP,这个对DELPHI的程序就可能不止在这里中断一次,但跳去的地方一定是壳抽程序的代码。
 
 - 00963756    8BC0      MOV EAX,EAX
 
 - 00963758    55        PUSH EBP
 
 - 00963759    8BEC      MOV EBP,ESP
 
 - 0096375B    53        PUSH EBX
 
 - 0096375C    8BD8      MOV EBX,EAX
 
 - 0096375E    8BC2      MOV EAX,EDX
 
 - 00963760    8BD1      MOV EDX,ECX
 
 - 00963762    E8 79FFFF>CALL 009636E0
 
 - 00963767    C603 E9   MOV BYTE PTR DS:[EBX],0E9
 
 - 0096376A    8D53 01   LEA EDX,DWORD PTR DS:[EBX+1]             ; 这里原程跳就是壳抽程序代码的开始地方
 
 - 0096376D    8902      MOV DWORD PTR DS:[EDX],EAX
 
 - 0096376F    8B45 08   MOV EAX,DWORD PTR SS:[EBP+8]
 
 - 00963772    8910      MOV DWORD PTR DS:[EAX],EDX
 
 - 00963774    B8 050000>MOV EAX,5
 
 - 00963779    5B        POP EBX
 
 - 0096377A    5D        POP EBP
 
 - 0096377B    C2 0400   RETN 4                                   ; 直接执行到这里,然后到4010cc处看看
 
 - ……
 
 - 004010CC  - E9 48F177>JMP 00B80219                             ; 这里跳去的地方就是壳抽程序的代码的开始处
 
 - 004010D1    7D 5E     JGE SHORT 00401131
 
 - 004010D3    FF15 00C0>CALL DWORD PTR DS:[40C000]               ; kernel32.GetCommandLineA
 
 - 00B80219就是壳执行原程序的开始处.所以我们直接在00B80219处下个断,然后运行,再次中断后我们就可以比较直观的看到被抽的代码。
 
 - 00B80219    55        PUSH EBP                                 ; 在这里下断,这就是程序的第一行代码
 
 - 00B8021A    336C24 08 XOR EBP,DWORD PTR SS:[ESP+8]
 
 - 00B8021E    336C24 28 XOR EBP,DWORD PTR SS:[ESP+28]
 
 - 00B80222    8BEC      MOV EBP,ESP                              ; 第二行
 
 - ……
 
 - 00B80273    83EC 44   SUB ESP,44                               ; 第三行
 
 - 00B80276    56        PUSH ESI                                 ; 最后一行代码
 
 - 00B80277  ^ E9 ADFFFF>JMP 00B80229
 
 - 这样程序被抽的代码就找回来的,当然,如果是加的DELPHI或其它的C的程序抽的代码就不是这么少了。
 
 - 好了,现在我们被上代码,然后DUMP和修复一下就行了.
 
  
- Greetz:
 
 -  Fly.Jingulong,yock,tDasm.David.ahao.UFO(brother).alan(sister).all of my friends and you!
 
  
- By loveboom[DFCG][FCG]
 
 - Email:[email protected]
 
 - 附件:aspr.rar 附件:aspr.rar转载原创帖请注明出自看雪论坛pediy.com,本贴地址请保留:[url]http://bbs.pediy.com/showthread.php?s=&threadid=6320[/url] 
 
  复制代码 
 
由 loveboom 于 2004-10-28 23:07 最后编辑 
========================= 
 
破解的文章是有,但菜鸟实在很难看得明白,请高手做一个动画教程 |   
 
 
 
 |