|
作者:vifun http://bbs.pediy.com/
" W7 }$ O0 K. m* D0 p3 Q4 f工具:
* v7 j2 r1 g9 v& |: y( rOllyDbg 1.10
& Z: M! d0 J, a3 Q' q) l! ^& X$ U" V. q3 H/ {* q
crackme:
- c5 v5 b9 k& Q" R- F. u___crakme/download">http://www.crackmes.de/users/zionz/crackmes/zi___crakme/download
3 t( m% T1 e# A& u" w& @/ Q总结:
5 [& L, }, u! m$ h1. 不要一开始就用工具,先试运行一下,感觉一下可疑的地方,获取一些重要的信息,如错误提示。
' j0 X6 L; H. h) Z2. 从内存中查找字符串,输入的信息肯定在内存中的,一定找得到!
! a- ^" B$ T& S p" |8 F3. 大部分软件是等字符串全部输入了再处理的,内存跟踪,死盯着它!
( A, x- X0 h4 O" M& _4. 有些程序是把字符串复制几份放不同地方的,每次被断的时候可以考虑重新搜索一次内存,在所有找到的字符串上下断点。 - f/ K t' T$ c
5. 后发先致,先从最后一次读取入手,先分析最后的处理算法,以免在前面一直浪费时间还影响信心。
b; y4 l9 X6 i* G% l1 _: l6. 细心、耐心、信心!!
& [) k3 k4 h/ _% Q L: Y @% b为什么先写总结呢?个人觉得这次破解的体会比获得的知识更重要。这个crackme难度不大,但能给刚入门的cracker一点启示。
7 J b9 s# `0 `5 T/ S
7 ]! z$ v' w- v; ~6 m, V提议: & |0 E/ f7 s5 W4 B
作为老鸟,或许感到很多事是必然的,但对我等菜鸟就不是那么明确了。以后破解文章能不能不单是过程的记录(比如突然冒出一个来到这里),最好还能是一种思想的启示(为什么你要来这里,怎么使你来这里)。 $ ?" l6 Q; \; M+ T2 i6 O _
最好再加上破解时间,因为一篇文章,看起来那么几百字,感觉像3、5分钟就破完一个程序一样,给初学者信心比较大的打击:"怎么我破了整天都没有搞定呢?"。加上时间,大家就可以看出差距了:"原来××牛人都用了半天,我还不太蠢^_^"。 6 n/ x, l5 f# L3 k* M6 D6 C
老鸟看到这里就基本上不用看下去了,下面的破解实在是见笑^_^
7 ^, j' i% U) r, Y& C v* V, a+ b! j
正文:
* [# M) i4 `$ K, }, V有感于自己也曾经是菜菜鸟(现在是菜鸟^_^),也碰到过不少菜菜鸟级的问题,藉完成一简单破解之际,特发此文,谈谈菜菜鸟最想问的问题--"为什么这样做啊","为什么决定来这里看看",希望能给未来的菜鸟一点教益。老鸟如果看烦了,小的先陪个罪^_^
* G1 k& ~7 u" F* T2 O; N/ [/ S昨天在http://www.crackmes.de/ 随手down了个解决了的crackme(___crakme">http://www.crackmes.de/users/zionz/crackmes/zi___crakme)打算学习学习外国人的先进经验(我也是菜鸟啊),没想到两方案都是违背了作者初衷的,自己破吧! : V' U2 }2 d3 A$ }% j* L- d( A
先运行一下那个crackme(还是有个总体的印象好,不要什么都不清楚就用工具破解)。好了,发现是命令行界面的,随便输个号进去,回车,显示"WRONG SERIAL"(注意大小写,这个很重要,把提示都记准确一点)。
! w4 p9 ], j0 A- |- C5 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 U9 f, T* z2 K. h6 n& k. \
1016CD75 45 4E 54 45 52 20 53 45 52 49 41 ENTER SERIA$ t- u- X3 t9 }( b; j7 z
1016CD85 4C 20 54 4F 20 43 4F 4E 54 49 4E 55 45 3A 00 41 L TO CONTINUE:.A
' J, L& S# ^5 G9 a5 b1016CD95 58 39 34 33 00 57 45 4C 4C 20 44 4F 4E 45 21 00 X943.WELL DONE!.
! L- W% ~$ D" B8 H7 L! j" G, ~" p1016CDA5 57 52 4F 4E 47 20 53 45 52 49 41 4C WRONG SERIAL
' P7 H+ b' Q' t' X( a呵呵,很多字符串哦!AX943是什么,难道就是......按[F9]允许,然后输入AX943,成功了!
* T' P2 D; E0 h x: A# [& T7 [两个外国人的方案都是到此为止了。如果是破解应用软件,到此也的确够了。此crackme的作者明确表示要求通过任意序列号(Note: Consider it cracked if it accept any serial, not finding the right one.)因此我们继续! $ t# o1 u P% S2 p9 ?+ F) t6 |
[Ctrl+F2]重新开始,按[F9]运行,出现了提示输入的界面。输个好记并且不容易在内存中存在的字符串,我这里输的是QWERTYUIOP(键盘第一行字母,都大写的)。回到OD,依然[Alt+M],然后[Ctrl+B]调出搜索窗口,输入QWERTYUIOP,按ok。很快OD就找到了 7 [8 J* g# S- }; ~: {2 v$ d
00A5D321 51 57 45 52 54 59 55 49 4F 50 00 0D F0 AD BA QWERTYUIOP..瓠?
& |8 }) J/ ]; p/ n2 o) f右击51(就是那个Q),选"Breakpoint","Memory,on access",这样当crackme读取这个序列号的时候就被中断了。回到crackme,按回车,OD把它中断在 $ j/ K" m e+ _
10045B7E 0FBE00 MOVSX EAX,BYTE PTR DS:[EAX] ; C' _" f+ j0 \* k
先不要急,继续[F9]运行,看看它要被读多少次(为什么这样呢,因为很多时候序列号都要被重复读取的,但重要的比较或者运算很可能在最后那次才出现,否则,最后一次读来干嘛就很值得怀疑了) 8 b. p- i* |/ E: V
好了,让它运行都结束,出现WRONG SERIAL(当然的结果,浪费少少时间不要紧),发现一共读了5次!我决定从最后一次入手!!(前几次很可能是一些验空串、去空格等预处理) / Y0 r$ d( L; V$ \* h
再一次[Ctrl+F2],再一次输入QWERTYUIOP,查找,并下断点,运行。跳过前4次的中断,我们来到最后那次读取的地方,是
; \/ n2 t I: q7 ]( V10004DEB F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] ) H$ c% }* b! w* D
一看知道是比较了,右边寄存器的窗口还显示出
8 G: H5 F2 g# z" @' sESI 00A5D321 ASCII "QWERTYUIOP"
6 E$ y# I# d; F7 ]% PEDI 00A59FC1 ASCII "AX943" 6 O# j: p9 W Y
为了通过任意序列号,暴力改下面的跳转吧!
! R: p6 u2 z9 l4 |: N8 E X+ K10004DED 74 05 JE SHORT Zi__Crac.10004DF4
+ G1 \! l( i$ C4 Y" K原来是相等就跳,我把74改为EB,无条件跳转! 8 H1 t; |+ q0 z. T0 U
运行crackme,还是WRONG SERIAL!应该是跳转后还有判断吧......
- D7 C6 q+ M1 |) W& B再次运行,跟踪,来到10004DED,无条件跳转后,按[F8]跟下去,很快就发现又有比较了 9 g* r1 l* a q0 u5 B; c
10004DFB 3BD6 CMP EDX,ESI
% @3 Z! a3 ]/ V( n* m& z! U/ F5 J: E代码窗口下面还有提示:
' j1 Y* {% J. A. I% {$ H% N+ O) GESI=00000005 [8 R5 H2 X: e3 L; ~
EDX=0000000A
" m3 V: E0 ?; o1 {0 k" y$ E+ `想一下,5应该是AX943的长度,0A就是QWERTYUIOP的长度10,好,继续改跳转 7 q" y1 t+ v) i& G: ]' O
10004DFD 73 05 JNB SHORT Zi__Crac.10004E04
3 V; i. g# w' J5 E E0 I将73改为EB,无条件跳转! % ^' t. s, G9 v2 {! |8 u/ e0 W
细想原来的JNB这个指令有可疑,为什么不是JNE呢,难道下面还有JB指令?继续[F8]跟!
) H. w9 w$ d9 m6 S+ j3 M! C果然没有错,很快又来一个比较了 # w( l" S# T' G" u2 f/ B# b! L$ T/ P
10004E06 3BD6 CMP EDX,ESI 6 R, h# C& H5 p9 S# `+ y
而且下面紧接的是
' M9 V" m, {8 q: e% y10004E08 0F95C0 SETNE AL * J W* T1 j8 Q7 ^) J
呵呵,终于来"NE"了(不相等就怎么怎么样)!!
6 f4 u/ ]! c- g1 j' S再看下面
. ?3 ?# m o4 d6 X10004E0B 8BF0 MOV ESI,EAX+ Z" w4 l# T* a; K! x
10004E0D 85DB TEST EBX,EBX+ i+ z+ T6 n2 I9 w, @( z5 I8 k; A
10004E0F BF 38AD1210 MOV EDI,Zi__Crac.1012AD38: P4 D* V' z" F3 Q6 W! G4 v% p
10004E14 74 33 JE SHORT Zi__Crac.10004E49
9 J1 N/ G5 {/ u2 ~ [& M" e! O: [) n10004E16 8BCB MOV ECX,EBX
% @" B1 U% v+ h( J10004E18 E8 03FCFFFF CALL Zi__Crac.10004A20 2 U- O: ~& f* M& E; z5 o! E" P
( g/ B+ W- I! T9 D: a/ O- c+ K
ESI和EAX装的就是比较的结果,然后就是一个CALL!!决不能让你存!!改掉!!目的是要ESI的数值无条件是0(使10004E06处的比较结果一定相等)。考虑到10004E0B的指令有2字节,改为 ) ?% e$ J& u2 x7 P
10004E0B 33F6 XOR ESI,ESI
! Q6 E p6 O7 z$ u- G运行......全部通过了^_^ ; F; [3 q3 j7 D' @! e% L8 q6 m
以后用16进制编辑器怎么改就不用多说了,基本工具使用的问题。
4 v# N5 {$ Q; m1 T- c0 T6 b" Y菜鸟一个,有意见或建议请不吝赐教,共同进步 : ) 7 Y9 u+ ?6 z+ v+ X+ Z7 @6 G
0 K) W2 L& U8 u, E5 |& Y* \
破解用时:18分钟 : (3 D& T* j' X! |: s* n
: a; t8 |% f: b" \4 [9 J, t6 k6 Y
. C; H5 V" z% U8 g" h% c6 W
|