|
作者:vifun http://bbs.pediy.com/ . V* ^ O5 |6 W9 [
工具:/ a7 F0 L4 v/ x! s, p X
OllyDbg 1.10
5 @* c# s9 R" D7 u P$ v# u
( q- [5 m: M* d% S+ ~crackme: 9 B! L2 X& v$ G! L" P) r
___crakme/download">http://www.crackmes.de/users/zionz/crackmes/zi___crakme/download
2 o/ w0 H' d$ e) n总结:
; l3 I- g, H1 }' s, h& L/ f1. 不要一开始就用工具,先试运行一下,感觉一下可疑的地方,获取一些重要的信息,如错误提示。
2 t# |: W0 M0 ~, @/ t1 Z5 p2. 从内存中查找字符串,输入的信息肯定在内存中的,一定找得到! . l, p1 I/ m) d: _5 n, |
3. 大部分软件是等字符串全部输入了再处理的,内存跟踪,死盯着它! 1 W/ M2 x5 T! W& Z" R) w
4. 有些程序是把字符串复制几份放不同地方的,每次被断的时候可以考虑重新搜索一次内存,在所有找到的字符串上下断点。 / `, }$ L. }7 h P/ B1 k4 g
5. 后发先致,先从最后一次读取入手,先分析最后的处理算法,以免在前面一直浪费时间还影响信心。
4 a/ p8 I( p5 S3 ^6. 细心、耐心、信心!! # M6 x* C _* I$ N S
为什么先写总结呢?个人觉得这次破解的体会比获得的知识更重要。这个crackme难度不大,但能给刚入门的cracker一点启示。 # ]: A0 `) ` f5 ^5 M3 L
: O: P& c ]2 T! M( ~ Q提议:
* K. K+ H7 _. R. l+ }$ Z作为老鸟,或许感到很多事是必然的,但对我等菜鸟就不是那么明确了。以后破解文章能不能不单是过程的记录(比如突然冒出一个来到这里),最好还能是一种思想的启示(为什么你要来这里,怎么使你来这里)。
3 K# w" Z) X5 k最好再加上破解时间,因为一篇文章,看起来那么几百字,感觉像3、5分钟就破完一个程序一样,给初学者信心比较大的打击:"怎么我破了整天都没有搞定呢?"。加上时间,大家就可以看出差距了:"原来××牛人都用了半天,我还不太蠢^_^"。
D0 a* M9 Z8 d老鸟看到这里就基本上不用看下去了,下面的破解实在是见笑^_^
( y0 V0 j6 j s+ G2 W( T. X. C0 N5 j. }3 i4 n
正文:
# M7 \ Q7 _+ ]# x- A有感于自己也曾经是菜菜鸟(现在是菜鸟^_^),也碰到过不少菜菜鸟级的问题,藉完成一简单破解之际,特发此文,谈谈菜菜鸟最想问的问题--"为什么这样做啊","为什么决定来这里看看",希望能给未来的菜鸟一点教益。老鸟如果看烦了,小的先陪个罪^_^ R- ]8 c6 ~2 e$ d( O
昨天在http://www.crackmes.de/ 随手down了个解决了的crackme(___crakme">http://www.crackmes.de/users/zionz/crackmes/zi___crakme)打算学习学习外国人的先进经验(我也是菜鸟啊),没想到两方案都是违背了作者初衷的,自己破吧! 0 }3 E, {8 L& S. v& d, R
先运行一下那个crackme(还是有个总体的印象好,不要什么都不清楚就用工具破解)。好了,发现是命令行界面的,随便输个号进去,回车,显示"WRONG SERIAL"(注意大小写,这个很重要,把提示都记准确一点)。
; p; C; |& d ?5 x- X用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。好了这次有了!向上滚动看看上文(通常都要上下结合的啦),发现了
, h6 w, @$ ~5 j1016CD75 45 4E 54 45 52 20 53 45 52 49 41 ENTER SERIA7 M+ |- G9 i9 H K% [9 j8 D5 D
1016CD85 4C 20 54 4F 20 43 4F 4E 54 49 4E 55 45 3A 00 41 L TO CONTINUE:.A. b1 a, [7 J8 N( F3 f. z
1016CD95 58 39 34 33 00 57 45 4C 4C 20 44 4F 4E 45 21 00 X943.WELL DONE!.
+ D2 J+ F9 |" e' |6 Q% @1016CDA5 57 52 4F 4E 47 20 53 45 52 49 41 4C WRONG SERIAL
0 J- g; N2 } x$ Q& L, @呵呵,很多字符串哦!AX943是什么,难道就是......按[F9]允许,然后输入AX943,成功了! 0 J5 @3 i8 N$ j
两个外国人的方案都是到此为止了。如果是破解应用软件,到此也的确够了。此crackme的作者明确表示要求通过任意序列号(Note: Consider it cracked if it accept any serial, not finding the right one.)因此我们继续!
% ^% [/ U V: B6 y[Ctrl+F2]重新开始,按[F9]运行,出现了提示输入的界面。输个好记并且不容易在内存中存在的字符串,我这里输的是QWERTYUIOP(键盘第一行字母,都大写的)。回到OD,依然[Alt+M],然后[Ctrl+B]调出搜索窗口,输入QWERTYUIOP,按ok。很快OD就找到了
0 o% O1 D% \# k6 g2 s1 Z00A5D321 51 57 45 52 54 59 55 49 4F 50 00 0D F0 AD BA QWERTYUIOP..瓠? + E* E" Q o" D4 a1 W' H
右击51(就是那个Q),选"Breakpoint","Memory,on access",这样当crackme读取这个序列号的时候就被中断了。回到crackme,按回车,OD把它中断在 ; o7 `0 l6 h) Z8 f% @
10045B7E 0FBE00 MOVSX EAX,BYTE PTR DS:[EAX] ' W2 E( Y# t3 [- O, _# X# D5 E
先不要急,继续[F9]运行,看看它要被读多少次(为什么这样呢,因为很多时候序列号都要被重复读取的,但重要的比较或者运算很可能在最后那次才出现,否则,最后一次读来干嘛就很值得怀疑了)
6 {- k5 s/ m4 \" [/ b7 ~, J好了,让它运行都结束,出现WRONG SERIAL(当然的结果,浪费少少时间不要紧),发现一共读了5次!我决定从最后一次入手!!(前几次很可能是一些验空串、去空格等预处理)
9 K1 r0 D- e% [再一次[Ctrl+F2],再一次输入QWERTYUIOP,查找,并下断点,运行。跳过前4次的中断,我们来到最后那次读取的地方,是 9 j2 s8 z; f5 E& O$ N5 A
10004DEB F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
7 K% ^7 v0 q- i& y3 T' @7 k一看知道是比较了,右边寄存器的窗口还显示出
4 l% C* J! ~' z' J8 L9 LESI 00A5D321 ASCII "QWERTYUIOP"
9 R/ L+ Q2 ?" w4 NEDI 00A59FC1 ASCII "AX943" ' [7 r6 N* S! _: E6 v( @7 [' O4 p( y
为了通过任意序列号,暴力改下面的跳转吧!
$ F( F( S% {. e7 J1 T# W10004DED 74 05 JE SHORT Zi__Crac.10004DF4
% Z. [* l$ s; S/ m原来是相等就跳,我把74改为EB,无条件跳转! ! j" i) H* s% W) V
运行crackme,还是WRONG SERIAL!应该是跳转后还有判断吧...... " o" l$ H+ E$ |- r6 q* a
再次运行,跟踪,来到10004DED,无条件跳转后,按[F8]跟下去,很快就发现又有比较了
0 C0 ]. _: y1 A* D2 B7 K/ v10004DFB 3BD6 CMP EDX,ESI 4 m& ?+ I/ y5 }
代码窗口下面还有提示: 2 y& e/ U1 X' T
ESI=00000005
/ A5 @0 C/ P$ q+ xEDX=0000000A 7 @2 V# p0 u5 v# s# J( j) F
想一下,5应该是AX943的长度,0A就是QWERTYUIOP的长度10,好,继续改跳转
6 x, ^! t. J3 f& n9 `8 H7 O. W10004DFD 73 05 JNB SHORT Zi__Crac.10004E04
1 Y* C9 l0 {/ v! S将73改为EB,无条件跳转!
. I; p7 s6 h5 q n, [; L `细想原来的JNB这个指令有可疑,为什么不是JNE呢,难道下面还有JB指令?继续[F8]跟!
: C( q4 L1 U, S2 M2 n4 ~果然没有错,很快又来一个比较了 / s8 V. C4 j1 ^
10004E06 3BD6 CMP EDX,ESI " |; a7 M: z5 }- y: V: U
而且下面紧接的是 * N2 [9 o& v! C# N7 K
10004E08 0F95C0 SETNE AL
' e6 D$ A$ V! n1 o$ } m# u呵呵,终于来"NE"了(不相等就怎么怎么样)!! a2 J6 q. P1 X; E( A
再看下面 ' D+ H" ]$ M) A7 Z
10004E0B 8BF0 MOV ESI,EAX: w3 q; m! C% q" S6 |, u; p3 k
10004E0D 85DB TEST EBX,EBX
% Y) |9 J" @; p7 k0 c' k4 K10004E0F BF 38AD1210 MOV EDI,Zi__Crac.1012AD38
' A6 H# N, ~+ d0 }3 z' C10004E14 74 33 JE SHORT Zi__Crac.10004E49" l m; h! U! @5 z$ ~! F
10004E16 8BCB MOV ECX,EBX
, _4 T# \3 |+ C2 a2 O10004E18 E8 03FCFFFF CALL Zi__Crac.10004A20 7 t2 b7 A, c, W' J# x
1 l2 K# D9 p8 s# |1 j" NESI和EAX装的就是比较的结果,然后就是一个CALL!!决不能让你存!!改掉!!目的是要ESI的数值无条件是0(使10004E06处的比较结果一定相等)。考虑到10004E0B的指令有2字节,改为 1 [' I$ g: y+ N1 I" @
10004E0B 33F6 XOR ESI,ESI ; t* x/ a" \; u; ^- w" g6 E; z
运行......全部通过了^_^
& _! ~* h6 E4 ?% C6 l, E8 m1 e( D以后用16进制编辑器怎么改就不用多说了,基本工具使用的问题。
9 b P5 E) r5 P0 e2 s8 h! i8 g菜鸟一个,有意见或建议请不吝赐教,共同进步 : ) * v; P, b4 E1 i$ ]3 c1 r- o8 m( b
; W2 J7 j3 M1 b% F
破解用时:18分钟 : (6 {9 j' D/ F N. J, J
% k2 v' S. D$ c5 q" z" k% T9 ?4 t/ G0 T2 ]7 F% s
|