|
作者:vifun http://bbs.pediy.com/
- V" O5 z. ]- T9 E工具:0 x3 U7 J. K# n% `8 G6 ^
OllyDbg 1.10 + ^* L+ g% @* B' K! K2 u% Z
3 f3 z& w i) c& l3 Y, E# n O* a% B
crackme:
. W2 I6 e+ a9 N1 x0 X___crakme/download">http://www.crackmes.de/users/zionz/crackmes/zi___crakme/download
) f( ~0 a( w ~' B3 ^1 j9 Q总结: 4 w( F* S( y3 C: o3 x
1. 不要一开始就用工具,先试运行一下,感觉一下可疑的地方,获取一些重要的信息,如错误提示。 & E( m7 |# \1 Q7 \. A# a6 [
2. 从内存中查找字符串,输入的信息肯定在内存中的,一定找得到!
% A! v! F, Y2 D9 ] Q# W3 Q p$ T3. 大部分软件是等字符串全部输入了再处理的,内存跟踪,死盯着它! ) \0 s/ r- d. o! \+ M0 i
4. 有些程序是把字符串复制几份放不同地方的,每次被断的时候可以考虑重新搜索一次内存,在所有找到的字符串上下断点。 0 v- p' Z% i- w7 h
5. 后发先致,先从最后一次读取入手,先分析最后的处理算法,以免在前面一直浪费时间还影响信心。 + O$ n+ ?2 Z A6 \ n3 \5 S
6. 细心、耐心、信心!! 7 M f! p+ R5 D6 T A" Y
为什么先写总结呢?个人觉得这次破解的体会比获得的知识更重要。这个crackme难度不大,但能给刚入门的cracker一点启示。 2 B8 \- m1 C1 \- _
' }! C% |4 F8 b5 v, E1 z/ q1 K; S提议:
! b# q6 e1 V$ T2 A: o; u, X0 p作为老鸟,或许感到很多事是必然的,但对我等菜鸟就不是那么明确了。以后破解文章能不能不单是过程的记录(比如突然冒出一个来到这里),最好还能是一种思想的启示(为什么你要来这里,怎么使你来这里)。 ! c% ?, o8 v$ h8 b: q4 F
最好再加上破解时间,因为一篇文章,看起来那么几百字,感觉像3、5分钟就破完一个程序一样,给初学者信心比较大的打击:"怎么我破了整天都没有搞定呢?"。加上时间,大家就可以看出差距了:"原来××牛人都用了半天,我还不太蠢^_^"。
4 x# |( s; z2 o0 e- f' R老鸟看到这里就基本上不用看下去了,下面的破解实在是见笑^_^
/ i- n3 c& X, Q# J% j! Q A$ u9 z5 S
正文: ( s; Y2 h i1 x
有感于自己也曾经是菜菜鸟(现在是菜鸟^_^),也碰到过不少菜菜鸟级的问题,藉完成一简单破解之际,特发此文,谈谈菜菜鸟最想问的问题--"为什么这样做啊","为什么决定来这里看看",希望能给未来的菜鸟一点教益。老鸟如果看烦了,小的先陪个罪^_^
8 s |: X7 Q# F8 a" h& c# n昨天在http://www.crackmes.de/ 随手down了个解决了的crackme(___crakme">http://www.crackmes.de/users/zionz/crackmes/zi___crakme)打算学习学习外国人的先进经验(我也是菜鸟啊),没想到两方案都是违背了作者初衷的,自己破吧!
4 o5 \7 |0 T# Y$ G h' d先运行一下那个crackme(还是有个总体的印象好,不要什么都不清楚就用工具破解)。好了,发现是命令行界面的,随便输个号进去,回车,显示"WRONG SERIAL"(注意大小写,这个很重要,把提示都记准确一点)。 . I/ {" X- p) U8 p/ m
用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。好了这次有了!向上滚动看看上文(通常都要上下结合的啦),发现了
6 n3 h8 E1 k( z0 @+ V1016CD75 45 4E 54 45 52 20 53 45 52 49 41 ENTER SERIA1 j, U U- J2 g& V% E
1016CD85 4C 20 54 4F 20 43 4F 4E 54 49 4E 55 45 3A 00 41 L TO CONTINUE:.A
/ n5 N2 l6 O/ N' q6 X: R1016CD95 58 39 34 33 00 57 45 4C 4C 20 44 4F 4E 45 21 00 X943.WELL DONE!.! V1 W! L1 G* G" ?
1016CDA5 57 52 4F 4E 47 20 53 45 52 49 41 4C WRONG SERIAL , r& D( A- X! A4 p5 b+ q+ O
呵呵,很多字符串哦!AX943是什么,难道就是......按[F9]允许,然后输入AX943,成功了! $ Z. ]% _ p! `* v
两个外国人的方案都是到此为止了。如果是破解应用软件,到此也的确够了。此crackme的作者明确表示要求通过任意序列号(Note: Consider it cracked if it accept any serial, not finding the right one.)因此我们继续! 9 d9 Q' v+ V( K: d9 a8 ?
[Ctrl+F2]重新开始,按[F9]运行,出现了提示输入的界面。输个好记并且不容易在内存中存在的字符串,我这里输的是QWERTYUIOP(键盘第一行字母,都大写的)。回到OD,依然[Alt+M],然后[Ctrl+B]调出搜索窗口,输入QWERTYUIOP,按ok。很快OD就找到了 0 B. z2 I/ U7 N# w: {
00A5D321 51 57 45 52 54 59 55 49 4F 50 00 0D F0 AD BA QWERTYUIOP..瓠? 6 g5 D" x- |9 I5 D! m) W
右击51(就是那个Q),选"Breakpoint","Memory,on access",这样当crackme读取这个序列号的时候就被中断了。回到crackme,按回车,OD把它中断在
: B$ g# u! X4 ^+ B# M- r! [1 W0 m7 e10045B7E 0FBE00 MOVSX EAX,BYTE PTR DS:[EAX] ) b A/ R4 y/ t0 Y8 ~. ^4 L
先不要急,继续[F9]运行,看看它要被读多少次(为什么这样呢,因为很多时候序列号都要被重复读取的,但重要的比较或者运算很可能在最后那次才出现,否则,最后一次读来干嘛就很值得怀疑了)
! l; H: N' D8 l. j! l9 d好了,让它运行都结束,出现WRONG SERIAL(当然的结果,浪费少少时间不要紧),发现一共读了5次!我决定从最后一次入手!!(前几次很可能是一些验空串、去空格等预处理) 9 V6 @% T- o4 N2 ?0 H$ A# x4 R, O7 I* n
再一次[Ctrl+F2],再一次输入QWERTYUIOP,查找,并下断点,运行。跳过前4次的中断,我们来到最后那次读取的地方,是 + W; h% D3 \! [7 E2 u- |
10004DEB F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
0 Q" c8 ]" n7 j一看知道是比较了,右边寄存器的窗口还显示出 % U7 N, t4 I l% t% a; G7 k
ESI 00A5D321 ASCII "QWERTYUIOP"
0 s& D4 t0 `3 s' R" Q& k) j2 t" tEDI 00A59FC1 ASCII "AX943"
, x/ e% G! y8 |/ T& p为了通过任意序列号,暴力改下面的跳转吧!
4 ^; V9 k( s& `" E10004DED 74 05 JE SHORT Zi__Crac.10004DF4
; s7 M% z; f3 P% p! ~, \- u" Y原来是相等就跳,我把74改为EB,无条件跳转!
7 x7 j1 k) k* j# j运行crackme,还是WRONG SERIAL!应该是跳转后还有判断吧...... ; b! `6 s# t0 T
再次运行,跟踪,来到10004DED,无条件跳转后,按[F8]跟下去,很快就发现又有比较了 / a+ k% _$ m" v4 W: Y
10004DFB 3BD6 CMP EDX,ESI
8 G& o; M D. U: _/ _1 o代码窗口下面还有提示: 4 _/ Z8 w+ v9 D; F
ESI=00000005
! q# Q- q) x/ x& o7 f7 HEDX=0000000A . r2 i! ~. x- P# C, C
想一下,5应该是AX943的长度,0A就是QWERTYUIOP的长度10,好,继续改跳转 8 v: L& k0 P+ }( v( {+ N2 O3 h
10004DFD 73 05 JNB SHORT Zi__Crac.10004E04
; [2 a* Y1 V2 M' \9 K% W将73改为EB,无条件跳转! A5 u# A5 l6 H
细想原来的JNB这个指令有可疑,为什么不是JNE呢,难道下面还有JB指令?继续[F8]跟!
@% K( m3 I. _+ }8 ~5 Z! l+ A果然没有错,很快又来一个比较了 . O1 N& D) h. j, E( L
10004E06 3BD6 CMP EDX,ESI
" s; c# B2 W1 Q% d9 {$ E而且下面紧接的是
+ z! }9 b d. V- y10004E08 0F95C0 SETNE AL " ?# u# s7 L5 i& G+ Q
呵呵,终于来"NE"了(不相等就怎么怎么样)!!
$ O2 U# j6 o4 h. u- i( }* Z7 {再看下面
6 ]/ }) R# Z- M10004E0B 8BF0 MOV ESI,EAX
; S9 w- x$ z, I0 a+ A2 C7 D t/ l10004E0D 85DB TEST EBX,EBX" F% L/ B c: q% x# c
10004E0F BF 38AD1210 MOV EDI,Zi__Crac.1012AD38- a5 C- x- c/ \; L: v
10004E14 74 33 JE SHORT Zi__Crac.10004E49
% i9 x' ]0 f+ F4 O# R( o2 f10004E16 8BCB MOV ECX,EBX3 a& C8 D5 P% R3 g
10004E18 E8 03FCFFFF CALL Zi__Crac.10004A20 $ R3 O: {, W* F0 w2 X
3 D9 R, d: N uESI和EAX装的就是比较的结果,然后就是一个CALL!!决不能让你存!!改掉!!目的是要ESI的数值无条件是0(使10004E06处的比较结果一定相等)。考虑到10004E0B的指令有2字节,改为 , ~6 z( T t$ R- ^. [9 A
10004E0B 33F6 XOR ESI,ESI
& P; N, Z7 f0 I4 I. B- Y运行......全部通过了^_^ : E! n! B6 ~" g* B# m! `+ {3 p
以后用16进制编辑器怎么改就不用多说了,基本工具使用的问题。 ( C2 {0 J/ G+ E1 A' B0 u- e
菜鸟一个,有意见或建议请不吝赐教,共同进步 : )
1 X% ], u5 d( r4 [
3 ?; V( {" f/ q破解用时:18分钟 : (
2 r0 E' e: a: O# d ( T$ q6 L6 u1 S' f* H
" s' I/ j( ?, h# ]$ m* b# u! o5 b |