|
作者:vifun http://bbs.pediy.com/
B* Y5 [$ A% g$ S1 Z/ j# ?2 f" Z工具:
3 I' T( `3 k; p) p+ {OllyDbg 1.10
' I( G8 `5 k% W$ N! _& k3 V
4 ~5 ^$ q; P/ @1 F4 A4 Q5 tcrackme: m$ d$ ?/ L0 c4 k% d! ^$ j' R5 N; T
___crakme/download">http://www.crackmes.de/users/zionz/crackmes/zi___crakme/download ( z8 ?& B( Y% [: X! \
总结:
/ [6 e: R Z! m1. 不要一开始就用工具,先试运行一下,感觉一下可疑的地方,获取一些重要的信息,如错误提示。
2 q" e4 R* z+ |) I+ x I2. 从内存中查找字符串,输入的信息肯定在内存中的,一定找得到!
5 T5 c; J9 w0 v E3. 大部分软件是等字符串全部输入了再处理的,内存跟踪,死盯着它!
7 L/ A9 x4 ~* G8 g1 c+ r4. 有些程序是把字符串复制几份放不同地方的,每次被断的时候可以考虑重新搜索一次内存,在所有找到的字符串上下断点。
" v. r5 j1 i8 u ]- W% F5. 后发先致,先从最后一次读取入手,先分析最后的处理算法,以免在前面一直浪费时间还影响信心。
* J- o* b* v5 d) d# Z, N6. 细心、耐心、信心!! 5 @5 j- W; Y6 ]; f2 |
为什么先写总结呢?个人觉得这次破解的体会比获得的知识更重要。这个crackme难度不大,但能给刚入门的cracker一点启示。
# t; x+ Y0 z) G# Q3 v4 Q
/ {' G& p% o7 }- r# X, d提议: P m2 S' _# c4 p* c& R
作为老鸟,或许感到很多事是必然的,但对我等菜鸟就不是那么明确了。以后破解文章能不能不单是过程的记录(比如突然冒出一个来到这里),最好还能是一种思想的启示(为什么你要来这里,怎么使你来这里)。
3 u9 ]2 M& V7 C3 L最好再加上破解时间,因为一篇文章,看起来那么几百字,感觉像3、5分钟就破完一个程序一样,给初学者信心比较大的打击:"怎么我破了整天都没有搞定呢?"。加上时间,大家就可以看出差距了:"原来××牛人都用了半天,我还不太蠢^_^"。 2 c' ?* H$ \7 j$ n' m9 Q/ [1 M& m
老鸟看到这里就基本上不用看下去了,下面的破解实在是见笑^_^ 8 b2 G+ V- g1 m2 ^ t% Y
( E+ y5 O( R* @. E正文:
+ x9 F. D+ p5 ?! ]5 e6 R( U- Q有感于自己也曾经是菜菜鸟(现在是菜鸟^_^),也碰到过不少菜菜鸟级的问题,藉完成一简单破解之际,特发此文,谈谈菜菜鸟最想问的问题--"为什么这样做啊","为什么决定来这里看看",希望能给未来的菜鸟一点教益。老鸟如果看烦了,小的先陪个罪^_^ 6 r) P, X9 ~- R+ |: P
昨天在http://www.crackmes.de/ 随手down了个解决了的crackme(___crakme">http://www.crackmes.de/users/zionz/crackmes/zi___crakme)打算学习学习外国人的先进经验(我也是菜鸟啊),没想到两方案都是违背了作者初衷的,自己破吧! . G4 u1 u: b# |! l8 e
先运行一下那个crackme(还是有个总体的印象好,不要什么都不清楚就用工具破解)。好了,发现是命令行界面的,随便输个号进去,回车,显示"WRONG SERIAL"(注意大小写,这个很重要,把提示都记准确一点)。 1 h- D9 Z, Q3 V
用OD试着打开,发现没有壳也没有压缩的(这个不用问为什么了吧,OD正常分析通过了)。在代码窗口右击,选"Search for","All referenced text strings",待OD弹出text string窗口后,再右击这个窗口里面随便一处,选"search for text",输入WRONG(全大写,跟提示一样),把Case sensitive和Entire scope选上,按ok。OD提示找不到。好了,这样找不到,试试那样吧:搜索内存,[Alt+M]打开Memory map窗口,右击选中"Search",在ASCII中输入WRONG,同样将Case sensitive和Entire scope选上,按ok。好了这次有了!向上滚动看看上文(通常都要上下结合的啦),发现了 1 R1 U" x ~ J( J1 R; Q# K1 K
1016CD75 45 4E 54 45 52 20 53 45 52 49 41 ENTER SERIA
% b8 e! E0 S% b! p S* c+ Q4 T1016CD85 4C 20 54 4F 20 43 4F 4E 54 49 4E 55 45 3A 00 41 L TO CONTINUE:.A
0 r2 |; ]/ K% ?7 U! v6 R1016CD95 58 39 34 33 00 57 45 4C 4C 20 44 4F 4E 45 21 00 X943.WELL DONE!.
" \* S0 O. u1 G' r1016CDA5 57 52 4F 4E 47 20 53 45 52 49 41 4C WRONG SERIAL 3 q( ^9 o+ @! r
呵呵,很多字符串哦!AX943是什么,难道就是......按[F9]允许,然后输入AX943,成功了! # h% J$ f/ L6 \' O
两个外国人的方案都是到此为止了。如果是破解应用软件,到此也的确够了。此crackme的作者明确表示要求通过任意序列号(Note: Consider it cracked if it accept any serial, not finding the right one.)因此我们继续!
, k) I2 k/ ~7 C0 M3 \: @: {[Ctrl+F2]重新开始,按[F9]运行,出现了提示输入的界面。输个好记并且不容易在内存中存在的字符串,我这里输的是QWERTYUIOP(键盘第一行字母,都大写的)。回到OD,依然[Alt+M],然后[Ctrl+B]调出搜索窗口,输入QWERTYUIOP,按ok。很快OD就找到了 " a# G; ]" J! A2 t" m- [
00A5D321 51 57 45 52 54 59 55 49 4F 50 00 0D F0 AD BA QWERTYUIOP..瓠? " d& h! T& u9 a+ }# B3 u* l( l
右击51(就是那个Q),选"Breakpoint","Memory,on access",这样当crackme读取这个序列号的时候就被中断了。回到crackme,按回车,OD把它中断在 0 ?! J& ~* d$ D9 U8 f8 z1 Z, T
10045B7E 0FBE00 MOVSX EAX,BYTE PTR DS:[EAX]
, C; F4 n, S M& f; {: t先不要急,继续[F9]运行,看看它要被读多少次(为什么这样呢,因为很多时候序列号都要被重复读取的,但重要的比较或者运算很可能在最后那次才出现,否则,最后一次读来干嘛就很值得怀疑了) % j* s& j/ ]5 p) @7 \8 S7 e5 r9 c
好了,让它运行都结束,出现WRONG SERIAL(当然的结果,浪费少少时间不要紧),发现一共读了5次!我决定从最后一次入手!!(前几次很可能是一些验空串、去空格等预处理) 9 U8 F5 b" V' v
再一次[Ctrl+F2],再一次输入QWERTYUIOP,查找,并下断点,运行。跳过前4次的中断,我们来到最后那次读取的地方,是 : @4 m$ c2 K/ W/ k/ ?
10004DEB F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] 1 j( H, F- V3 N/ \8 K+ s4 j$ }
一看知道是比较了,右边寄存器的窗口还显示出
+ w0 U: F. G' DESI 00A5D321 ASCII "QWERTYUIOP"! A* u3 {! i/ Z
EDI 00A59FC1 ASCII "AX943" ( W# V9 g+ k/ z( i5 ^# \" {
为了通过任意序列号,暴力改下面的跳转吧! " S$ b8 F1 g5 j/ v. o# m
10004DED 74 05 JE SHORT Zi__Crac.10004DF4 2 ~5 P9 D2 v. Q- c4 U9 k. u
原来是相等就跳,我把74改为EB,无条件跳转! " Z% v( Q, I% L, ^
运行crackme,还是WRONG SERIAL!应该是跳转后还有判断吧...... 2 V9 W) ?& n, a, U+ F# T& }
再次运行,跟踪,来到10004DED,无条件跳转后,按[F8]跟下去,很快就发现又有比较了
* b- a& L% e2 A5 B- K10004DFB 3BD6 CMP EDX,ESI 1 s5 ]* ?! ]* K4 g
代码窗口下面还有提示:
; D+ f6 i9 _9 mESI=00000005" Y' {; V* a) O+ X0 x4 Y p
EDX=0000000A
- I8 p$ w7 }: q* i# C想一下,5应该是AX943的长度,0A就是QWERTYUIOP的长度10,好,继续改跳转
. Q) c& J: ?1 z8 C10004DFD 73 05 JNB SHORT Zi__Crac.10004E04 & j/ [6 O+ j4 O! Z3 v' m
将73改为EB,无条件跳转!
) j7 i% A' J6 O& u# K细想原来的JNB这个指令有可疑,为什么不是JNE呢,难道下面还有JB指令?继续[F8]跟! ( b# X" _# Q; }/ V
果然没有错,很快又来一个比较了
( g; s) F! l8 C5 m* @6 a% x10004E06 3BD6 CMP EDX,ESI
; K' V7 U1 c- p8 C: z) S7 D0 p! ]5 O而且下面紧接的是 : @# [9 ?3 D0 e- U& u
10004E08 0F95C0 SETNE AL
6 x3 S0 l' V7 ], @4 }# \呵呵,终于来"NE"了(不相等就怎么怎么样)!! + V: ~# A' _9 j5 g6 e2 f1 `
再看下面 2 t1 v6 j6 @& H3 Y) h& G) d
10004E0B 8BF0 MOV ESI,EAX
- n$ r) J; v( E! f10004E0D 85DB TEST EBX,EBX+ Z9 U' D& p4 n
10004E0F BF 38AD1210 MOV EDI,Zi__Crac.1012AD38
" C3 O3 X. e3 B5 e% `& v) G10004E14 74 33 JE SHORT Zi__Crac.10004E49
, @; [+ i* Q7 c2 I! K5 W6 V6 D10004E16 8BCB MOV ECX,EBX, e7 U- b+ }; I8 Z
10004E18 E8 03FCFFFF CALL Zi__Crac.10004A20 % ^$ T9 W7 }3 K, g- M. y/ J4 s4 m
; w4 h: d# ^! h% h9 f& t# MESI和EAX装的就是比较的结果,然后就是一个CALL!!决不能让你存!!改掉!!目的是要ESI的数值无条件是0(使10004E06处的比较结果一定相等)。考虑到10004E0B的指令有2字节,改为
' c6 ]) Z1 b3 L' w/ v! a10004E0B 33F6 XOR ESI,ESI
/ a/ e, t4 s( j) {运行......全部通过了^_^
1 }- i+ c1 @3 u I2 @' g3 e- j以后用16进制编辑器怎么改就不用多说了,基本工具使用的问题。
" Z; l* x8 c \& S6 T8 y菜鸟一个,有意见或建议请不吝赐教,共同进步 : ) ) o( {! ^/ \; |0 A5 x4 Q
' P8 r6 R1 P: L6 V) A" C破解用时:18分钟 : (9 b% w4 |0 z4 d1 d# c4 ^# O7 K* {
, y6 d- _5 D% I% r4 }8 ~
5 G" h6 g5 E- `2 ` |