|
作者:vifun http://bbs.pediy.com/
2 A0 Z' K; S" Z/ i5 N工具:
- Z* C N1 V. E, V- l: H* oOllyDbg 1.10
9 j% t! Q0 i! h) T( E7 t/ S2 ?$ S3 R, J5 v
crackme: : B' Y% N9 t% D4 q2 O& e
___crakme/download">http://www.crackmes.de/users/zionz/crackmes/zi___crakme/download ) u2 Z q2 _7 \: r
总结: 8 [% U5 q, ]0 O; Q1 ~ m9 G
1. 不要一开始就用工具,先试运行一下,感觉一下可疑的地方,获取一些重要的信息,如错误提示。
: _. A+ d& m i s1 q+ u6 l2. 从内存中查找字符串,输入的信息肯定在内存中的,一定找得到! # V6 i& }+ V$ b/ e
3. 大部分软件是等字符串全部输入了再处理的,内存跟踪,死盯着它! ) f( S) X" E) c9 [6 A/ m
4. 有些程序是把字符串复制几份放不同地方的,每次被断的时候可以考虑重新搜索一次内存,在所有找到的字符串上下断点。
6 V& M$ v8 Z" w; S P5. 后发先致,先从最后一次读取入手,先分析最后的处理算法,以免在前面一直浪费时间还影响信心。
; ~ I7 o5 Z/ ^4 w6. 细心、耐心、信心!! + j' v4 E0 w4 E7 n* a" P
为什么先写总结呢?个人觉得这次破解的体会比获得的知识更重要。这个crackme难度不大,但能给刚入门的cracker一点启示。
2 Q) B. ?' G6 ]% ]
; Q8 H5 B! f( j* X提议: 6 M/ {3 F7 R& P6 Z
作为老鸟,或许感到很多事是必然的,但对我等菜鸟就不是那么明确了。以后破解文章能不能不单是过程的记录(比如突然冒出一个来到这里),最好还能是一种思想的启示(为什么你要来这里,怎么使你来这里)。 + U8 J" Y, h# \% m8 L% O
最好再加上破解时间,因为一篇文章,看起来那么几百字,感觉像3、5分钟就破完一个程序一样,给初学者信心比较大的打击:"怎么我破了整天都没有搞定呢?"。加上时间,大家就可以看出差距了:"原来××牛人都用了半天,我还不太蠢^_^"。
5 R) K9 B& w% r" J& Z1 u$ ?老鸟看到这里就基本上不用看下去了,下面的破解实在是见笑^_^ ) ?% `3 u! G, Y* A* T6 p* _
2 s3 y$ W. `+ }4 g" y* w+ O3 T& z; O6 p正文:
. U* s: x! c. R. ~& ?3 q有感于自己也曾经是菜菜鸟(现在是菜鸟^_^),也碰到过不少菜菜鸟级的问题,藉完成一简单破解之际,特发此文,谈谈菜菜鸟最想问的问题--"为什么这样做啊","为什么决定来这里看看",希望能给未来的菜鸟一点教益。老鸟如果看烦了,小的先陪个罪^_^ - W. M2 @- j; }6 k# T' q9 ^
昨天在http://www.crackmes.de/ 随手down了个解决了的crackme(___crakme">http://www.crackmes.de/users/zionz/crackmes/zi___crakme)打算学习学习外国人的先进经验(我也是菜鸟啊),没想到两方案都是违背了作者初衷的,自己破吧!
+ }+ R) V f+ S9 i4 \/ _' `先运行一下那个crackme(还是有个总体的印象好,不要什么都不清楚就用工具破解)。好了,发现是命令行界面的,随便输个号进去,回车,显示"WRONG SERIAL"(注意大小写,这个很重要,把提示都记准确一点)。
5 T- @" @$ I3 a. I2 |. R, |用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。好了这次有了!向上滚动看看上文(通常都要上下结合的啦),发现了 ' @: T! l% J0 j6 b* X7 U$ p
1016CD75 45 4E 54 45 52 20 53 45 52 49 41 ENTER SERIA' Q6 J n' ]5 B' d$ X
1016CD85 4C 20 54 4F 20 43 4F 4E 54 49 4E 55 45 3A 00 41 L TO CONTINUE:.A
; D7 |2 [& n6 N8 _- D1016CD95 58 39 34 33 00 57 45 4C 4C 20 44 4F 4E 45 21 00 X943.WELL DONE!., t$ _: H) m2 X Q( P. A3 P
1016CDA5 57 52 4F 4E 47 20 53 45 52 49 41 4C WRONG SERIAL ! z J. }# a% m' y2 z' J
呵呵,很多字符串哦!AX943是什么,难道就是......按[F9]允许,然后输入AX943,成功了! : C B1 }2 {3 H8 B, B% `
两个外国人的方案都是到此为止了。如果是破解应用软件,到此也的确够了。此crackme的作者明确表示要求通过任意序列号(Note: Consider it cracked if it accept any serial, not finding the right one.)因此我们继续! : t5 p& F. [; _; _( Y4 N
[Ctrl+F2]重新开始,按[F9]运行,出现了提示输入的界面。输个好记并且不容易在内存中存在的字符串,我这里输的是QWERTYUIOP(键盘第一行字母,都大写的)。回到OD,依然[Alt+M],然后[Ctrl+B]调出搜索窗口,输入QWERTYUIOP,按ok。很快OD就找到了 + E' U/ m0 I6 u
00A5D321 51 57 45 52 54 59 55 49 4F 50 00 0D F0 AD BA QWERTYUIOP..瓠? " u# I8 J" ^' y7 Q7 Q
右击51(就是那个Q),选"Breakpoint","Memory,on access",这样当crackme读取这个序列号的时候就被中断了。回到crackme,按回车,OD把它中断在 : f0 h2 |1 k( i! i
10045B7E 0FBE00 MOVSX EAX,BYTE PTR DS:[EAX] + t5 h, W6 m1 D- R2 T; p) l
先不要急,继续[F9]运行,看看它要被读多少次(为什么这样呢,因为很多时候序列号都要被重复读取的,但重要的比较或者运算很可能在最后那次才出现,否则,最后一次读来干嘛就很值得怀疑了) 6 x, _# v9 O E6 \
好了,让它运行都结束,出现WRONG SERIAL(当然的结果,浪费少少时间不要紧),发现一共读了5次!我决定从最后一次入手!!(前几次很可能是一些验空串、去空格等预处理)
# W( g/ o- U# g2 P# A再一次[Ctrl+F2],再一次输入QWERTYUIOP,查找,并下断点,运行。跳过前4次的中断,我们来到最后那次读取的地方,是
; }' {: q( _& k' f- w% x3 t10004DEB F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] / N$ K k) F) f$ d5 @
一看知道是比较了,右边寄存器的窗口还显示出 - m8 h$ u! u' ]" S0 D: j2 x! E& c
ESI 00A5D321 ASCII "QWERTYUIOP"
2 U$ k, U) ~" E% ~" L+ jEDI 00A59FC1 ASCII "AX943"
" B( A* h0 s3 C/ Y8 S! }为了通过任意序列号,暴力改下面的跳转吧! 5 e# s3 h a1 ~( z, [- Q9 n
10004DED 74 05 JE SHORT Zi__Crac.10004DF4 5 X# `( _3 Z+ S% J
原来是相等就跳,我把74改为EB,无条件跳转!
; d0 ~% |4 i( p" G- J运行crackme,还是WRONG SERIAL!应该是跳转后还有判断吧......
8 g/ e+ j2 S& c8 \3 ^5 ]再次运行,跟踪,来到10004DED,无条件跳转后,按[F8]跟下去,很快就发现又有比较了 % S) U# Y% |' [' ~* \; x1 Q
10004DFB 3BD6 CMP EDX,ESI 5 ?# P' ]; t$ d* ~$ l7 G
代码窗口下面还有提示:
, H5 V( o( S; }3 X- R6 bESI=00000005
( p3 ]: e& ^- c+ P. ]$ SEDX=0000000A
8 u$ j# _- u4 ?8 t# J5 I想一下,5应该是AX943的长度,0A就是QWERTYUIOP的长度10,好,继续改跳转
( J- }$ a8 Z0 I" K10004DFD 73 05 JNB SHORT Zi__Crac.10004E04
! I+ d' s S, P$ E2 g" l将73改为EB,无条件跳转! 3 P7 I' x6 _0 z) M* r
细想原来的JNB这个指令有可疑,为什么不是JNE呢,难道下面还有JB指令?继续[F8]跟! $ t' M# q! G3 _* ?. j8 l
果然没有错,很快又来一个比较了 - q! }; R/ X6 E! y& {1 \7 x
10004E06 3BD6 CMP EDX,ESI
' J3 T8 y! e X6 l而且下面紧接的是
# J* e; Z# m- t" ?: m10004E08 0F95C0 SETNE AL 4 e& w( e! v6 U B" L
呵呵,终于来"NE"了(不相等就怎么怎么样)!! ) U! I4 x$ K* O& ~
再看下面
- R, h$ H3 r, l: C) [10004E0B 8BF0 MOV ESI,EAX
5 M7 E J. m* t, ^10004E0D 85DB TEST EBX,EBX* E9 `" _2 \& S$ D! o
10004E0F BF 38AD1210 MOV EDI,Zi__Crac.1012AD38
2 P- c+ b0 V( U- ]$ u, N10004E14 74 33 JE SHORT Zi__Crac.10004E493 ^3 s( o5 r( J1 Z
10004E16 8BCB MOV ECX,EBX1 W' S5 f* L9 |
10004E18 E8 03FCFFFF CALL Zi__Crac.10004A20 * J5 T) ^: m! H1 G6 G
, G9 m4 |3 F! f2 C1 rESI和EAX装的就是比较的结果,然后就是一个CALL!!决不能让你存!!改掉!!目的是要ESI的数值无条件是0(使10004E06处的比较结果一定相等)。考虑到10004E0B的指令有2字节,改为
1 p4 O' w! E ~" x$ x10004E0B 33F6 XOR ESI,ESI , h, t3 V7 _ ~
运行......全部通过了^_^
* P1 j1 ~ w" R; J6 C4 E, _/ B6 i4 @以后用16进制编辑器怎么改就不用多说了,基本工具使用的问题。 7 h6 P8 F3 Z5 n0 e l
菜鸟一个,有意见或建议请不吝赐教,共同进步 : ) 7 ~* }6 a( `- h# l0 ~; E u
# l e4 S- l7 e/ `, \# w6 Z' t5 a
破解用时:18分钟 : (, X9 n5 a: F5 Q F6 y a
% q" L: r; m" `! N6 V0 K" m# I0 |
: S5 X" R2 {; L. ?7 }) D
|