|
作者:vifun http://bbs.pediy.com/
/ \& c5 i$ g. Y工具:
! C; P7 v4 L$ x, ~! ^ wOllyDbg 1.10 , x% v' r" `; z( e
/ {6 s: C+ c" h) |! ^, |% }
crackme: $ O! W: N5 V+ X/ y; U4 I
___crakme/download">http://www.crackmes.de/users/zionz/crackmes/zi___crakme/download
# z2 ?( v. B8 u9 k1 y总结: & m( s b, c2 F- s8 ]# E
1. 不要一开始就用工具,先试运行一下,感觉一下可疑的地方,获取一些重要的信息,如错误提示。
6 n* l# K7 H' X3 G2 L1 r& U8 [) m2. 从内存中查找字符串,输入的信息肯定在内存中的,一定找得到!
7 t" b5 w# C, S' K" e, W; o3. 大部分软件是等字符串全部输入了再处理的,内存跟踪,死盯着它!
5 Q; d9 V9 L! I+ [. G+ z; a& x& a( ?4. 有些程序是把字符串复制几份放不同地方的,每次被断的时候可以考虑重新搜索一次内存,在所有找到的字符串上下断点。 5 a) W% s+ d1 E7 U' l, l( M
5. 后发先致,先从最后一次读取入手,先分析最后的处理算法,以免在前面一直浪费时间还影响信心。
- S1 C5 z6 w6 g- h* i1 L6. 细心、耐心、信心!! ' D& M Y9 K* t6 i, h
为什么先写总结呢?个人觉得这次破解的体会比获得的知识更重要。这个crackme难度不大,但能给刚入门的cracker一点启示。
) ~/ Y! o* a: E5 r
8 k/ `' C) U$ w$ e* D8 x" t提议: 7 i- {' L; f1 j m. E0 M
作为老鸟,或许感到很多事是必然的,但对我等菜鸟就不是那么明确了。以后破解文章能不能不单是过程的记录(比如突然冒出一个来到这里),最好还能是一种思想的启示(为什么你要来这里,怎么使你来这里)。
2 Y8 ?' b7 ?) H5 x最好再加上破解时间,因为一篇文章,看起来那么几百字,感觉像3、5分钟就破完一个程序一样,给初学者信心比较大的打击:"怎么我破了整天都没有搞定呢?"。加上时间,大家就可以看出差距了:"原来××牛人都用了半天,我还不太蠢^_^"。 4 s$ \1 E4 D( `0 s) t' f5 Q
老鸟看到这里就基本上不用看下去了,下面的破解实在是见笑^_^
6 K. [4 Z% p; P2 Z2 ?/ t
# i0 ~8 H1 d+ p" X6 Y5 x5 u" h# V: o! X正文: / j {5 e9 Q& p5 f7 W$ B
有感于自己也曾经是菜菜鸟(现在是菜鸟^_^),也碰到过不少菜菜鸟级的问题,藉完成一简单破解之际,特发此文,谈谈菜菜鸟最想问的问题--"为什么这样做啊","为什么决定来这里看看",希望能给未来的菜鸟一点教益。老鸟如果看烦了,小的先陪个罪^_^ / f& n( I7 d, }- T+ [
昨天在http://www.crackmes.de/ 随手down了个解决了的crackme(___crakme">http://www.crackmes.de/users/zionz/crackmes/zi___crakme)打算学习学习外国人的先进经验(我也是菜鸟啊),没想到两方案都是违背了作者初衷的,自己破吧! ) @& K- ?5 _( A
先运行一下那个crackme(还是有个总体的印象好,不要什么都不清楚就用工具破解)。好了,发现是命令行界面的,随便输个号进去,回车,显示"WRONG SERIAL"(注意大小写,这个很重要,把提示都记准确一点)。 , C: A" P$ `- @- m" D
用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。好了这次有了!向上滚动看看上文(通常都要上下结合的啦),发现了 / H. H2 M% G+ a( W3 E( M
1016CD75 45 4E 54 45 52 20 53 45 52 49 41 ENTER SERIA
; w! K$ }) Y. c1016CD85 4C 20 54 4F 20 43 4F 4E 54 49 4E 55 45 3A 00 41 L TO CONTINUE:.A
& ?% ~- U9 ~' q% n2 C* N% e1016CD95 58 39 34 33 00 57 45 4C 4C 20 44 4F 4E 45 21 00 X943.WELL DONE!. V. j3 q5 P d5 q( b& x. q
1016CDA5 57 52 4F 4E 47 20 53 45 52 49 41 4C WRONG SERIAL
& m7 f. f# N, s; H3 j/ Z" {# `" B7 w呵呵,很多字符串哦!AX943是什么,难道就是......按[F9]允许,然后输入AX943,成功了!
6 W9 ?8 X/ P' ]+ e两个外国人的方案都是到此为止了。如果是破解应用软件,到此也的确够了。此crackme的作者明确表示要求通过任意序列号(Note: Consider it cracked if it accept any serial, not finding the right one.)因此我们继续! # t4 `! M4 B* f5 x" r
[Ctrl+F2]重新开始,按[F9]运行,出现了提示输入的界面。输个好记并且不容易在内存中存在的字符串,我这里输的是QWERTYUIOP(键盘第一行字母,都大写的)。回到OD,依然[Alt+M],然后[Ctrl+B]调出搜索窗口,输入QWERTYUIOP,按ok。很快OD就找到了
7 S& t& Q4 W( U: \6 p1 E4 x7 b/ w8 j: O00A5D321 51 57 45 52 54 59 55 49 4F 50 00 0D F0 AD BA QWERTYUIOP..瓠?
/ q8 X( |% {! @/ {$ Z1 z! s右击51(就是那个Q),选"Breakpoint","Memory,on access",这样当crackme读取这个序列号的时候就被中断了。回到crackme,按回车,OD把它中断在
) U, e* U! U& z. s- E, U% m10045B7E 0FBE00 MOVSX EAX,BYTE PTR DS:[EAX] 3 _5 j. @; ]3 f3 c% a
先不要急,继续[F9]运行,看看它要被读多少次(为什么这样呢,因为很多时候序列号都要被重复读取的,但重要的比较或者运算很可能在最后那次才出现,否则,最后一次读来干嘛就很值得怀疑了) 2 r8 ~9 `4 I: j3 f1 L
好了,让它运行都结束,出现WRONG SERIAL(当然的结果,浪费少少时间不要紧),发现一共读了5次!我决定从最后一次入手!!(前几次很可能是一些验空串、去空格等预处理) % a( c; w3 w: K5 M) J
再一次[Ctrl+F2],再一次输入QWERTYUIOP,查找,并下断点,运行。跳过前4次的中断,我们来到最后那次读取的地方,是 4 N1 `4 l) P: i) G0 [
10004DEB F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] $ B. q& ]$ k) S' T h) M
一看知道是比较了,右边寄存器的窗口还显示出
0 x6 O q/ Q, L; E, W7 w6 `8 U$ jESI 00A5D321 ASCII "QWERTYUIOP"
# D1 }, T K) YEDI 00A59FC1 ASCII "AX943" }: z# v4 q! a$ q4 l- _9 a
为了通过任意序列号,暴力改下面的跳转吧!
4 _! n! J+ v4 @+ S2 V% ^10004DED 74 05 JE SHORT Zi__Crac.10004DF4 0 k! r+ A" j3 }- i
原来是相等就跳,我把74改为EB,无条件跳转!
% t8 B; v, c4 d6 T! G* g+ Z运行crackme,还是WRONG SERIAL!应该是跳转后还有判断吧......
3 P0 s; z3 l/ N0 N) X8 _3 c3 _; @再次运行,跟踪,来到10004DED,无条件跳转后,按[F8]跟下去,很快就发现又有比较了 4 C( ]1 w# G% p+ S+ t/ W
10004DFB 3BD6 CMP EDX,ESI
. z4 a# \9 \2 `8 |) B7 n代码窗口下面还有提示:
6 k; q, \# Y- \/ B- b8 NESI=00000005
% U7 z: r# `9 A Y- J- REDX=0000000A
/ W* `; A: |( }, i; `' Q+ \* y想一下,5应该是AX943的长度,0A就是QWERTYUIOP的长度10,好,继续改跳转
* Y4 ]0 G4 n& H0 [6 J$ S0 D10004DFD 73 05 JNB SHORT Zi__Crac.10004E04 4 s8 M# B X& u3 Z8 l2 }
将73改为EB,无条件跳转!
, v' A. I. p! k# U% h. U" W: D细想原来的JNB这个指令有可疑,为什么不是JNE呢,难道下面还有JB指令?继续[F8]跟! $ R4 q" k) `* I5 P
果然没有错,很快又来一个比较了
) M( c7 f( L& G4 z' v/ V; _10004E06 3BD6 CMP EDX,ESI " D8 g# J2 R/ I8 g# r; F8 L# C
而且下面紧接的是 " d: R. D7 O! {! L6 [) C; @
10004E08 0F95C0 SETNE AL 4 G* M8 R$ C2 t; P! B0 L* [* a) Z2 m% j
呵呵,终于来"NE"了(不相等就怎么怎么样)!! 8 T( W$ ]9 i T. X+ e" n# w
再看下面 / ~2 G" f% }! o9 O& f& k( A
10004E0B 8BF0 MOV ESI,EAX# n9 N& w8 k. P9 H; L5 [
10004E0D 85DB TEST EBX,EBX) O3 w7 \% `4 p/ \" u/ S7 E( K' d
10004E0F BF 38AD1210 MOV EDI,Zi__Crac.1012AD38
3 D ]5 g, n5 Z3 C7 E+ r10004E14 74 33 JE SHORT Zi__Crac.10004E49
" e2 c+ r3 M S5 t$ \10004E16 8BCB MOV ECX,EBX
- x# `+ S1 D& B- f3 L% R10004E18 E8 03FCFFFF CALL Zi__Crac.10004A20
1 ?5 i/ V( {! r+ X4 I% P1 I
0 _: Z/ ^2 @1 Y N1 h) s r6 YESI和EAX装的就是比较的结果,然后就是一个CALL!!决不能让你存!!改掉!!目的是要ESI的数值无条件是0(使10004E06处的比较结果一定相等)。考虑到10004E0B的指令有2字节,改为
0 [' G. F8 b8 `/ L2 g! _2 f10004E0B 33F6 XOR ESI,ESI + `6 j3 {' `& `* c, \) ?' @
运行......全部通过了^_^ $ g2 Z! Z9 e2 t$ v* S8 L
以后用16进制编辑器怎么改就不用多说了,基本工具使用的问题。 % _; [8 f+ R4 O. D7 C; W; q2 G+ u
菜鸟一个,有意见或建议请不吝赐教,共同进步 : )
6 M: X& ?8 W/ m% h# q
6 [" H& @3 x9 O/ ^- \* B破解用时:18分钟 : (
+ [& j+ \) A+ c- n9 ?( l5 Z9 t1 j& [
3 g. S/ _) D% y+ b! A8 v j3 K
( V5 s G5 q X4 L! P9 h2 X* \, k1 g- ?; P |