|
作者:vifun http://bbs.pediy.com/ 5 ?1 J1 o9 r8 O# j
工具:( X9 r6 ^3 C5 r
OllyDbg 1.10 F2 F) @6 L, y6 F7 `( O! T h* m* o
7 w& _9 z4 u: Y4 W6 }" V1 ycrackme:
5 d; d8 C4 H t% g___crakme/download">http://www.crackmes.de/users/zionz/crackmes/zi___crakme/download 5 T& s7 i9 w# D7 N% R0 V" s1 v) j
总结: / | U6 g+ o% |9 t5 b
1. 不要一开始就用工具,先试运行一下,感觉一下可疑的地方,获取一些重要的信息,如错误提示。
3 T! I- f( q3 T2. 从内存中查找字符串,输入的信息肯定在内存中的,一定找得到! 3 k6 I. S4 X; ~0 t: u
3. 大部分软件是等字符串全部输入了再处理的,内存跟踪,死盯着它!
- r; }, h0 m; I$ G) M' q _4. 有些程序是把字符串复制几份放不同地方的,每次被断的时候可以考虑重新搜索一次内存,在所有找到的字符串上下断点。
6 Y3 H# m% z; s6 O6 I2 e5. 后发先致,先从最后一次读取入手,先分析最后的处理算法,以免在前面一直浪费时间还影响信心。 + N$ v4 ~6 ], s+ R; ]
6. 细心、耐心、信心!!
s! z9 J2 `& U( y; ?% c为什么先写总结呢?个人觉得这次破解的体会比获得的知识更重要。这个crackme难度不大,但能给刚入门的cracker一点启示。
, \* o. X, ]2 S4 f" c+ h& D2 ~+ y
' ?9 P5 W8 t$ ~. E4 z; s2 _0 f提议:
5 v' R2 \0 O* Q/ W作为老鸟,或许感到很多事是必然的,但对我等菜鸟就不是那么明确了。以后破解文章能不能不单是过程的记录(比如突然冒出一个来到这里),最好还能是一种思想的启示(为什么你要来这里,怎么使你来这里)。 6 I0 w4 Z* A0 z0 L
最好再加上破解时间,因为一篇文章,看起来那么几百字,感觉像3、5分钟就破完一个程序一样,给初学者信心比较大的打击:"怎么我破了整天都没有搞定呢?"。加上时间,大家就可以看出差距了:"原来××牛人都用了半天,我还不太蠢^_^"。
3 [. ]. r" ~$ N% w3 L老鸟看到这里就基本上不用看下去了,下面的破解实在是见笑^_^ 0 H; |: \. n" v. d
* Y! e) U% _, r q: r M4 Y正文: * l; ?7 S4 |! a6 a& V
有感于自己也曾经是菜菜鸟(现在是菜鸟^_^),也碰到过不少菜菜鸟级的问题,藉完成一简单破解之际,特发此文,谈谈菜菜鸟最想问的问题--"为什么这样做啊","为什么决定来这里看看",希望能给未来的菜鸟一点教益。老鸟如果看烦了,小的先陪个罪^_^
3 Q5 C& r0 p# N昨天在http://www.crackmes.de/ 随手down了个解决了的crackme(___crakme">http://www.crackmes.de/users/zionz/crackmes/zi___crakme)打算学习学习外国人的先进经验(我也是菜鸟啊),没想到两方案都是违背了作者初衷的,自己破吧! + l9 Q8 Y/ |. |2 X/ K
先运行一下那个crackme(还是有个总体的印象好,不要什么都不清楚就用工具破解)。好了,发现是命令行界面的,随便输个号进去,回车,显示"WRONG SERIAL"(注意大小写,这个很重要,把提示都记准确一点)。 ( l" z9 a+ b( _* u
用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。好了这次有了!向上滚动看看上文(通常都要上下结合的啦),发现了
" d; t p/ P# R/ i2 l1016CD75 45 4E 54 45 52 20 53 45 52 49 41 ENTER SERIA+ K" @4 f* q! R' o
1016CD85 4C 20 54 4F 20 43 4F 4E 54 49 4E 55 45 3A 00 41 L TO CONTINUE:.A, w" y# G/ `+ e0 f) c. }
1016CD95 58 39 34 33 00 57 45 4C 4C 20 44 4F 4E 45 21 00 X943.WELL DONE!., s% G G' }( Y4 e3 \
1016CDA5 57 52 4F 4E 47 20 53 45 52 49 41 4C WRONG SERIAL ! L! r8 l# x, P8 ^4 W& c
呵呵,很多字符串哦!AX943是什么,难道就是......按[F9]允许,然后输入AX943,成功了! $ N9 T) J) g; C2 E1 f+ A
两个外国人的方案都是到此为止了。如果是破解应用软件,到此也的确够了。此crackme的作者明确表示要求通过任意序列号(Note: Consider it cracked if it accept any serial, not finding the right one.)因此我们继续! $ ?8 v: c0 i: D3 V! i. `5 H
[Ctrl+F2]重新开始,按[F9]运行,出现了提示输入的界面。输个好记并且不容易在内存中存在的字符串,我这里输的是QWERTYUIOP(键盘第一行字母,都大写的)。回到OD,依然[Alt+M],然后[Ctrl+B]调出搜索窗口,输入QWERTYUIOP,按ok。很快OD就找到了
, t% ?1 c8 V# K6 G/ \00A5D321 51 57 45 52 54 59 55 49 4F 50 00 0D F0 AD BA QWERTYUIOP..瓠? 8 `& W1 s" U3 t( @( j/ n/ u- B, L# {
右击51(就是那个Q),选"Breakpoint","Memory,on access",这样当crackme读取这个序列号的时候就被中断了。回到crackme,按回车,OD把它中断在
: X3 a$ f: X5 V; W X* Q# n10045B7E 0FBE00 MOVSX EAX,BYTE PTR DS:[EAX] ! J+ w6 v4 q) X" U) o
先不要急,继续[F9]运行,看看它要被读多少次(为什么这样呢,因为很多时候序列号都要被重复读取的,但重要的比较或者运算很可能在最后那次才出现,否则,最后一次读来干嘛就很值得怀疑了) , b1 O! T- c( e7 `) f
好了,让它运行都结束,出现WRONG SERIAL(当然的结果,浪费少少时间不要紧),发现一共读了5次!我决定从最后一次入手!!(前几次很可能是一些验空串、去空格等预处理) : y) K# d! v6 Q( S
再一次[Ctrl+F2],再一次输入QWERTYUIOP,查找,并下断点,运行。跳过前4次的中断,我们来到最后那次读取的地方,是 . T. o2 N' U! R5 s- ?$ ~
10004DEB F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] " |$ i j3 q+ v+ j* J
一看知道是比较了,右边寄存器的窗口还显示出 & g8 F$ E) j! U8 g. Z
ESI 00A5D321 ASCII "QWERTYUIOP"' W b2 J9 D ^4 D* h
EDI 00A59FC1 ASCII "AX943"
) Q9 x8 Z% K" h# J4 G为了通过任意序列号,暴力改下面的跳转吧! 6 M3 c; D5 C/ y7 J* [: r
10004DED 74 05 JE SHORT Zi__Crac.10004DF4
2 s9 g# U* y$ w* h+ S2 q原来是相等就跳,我把74改为EB,无条件跳转! 1 [/ }6 J! I2 J# a. P
运行crackme,还是WRONG SERIAL!应该是跳转后还有判断吧......
8 o, a/ w) t6 Y& O! _7 R再次运行,跟踪,来到10004DED,无条件跳转后,按[F8]跟下去,很快就发现又有比较了 5 Q, ?# [/ W+ {2 y; @$ k- E5 I
10004DFB 3BD6 CMP EDX,ESI ' p- d: W7 h3 z
代码窗口下面还有提示: $ X$ c/ [- S6 P% }. k
ESI=00000005
. w& \9 S, e8 C9 U- m# y# |5 t2 xEDX=0000000A
. i* |3 J4 W4 J4 p, S" z% B8 A想一下,5应该是AX943的长度,0A就是QWERTYUIOP的长度10,好,继续改跳转 * } A9 j) D* C6 X
10004DFD 73 05 JNB SHORT Zi__Crac.10004E04 + k5 \7 G: z. C/ ?3 j, s& R
将73改为EB,无条件跳转!
/ C$ @& s' Y8 l# T+ e" d细想原来的JNB这个指令有可疑,为什么不是JNE呢,难道下面还有JB指令?继续[F8]跟!
- c8 e0 R: M7 O* b; T. j果然没有错,很快又来一个比较了
3 }" q5 j' O9 P4 s2 g10004E06 3BD6 CMP EDX,ESI ( O% ]. r: K# ^5 d$ G9 T( P# [
而且下面紧接的是
* p/ B& P/ _" e G3 r10004E08 0F95C0 SETNE AL ) O" e) y {, s% b2 j H, @' F8 p
呵呵,终于来"NE"了(不相等就怎么怎么样)!! 9 G4 v/ l0 {1 z& A6 n6 @+ k
再看下面
- l' h; v, C' d0 {; L/ n( z10004E0B 8BF0 MOV ESI,EAX
) q$ G: [% z% E* o9 z( O10004E0D 85DB TEST EBX,EBX
: p: K0 M: N# E8 r$ Z+ I10004E0F BF 38AD1210 MOV EDI,Zi__Crac.1012AD38
( d9 x, p8 n! d10004E14 74 33 JE SHORT Zi__Crac.10004E498 F/ x# r4 t* h3 i6 {) o' L
10004E16 8BCB MOV ECX,EBX
/ I4 D8 S/ r9 \ C% B10004E18 E8 03FCFFFF CALL Zi__Crac.10004A20 A" t$ E9 B$ U
2 R3 }% r- V2 F. d
ESI和EAX装的就是比较的结果,然后就是一个CALL!!决不能让你存!!改掉!!目的是要ESI的数值无条件是0(使10004E06处的比较结果一定相等)。考虑到10004E0B的指令有2字节,改为
5 Q) W( r4 y3 ~1 f9 A I" i10004E0B 33F6 XOR ESI,ESI
( r- P9 K) x$ W- L+ ^8 l! k* M运行......全部通过了^_^ : i+ {: @; f1 g8 o- s' G
以后用16进制编辑器怎么改就不用多说了,基本工具使用的问题。
1 L% o e$ `) I! A! y菜鸟一个,有意见或建议请不吝赐教,共同进步 : ) ( z9 d% T7 l( o6 }2 w" s
/ {- V' r1 y' [# l4 ]: [) {
破解用时:18分钟 : (( R7 Y. k; S- p W; T
5 q0 t. F' B3 e* j
( }' d9 ~; j' B
|