|
作者:vifun http://bbs.pediy.com/
2 I+ t- b$ S8 I$ |% b: _! o" W5 G" ~工具:$ \' {, S& l5 U% M9 b
OllyDbg 1.10
" s' Y9 u' [2 N; M. v
+ F$ h3 S% H: j* a' {crackme: 8 F+ k, y& j, N% ~3 ]; {- a
___crakme/download">http://www.crackmes.de/users/zionz/crackmes/zi___crakme/download 4 f) B9 \, R5 z) @
总结:
; V5 _: @' a9 M' `1. 不要一开始就用工具,先试运行一下,感觉一下可疑的地方,获取一些重要的信息,如错误提示。 ! T3 c2 y& Q9 e- |/ G. f
2. 从内存中查找字符串,输入的信息肯定在内存中的,一定找得到! % i3 W H/ e. |3 b# l, M
3. 大部分软件是等字符串全部输入了再处理的,内存跟踪,死盯着它! # G/ F+ |0 C0 S- D4 [% Z0 [
4. 有些程序是把字符串复制几份放不同地方的,每次被断的时候可以考虑重新搜索一次内存,在所有找到的字符串上下断点。 % S& Q- F' Q) u9 p$ O# j
5. 后发先致,先从最后一次读取入手,先分析最后的处理算法,以免在前面一直浪费时间还影响信心。 Y7 f- i9 Q3 Z5 E; q
6. 细心、耐心、信心!! $ T% q4 j* X$ j5 w0 i! K3 ]* `
为什么先写总结呢?个人觉得这次破解的体会比获得的知识更重要。这个crackme难度不大,但能给刚入门的cracker一点启示。 ! s+ [ ]$ K9 k; E7 R
: k1 H" \; k1 r) p! u- o提议: , r) i, z+ E y3 w. l, c
作为老鸟,或许感到很多事是必然的,但对我等菜鸟就不是那么明确了。以后破解文章能不能不单是过程的记录(比如突然冒出一个来到这里),最好还能是一种思想的启示(为什么你要来这里,怎么使你来这里)。
% h! Y8 f# L& {8 n& p& ~$ l: O最好再加上破解时间,因为一篇文章,看起来那么几百字,感觉像3、5分钟就破完一个程序一样,给初学者信心比较大的打击:"怎么我破了整天都没有搞定呢?"。加上时间,大家就可以看出差距了:"原来××牛人都用了半天,我还不太蠢^_^"。 ! G0 c# v% K9 w1 ]9 M% L) c) b T) O
老鸟看到这里就基本上不用看下去了,下面的破解实在是见笑^_^ + G: b. e) p# ?- s; q/ e7 \
, i6 i- T$ L" }4 x2 W0 Q- W: L6 K正文: ' n/ O& J1 N8 @8 W: J0 O" s
有感于自己也曾经是菜菜鸟(现在是菜鸟^_^),也碰到过不少菜菜鸟级的问题,藉完成一简单破解之际,特发此文,谈谈菜菜鸟最想问的问题--"为什么这样做啊","为什么决定来这里看看",希望能给未来的菜鸟一点教益。老鸟如果看烦了,小的先陪个罪^_^
! D8 o" X9 l3 N& C$ X昨天在http://www.crackmes.de/ 随手down了个解决了的crackme(___crakme">http://www.crackmes.de/users/zionz/crackmes/zi___crakme)打算学习学习外国人的先进经验(我也是菜鸟啊),没想到两方案都是违背了作者初衷的,自己破吧! ! O; n" V; j" S: [
先运行一下那个crackme(还是有个总体的印象好,不要什么都不清楚就用工具破解)。好了,发现是命令行界面的,随便输个号进去,回车,显示"WRONG SERIAL"(注意大小写,这个很重要,把提示都记准确一点)。 ! k- \1 {: b. O2 b0 b1 j+ 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。好了这次有了!向上滚动看看上文(通常都要上下结合的啦),发现了
3 p r7 G$ q4 I2 W& J* n1016CD75 45 4E 54 45 52 20 53 45 52 49 41 ENTER SERIA
6 d4 x# q- g" L2 p1016CD85 4C 20 54 4F 20 43 4F 4E 54 49 4E 55 45 3A 00 41 L TO CONTINUE:.A
! J/ Z0 x3 R/ O$ Z1016CD95 58 39 34 33 00 57 45 4C 4C 20 44 4F 4E 45 21 00 X943.WELL DONE!.
9 \/ P P* o) l) U4 S1016CDA5 57 52 4F 4E 47 20 53 45 52 49 41 4C WRONG SERIAL & A$ D& n. T4 z$ n- P
呵呵,很多字符串哦!AX943是什么,难道就是......按[F9]允许,然后输入AX943,成功了!
" ?" R3 e2 e% O( O" U/ e) O两个外国人的方案都是到此为止了。如果是破解应用软件,到此也的确够了。此crackme的作者明确表示要求通过任意序列号(Note: Consider it cracked if it accept any serial, not finding the right one.)因此我们继续! % }( N8 }- t% L$ E* _3 K4 I
[Ctrl+F2]重新开始,按[F9]运行,出现了提示输入的界面。输个好记并且不容易在内存中存在的字符串,我这里输的是QWERTYUIOP(键盘第一行字母,都大写的)。回到OD,依然[Alt+M],然后[Ctrl+B]调出搜索窗口,输入QWERTYUIOP,按ok。很快OD就找到了
: ]& Y7 g& f$ _00A5D321 51 57 45 52 54 59 55 49 4F 50 00 0D F0 AD BA QWERTYUIOP..瓠?
' K% X! \( K6 D% l* {3 O! D) e! [右击51(就是那个Q),选"Breakpoint","Memory,on access",这样当crackme读取这个序列号的时候就被中断了。回到crackme,按回车,OD把它中断在 , r' N* ~- R6 Z! q1 N: h
10045B7E 0FBE00 MOVSX EAX,BYTE PTR DS:[EAX]
" B) R! J3 w1 l- V先不要急,继续[F9]运行,看看它要被读多少次(为什么这样呢,因为很多时候序列号都要被重复读取的,但重要的比较或者运算很可能在最后那次才出现,否则,最后一次读来干嘛就很值得怀疑了)
! v$ \/ ~( k, |0 b2 S; Y好了,让它运行都结束,出现WRONG SERIAL(当然的结果,浪费少少时间不要紧),发现一共读了5次!我决定从最后一次入手!!(前几次很可能是一些验空串、去空格等预处理)
/ _! t& l3 \7 X- g. S3 R再一次[Ctrl+F2],再一次输入QWERTYUIOP,查找,并下断点,运行。跳过前4次的中断,我们来到最后那次读取的地方,是 ! Q- P9 u5 C: A5 J9 [ D* M2 \
10004DEB F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
, f2 |, H" j7 j6 A: ?0 ~一看知道是比较了,右边寄存器的窗口还显示出 + k- w: A/ Q9 g# H- B2 R! P( `
ESI 00A5D321 ASCII "QWERTYUIOP"
! I$ z, p% Y& C3 `% @EDI 00A59FC1 ASCII "AX943" : m# ^; h& j5 C! `2 k5 t, A* {
为了通过任意序列号,暴力改下面的跳转吧! / _3 x4 V6 H2 K1 S3 T# T
10004DED 74 05 JE SHORT Zi__Crac.10004DF4
( N9 @/ l# N. g3 {原来是相等就跳,我把74改为EB,无条件跳转!
" q2 V* `3 ?/ R$ k运行crackme,还是WRONG SERIAL!应该是跳转后还有判断吧...... ( p# t4 F' Z; X5 p. q& b
再次运行,跟踪,来到10004DED,无条件跳转后,按[F8]跟下去,很快就发现又有比较了 : x. G8 E9 v0 s" s8 R2 M9 _1 R
10004DFB 3BD6 CMP EDX,ESI
0 f/ T: H" j8 _; `0 @5 w# L3 a代码窗口下面还有提示: * X1 ^: Y. w4 }- N
ESI=00000005
1 X0 Z5 V8 D$ ]7 GEDX=0000000A . k l8 G9 y( y, h
想一下,5应该是AX943的长度,0A就是QWERTYUIOP的长度10,好,继续改跳转
$ J* v8 `; D3 ]5 L10004DFD 73 05 JNB SHORT Zi__Crac.10004E04 4 I7 t0 Z% B2 Z
将73改为EB,无条件跳转! " v6 I# m+ Q: o
细想原来的JNB这个指令有可疑,为什么不是JNE呢,难道下面还有JB指令?继续[F8]跟! 5 P2 w& h8 A% z8 }1 ?) M0 A: @
果然没有错,很快又来一个比较了
8 j) Z5 l* A# I% {, x% N$ ` z10004E06 3BD6 CMP EDX,ESI
: t' G6 Z* x3 f, Q而且下面紧接的是 6 y [/ m! z. H9 @6 e7 k
10004E08 0F95C0 SETNE AL
- {" u8 F/ a' h, \& r! [4 Z. v* R$ `/ Y呵呵,终于来"NE"了(不相等就怎么怎么样)!! & j% [) d9 ]: ^4 A
再看下面
9 y3 I/ k, V' N9 w; ^2 C! D10004E0B 8BF0 MOV ESI,EAX9 L! }+ n. g8 A) T, h% S9 U
10004E0D 85DB TEST EBX,EBX5 J2 \" j5 d. _7 n
10004E0F BF 38AD1210 MOV EDI,Zi__Crac.1012AD38
& F, O. T# ]7 [2 N! ~$ ^10004E14 74 33 JE SHORT Zi__Crac.10004E49
( p+ M3 E9 e8 q10004E16 8BCB MOV ECX,EBX
7 }; t0 d' Y+ G10004E18 E8 03FCFFFF CALL Zi__Crac.10004A20
b, V ~7 _0 Q+ N6 N* [/ Q5 w3 @) F; _' x( G" A9 j
ESI和EAX装的就是比较的结果,然后就是一个CALL!!决不能让你存!!改掉!!目的是要ESI的数值无条件是0(使10004E06处的比较结果一定相等)。考虑到10004E0B的指令有2字节,改为
, {- Z/ f) E4 q4 G10004E0B 33F6 XOR ESI,ESI
& O6 Y7 M2 u$ T6 w; Z运行......全部通过了^_^ 8 k! E2 t( K! ]% i! K, y
以后用16进制编辑器怎么改就不用多说了,基本工具使用的问题。 3 p2 |0 Z2 N* M( P* D
菜鸟一个,有意见或建议请不吝赐教,共同进步 : )
8 B1 a5 S) ], r& H8 i& N3 [# X$ W+ m
破解用时:18分钟 : (
6 x( f5 n! j S * T% Q- q+ c' A/ i
4 e4 t* q6 z9 N" \ O |