|
作者:vifun http://bbs.pediy.com/
) x- d* W, A0 p8 R0 o# W工具:
' Q( u" k8 P$ D& {OllyDbg 1.10
3 I& w H/ h, y$ ]0 n; O/ ^+ z2 {( t
crackme:
+ p v: G+ {( ~$ P4 p4 e___crakme/download">http://www.crackmes.de/users/zionz/crackmes/zi___crakme/download
6 z T4 @+ u. X$ J2 C: z* L总结:
6 z! e' k1 s4 I: l6 ]1. 不要一开始就用工具,先试运行一下,感觉一下可疑的地方,获取一些重要的信息,如错误提示。 ' P3 W3 Z C$ Z6 s! s2 L% `2 y
2. 从内存中查找字符串,输入的信息肯定在内存中的,一定找得到!
* l8 R9 D0 A, q# X0 Z. t8 J8 Q) x) T3. 大部分软件是等字符串全部输入了再处理的,内存跟踪,死盯着它!
9 R8 T+ G+ b3 A$ K) H1 m, l4. 有些程序是把字符串复制几份放不同地方的,每次被断的时候可以考虑重新搜索一次内存,在所有找到的字符串上下断点。
, n) ?# p. H& u2 o' O/ d5. 后发先致,先从最后一次读取入手,先分析最后的处理算法,以免在前面一直浪费时间还影响信心。
0 q5 n: m( M0 C7 k3 N6. 细心、耐心、信心!! $ I* E! T: e8 ?; K
为什么先写总结呢?个人觉得这次破解的体会比获得的知识更重要。这个crackme难度不大,但能给刚入门的cracker一点启示。 . e9 G, w8 r' Y, i
+ Z* W' b# P7 b/ `
提议: 0 |- @ O" G0 X) Y: e9 S0 X9 f
作为老鸟,或许感到很多事是必然的,但对我等菜鸟就不是那么明确了。以后破解文章能不能不单是过程的记录(比如突然冒出一个来到这里),最好还能是一种思想的启示(为什么你要来这里,怎么使你来这里)。
3 S. @8 e3 ^5 M9 @/ z. }; Y8 Y最好再加上破解时间,因为一篇文章,看起来那么几百字,感觉像3、5分钟就破完一个程序一样,给初学者信心比较大的打击:"怎么我破了整天都没有搞定呢?"。加上时间,大家就可以看出差距了:"原来××牛人都用了半天,我还不太蠢^_^"。
; Y/ Q# I5 p1 J! |' B老鸟看到这里就基本上不用看下去了,下面的破解实在是见笑^_^
% {1 q/ n# |. y- t5 u1 ^2 R2 Z! {- e' B4 |3 a. b$ S& J1 _
正文: 9 i0 A4 D, _+ K. R. N2 d) O. i- Z1 d
有感于自己也曾经是菜菜鸟(现在是菜鸟^_^),也碰到过不少菜菜鸟级的问题,藉完成一简单破解之际,特发此文,谈谈菜菜鸟最想问的问题--"为什么这样做啊","为什么决定来这里看看",希望能给未来的菜鸟一点教益。老鸟如果看烦了,小的先陪个罪^_^ ! v3 v+ _# | H7 W
昨天在http://www.crackmes.de/ 随手down了个解决了的crackme(___crakme">http://www.crackmes.de/users/zionz/crackmes/zi___crakme)打算学习学习外国人的先进经验(我也是菜鸟啊),没想到两方案都是违背了作者初衷的,自己破吧!
" R* e0 T4 K A$ a先运行一下那个crackme(还是有个总体的印象好,不要什么都不清楚就用工具破解)。好了,发现是命令行界面的,随便输个号进去,回车,显示"WRONG SERIAL"(注意大小写,这个很重要,把提示都记准确一点)。
3 M" z, w; Y9 p: e- ~1 s用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。好了这次有了!向上滚动看看上文(通常都要上下结合的啦),发现了
- g( }: Y# i; k1016CD75 45 4E 54 45 52 20 53 45 52 49 41 ENTER SERIA
, V T% x0 n1 _5 h1016CD85 4C 20 54 4F 20 43 4F 4E 54 49 4E 55 45 3A 00 41 L TO CONTINUE:.A) l( q5 @ L' f. t$ a* W5 @8 A. O
1016CD95 58 39 34 33 00 57 45 4C 4C 20 44 4F 4E 45 21 00 X943.WELL DONE!.+ Z% p0 h1 L/ l0 S! e
1016CDA5 57 52 4F 4E 47 20 53 45 52 49 41 4C WRONG SERIAL
2 y2 I$ F0 }" G ]) q呵呵,很多字符串哦!AX943是什么,难道就是......按[F9]允许,然后输入AX943,成功了!
% R6 @2 ~' ?: F4 N- ~两个外国人的方案都是到此为止了。如果是破解应用软件,到此也的确够了。此crackme的作者明确表示要求通过任意序列号(Note: Consider it cracked if it accept any serial, not finding the right one.)因此我们继续! - L3 M; M; K9 K9 }; N
[Ctrl+F2]重新开始,按[F9]运行,出现了提示输入的界面。输个好记并且不容易在内存中存在的字符串,我这里输的是QWERTYUIOP(键盘第一行字母,都大写的)。回到OD,依然[Alt+M],然后[Ctrl+B]调出搜索窗口,输入QWERTYUIOP,按ok。很快OD就找到了
0 f7 e: Y7 P3 }; A) w' Y* ^00A5D321 51 57 45 52 54 59 55 49 4F 50 00 0D F0 AD BA QWERTYUIOP..瓠?
# A7 X- s- b$ K- _' K, X- y右击51(就是那个Q),选"Breakpoint","Memory,on access",这样当crackme读取这个序列号的时候就被中断了。回到crackme,按回车,OD把它中断在 1 R1 m) i e5 E+ ^+ S+ {
10045B7E 0FBE00 MOVSX EAX,BYTE PTR DS:[EAX]
% l4 P; x+ O+ |7 \! f* _6 N先不要急,继续[F9]运行,看看它要被读多少次(为什么这样呢,因为很多时候序列号都要被重复读取的,但重要的比较或者运算很可能在最后那次才出现,否则,最后一次读来干嘛就很值得怀疑了) # W( P* X* I4 { W) J
好了,让它运行都结束,出现WRONG SERIAL(当然的结果,浪费少少时间不要紧),发现一共读了5次!我决定从最后一次入手!!(前几次很可能是一些验空串、去空格等预处理) ) \2 T* d, P+ S7 D
再一次[Ctrl+F2],再一次输入QWERTYUIOP,查找,并下断点,运行。跳过前4次的中断,我们来到最后那次读取的地方,是 / a- T, ^% e' {# Q
10004DEB F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] " P7 R+ }4 Q$ L2 Q, b1 M- J9 E
一看知道是比较了,右边寄存器的窗口还显示出
4 K' P& R9 W( S& u! P8 ZESI 00A5D321 ASCII "QWERTYUIOP"
" U5 H. D! k e# W" YEDI 00A59FC1 ASCII "AX943" 4 K9 `( k' j# D d( ^1 c
为了通过任意序列号,暴力改下面的跳转吧!
3 B W( H0 ^- c7 X& B' `6 f10004DED 74 05 JE SHORT Zi__Crac.10004DF4 5 `6 R! S1 g! r: r+ D8 G. E
原来是相等就跳,我把74改为EB,无条件跳转!
7 c1 X$ _( Z0 u9 F; ^' l运行crackme,还是WRONG SERIAL!应该是跳转后还有判断吧......
" _* [9 @4 u) n+ K% }$ M, c/ S再次运行,跟踪,来到10004DED,无条件跳转后,按[F8]跟下去,很快就发现又有比较了 m( F7 ]# s/ ~2 F" i. `
10004DFB 3BD6 CMP EDX,ESI 6 b2 i+ I' T. D* n/ s' m2 d% s
代码窗口下面还有提示: 3 d6 x8 Y8 h& x* S
ESI=000000053 l2 z4 l0 ]8 I0 y) Q1 n2 ~
EDX=0000000A
8 f% b9 f1 U' m想一下,5应该是AX943的长度,0A就是QWERTYUIOP的长度10,好,继续改跳转 % ^& r* M4 |) c! i- }0 W8 N5 ~
10004DFD 73 05 JNB SHORT Zi__Crac.10004E04
- G" z0 i) ~; s' j% r* }' ?$ S$ |# I将73改为EB,无条件跳转!
; J4 H' ^& A* a: c& T: {8 G+ w3 g7 y细想原来的JNB这个指令有可疑,为什么不是JNE呢,难道下面还有JB指令?继续[F8]跟! o/ c9 l, [0 G7 S" P
果然没有错,很快又来一个比较了 3 b& I8 g; M: @# A! }) b, F* [. h
10004E06 3BD6 CMP EDX,ESI 6 }; B1 B1 }) S6 O) e$ u( E: q
而且下面紧接的是 ( q3 Q9 H: W# w+ F) P$ i* d
10004E08 0F95C0 SETNE AL
! x- U9 @. b! ?* P! |: p8 u/ h呵呵,终于来"NE"了(不相等就怎么怎么样)!!
+ U' R6 P4 K3 F! Y9 y4 P再看下面
" U$ D6 @% z1 ?10004E0B 8BF0 MOV ESI,EAX( c: M) ^0 {3 V& `+ H" U0 J# O
10004E0D 85DB TEST EBX,EBX) m) B- N7 S, t8 z7 d
10004E0F BF 38AD1210 MOV EDI,Zi__Crac.1012AD38
; t9 P# z W6 `- f10004E14 74 33 JE SHORT Zi__Crac.10004E49
7 E$ ^& J0 q9 q" l! l# n10004E16 8BCB MOV ECX,EBX& y9 B5 ~0 b( z' g$ J% t* u8 P( n
10004E18 E8 03FCFFFF CALL Zi__Crac.10004A20 % O- ?% G Q* B! n& G1 o
7 H& L$ G! W% M8 {
ESI和EAX装的就是比较的结果,然后就是一个CALL!!决不能让你存!!改掉!!目的是要ESI的数值无条件是0(使10004E06处的比较结果一定相等)。考虑到10004E0B的指令有2字节,改为
% H* V3 b, x7 P1 @10004E0B 33F6 XOR ESI,ESI % m* L9 I. Q( q+ a: C
运行......全部通过了^_^ & @: g% R+ }( x+ M" J/ ]+ w
以后用16进制编辑器怎么改就不用多说了,基本工具使用的问题。
( W( L9 I; `7 c# ?菜鸟一个,有意见或建议请不吝赐教,共同进步 : ) 4 S4 q" o9 a5 S. f+ ^% u
3 }2 }4 }' K6 e0 W# C- o
破解用时:18分钟 : (
: Z# D4 g* f2 G
" R9 l4 V& q ^
+ S, t- V6 _$ L, a9 ` |