|
作者:vifun http://bbs.pediy.com/
- Z) B. ?6 T( n4 r& z/ N工具:; Q3 H5 S0 [& R! \. i2 C; }
OllyDbg 1.10 2 |* u" E4 G4 e
) X; d V: n# C5 v# e! ]crackme: # X N+ t0 N1 @5 Z, Z
___crakme/download">http://www.crackmes.de/users/zionz/crackmes/zi___crakme/download 7 f3 z2 }) H, I6 [3 h
总结: & N4 n& m8 ?0 S( d( {. I# `
1. 不要一开始就用工具,先试运行一下,感觉一下可疑的地方,获取一些重要的信息,如错误提示。
8 \0 }* X7 k% w4 r B9 U5 b8 E2 T2. 从内存中查找字符串,输入的信息肯定在内存中的,一定找得到! ' p+ W; X2 q' p/ Q
3. 大部分软件是等字符串全部输入了再处理的,内存跟踪,死盯着它! ( V: M! d( j6 J5 d" [& P) `! Y
4. 有些程序是把字符串复制几份放不同地方的,每次被断的时候可以考虑重新搜索一次内存,在所有找到的字符串上下断点。 8 Y$ A# D* V* U, ~
5. 后发先致,先从最后一次读取入手,先分析最后的处理算法,以免在前面一直浪费时间还影响信心。 ; ~ R7 O/ T* j9 ]/ Q4 ]
6. 细心、耐心、信心!! % p8 Z' A( |4 R# u+ b; o' y9 [
为什么先写总结呢?个人觉得这次破解的体会比获得的知识更重要。这个crackme难度不大,但能给刚入门的cracker一点启示。 ; N' t3 X: V8 h/ }% z) W
; _# P7 o7 h) p0 Z ^4 G" E
提议:
7 O4 u4 z) _6 q" u) Z- \作为老鸟,或许感到很多事是必然的,但对我等菜鸟就不是那么明确了。以后破解文章能不能不单是过程的记录(比如突然冒出一个来到这里),最好还能是一种思想的启示(为什么你要来这里,怎么使你来这里)。
0 b$ `# E( @6 G" f" x6 O+ I. ~5 l$ ~最好再加上破解时间,因为一篇文章,看起来那么几百字,感觉像3、5分钟就破完一个程序一样,给初学者信心比较大的打击:"怎么我破了整天都没有搞定呢?"。加上时间,大家就可以看出差距了:"原来××牛人都用了半天,我还不太蠢^_^"。
& E2 X/ v2 S/ t0 k3 U3 O% K, r老鸟看到这里就基本上不用看下去了,下面的破解实在是见笑^_^ + ^$ S: D8 F% F# @
* `9 o" \( ?# s; `# t正文: ! i: |$ ?( Q) R5 p( K1 O
有感于自己也曾经是菜菜鸟(现在是菜鸟^_^),也碰到过不少菜菜鸟级的问题,藉完成一简单破解之际,特发此文,谈谈菜菜鸟最想问的问题--"为什么这样做啊","为什么决定来这里看看",希望能给未来的菜鸟一点教益。老鸟如果看烦了,小的先陪个罪^_^
; F; x& m. k0 F$ z1 i昨天在http://www.crackmes.de/ 随手down了个解决了的crackme(___crakme">http://www.crackmes.de/users/zionz/crackmes/zi___crakme)打算学习学习外国人的先进经验(我也是菜鸟啊),没想到两方案都是违背了作者初衷的,自己破吧! 0 z9 c& I# T: F* I
先运行一下那个crackme(还是有个总体的印象好,不要什么都不清楚就用工具破解)。好了,发现是命令行界面的,随便输个号进去,回车,显示"WRONG SERIAL"(注意大小写,这个很重要,把提示都记准确一点)。 " n. i& q4 n& R M- o. S S
用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。好了这次有了!向上滚动看看上文(通常都要上下结合的啦),发现了 ; Q5 S8 L* V9 a$ F* ]
1016CD75 45 4E 54 45 52 20 53 45 52 49 41 ENTER SERIA
9 U- ~9 d7 f5 i% I1016CD85 4C 20 54 4F 20 43 4F 4E 54 49 4E 55 45 3A 00 41 L TO CONTINUE:.A( S9 X- x, e, i D' ~1 O" u. a1 f
1016CD95 58 39 34 33 00 57 45 4C 4C 20 44 4F 4E 45 21 00 X943.WELL DONE!.
( p* K3 L- x+ Z# h' A) K1016CDA5 57 52 4F 4E 47 20 53 45 52 49 41 4C WRONG SERIAL
, b& i0 U2 O/ ]* E呵呵,很多字符串哦!AX943是什么,难道就是......按[F9]允许,然后输入AX943,成功了!
* `9 h! ~: l; n+ |7 b8 F两个外国人的方案都是到此为止了。如果是破解应用软件,到此也的确够了。此crackme的作者明确表示要求通过任意序列号(Note: Consider it cracked if it accept any serial, not finding the right one.)因此我们继续!
) G A" j& d& F3 I[Ctrl+F2]重新开始,按[F9]运行,出现了提示输入的界面。输个好记并且不容易在内存中存在的字符串,我这里输的是QWERTYUIOP(键盘第一行字母,都大写的)。回到OD,依然[Alt+M],然后[Ctrl+B]调出搜索窗口,输入QWERTYUIOP,按ok。很快OD就找到了 / e3 c% A0 \) V5 A1 t* I" g
00A5D321 51 57 45 52 54 59 55 49 4F 50 00 0D F0 AD BA QWERTYUIOP..瓠? % H: c, u" G# G
右击51(就是那个Q),选"Breakpoint","Memory,on access",这样当crackme读取这个序列号的时候就被中断了。回到crackme,按回车,OD把它中断在 . H' R3 B' y' ]- s. W& o4 s1 d
10045B7E 0FBE00 MOVSX EAX,BYTE PTR DS:[EAX] . X2 Z( D, m0 V/ e, U6 {
先不要急,继续[F9]运行,看看它要被读多少次(为什么这样呢,因为很多时候序列号都要被重复读取的,但重要的比较或者运算很可能在最后那次才出现,否则,最后一次读来干嘛就很值得怀疑了)
; o- O9 v* H% T# S2 N0 Q好了,让它运行都结束,出现WRONG SERIAL(当然的结果,浪费少少时间不要紧),发现一共读了5次!我决定从最后一次入手!!(前几次很可能是一些验空串、去空格等预处理) 5 O- c4 M* B. _, ~
再一次[Ctrl+F2],再一次输入QWERTYUIOP,查找,并下断点,运行。跳过前4次的中断,我们来到最后那次读取的地方,是 / G! G" M# u2 d6 t+ {
10004DEB F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] 8 b* z( X9 q6 h) f) B
一看知道是比较了,右边寄存器的窗口还显示出 + b4 \- l+ {& R) }0 Z! i' ^
ESI 00A5D321 ASCII "QWERTYUIOP"$ `4 n: b! z# F$ l! i4 m& t o5 ?& N2 ]
EDI 00A59FC1 ASCII "AX943" $ p; W! w U- w& w# E
为了通过任意序列号,暴力改下面的跳转吧!
- R! }7 j3 S# H$ p7 p2 r; j10004DED 74 05 JE SHORT Zi__Crac.10004DF4
. ]7 [3 ~4 ]9 }9 Y3 m原来是相等就跳,我把74改为EB,无条件跳转!
$ l5 p* N' |7 Y# x2 N7 y1 O7 T运行crackme,还是WRONG SERIAL!应该是跳转后还有判断吧...... 7 `6 w1 e5 q5 l9 z" Z, v0 u
再次运行,跟踪,来到10004DED,无条件跳转后,按[F8]跟下去,很快就发现又有比较了
- S& z8 d- i, W, ^; G. s3 e2 q& E10004DFB 3BD6 CMP EDX,ESI % _( w4 b0 q3 i- P* i( v( I# R1 L
代码窗口下面还有提示:
: F' x+ e! E! c9 F/ o! ~# v% yESI=00000005
' F4 u' Q# o. w! o& Y3 |7 y: u- nEDX=0000000A
/ Y1 d. t6 ~* j2 p1 J% c9 o% y2 H想一下,5应该是AX943的长度,0A就是QWERTYUIOP的长度10,好,继续改跳转
, f. [" h' T! p7 r7 ^10004DFD 73 05 JNB SHORT Zi__Crac.10004E04
O/ u4 y$ w; ?0 {3 z+ }+ o将73改为EB,无条件跳转!
: R* `; f5 K' T; \, {细想原来的JNB这个指令有可疑,为什么不是JNE呢,难道下面还有JB指令?继续[F8]跟!
7 `( A( s) e% E; Y0 ~" d果然没有错,很快又来一个比较了 % b* B7 [! n# {! l
10004E06 3BD6 CMP EDX,ESI
2 I6 [, b, i5 a而且下面紧接的是
) W3 }+ \0 h* n( f! t- B10004E08 0F95C0 SETNE AL
1 V( D- {/ q& E% k& Y呵呵,终于来"NE"了(不相等就怎么怎么样)!! 4 A2 L# ~; Q7 @* x0 m2 }1 X0 L9 m
再看下面 # D: a1 t5 T6 L: p4 \
10004E0B 8BF0 MOV ESI,EAX- i9 O; z. i5 `% c4 d* n. u3 d+ q
10004E0D 85DB TEST EBX,EBX1 {( k) h! n4 ?4 _! j8 ]
10004E0F BF 38AD1210 MOV EDI,Zi__Crac.1012AD38' k5 P) j5 }! u, ~5 P
10004E14 74 33 JE SHORT Zi__Crac.10004E49
7 X$ Z, T6 K0 S1 E+ _7 ]5 A/ q10004E16 8BCB MOV ECX,EBX
# U6 a' l* ~6 }; r) z9 x10004E18 E8 03FCFFFF CALL Zi__Crac.10004A20
+ |* J, {$ B7 W' n- s2 ]
, p1 @$ Z- C# N8 o7 qESI和EAX装的就是比较的结果,然后就是一个CALL!!决不能让你存!!改掉!!目的是要ESI的数值无条件是0(使10004E06处的比较结果一定相等)。考虑到10004E0B的指令有2字节,改为
1 S# x& a! x" v9 S) o10004E0B 33F6 XOR ESI,ESI 5 R" H, S) H% I
运行......全部通过了^_^
. K+ {$ K T8 k以后用16进制编辑器怎么改就不用多说了,基本工具使用的问题。
M" F. n- w. E2 _菜鸟一个,有意见或建议请不吝赐教,共同进步 : ) 1 N; n0 b/ S& Y# v/ J+ g: M
& Y8 }# w! t% T6 ~: k; h
破解用时:18分钟 : (
9 D* j) y0 h! [
b7 g& ?, T) T1 e8 T( b# Z, v% V$ k" T6 T* |
|