|
作者:vifun http://bbs.pediy.com/ 3 c0 }* b+ I, F/ C0 p
工具:
: D" e( l; X, zOllyDbg 1.10 ! C) s$ l7 i+ Z* E) q
* K! L" O2 b+ V$ lcrackme:
2 e8 j+ [9 D$ c) v$ u___crakme/download">http://www.crackmes.de/users/zionz/crackmes/zi___crakme/download , F. o) i1 J- i, A o1 ]* p/ ]
总结: ( @$ m2 j7 z8 K7 C5 Y
1. 不要一开始就用工具,先试运行一下,感觉一下可疑的地方,获取一些重要的信息,如错误提示。
# c) i0 f( f7 D$ {. y: I7 s( k S2. 从内存中查找字符串,输入的信息肯定在内存中的,一定找得到!
A' V' m% B4 K# I6 H3. 大部分软件是等字符串全部输入了再处理的,内存跟踪,死盯着它!
# |% _9 z$ T6 n0 s0 g4. 有些程序是把字符串复制几份放不同地方的,每次被断的时候可以考虑重新搜索一次内存,在所有找到的字符串上下断点。 , P3 c' ]; |/ m# n: n8 I8 E& P1 c1 V
5. 后发先致,先从最后一次读取入手,先分析最后的处理算法,以免在前面一直浪费时间还影响信心。
, }4 e" J+ S4 Q! i0 d6. 细心、耐心、信心!! 0 D$ Q, |* B3 ]! A
为什么先写总结呢?个人觉得这次破解的体会比获得的知识更重要。这个crackme难度不大,但能给刚入门的cracker一点启示。
! V/ e" P) t5 ]
0 f \$ a0 ~- p- u提议:
/ p- k: l8 F2 c% h( I* V作为老鸟,或许感到很多事是必然的,但对我等菜鸟就不是那么明确了。以后破解文章能不能不单是过程的记录(比如突然冒出一个来到这里),最好还能是一种思想的启示(为什么你要来这里,怎么使你来这里)。
$ F3 T& x! f& e! q) y( ]# e! r最好再加上破解时间,因为一篇文章,看起来那么几百字,感觉像3、5分钟就破完一个程序一样,给初学者信心比较大的打击:"怎么我破了整天都没有搞定呢?"。加上时间,大家就可以看出差距了:"原来××牛人都用了半天,我还不太蠢^_^"。
" G* v. F/ I% U5 Z L; Y) V& k$ \老鸟看到这里就基本上不用看下去了,下面的破解实在是见笑^_^
# X3 e6 V$ O; @( L8 X
" O0 z- c8 B0 U% j8 ?正文:
* k* Q" `1 g4 r) x有感于自己也曾经是菜菜鸟(现在是菜鸟^_^),也碰到过不少菜菜鸟级的问题,藉完成一简单破解之际,特发此文,谈谈菜菜鸟最想问的问题--"为什么这样做啊","为什么决定来这里看看",希望能给未来的菜鸟一点教益。老鸟如果看烦了,小的先陪个罪^_^
& u* V8 M G- f$ n7 t1 D5 h a昨天在http://www.crackmes.de/ 随手down了个解决了的crackme(___crakme">http://www.crackmes.de/users/zionz/crackmes/zi___crakme)打算学习学习外国人的先进经验(我也是菜鸟啊),没想到两方案都是违背了作者初衷的,自己破吧! 1 K6 l+ [* E: x! q) `- Q! r1 t7 Y2 F
先运行一下那个crackme(还是有个总体的印象好,不要什么都不清楚就用工具破解)。好了,发现是命令行界面的,随便输个号进去,回车,显示"WRONG SERIAL"(注意大小写,这个很重要,把提示都记准确一点)。
' o* z4 v! L. g; w2 Q用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。好了这次有了!向上滚动看看上文(通常都要上下结合的啦),发现了 2 [" B6 [, C |3 ^
1016CD75 45 4E 54 45 52 20 53 45 52 49 41 ENTER SERIA
/ s9 [ l" ]' }7 B7 p1016CD85 4C 20 54 4F 20 43 4F 4E 54 49 4E 55 45 3A 00 41 L TO CONTINUE:.A. Y% B4 h' d2 U* S$ H4 Z9 y
1016CD95 58 39 34 33 00 57 45 4C 4C 20 44 4F 4E 45 21 00 X943.WELL DONE!.. _6 [2 b4 S6 l
1016CDA5 57 52 4F 4E 47 20 53 45 52 49 41 4C WRONG SERIAL & M! o( A0 j% z+ _& u3 p" g- q4 z% Z1 i" r
呵呵,很多字符串哦!AX943是什么,难道就是......按[F9]允许,然后输入AX943,成功了! 7 s, @9 ~; i6 h# h1 @
两个外国人的方案都是到此为止了。如果是破解应用软件,到此也的确够了。此crackme的作者明确表示要求通过任意序列号(Note: Consider it cracked if it accept any serial, not finding the right one.)因此我们继续! l0 X! X7 V+ K4 v
[Ctrl+F2]重新开始,按[F9]运行,出现了提示输入的界面。输个好记并且不容易在内存中存在的字符串,我这里输的是QWERTYUIOP(键盘第一行字母,都大写的)。回到OD,依然[Alt+M],然后[Ctrl+B]调出搜索窗口,输入QWERTYUIOP,按ok。很快OD就找到了 . t" _( g1 |8 f: q: J
00A5D321 51 57 45 52 54 59 55 49 4F 50 00 0D F0 AD BA QWERTYUIOP..瓠? Y4 @: h- N# X6 _! i
右击51(就是那个Q),选"Breakpoint","Memory,on access",这样当crackme读取这个序列号的时候就被中断了。回到crackme,按回车,OD把它中断在
$ b& n( l6 o0 F$ X# _- ?+ S10045B7E 0FBE00 MOVSX EAX,BYTE PTR DS:[EAX] v a- [4 P2 P4 p( ^" y
先不要急,继续[F9]运行,看看它要被读多少次(为什么这样呢,因为很多时候序列号都要被重复读取的,但重要的比较或者运算很可能在最后那次才出现,否则,最后一次读来干嘛就很值得怀疑了) 6 m* p( }# m' t& C" a. h
好了,让它运行都结束,出现WRONG SERIAL(当然的结果,浪费少少时间不要紧),发现一共读了5次!我决定从最后一次入手!!(前几次很可能是一些验空串、去空格等预处理)
9 `4 F3 l5 F o% B; Q/ D$ }+ _再一次[Ctrl+F2],再一次输入QWERTYUIOP,查找,并下断点,运行。跳过前4次的中断,我们来到最后那次读取的地方,是
8 Q4 k- a. f: I. M. w10004DEB F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
" K' i; ]- D8 J9 d& a; y一看知道是比较了,右边寄存器的窗口还显示出 1 Y" F' L, d$ a
ESI 00A5D321 ASCII "QWERTYUIOP"
2 @& k4 e |! vEDI 00A59FC1 ASCII "AX943"
v- A% D- O& ` b为了通过任意序列号,暴力改下面的跳转吧!
# Q8 {# S% ]' L% k) L; Y/ P' H10004DED 74 05 JE SHORT Zi__Crac.10004DF4 8 J' }+ r' _% _- J" \: `2 Q6 Z
原来是相等就跳,我把74改为EB,无条件跳转!
, a5 k8 b8 Y# v2 P6 M! z运行crackme,还是WRONG SERIAL!应该是跳转后还有判断吧...... . C- _& b& z4 S/ ]8 e! {
再次运行,跟踪,来到10004DED,无条件跳转后,按[F8]跟下去,很快就发现又有比较了 ' ~ _5 m8 C! N6 n* ?
10004DFB 3BD6 CMP EDX,ESI 5 ~- [* Z6 X- `
代码窗口下面还有提示: $ b7 p! ^: z8 k( o5 e
ESI=00000005( u. F7 R& V! y& P$ x( w
EDX=0000000A ; N1 r9 l. i5 j( n
想一下,5应该是AX943的长度,0A就是QWERTYUIOP的长度10,好,继续改跳转
! J7 {6 P7 F" `, {4 h8 K$ y% B1 }10004DFD 73 05 JNB SHORT Zi__Crac.10004E04
9 l- C2 _0 j+ d$ r# I+ l/ [! q1 U将73改为EB,无条件跳转! 1 r v3 O. W- W* k( A% [
细想原来的JNB这个指令有可疑,为什么不是JNE呢,难道下面还有JB指令?继续[F8]跟! ! n( n& z7 L1 ~9 L% k, N
果然没有错,很快又来一个比较了
: a2 a2 a* P1 [( ]* H6 u$ ?10004E06 3BD6 CMP EDX,ESI
) Q8 X8 M% i3 w2 y* Q而且下面紧接的是
+ `* e6 H ^2 ~8 r10004E08 0F95C0 SETNE AL
) j( V; U, O6 Z呵呵,终于来"NE"了(不相等就怎么怎么样)!! 2 G0 Y; V! N3 x0 Z# W. I
再看下面 / n/ I/ A! P8 q: _+ C
10004E0B 8BF0 MOV ESI,EAX9 y l# C' J" D
10004E0D 85DB TEST EBX,EBX3 E4 d- s, l0 T7 g, Q6 S( u
10004E0F BF 38AD1210 MOV EDI,Zi__Crac.1012AD388 B6 l8 M& u. f
10004E14 74 33 JE SHORT Zi__Crac.10004E49
* V: S: q% |! V6 V10004E16 8BCB MOV ECX,EBX
# p- H5 H% A3 t' V& X2 a10004E18 E8 03FCFFFF CALL Zi__Crac.10004A20 . U0 e2 s: N! o$ b6 B& b- c; W; j
/ {* D; A* D. z+ xESI和EAX装的就是比较的结果,然后就是一个CALL!!决不能让你存!!改掉!!目的是要ESI的数值无条件是0(使10004E06处的比较结果一定相等)。考虑到10004E0B的指令有2字节,改为
& B2 L$ [/ f! J10004E0B 33F6 XOR ESI,ESI
* o+ ~- H6 Y3 e$ M: n4 C7 X5 ?6 ?运行......全部通过了^_^ $ w& A7 i# z& f& y
以后用16进制编辑器怎么改就不用多说了,基本工具使用的问题。 : c! k% F8 X* E$ W' h6 ~3 \
菜鸟一个,有意见或建议请不吝赐教,共同进步 : )
1 T" c0 Q! ~7 M# r7 h4 A3 p2 T) s# i- a
破解用时:18分钟 : (
+ ~! f5 ]/ v; @4 ?* C/ o+ h7 A
E: d' p. \. T' C% B Z5 M0 D( H0 f; f6 d* L
|