|
作者:vifun http://bbs.pediy.com/
8 X- {$ E! ?/ J: |! @! H工具:
" o% O* |, L b8 q3 @" M6 tOllyDbg 1.10 % g% ]5 `5 ^6 M0 X4 D. n3 V
( C. U8 c+ R x
crackme: Y# h5 A) X! I% v. x" R \# r+ P
___crakme/download">http://www.crackmes.de/users/zionz/crackmes/zi___crakme/download
0 w, s: q0 I3 i总结: ; t E# V6 F0 a
1. 不要一开始就用工具,先试运行一下,感觉一下可疑的地方,获取一些重要的信息,如错误提示。 4 B. h4 o' w, X/ _1 `( N
2. 从内存中查找字符串,输入的信息肯定在内存中的,一定找得到!
5 J, F' p4 v, w0 ?& [! a) ?: E6 T3. 大部分软件是等字符串全部输入了再处理的,内存跟踪,死盯着它! % ]1 `: Y" f0 K& p/ u
4. 有些程序是把字符串复制几份放不同地方的,每次被断的时候可以考虑重新搜索一次内存,在所有找到的字符串上下断点。
# O* X2 r: i; d0 V! C! r& K6 J6 S5. 后发先致,先从最后一次读取入手,先分析最后的处理算法,以免在前面一直浪费时间还影响信心。 % `+ u2 c/ P1 D
6. 细心、耐心、信心!!
% O' }( L. K$ Y为什么先写总结呢?个人觉得这次破解的体会比获得的知识更重要。这个crackme难度不大,但能给刚入门的cracker一点启示。 3 v- \+ G2 l- v3 e4 u" C7 L- u
" T! O9 s. Y: K* d* k
提议: . b+ ]# X* t7 L
作为老鸟,或许感到很多事是必然的,但对我等菜鸟就不是那么明确了。以后破解文章能不能不单是过程的记录(比如突然冒出一个来到这里),最好还能是一种思想的启示(为什么你要来这里,怎么使你来这里)。 * e7 A8 R/ A2 k
最好再加上破解时间,因为一篇文章,看起来那么几百字,感觉像3、5分钟就破完一个程序一样,给初学者信心比较大的打击:"怎么我破了整天都没有搞定呢?"。加上时间,大家就可以看出差距了:"原来××牛人都用了半天,我还不太蠢^_^"。 2 J6 c0 X2 ]0 G2 O3 Q3 O( u4 l' t
老鸟看到这里就基本上不用看下去了,下面的破解实在是见笑^_^
2 z& N: n: s7 t: Y+ [, o2 C6 D$ N1 Q
正文:
: l1 K/ u% i% _. w8 e* |有感于自己也曾经是菜菜鸟(现在是菜鸟^_^),也碰到过不少菜菜鸟级的问题,藉完成一简单破解之际,特发此文,谈谈菜菜鸟最想问的问题--"为什么这样做啊","为什么决定来这里看看",希望能给未来的菜鸟一点教益。老鸟如果看烦了,小的先陪个罪^_^
4 U5 |; j7 }5 |% |: h2 u7 \昨天在http://www.crackmes.de/ 随手down了个解决了的crackme(___crakme">http://www.crackmes.de/users/zionz/crackmes/zi___crakme)打算学习学习外国人的先进经验(我也是菜鸟啊),没想到两方案都是违背了作者初衷的,自己破吧!
g6 p+ H$ \: q3 A; J" t先运行一下那个crackme(还是有个总体的印象好,不要什么都不清楚就用工具破解)。好了,发现是命令行界面的,随便输个号进去,回车,显示"WRONG SERIAL"(注意大小写,这个很重要,把提示都记准确一点)。 * m* k+ n' s p8 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。好了这次有了!向上滚动看看上文(通常都要上下结合的啦),发现了 1 w c* j7 h0 u3 E" s( ~7 @
1016CD75 45 4E 54 45 52 20 53 45 52 49 41 ENTER SERIA
0 A; @' E o* n1 k1016CD85 4C 20 54 4F 20 43 4F 4E 54 49 4E 55 45 3A 00 41 L TO CONTINUE:.A
4 ?4 j6 b& q* X! }0 X4 D9 B, C1016CD95 58 39 34 33 00 57 45 4C 4C 20 44 4F 4E 45 21 00 X943.WELL DONE!.$ g7 V8 S% |8 l$ o2 n$ \/ N
1016CDA5 57 52 4F 4E 47 20 53 45 52 49 41 4C WRONG SERIAL
* u1 C, r5 H* q# w$ \( w% ?呵呵,很多字符串哦!AX943是什么,难道就是......按[F9]允许,然后输入AX943,成功了!
2 u" i! I) {% P9 `) C2 J两个外国人的方案都是到此为止了。如果是破解应用软件,到此也的确够了。此crackme的作者明确表示要求通过任意序列号(Note: Consider it cracked if it accept any serial, not finding the right one.)因此我们继续! 7 x: ~1 Y1 J2 ^2 ~! B2 v7 z5 Y
[Ctrl+F2]重新开始,按[F9]运行,出现了提示输入的界面。输个好记并且不容易在内存中存在的字符串,我这里输的是QWERTYUIOP(键盘第一行字母,都大写的)。回到OD,依然[Alt+M],然后[Ctrl+B]调出搜索窗口,输入QWERTYUIOP,按ok。很快OD就找到了 7 ^" \6 w6 y% |7 J1 I; e
00A5D321 51 57 45 52 54 59 55 49 4F 50 00 0D F0 AD BA QWERTYUIOP..瓠? # p$ t+ ]9 @% R: n& @% B' q; V4 @
右击51(就是那个Q),选"Breakpoint","Memory,on access",这样当crackme读取这个序列号的时候就被中断了。回到crackme,按回车,OD把它中断在
$ j5 m& _2 q! y10045B7E 0FBE00 MOVSX EAX,BYTE PTR DS:[EAX]
+ Q& r& `' k& u6 }! y* ?/ E* r3 i先不要急,继续[F9]运行,看看它要被读多少次(为什么这样呢,因为很多时候序列号都要被重复读取的,但重要的比较或者运算很可能在最后那次才出现,否则,最后一次读来干嘛就很值得怀疑了) * O, o |0 P. t
好了,让它运行都结束,出现WRONG SERIAL(当然的结果,浪费少少时间不要紧),发现一共读了5次!我决定从最后一次入手!!(前几次很可能是一些验空串、去空格等预处理)
* t8 r: m4 Z# V再一次[Ctrl+F2],再一次输入QWERTYUIOP,查找,并下断点,运行。跳过前4次的中断,我们来到最后那次读取的地方,是 2 G' l: Y0 G3 N/ Y" `" o
10004DEB F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
* s# N8 H' y' x: k! S5 P+ } {* ~一看知道是比较了,右边寄存器的窗口还显示出
1 _0 [4 A0 _ ]ESI 00A5D321 ASCII "QWERTYUIOP"' D7 z* |, B5 ~. k3 ^* L3 g
EDI 00A59FC1 ASCII "AX943" + R0 ~7 V0 b1 B# W2 k" D$ J( F" V4 g
为了通过任意序列号,暴力改下面的跳转吧!
+ r0 v! b4 J) u; I2 N: y0 T5 s10004DED 74 05 JE SHORT Zi__Crac.10004DF4 2 p9 ?9 k& `; A# u1 i8 j
原来是相等就跳,我把74改为EB,无条件跳转! / M: U; |9 o2 u x4 A
运行crackme,还是WRONG SERIAL!应该是跳转后还有判断吧......
5 \; u* o# n. q再次运行,跟踪,来到10004DED,无条件跳转后,按[F8]跟下去,很快就发现又有比较了 ) s. e x5 V9 G9 N; M" Q
10004DFB 3BD6 CMP EDX,ESI
* R" x! P2 W$ p4 P代码窗口下面还有提示:
" \! [7 V* z8 e. I# }5 cESI=000000058 } I0 |$ `& C3 W& @7 N6 b
EDX=0000000A % X9 [' k$ J- j6 m7 u
想一下,5应该是AX943的长度,0A就是QWERTYUIOP的长度10,好,继续改跳转
% e* O. O6 x$ t$ ?10004DFD 73 05 JNB SHORT Zi__Crac.10004E04 # ^) v [2 g4 c# [. s P3 ?. A
将73改为EB,无条件跳转! : h Z }( ?. Y- ^
细想原来的JNB这个指令有可疑,为什么不是JNE呢,难道下面还有JB指令?继续[F8]跟!
6 }4 I# c! [ T4 X, e* o果然没有错,很快又来一个比较了
4 g+ q) I& m' d3 d- n# U' A' [10004E06 3BD6 CMP EDX,ESI
" [) r" D. z, q+ V+ ]% x" c, l# f而且下面紧接的是 & j2 D% ~: L3 q |! T1 k- t
10004E08 0F95C0 SETNE AL 9 O5 n9 f4 ^! J1 Y
呵呵,终于来"NE"了(不相等就怎么怎么样)!! 0 _5 d% ]5 I$ U. r
再看下面
% @, Z: H$ Y4 o& D: f5 W5 U' V5 L; z10004E0B 8BF0 MOV ESI,EAX) p& A( J( M! o1 S! k
10004E0D 85DB TEST EBX,EBX
: k/ ^3 i: q$ R" V6 M. R5 k+ w, F10004E0F BF 38AD1210 MOV EDI,Zi__Crac.1012AD38
# I& E0 q8 {8 n7 e10004E14 74 33 JE SHORT Zi__Crac.10004E49
% H2 Q" ]4 p- T8 R$ H2 A10004E16 8BCB MOV ECX,EBX
* E! l. w9 M: F; M4 h7 Z10004E18 E8 03FCFFFF CALL Zi__Crac.10004A20
% T7 s0 M/ q( Z" k8 E" v: E+ e; Q* r
ESI和EAX装的就是比较的结果,然后就是一个CALL!!决不能让你存!!改掉!!目的是要ESI的数值无条件是0(使10004E06处的比较结果一定相等)。考虑到10004E0B的指令有2字节,改为 2 A& r: p; _ d9 K% r+ {/ @: ]
10004E0B 33F6 XOR ESI,ESI ' h) ^0 J' r9 W% j( D$ r
运行......全部通过了^_^
p q w- }8 u" h以后用16进制编辑器怎么改就不用多说了,基本工具使用的问题。 . k2 p) e/ n' t: L1 Y
菜鸟一个,有意见或建议请不吝赐教,共同进步 : )
2 e/ e! m- ]) y3 B! `9 L6 H0 y8 p* [
破解用时:18分钟 : (; ^8 O$ k ?8 M
4 A/ i) [) q Z6 |% H1 c0 Z2 H, Y0 b# ^/ g0 X
|