能力值:
( LV2,RANK:10 )
|
-
-
2 楼
顶一下
这个是不是有点难啊?
我是 看了 CCDebuger 的脱壳教程 才开始学脱壳的
的确 从没有哪些文章 能象CCDebuger所写的 那么的详细 那么的通俗易懂.
感觉看CCDebuger的文章真的是种享受.
真希望CCDebuger 大虾 有时间的话分析下这个壳 .
|
能力值:
(RANK:990 )
|
-
-
3 楼
不要乱盖,我没写过多少脱壳教程。你这种点名是论坛禁止的,点名只能让其他想帮忙的人不愿帮你。希望下次不要再有这种情况。你这个壳是 Krypton 0.2 的主程序,02 年的东西了,现在基本上看不到了,我也当收藏。这个壳很简单的,我记了个笔记,顺便写个脱壳脚本,你自己看吧。
一、OEP:
不忽略所有异常,用异常计数器插件先第一步计数,程序运行起来后CTR+F2重新载入程序,用异常计数器选第二步:带我到 OEP,当程序暂停时,ALT+M 打开内存,在代码段上按 F2 设断点,再回到反汇编窗口,按 SHIF+F9,断下来的时候往下看一下:
004E3A58 8B95 B6BB4100 MOV EDX,DWORD PTR SS:[EBP+41BBB6]
004E3A5E FFE2 JMP EDX ; 跳到 OEP
004E3A60 51 PUSH ECX
004E3A61 836C24 04 06 SUB DWORD PTR SS:[ESP+4],6
那个 JMP EDX 就是跳到 OEP 的。在这条命令上设断,F9,再按 F8,就到 OEP 了:
00401000 6A 00 PUSH 0 ; OEP
00401002 E8 C1100000 CALL 004020C8
00401007 A3 583B4000 MOV DWORD PTR DS:[403B58],EAX
--------------------------------------------------------------------------------------------------
二、输入表:
到 OEP 后,右键选择“分析->从模块中删除分析”,随便找个 API 调用看看,可以知道输入表加密了:
004020C8 - FF25 04D14100 JMP DWORD PTR DS:[41D104] ; 输入表被加密了
004020CE - FF25 0CD14100 JMP DWORD PTR DS:[41D10C]
004020D4 - FF25 10D14100 JMP DWORD PTR DS:[41D110]
004020DA - FF25 14D14100 JMP DWORD PTR DS:[41D114]
--------------------------------------------------------------------------------------------------
现在 CTR+F2 重新载入程序,为方便调试,忽略所有异常。定位到数据窗口,CTR+G 转到我们前面看到的地址 41D104,设内存写入断点。一直按 F9,当断下来看到如下代码时就看到处理输入表的部分了:
--------------------------------------------------------------------------------------------------
004E311F 8907 MOV DWORD PTR DS:[EDI],EAX ; 获取的函数地址送到输入表中的相关位置。如果前面没NOP,这里会加密
004E3121 EB 45 JMP SHORT 004E3168
004E3123 DF69 4E FILD QWORD PTR DS:[ECX+4E]
004E3126 58 POP EAX
--------------------------------------------------------------------------------------------------
删除内存断点,一路 F8 跟跟看:
004E2812 8B95 2C784000 MOV EDX,DWORD PTR SS:[EBP+40782C] ; 处理输入表
004E2818 8B06 MOV EAX,DWORD PTR DS:[ESI]
004E281A 0BC0 OR EAX,EAX
004E281C 75 03 JNZ SHORT 004E2821
004E281E 8B46 10 MOV EAX,DWORD PTR DS:[ESI+10]
004E2821 03C2 ADD EAX,EDX ; 基址+输入表函数RVA
004E2823 0385 1C784000 ADD EAX,DWORD PTR SS:[EBP+40781C]
004E2829 8B18 MOV EBX,DWORD PTR DS:[EAX]
004E282B 8B7E 10 MOV EDI,DWORD PTR DS:[ESI+10]
004E282E 03FA ADD EDI,EDX
004E2830 03BD 1C784000 ADD EDI,DWORD PTR SS:[EBP+40781C]
004E2836 85DB TEST EBX,EBX
004E2838 0F84 B9090000 JE 004E31F7
004E283E F7C3 00000011 TEST EBX,11000000
004E2844 75 2A JNZ SHORT 004E2870
004E2846 F7C3 00000080 TEST EBX,80000000
004E284C 75 22 JNZ SHORT 004E2870
004E284E 03DA ADD EBX,EDX
004E2850 83C3 02 ADD EBX,2
004E2853 813B 46617461 CMP DWORD PTR DS:[EBX],61746146
004E2859 75 0D JNZ SHORT 004E2868
004E285B 817B 04 6C45786>CMP DWORD PTR DS:[EBX+4],6978456C
004E2862 0F84 8F090000 JE 004E31F7
004E2868 899D 6F714000 MOV DWORD PTR SS:[EBP+40716F],EBX
004E286E EB 17 JMP SHORT 004E2887
004E2870 90 NOP
004E2871 90 NOP
004E2872 81EB 00000011 SUB EBX,11000000
004E2878 C1CB 03 ROR EBX,3
004E287B C785 6F714000 0>MOV DWORD PTR SS:[EBP+40716F],0
004E2885 /EB 11 JMP SHORT 004E2898
004E2887 |90 NOP
004E2888 |90 NOP
004E2889 |C00B 02 ROR BYTE PTR DS:[EBX],2
004E288C |43 INC EBX
004E288D |803B 00 CMP BYTE PTR DS:[EBX],0
004E2890 ^|75 F5 JNZ SHORT 004E2887
004E2892 |8B9D 6F714000 MOV EBX,DWORD PTR SS:[EBP+40716F]
004E2898 \90 NOP
004E2899 81E3 FFFFFF0F AND EBX,0FFFFFFF
004E289F 53 PUSH EBX
004E28A0 FFB5 18784000 PUSH DWORD PTR SS:[EBP+407818]
004E28A6 FF95 50BE4100 CALL DWORD PTR SS:[EBP+41BE50]
004E28AC 83BD 6F714000 0>CMP DWORD PTR SS:[EBP+40716F],0
004E28B3 74 13 JE SHORT 004E28C8
004E28B5 8B8D 6F714000 MOV ECX,DWORD PTR SS:[EBP+40716F] ; 解码后的输入表函数ASCII字串
004E28BB 90 NOP
004E28BC 90 NOP
004E28BD 90 NOP
004E28BE D221 SHL BYTE PTR DS:[ECX],CL ; 继续加密原来的函数ASCII字串
004E28C0 3001 XOR BYTE PTR DS:[ECX],AL
004E28C2 41 INC ECX
004E28C3 8039 00 CMP BYTE PTR DS:[ECX],0
004E28C6 ^ 75 F3 JNZ SHORT 004E28BB
004E28C8 0BC0 OR EAX,EAX
004E28CA ^ 0F84 CADFFFFF JE 004E089A
004E28D0 EB 44 JMP SHORT 004E2916
--------------------------------------------------------------------------------------------------
004E29AF 8985 96714000 MOV DWORD PTR SS:[EBP+407196],EAX ; 保存获取的输入表函数地址
004E29B5 EB 45 JMP SHORT 004E29FC
004E29B7 DF69 4E FILD QWORD PTR DS:[ECX+4E]
004E29BA 58 POP EAX
--------------------------------------------------------------------------------------------------
004E30D5 8B85 A6714000 MOV EAX,DWORD PTR SS:[EBP+4071A6] ; 加密输入表的,NOP掉
004E30DB EB 38 JMP SHORT 004E3115
004E30DD DF69 4E FILD QWORD PTR DS:[ECX+4E]
004E30E0 58 POP EAX
--------------------------------------------------------------------------------------------------
三、脱壳脚本:
/*
Script written by CCDebuger
Script : Krypton 0.2 Unpack
版本 : v0.1
日期 : 17-04-2009
调试环境 : OllyDbg 1.1, ODBGScript 1.65, WINXP, WIN2000
调试选项 : 设置 OllyDbg 忽略所有异常选项
工具 : OllyDbg, ODBGScript 1.65
感谢 : Oleh Yuschuk - author of OllyDbg
SHaG - author of OllyScript
hnhuqiong - author of ODbgScript
*/
var temp
cmp $VERSION, "1.65"
jb errorver
bc
bphwcall
dbh
findop eip, #FFE6#
mov temp, $RESULT
bp temp
esto
bc
sto
find eip, #8B95????????8B060BC0#
mov temp, $RESULT
bp temp
esto
bc
find eip, #8B85????????EB#
mov temp, $RESULT
add temp, 6
/*查找以下命令:
004E30D5 8B85 A6714000 MOV EAX,DWORD PTR SS:[EBP+4071A6] ; 加密输入表的,NOP掉
*/
find temp, #8B85????????EB#
mov temp, $RESULT
mov [temp], #909090909090#
/*查找以下命令:
004E3A5E FFE2 JMP EDX ; 跳到 OEP
004E3A60 51 PUSH ECX
*/
find temp, #FFE251#
mov temp, $RESULT
bphws temp, "x"
esto
bphwc
sto
cmt eip, "已到 OEP,请用 ImportREC 重建输入表"
ret
errorver:
msg "运行此脚本需要 ODbgScript 1.65 或更高的版本,您的版本过低,请更新 ODbgScript 后再试。"
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
我觉得CCDebuger的伟大之处就在于 他写的文章层次分明,重点突出.
使刚入门的菜鸟也能看懂 . 我今天抽时间 看了下
终于能自己脱掉了.
不过 其实文章的中的关键点我自己也曾跟到过, 例如
004E311F 8907 MOV DWORD PTR DS:[EDI],EAX ; 获取的函数地址送到输入表中的相关位置。如果前面没NOP,这里会加密
这里我跟到后 前后都充斥着无数的花指令
我鼠标在OD往上一拉 ,代码就变了 慢慢按F8跟把 好象有循环 不知道啥时候能跳出来 其实我遇到难点就是花指令 如何识别花指令 如何使代码的世界清净点呢???? 这是我最困惑的地方.
|
能力值:
(RANK:990 )
|
-
-
6 楼
说话别那么夸张,我没那么伟大。
花指令无所谓,在相关位置设个断点,CTR+F12跟踪步过,到设的断点暂停时看一下跟踪的记录窗口就可以了。这里你看到的应该都是正常的指令。
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
请问直接单步能脱掉吗?
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
CCDebuger 大虾
我这个附件中的用你脚本脱后 运行没反映
我自己手脱也是没反映
我也查下原因.
|
能力值:
( LV9,RANK:180 )
|
-
-
9 楼
简单的: 补上 630000 这个段 (RVA=230000)
困难的: 不用补段. 依你现在的状况...等你日后更利害一点再来看.
nba2005 可以脱一下 8 楼那个(不补段), 再用你的文笔给8楼开个光.
|
能力值:
( LV2,RANK:10 )
|
-
-
10 楼
不完美啊
看来这个古董壳 有意思的地方以前牛人都没发现啊
他不但把call dword ptr ds:[40c004]类型的给改了
把mov eax,dword ptr ds:[40c004]这种类型的也全改了 好象 其实现在来说关键是这种的修复
|
能力值:
( LV2,RANK:10 )
|
-
-
11 楼
脱是脱了 就是运行错误啊!
|
能力值:
( LV2,RANK:10 )
|
-
-
12 楼
终于搞定了 不用补区段的拙劣方式
////////////////////////////////////////////
完了后运行没反映。
找到一个出错的地方。
CALL DWORD PTR DS:[397BF5]
f7进去 看他怎么处理的
可以看到一个地址比较重要EAX=00374375,指令是从这里取的。 dd 374375
00374375 004010E9
00374379 07F00D8B
0037437D 11F80041
00374381 1D8B0040
00374385 0040C0BC
00374389 00401290
0037438D DDBC158B
00374391 15870040
00374395 0D8B0040 发现004010e9处的原始指令原来藏在这里。
看来要patch代码了。
首先把/*373A46*/ MOV DWORD PTR DS:[EAX+2],EBX
改为00373A46 /EB 18 JMP SHORT 00373A60
然后在下面patch代码
00373A60 E8 00000000 CALL 00373A65
00373A65 5B POP EBX
00373A66 81C3 10090000 ADD EBX,910 //得到存原始指令地址
00373A6C 8B13 MOV EDX,DWORD PTR DS:[EBX]
00373A6E 3BC2 CMP EAX,EDX
00373A70 74 05 JE SHORT 00373A77
00373A72 83C3 0A ADD EBX,0A //4字节地址+6字节指令=0A
00373A75 ^ EB F5 JMP SHORT 00373A6C
00373A77 83C3 04 ADD EBX,4
00373A7A 8B13 MOV EDX,DWORD PTR DS:[EBX]
00373A7C 8910 MOV DWORD PTR DS:[EAX],EDX //patch后四字节指令
00373A7E 83C0 04 ADD EAX,4
00373A81 83C3 04 ADD EBX,4
00373A84 66:8B13 MOV DX,WORD PTR DS:[EBX]
00373A87 66:8910 MOV WORD PTR DS:[EAX],DX //patch前2字节指令
00373A8A EB BD JMP SHORT 00373A49 //跳回去
现在再走到OEP后 直接用OD插件脱壳就可以顺利运行了.. 终于弄懂了这个古董了.
|
能力值:
( LV3,RANK:20 )
|
-
-
14 楼
到达OEP没多少难度,但是输入表加密一直都弄不好。看看大牛写的那叫一个轻松呀。膜拜
好好学习下怎么避过加密的
|
能力值:
( LV2,RANK:10 )
|
-
-
15 楼
全靠 CCDebuger大虾的 栽培啊
|