|
作者:vifun http://bbs.pediy.com/
( ~* g/ a& l$ i" `# E1 s/ m3 c工具:
! b! _7 V! }/ N. z7 `% v7 ]* KOllyDbg 1.10 / x! @. e) d. ^" x2 n: U0 }
, O1 }- J# R! ycrackme: 5 J& r, k6 U7 Z
___crakme/download">http://www.crackmes.de/users/zionz/crackmes/zi___crakme/download # v! `) m8 T4 d4 ~# G- l
总结: 6 c8 C3 k4 M) q" Z/ \ b* I
1. 不要一开始就用工具,先试运行一下,感觉一下可疑的地方,获取一些重要的信息,如错误提示。
2 K) e6 P1 X# G% F b$ w2. 从内存中查找字符串,输入的信息肯定在内存中的,一定找得到!
+ r, n2 M* A5 C. K3. 大部分软件是等字符串全部输入了再处理的,内存跟踪,死盯着它!
7 X1 k" r: _: C4. 有些程序是把字符串复制几份放不同地方的,每次被断的时候可以考虑重新搜索一次内存,在所有找到的字符串上下断点。
0 O7 j$ _2 C* w' A5. 后发先致,先从最后一次读取入手,先分析最后的处理算法,以免在前面一直浪费时间还影响信心。 " s: Q# i7 Q% v/ g2 k
6. 细心、耐心、信心!!
; T6 `- w+ L. l% r7 h$ M+ z# W为什么先写总结呢?个人觉得这次破解的体会比获得的知识更重要。这个crackme难度不大,但能给刚入门的cracker一点启示。 3 c: Z3 ]! z/ O9 Q& A$ e
, Z* g3 i9 j- Z: U% O提议: # N& C0 ]- S1 E$ _' |
作为老鸟,或许感到很多事是必然的,但对我等菜鸟就不是那么明确了。以后破解文章能不能不单是过程的记录(比如突然冒出一个来到这里),最好还能是一种思想的启示(为什么你要来这里,怎么使你来这里)。 4 a3 s7 Y4 l* C% k% w* a, ^
最好再加上破解时间,因为一篇文章,看起来那么几百字,感觉像3、5分钟就破完一个程序一样,给初学者信心比较大的打击:"怎么我破了整天都没有搞定呢?"。加上时间,大家就可以看出差距了:"原来××牛人都用了半天,我还不太蠢^_^"。 0 ^7 b4 M% c( B F5 Q( i) q
老鸟看到这里就基本上不用看下去了,下面的破解实在是见笑^_^
! ~0 `# C- w& \3 Q
' t: j$ s4 S+ ?$ W. {正文: * H0 ` z2 |( R5 W6 I. m. ~7 w. q; T: p
有感于自己也曾经是菜菜鸟(现在是菜鸟^_^),也碰到过不少菜菜鸟级的问题,藉完成一简单破解之际,特发此文,谈谈菜菜鸟最想问的问题--"为什么这样做啊","为什么决定来这里看看",希望能给未来的菜鸟一点教益。老鸟如果看烦了,小的先陪个罪^_^ , {1 T0 s1 H- T+ R* i1 U: S
昨天在http://www.crackmes.de/ 随手down了个解决了的crackme(___crakme">http://www.crackmes.de/users/zionz/crackmes/zi___crakme)打算学习学习外国人的先进经验(我也是菜鸟啊),没想到两方案都是违背了作者初衷的,自己破吧!
8 P; ]& R0 W) |3 S% v7 T先运行一下那个crackme(还是有个总体的印象好,不要什么都不清楚就用工具破解)。好了,发现是命令行界面的,随便输个号进去,回车,显示"WRONG SERIAL"(注意大小写,这个很重要,把提示都记准确一点)。 * w7 Q7 I% _7 j8 @8 O* j2 a# 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。好了这次有了!向上滚动看看上文(通常都要上下结合的啦),发现了
8 u, L% c2 v* y$ L1016CD75 45 4E 54 45 52 20 53 45 52 49 41 ENTER SERIA
, Q+ ]1 ]% U- i1016CD85 4C 20 54 4F 20 43 4F 4E 54 49 4E 55 45 3A 00 41 L TO CONTINUE:.A
/ y7 @5 X* \- P, a+ y1016CD95 58 39 34 33 00 57 45 4C 4C 20 44 4F 4E 45 21 00 X943.WELL DONE!.
( T8 ?3 |/ ~' i2 i1016CDA5 57 52 4F 4E 47 20 53 45 52 49 41 4C WRONG SERIAL 3 ]: u6 p9 o# t6 v& _3 e, h# ^1 h3 N
呵呵,很多字符串哦!AX943是什么,难道就是......按[F9]允许,然后输入AX943,成功了!
* m' D, x9 |5 f" e2 u* O9 ?( |: O两个外国人的方案都是到此为止了。如果是破解应用软件,到此也的确够了。此crackme的作者明确表示要求通过任意序列号(Note: Consider it cracked if it accept any serial, not finding the right one.)因此我们继续! - K( c! v+ I6 _$ q7 K
[Ctrl+F2]重新开始,按[F9]运行,出现了提示输入的界面。输个好记并且不容易在内存中存在的字符串,我这里输的是QWERTYUIOP(键盘第一行字母,都大写的)。回到OD,依然[Alt+M],然后[Ctrl+B]调出搜索窗口,输入QWERTYUIOP,按ok。很快OD就找到了
) i0 \" b# V4 z8 y00A5D321 51 57 45 52 54 59 55 49 4F 50 00 0D F0 AD BA QWERTYUIOP..瓠?
. r* s2 ~( \$ T6 g/ V右击51(就是那个Q),选"Breakpoint","Memory,on access",这样当crackme读取这个序列号的时候就被中断了。回到crackme,按回车,OD把它中断在 + G+ @( c% [) ~! L+ A
10045B7E 0FBE00 MOVSX EAX,BYTE PTR DS:[EAX]
! Y4 q4 v4 @5 ~; G Z3 e$ }0 ]先不要急,继续[F9]运行,看看它要被读多少次(为什么这样呢,因为很多时候序列号都要被重复读取的,但重要的比较或者运算很可能在最后那次才出现,否则,最后一次读来干嘛就很值得怀疑了) ( B* ^/ A1 x- W% v* I. Z
好了,让它运行都结束,出现WRONG SERIAL(当然的结果,浪费少少时间不要紧),发现一共读了5次!我决定从最后一次入手!!(前几次很可能是一些验空串、去空格等预处理)
5 Y* Q2 U+ W# M3 Q再一次[Ctrl+F2],再一次输入QWERTYUIOP,查找,并下断点,运行。跳过前4次的中断,我们来到最后那次读取的地方,是
- i: Z$ y' D/ t$ T10004DEB F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
' f" R! m1 n* X, C6 \9 c一看知道是比较了,右边寄存器的窗口还显示出
& z, ?9 k# N! N+ rESI 00A5D321 ASCII "QWERTYUIOP". T5 l) W0 I1 Y' K4 ?3 P
EDI 00A59FC1 ASCII "AX943"
# v |7 h( G& |' d2 ^为了通过任意序列号,暴力改下面的跳转吧! 3 s& z' {3 f- c& F* f k
10004DED 74 05 JE SHORT Zi__Crac.10004DF4
v! }7 k" l Z J/ \: ~. I原来是相等就跳,我把74改为EB,无条件跳转!
- v: E$ l# X2 p9 e运行crackme,还是WRONG SERIAL!应该是跳转后还有判断吧......
. r8 S, J' y$ G9 U再次运行,跟踪,来到10004DED,无条件跳转后,按[F8]跟下去,很快就发现又有比较了 - c2 _0 ]3 Q) y* y8 K
10004DFB 3BD6 CMP EDX,ESI / g/ m+ z4 }8 R3 b+ h; G
代码窗口下面还有提示: 6 D0 U f. [7 A5 [
ESI=00000005
+ M3 V( p( @, W' `" ^7 [EDX=0000000A
5 _* `( Q6 k2 ^6 |: c; G$ Q" x# Z想一下,5应该是AX943的长度,0A就是QWERTYUIOP的长度10,好,继续改跳转 : H* C" E; |/ @" i: y7 g
10004DFD 73 05 JNB SHORT Zi__Crac.10004E04 , t& [# w1 h; t, E& b
将73改为EB,无条件跳转! 5 s C" ^8 T8 [$ S
细想原来的JNB这个指令有可疑,为什么不是JNE呢,难道下面还有JB指令?继续[F8]跟! . b* g d6 a8 W
果然没有错,很快又来一个比较了
0 |- V j" G9 H4 Z10004E06 3BD6 CMP EDX,ESI
+ x- f: s; r5 x) z3 w8 Y2 C而且下面紧接的是 0 l& j& X" d: `. E# r; v6 c% @0 ^- a
10004E08 0F95C0 SETNE AL
! z9 h: O, ^/ b1 O# ?% z- @$ x4 U( |呵呵,终于来"NE"了(不相等就怎么怎么样)!! 6 F' K; \7 ~. e2 e5 k) \7 A
再看下面
5 M" u d& P; `9 Z10004E0B 8BF0 MOV ESI,EAX
) G$ q6 ^5 F# t/ ^1 ~9 K. ^10004E0D 85DB TEST EBX,EBX& y3 J/ o e5 [, l
10004E0F BF 38AD1210 MOV EDI,Zi__Crac.1012AD38. Z0 x, D. z! p% N
10004E14 74 33 JE SHORT Zi__Crac.10004E49
) T1 Z1 {+ H' B. V R( X7 v/ t' Z10004E16 8BCB MOV ECX,EBX
, a# L1 ]' l# |7 C8 q+ }10004E18 E8 03FCFFFF CALL Zi__Crac.10004A20
) E. v4 d) t) D& M1 o7 Z, f4 M
ESI和EAX装的就是比较的结果,然后就是一个CALL!!决不能让你存!!改掉!!目的是要ESI的数值无条件是0(使10004E06处的比较结果一定相等)。考虑到10004E0B的指令有2字节,改为 " S+ k9 A- A2 b- m, e3 X
10004E0B 33F6 XOR ESI,ESI & ^% F% u7 G; C- D8 i1 e
运行......全部通过了^_^
" T4 r/ K) B0 v) x. E以后用16进制编辑器怎么改就不用多说了,基本工具使用的问题。 7 m3 a5 W$ N: H% V
菜鸟一个,有意见或建议请不吝赐教,共同进步 : ) * |3 a1 T/ ?' c/ b2 B9 t
! p4 L: \* n$ h破解用时:18分钟 : (
' S& F: J) o3 U& y$ ?+ E# Z ) `2 ^0 a( P# }
2 ?. e* i" Q/ D! `5 `. M |