|
作者:vifun http://bbs.pediy.com/ ! ?& G) B5 g7 T8 q, {, c' l
工具:. z0 C0 n2 J0 x4 V4 Y) E; O
OllyDbg 1.10
6 i6 R! K; o) \; s* ]# D2 ^$ g, ~- C1 q. T" P
crackme:
/ M; e- F3 G( u/ E___crakme/download">http://www.crackmes.de/users/zionz/crackmes/zi___crakme/download , q8 e9 J* w# K' y( n; x, b* `
总结:
# }, M' D# `4 o* w, Q$ z1. 不要一开始就用工具,先试运行一下,感觉一下可疑的地方,获取一些重要的信息,如错误提示。 3 A0 e e3 m' D$ Y, I' q
2. 从内存中查找字符串,输入的信息肯定在内存中的,一定找得到!
8 i& r* s, r% N- v3. 大部分软件是等字符串全部输入了再处理的,内存跟踪,死盯着它!
2 O' W5 k# P; k @6 W! D4. 有些程序是把字符串复制几份放不同地方的,每次被断的时候可以考虑重新搜索一次内存,在所有找到的字符串上下断点。
( b6 Q( m! d% b- W; z5. 后发先致,先从最后一次读取入手,先分析最后的处理算法,以免在前面一直浪费时间还影响信心。
9 p. O0 i- D6 x- T) d4 q1 F4 s. m6. 细心、耐心、信心!!
( E0 S3 h h" ^3 K为什么先写总结呢?个人觉得这次破解的体会比获得的知识更重要。这个crackme难度不大,但能给刚入门的cracker一点启示。
. D+ ]6 g6 l- R t
" r' ^; a# G8 Z提议:
( x) C9 x3 I7 S6 Y& i- K; l" A% ] T作为老鸟,或许感到很多事是必然的,但对我等菜鸟就不是那么明确了。以后破解文章能不能不单是过程的记录(比如突然冒出一个来到这里),最好还能是一种思想的启示(为什么你要来这里,怎么使你来这里)。
" `# O( Q2 t, \" G( v8 x- j( ~0 g最好再加上破解时间,因为一篇文章,看起来那么几百字,感觉像3、5分钟就破完一个程序一样,给初学者信心比较大的打击:"怎么我破了整天都没有搞定呢?"。加上时间,大家就可以看出差距了:"原来××牛人都用了半天,我还不太蠢^_^"。 $ M( u. H6 V' q! [" h6 v
老鸟看到这里就基本上不用看下去了,下面的破解实在是见笑^_^ & s: P- Z4 k5 Q1 l6 [3 T
4 c" ` |9 M4 a7 X0 u1 A正文:
9 j. [) D. Q- X2 b7 l9 f有感于自己也曾经是菜菜鸟(现在是菜鸟^_^),也碰到过不少菜菜鸟级的问题,藉完成一简单破解之际,特发此文,谈谈菜菜鸟最想问的问题--"为什么这样做啊","为什么决定来这里看看",希望能给未来的菜鸟一点教益。老鸟如果看烦了,小的先陪个罪^_^
. U# c: o9 T) j. g昨天在http://www.crackmes.de/ 随手down了个解决了的crackme(___crakme">http://www.crackmes.de/users/zionz/crackmes/zi___crakme)打算学习学习外国人的先进经验(我也是菜鸟啊),没想到两方案都是违背了作者初衷的,自己破吧! ) ^8 n/ q( |1 [- B7 c, h+ |
先运行一下那个crackme(还是有个总体的印象好,不要什么都不清楚就用工具破解)。好了,发现是命令行界面的,随便输个号进去,回车,显示"WRONG SERIAL"(注意大小写,这个很重要,把提示都记准确一点)。
3 |7 k' m9 e! t; g5 P用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。好了这次有了!向上滚动看看上文(通常都要上下结合的啦),发现了
2 Q" y7 h4 Q- v8 A' ~1016CD75 45 4E 54 45 52 20 53 45 52 49 41 ENTER SERIA( S1 @7 d: ` s( Q, K
1016CD85 4C 20 54 4F 20 43 4F 4E 54 49 4E 55 45 3A 00 41 L TO CONTINUE:.A8 @; g4 {1 Z( s4 [
1016CD95 58 39 34 33 00 57 45 4C 4C 20 44 4F 4E 45 21 00 X943.WELL DONE!.4 F# b0 q% `0 y
1016CDA5 57 52 4F 4E 47 20 53 45 52 49 41 4C WRONG SERIAL
/ ^& [7 D3 w9 z/ d* I0 H# }: {2 i呵呵,很多字符串哦!AX943是什么,难道就是......按[F9]允许,然后输入AX943,成功了!
; F* |1 h6 l' \$ N) n两个外国人的方案都是到此为止了。如果是破解应用软件,到此也的确够了。此crackme的作者明确表示要求通过任意序列号(Note: Consider it cracked if it accept any serial, not finding the right one.)因此我们继续!
+ G$ e9 C! a( P. M[Ctrl+F2]重新开始,按[F9]运行,出现了提示输入的界面。输个好记并且不容易在内存中存在的字符串,我这里输的是QWERTYUIOP(键盘第一行字母,都大写的)。回到OD,依然[Alt+M],然后[Ctrl+B]调出搜索窗口,输入QWERTYUIOP,按ok。很快OD就找到了 , T$ I5 N- ?% S9 s1 j3 F4 h. \% X
00A5D321 51 57 45 52 54 59 55 49 4F 50 00 0D F0 AD BA QWERTYUIOP..瓠? " g2 i# `6 i3 U3 W- M
右击51(就是那个Q),选"Breakpoint","Memory,on access",这样当crackme读取这个序列号的时候就被中断了。回到crackme,按回车,OD把它中断在 2 S! e: @ Q: \0 M
10045B7E 0FBE00 MOVSX EAX,BYTE PTR DS:[EAX] " }% n5 z: z" o1 l
先不要急,继续[F9]运行,看看它要被读多少次(为什么这样呢,因为很多时候序列号都要被重复读取的,但重要的比较或者运算很可能在最后那次才出现,否则,最后一次读来干嘛就很值得怀疑了) " Q! ?. I" J6 }. m1 H" X
好了,让它运行都结束,出现WRONG SERIAL(当然的结果,浪费少少时间不要紧),发现一共读了5次!我决定从最后一次入手!!(前几次很可能是一些验空串、去空格等预处理) $ z) u; K- p! I) r5 I! C. n) X u% w' k) T
再一次[Ctrl+F2],再一次输入QWERTYUIOP,查找,并下断点,运行。跳过前4次的中断,我们来到最后那次读取的地方,是 ' a, ]5 N7 j% j8 ]: r' d* j) A
10004DEB F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] , z) v2 |4 e9 O( v9 b- ~6 S' ?& i
一看知道是比较了,右边寄存器的窗口还显示出 5 L5 |8 O. g. H4 @7 J7 K9 c
ESI 00A5D321 ASCII "QWERTYUIOP"4 e: r" Z, |- t% x
EDI 00A59FC1 ASCII "AX943"
! u. `" s9 f+ D& g" k为了通过任意序列号,暴力改下面的跳转吧! , ?' Q2 s5 b8 ]. c6 _9 S5 h4 ]
10004DED 74 05 JE SHORT Zi__Crac.10004DF4
4 _3 s5 }+ ?5 i* o, @. o$ `原来是相等就跳,我把74改为EB,无条件跳转!
7 ], W; \1 d6 B, V8 |& B运行crackme,还是WRONG SERIAL!应该是跳转后还有判断吧......
8 A# I- b/ a: F" X再次运行,跟踪,来到10004DED,无条件跳转后,按[F8]跟下去,很快就发现又有比较了 0 U- o* O1 r8 V, _: l$ w/ C9 R
10004DFB 3BD6 CMP EDX,ESI
4 N6 q2 b. J+ H. ]7 @! c! ~4 I/ N% J! H代码窗口下面还有提示: # T. H8 W7 P% Y4 [
ESI=00000005+ E/ g4 P3 L, S3 e: `4 M a3 x
EDX=0000000A
8 B7 t j! N- k( w. Q1 ?想一下,5应该是AX943的长度,0A就是QWERTYUIOP的长度10,好,继续改跳转
) N1 v5 p; y1 @. O4 Z$ j& M10004DFD 73 05 JNB SHORT Zi__Crac.10004E04 $ O! S( a+ y2 Z2 I9 P- I. H0 A
将73改为EB,无条件跳转!
7 Z1 Y8 v# Q1 f4 t细想原来的JNB这个指令有可疑,为什么不是JNE呢,难道下面还有JB指令?继续[F8]跟! / z4 n; q, v w
果然没有错,很快又来一个比较了 1 s1 I, ]6 ~. o4 l
10004E06 3BD6 CMP EDX,ESI
5 N" o! Y) z1 |& p0 j而且下面紧接的是
$ h- q( `2 w9 Z' D0 c; y10004E08 0F95C0 SETNE AL * Q2 A/ S1 V0 E/ q2 ]
呵呵,终于来"NE"了(不相等就怎么怎么样)!! 7 n4 V. p* N5 r
再看下面 p7 S! R( B7 m+ G' D
10004E0B 8BF0 MOV ESI,EAX
- N$ w3 B% z. i' \' H10004E0D 85DB TEST EBX,EBX5 q& [$ y P; [8 u5 O7 u. E
10004E0F BF 38AD1210 MOV EDI,Zi__Crac.1012AD38
7 o5 D- f) P$ J7 F+ l10004E14 74 33 JE SHORT Zi__Crac.10004E49
$ f4 k; m. g: C8 X) h10004E16 8BCB MOV ECX,EBX
6 Q7 W. k. R$ h1 w10004E18 E8 03FCFFFF CALL Zi__Crac.10004A20
, Q- B, d1 L( c7 c6 T9 O3 V/ U3 {! X
ESI和EAX装的就是比较的结果,然后就是一个CALL!!决不能让你存!!改掉!!目的是要ESI的数值无条件是0(使10004E06处的比较结果一定相等)。考虑到10004E0B的指令有2字节,改为
G2 P8 P# i3 \9 I# m10004E0B 33F6 XOR ESI,ESI # ]3 u$ N+ Y' M' R! a9 @
运行......全部通过了^_^ 4 j# f4 M. [& S8 x# j
以后用16进制编辑器怎么改就不用多说了,基本工具使用的问题。 $ ] l& r9 O+ u0 d/ ?
菜鸟一个,有意见或建议请不吝赐教,共同进步 : )
w* G+ S2 }9 |7 X5 g/ h& m7 s: m! a6 y' S: a
破解用时:18分钟 : (
3 s& _, o6 N/ ~3 X
: r1 N" c9 C- x' K& L/ C9 u `
* N% }) x+ U/ z8 k/ W$ G# Q* H |