|
作者:vifun http://bbs.pediy.com/ 2 V( @4 V& u Y9 y" x+ p
工具:+ v* U6 h+ F5 A! n% E# v
OllyDbg 1.10 + Q6 ]0 {! W% q2 S! d H+ f
% U, s z0 }" V% z
crackme:
1 n N- d/ R N- [. Q I0 O___crakme/download">http://www.crackmes.de/users/zionz/crackmes/zi___crakme/download + E# f. c: f: [7 Y6 Z
总结: 1 U. y/ g+ d" t! H+ q5 M
1. 不要一开始就用工具,先试运行一下,感觉一下可疑的地方,获取一些重要的信息,如错误提示。 , X; s5 Z" U7 v& t) q: h+ X4 B
2. 从内存中查找字符串,输入的信息肯定在内存中的,一定找得到! # `* U$ |! \/ x. @* ^
3. 大部分软件是等字符串全部输入了再处理的,内存跟踪,死盯着它! X3 x* F8 `$ Z) P9 D. h( n3 t
4. 有些程序是把字符串复制几份放不同地方的,每次被断的时候可以考虑重新搜索一次内存,在所有找到的字符串上下断点。
& }% x s6 }" v/ Y8 k% T9 S. ~5. 后发先致,先从最后一次读取入手,先分析最后的处理算法,以免在前面一直浪费时间还影响信心。
& k- [3 B% q& q6. 细心、耐心、信心!!
( e6 q# c# \0 ^4 K: d2 d" v3 G为什么先写总结呢?个人觉得这次破解的体会比获得的知识更重要。这个crackme难度不大,但能给刚入门的cracker一点启示。
8 l2 i3 x' C3 L) ?, p( B- p) W {; X' T
提议: ; m( Q1 o! q" _; {
作为老鸟,或许感到很多事是必然的,但对我等菜鸟就不是那么明确了。以后破解文章能不能不单是过程的记录(比如突然冒出一个来到这里),最好还能是一种思想的启示(为什么你要来这里,怎么使你来这里)。
C+ W5 u5 z `7 n7 G& n0 Y) B5 k最好再加上破解时间,因为一篇文章,看起来那么几百字,感觉像3、5分钟就破完一个程序一样,给初学者信心比较大的打击:"怎么我破了整天都没有搞定呢?"。加上时间,大家就可以看出差距了:"原来××牛人都用了半天,我还不太蠢^_^"。
! U5 B4 i+ M( j, ~老鸟看到这里就基本上不用看下去了,下面的破解实在是见笑^_^
" [& G+ t) ~" O; d) Y* k. w( T. Z: l4 b
正文: ( I' ^4 h4 ]8 k4 j5 C
有感于自己也曾经是菜菜鸟(现在是菜鸟^_^),也碰到过不少菜菜鸟级的问题,藉完成一简单破解之际,特发此文,谈谈菜菜鸟最想问的问题--"为什么这样做啊","为什么决定来这里看看",希望能给未来的菜鸟一点教益。老鸟如果看烦了,小的先陪个罪^_^ 7 O0 n1 A/ ^$ k9 y' z2 l- S
昨天在http://www.crackmes.de/ 随手down了个解决了的crackme(___crakme">http://www.crackmes.de/users/zionz/crackmes/zi___crakme)打算学习学习外国人的先进经验(我也是菜鸟啊),没想到两方案都是违背了作者初衷的,自己破吧!
& @/ n' H& L% M: b& N7 n先运行一下那个crackme(还是有个总体的印象好,不要什么都不清楚就用工具破解)。好了,发现是命令行界面的,随便输个号进去,回车,显示"WRONG SERIAL"(注意大小写,这个很重要,把提示都记准确一点)。
0 m: S- d% E/ ]2 U* u, m用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。好了这次有了!向上滚动看看上文(通常都要上下结合的啦),发现了 g$ b$ g+ o6 Y. r
1016CD75 45 4E 54 45 52 20 53 45 52 49 41 ENTER SERIA
/ S& j: ^" j, o1 X( F1016CD85 4C 20 54 4F 20 43 4F 4E 54 49 4E 55 45 3A 00 41 L TO CONTINUE:.A3 L6 A! Q, e* O2 h
1016CD95 58 39 34 33 00 57 45 4C 4C 20 44 4F 4E 45 21 00 X943.WELL DONE!.' J0 I' Q9 z0 l Y7 @7 ]
1016CDA5 57 52 4F 4E 47 20 53 45 52 49 41 4C WRONG SERIAL * _( W( C% Q2 z, J# g
呵呵,很多字符串哦!AX943是什么,难道就是......按[F9]允许,然后输入AX943,成功了! : U* w/ ~' m, A2 }& f; c
两个外国人的方案都是到此为止了。如果是破解应用软件,到此也的确够了。此crackme的作者明确表示要求通过任意序列号(Note: Consider it cracked if it accept any serial, not finding the right one.)因此我们继续! ; N( B* x. k* [7 v+ F
[Ctrl+F2]重新开始,按[F9]运行,出现了提示输入的界面。输个好记并且不容易在内存中存在的字符串,我这里输的是QWERTYUIOP(键盘第一行字母,都大写的)。回到OD,依然[Alt+M],然后[Ctrl+B]调出搜索窗口,输入QWERTYUIOP,按ok。很快OD就找到了
6 O" i* f: U* x0 V9 i00A5D321 51 57 45 52 54 59 55 49 4F 50 00 0D F0 AD BA QWERTYUIOP..瓠? 8 i7 M# G" J5 S: |8 y1 U
右击51(就是那个Q),选"Breakpoint","Memory,on access",这样当crackme读取这个序列号的时候就被中断了。回到crackme,按回车,OD把它中断在
& r! ^* f9 C& a" p5 j; m2 @4 K% F10045B7E 0FBE00 MOVSX EAX,BYTE PTR DS:[EAX]
$ w4 I7 D$ h1 w' _6 _. B/ `% z( p先不要急,继续[F9]运行,看看它要被读多少次(为什么这样呢,因为很多时候序列号都要被重复读取的,但重要的比较或者运算很可能在最后那次才出现,否则,最后一次读来干嘛就很值得怀疑了)
- K% Z0 h8 U3 a% p好了,让它运行都结束,出现WRONG SERIAL(当然的结果,浪费少少时间不要紧),发现一共读了5次!我决定从最后一次入手!!(前几次很可能是一些验空串、去空格等预处理)
7 y* P5 `/ z, v2 [( u再一次[Ctrl+F2],再一次输入QWERTYUIOP,查找,并下断点,运行。跳过前4次的中断,我们来到最后那次读取的地方,是 4 p$ L; J% k7 ~- j* W8 U6 G" ]
10004DEB F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
8 b) o; |. i6 Z1 a( ^一看知道是比较了,右边寄存器的窗口还显示出
& A( X7 |2 K- u/ q" Y6 l' B; CESI 00A5D321 ASCII "QWERTYUIOP"
5 h& t A" I/ S, o; s" p4 g" a! XEDI 00A59FC1 ASCII "AX943"
- I0 D1 E1 J* i$ E! x为了通过任意序列号,暴力改下面的跳转吧!
0 A1 k7 \9 K- r10004DED 74 05 JE SHORT Zi__Crac.10004DF4
H( k- R" u" J# T; S4 L+ F$ B原来是相等就跳,我把74改为EB,无条件跳转! 6 }1 Y+ y. y) w# L2 f
运行crackme,还是WRONG SERIAL!应该是跳转后还有判断吧...... : _0 W( B- g; i! q6 C
再次运行,跟踪,来到10004DED,无条件跳转后,按[F8]跟下去,很快就发现又有比较了
* o8 u0 i j' U+ Y" V10004DFB 3BD6 CMP EDX,ESI 6 X8 w5 E# U! [! p( k, F
代码窗口下面还有提示:
4 }1 {) @+ Y% a& _+ v7 p" OESI=000000050 `3 O( L7 d& e f+ [1 m! ]2 Q' B0 g
EDX=0000000A F1 D b E4 u A s
想一下,5应该是AX943的长度,0A就是QWERTYUIOP的长度10,好,继续改跳转
. D% w: H8 C V4 @, b; l10004DFD 73 05 JNB SHORT Zi__Crac.10004E04 ! a$ k) _' C# { ]0 h
将73改为EB,无条件跳转!
+ X" U! c! A" Y, J s6 O细想原来的JNB这个指令有可疑,为什么不是JNE呢,难道下面还有JB指令?继续[F8]跟!
& I9 R8 Q z4 H果然没有错,很快又来一个比较了
: Z1 ]# H# J' ^) e10004E06 3BD6 CMP EDX,ESI
2 G; t9 j3 m8 B+ T% Z+ ~5 V' m而且下面紧接的是
6 @! i/ K. i& B5 Y- z% p10004E08 0F95C0 SETNE AL
( P1 u( q# E# `" l呵呵,终于来"NE"了(不相等就怎么怎么样)!!
. }! d: x; S$ Z7 D2 O再看下面 + ^# j3 G# V( B$ t; n) a
10004E0B 8BF0 MOV ESI,EAX
& @7 v5 l g$ A q4 l10004E0D 85DB TEST EBX,EBX
$ s4 e, [ A% M3 ^10004E0F BF 38AD1210 MOV EDI,Zi__Crac.1012AD383 y$ a) K3 n4 @/ x5 ^4 z9 F
10004E14 74 33 JE SHORT Zi__Crac.10004E493 T; C( c! p' l$ v+ X2 t
10004E16 8BCB MOV ECX,EBX
- E! H+ p5 F2 B0 D6 R X2 h4 S: D10004E18 E8 03FCFFFF CALL Zi__Crac.10004A20
0 M: x5 T* B2 [) U! O6 Z2 d3 `& k# x
ESI和EAX装的就是比较的结果,然后就是一个CALL!!决不能让你存!!改掉!!目的是要ESI的数值无条件是0(使10004E06处的比较结果一定相等)。考虑到10004E0B的指令有2字节,改为
4 }" R! B: o# s10004E0B 33F6 XOR ESI,ESI
3 A( b$ O0 m* v: Z; h运行......全部通过了^_^
7 x. t ~. p1 e' A8 T8 S, [, B2 _! r以后用16进制编辑器怎么改就不用多说了,基本工具使用的问题。 + L) ^! v1 m# P* l9 K( c
菜鸟一个,有意见或建议请不吝赐教,共同进步 : )
' K J% |% g0 _- m8 \: Z ?2 ^4 ~1 B7 y& `2 n) Q
破解用时:18分钟 : (
) R9 ]) V/ m3 M& N; s8 j
" o; V. @9 N I0 i
+ N4 P+ M2 b- O. h3 U2 l5 c. x% R |