|
作者:vifun http://bbs.pediy.com/ " L) Y, Q$ f$ f) R: ?" j& ?
工具:
3 r) T+ p: w% J3 S5 ^5 N4 cOllyDbg 1.10
* g" Z6 Y4 l% g2 K$ O; j5 B0 W2 k8 h: l
crackme: $ L! n& n3 A2 H9 G* i+ I
___crakme/download">http://www.crackmes.de/users/zionz/crackmes/zi___crakme/download % M( y b/ t4 @
总结:
1 c+ a4 x) l# K% I1 b; `1. 不要一开始就用工具,先试运行一下,感觉一下可疑的地方,获取一些重要的信息,如错误提示。
% F: V8 }8 }; ~, h- a' a4 E) y2. 从内存中查找字符串,输入的信息肯定在内存中的,一定找得到! 7 v7 u; W/ W* d4 {
3. 大部分软件是等字符串全部输入了再处理的,内存跟踪,死盯着它!
# G+ U" p" m {3 \1 _" l U' l4. 有些程序是把字符串复制几份放不同地方的,每次被断的时候可以考虑重新搜索一次内存,在所有找到的字符串上下断点。
_: k- u+ Q9 [( ^9 g3 f5. 后发先致,先从最后一次读取入手,先分析最后的处理算法,以免在前面一直浪费时间还影响信心。
( D- a) ^3 z, G9 T& }6. 细心、耐心、信心!!
6 b! |$ g7 o9 ?. i4 M/ L为什么先写总结呢?个人觉得这次破解的体会比获得的知识更重要。这个crackme难度不大,但能给刚入门的cracker一点启示。
2 C, }/ R; T, C. {, |0 ?( `& u2 i3 Z, A a; p
提议:
% o. [* W) k% L2 G0 Z( B3 H: Y作为老鸟,或许感到很多事是必然的,但对我等菜鸟就不是那么明确了。以后破解文章能不能不单是过程的记录(比如突然冒出一个来到这里),最好还能是一种思想的启示(为什么你要来这里,怎么使你来这里)。 $ o6 X$ r3 P2 D. |
最好再加上破解时间,因为一篇文章,看起来那么几百字,感觉像3、5分钟就破完一个程序一样,给初学者信心比较大的打击:"怎么我破了整天都没有搞定呢?"。加上时间,大家就可以看出差距了:"原来××牛人都用了半天,我还不太蠢^_^"。
; z5 K r! V: m& }" J老鸟看到这里就基本上不用看下去了,下面的破解实在是见笑^_^
, @! K" Y- L: _5 y, y! G/ c. {- D
- s/ r4 l5 W3 L9 F9 y3 z) K7 v5 _正文: : A7 i' K" M: N- i
有感于自己也曾经是菜菜鸟(现在是菜鸟^_^),也碰到过不少菜菜鸟级的问题,藉完成一简单破解之际,特发此文,谈谈菜菜鸟最想问的问题--"为什么这样做啊","为什么决定来这里看看",希望能给未来的菜鸟一点教益。老鸟如果看烦了,小的先陪个罪^_^
1 ]( j2 F5 d d昨天在http://www.crackmes.de/ 随手down了个解决了的crackme(___crakme">http://www.crackmes.de/users/zionz/crackmes/zi___crakme)打算学习学习外国人的先进经验(我也是菜鸟啊),没想到两方案都是违背了作者初衷的,自己破吧!
/ X- _0 z$ J6 z. y5 E) R5 S先运行一下那个crackme(还是有个总体的印象好,不要什么都不清楚就用工具破解)。好了,发现是命令行界面的,随便输个号进去,回车,显示"WRONG SERIAL"(注意大小写,这个很重要,把提示都记准确一点)。 / m2 Z5 R" g/ D2 P8 A- E
用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。好了这次有了!向上滚动看看上文(通常都要上下结合的啦),发现了
6 F$ Z6 H8 A D. n: G1016CD75 45 4E 54 45 52 20 53 45 52 49 41 ENTER SERIA
c2 L+ {% W8 i( I; L7 H3 [8 K# S1016CD85 4C 20 54 4F 20 43 4F 4E 54 49 4E 55 45 3A 00 41 L TO CONTINUE:.A& L' b4 ^/ Z6 N& P9 ?* p
1016CD95 58 39 34 33 00 57 45 4C 4C 20 44 4F 4E 45 21 00 X943.WELL DONE!.
) i/ z9 S! u9 A; V& m+ e& \7 X1016CDA5 57 52 4F 4E 47 20 53 45 52 49 41 4C WRONG SERIAL
) H& c. f K5 J6 Z' c5 w' O呵呵,很多字符串哦!AX943是什么,难道就是......按[F9]允许,然后输入AX943,成功了!
: k$ t% e$ @% _1 D1 l0 l) J两个外国人的方案都是到此为止了。如果是破解应用软件,到此也的确够了。此crackme的作者明确表示要求通过任意序列号(Note: Consider it cracked if it accept any serial, not finding the right one.)因此我们继续!
3 u7 v/ V& Q% n0 G[Ctrl+F2]重新开始,按[F9]运行,出现了提示输入的界面。输个好记并且不容易在内存中存在的字符串,我这里输的是QWERTYUIOP(键盘第一行字母,都大写的)。回到OD,依然[Alt+M],然后[Ctrl+B]调出搜索窗口,输入QWERTYUIOP,按ok。很快OD就找到了
5 f; m1 ~* v3 o5 Z1 z, Z/ Q00A5D321 51 57 45 52 54 59 55 49 4F 50 00 0D F0 AD BA QWERTYUIOP..瓠?
8 w( O9 l7 C3 ^7 E$ M右击51(就是那个Q),选"Breakpoint","Memory,on access",这样当crackme读取这个序列号的时候就被中断了。回到crackme,按回车,OD把它中断在
; v2 [0 a- q+ z" I10045B7E 0FBE00 MOVSX EAX,BYTE PTR DS:[EAX] $ W. K7 y! _ q1 V9 J3 B
先不要急,继续[F9]运行,看看它要被读多少次(为什么这样呢,因为很多时候序列号都要被重复读取的,但重要的比较或者运算很可能在最后那次才出现,否则,最后一次读来干嘛就很值得怀疑了) + u5 s5 H. F% Y( y: _$ K
好了,让它运行都结束,出现WRONG SERIAL(当然的结果,浪费少少时间不要紧),发现一共读了5次!我决定从最后一次入手!!(前几次很可能是一些验空串、去空格等预处理) , V+ ` {' y: ~1 U, x# @$ O. h
再一次[Ctrl+F2],再一次输入QWERTYUIOP,查找,并下断点,运行。跳过前4次的中断,我们来到最后那次读取的地方,是 / |! P; y3 U, P7 d
10004DEB F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
$ N- L/ N; V# w( ?! a一看知道是比较了,右边寄存器的窗口还显示出 4 j6 ? _, g& v8 d8 M5 z
ESI 00A5D321 ASCII "QWERTYUIOP"
; f+ o4 H& u ~EDI 00A59FC1 ASCII "AX943"
1 c2 \* j9 Q* H5 `为了通过任意序列号,暴力改下面的跳转吧!
' q, B3 ^3 h8 f9 }: S1 c5 p5 r o$ O10004DED 74 05 JE SHORT Zi__Crac.10004DF4 " p" n* {3 Q1 O. \
原来是相等就跳,我把74改为EB,无条件跳转!
$ V: j* l# u' v }+ f运行crackme,还是WRONG SERIAL!应该是跳转后还有判断吧...... : g% A/ J4 G: K. k
再次运行,跟踪,来到10004DED,无条件跳转后,按[F8]跟下去,很快就发现又有比较了
$ r& r. d5 v9 W6 |3 Y* N10004DFB 3BD6 CMP EDX,ESI ; \0 m2 L( ~9 i. J6 B
代码窗口下面还有提示: ! ?" X8 ?! D* l5 `' g- x- s
ESI=00000005( {, l7 Y# |1 w# }- e' T& s- W
EDX=0000000A ; N5 p% U" M, E4 @- u9 D! n
想一下,5应该是AX943的长度,0A就是QWERTYUIOP的长度10,好,继续改跳转
9 p( C: e0 y3 F3 m, V10004DFD 73 05 JNB SHORT Zi__Crac.10004E04
; w( b! x2 ?% o9 l- w* V7 b0 u: F将73改为EB,无条件跳转!
k6 ]: J: e D细想原来的JNB这个指令有可疑,为什么不是JNE呢,难道下面还有JB指令?继续[F8]跟!
/ `/ D+ }8 O9 V. p( j \& G果然没有错,很快又来一个比较了 # j$ C) M! H% M0 C+ z/ |
10004E06 3BD6 CMP EDX,ESI # g9 N% ~% R2 E, P( O M. @
而且下面紧接的是 . a# @% j2 E/ t! U
10004E08 0F95C0 SETNE AL
- g8 g7 ^) B0 x" m& O呵呵,终于来"NE"了(不相等就怎么怎么样)!!
1 @1 W3 G3 h6 d+ ]% \再看下面
% A: h3 V' `, w+ T; D10004E0B 8BF0 MOV ESI,EAX1 d2 ^4 Q: f. M6 y1 n( L
10004E0D 85DB TEST EBX,EBX
3 \! T# M8 |/ d6 P10004E0F BF 38AD1210 MOV EDI,Zi__Crac.1012AD38
3 u& V1 u$ N6 A6 c+ K2 f: T3 _. m10004E14 74 33 JE SHORT Zi__Crac.10004E49
- i- x6 \7 j5 {% L; R10004E16 8BCB MOV ECX,EBX
* I m# |& j8 w1 p! @$ O10004E18 E8 03FCFFFF CALL Zi__Crac.10004A20
. y9 b X; Q' ~& e5 R7 |( e; {
' Q. ]* w7 r% n( r0 ^' S* @ESI和EAX装的就是比较的结果,然后就是一个CALL!!决不能让你存!!改掉!!目的是要ESI的数值无条件是0(使10004E06处的比较结果一定相等)。考虑到10004E0B的指令有2字节,改为
K. T! J8 ]" i# o+ Q" M& F10004E0B 33F6 XOR ESI,ESI
( I* S; O8 b( p" o5 W6 ?运行......全部通过了^_^
; k5 f8 g9 z# z. s以后用16进制编辑器怎么改就不用多说了,基本工具使用的问题。
! M S- v' d7 T+ I+ X菜鸟一个,有意见或建议请不吝赐教,共同进步 : )
: X9 }2 e" h: L8 l* E7 H) l9 `% H
破解用时:18分钟 : (
$ ~4 c" s0 f. H' o& u9 U 5 p4 ]) |# e e; |+ M
8 m) l* \( u S# `" w
|