|
作者:vifun http://bbs.pediy.com/ - Y: @6 g5 z' J( ?! V
工具:
9 ?- x- N }/ KOllyDbg 1.10 0 u4 s4 Q: q6 N! K# j% s$ _* I# z
, v9 D9 s% j" I
crackme: - q5 i/ {' Y) g0 e* r- V2 x' ?. }
___crakme/download">http://www.crackmes.de/users/zionz/crackmes/zi___crakme/download
1 F8 S6 v" N0 s9 Z1 p# Z总结: + s7 ]0 S# J) Z5 U/ W, g
1. 不要一开始就用工具,先试运行一下,感觉一下可疑的地方,获取一些重要的信息,如错误提示。
: O* O; n3 o% O% u2. 从内存中查找字符串,输入的信息肯定在内存中的,一定找得到!
! `0 m& n/ n( [: z$ h) J3. 大部分软件是等字符串全部输入了再处理的,内存跟踪,死盯着它!
# N5 [- b. ?7 Z. `1 d; o- G4. 有些程序是把字符串复制几份放不同地方的,每次被断的时候可以考虑重新搜索一次内存,在所有找到的字符串上下断点。
/ Y& }0 v% t3 q. v4 U5. 后发先致,先从最后一次读取入手,先分析最后的处理算法,以免在前面一直浪费时间还影响信心。
% R$ Z# y" Q; f! R" U; M* d! Y& h1 w6. 细心、耐心、信心!!
& p$ ~ R% V: u6 y" v1 I为什么先写总结呢?个人觉得这次破解的体会比获得的知识更重要。这个crackme难度不大,但能给刚入门的cracker一点启示。
& [# h* t) z. L9 ~, x$ z' y; |3 w2 ~
$ G+ a3 `' V; }* e提议:
0 i# Z o' U c$ G作为老鸟,或许感到很多事是必然的,但对我等菜鸟就不是那么明确了。以后破解文章能不能不单是过程的记录(比如突然冒出一个来到这里),最好还能是一种思想的启示(为什么你要来这里,怎么使你来这里)。
* J7 U$ O; X# |最好再加上破解时间,因为一篇文章,看起来那么几百字,感觉像3、5分钟就破完一个程序一样,给初学者信心比较大的打击:"怎么我破了整天都没有搞定呢?"。加上时间,大家就可以看出差距了:"原来××牛人都用了半天,我还不太蠢^_^"。 $ c2 }7 P# s2 C. n2 S: {
老鸟看到这里就基本上不用看下去了,下面的破解实在是见笑^_^
4 U9 J: I4 @" e4 ] e2 e) `, ?6 {1 y/ k* z! w% v
正文:
0 W! ]( v6 @/ T5 ?2 W( O有感于自己也曾经是菜菜鸟(现在是菜鸟^_^),也碰到过不少菜菜鸟级的问题,藉完成一简单破解之际,特发此文,谈谈菜菜鸟最想问的问题--"为什么这样做啊","为什么决定来这里看看",希望能给未来的菜鸟一点教益。老鸟如果看烦了,小的先陪个罪^_^
- j; K# S% Y- @- ]% B! D9 ^" M昨天在http://www.crackmes.de/ 随手down了个解决了的crackme(___crakme">http://www.crackmes.de/users/zionz/crackmes/zi___crakme)打算学习学习外国人的先进经验(我也是菜鸟啊),没想到两方案都是违背了作者初衷的,自己破吧!
& ~) s$ Y" i9 v E4 Y先运行一下那个crackme(还是有个总体的印象好,不要什么都不清楚就用工具破解)。好了,发现是命令行界面的,随便输个号进去,回车,显示"WRONG SERIAL"(注意大小写,这个很重要,把提示都记准确一点)。 ( w7 n* q. h! k" B6 Q5 [' V
用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。好了这次有了!向上滚动看看上文(通常都要上下结合的啦),发现了 ( j$ h# }1 o s/ f0 |; M
1016CD75 45 4E 54 45 52 20 53 45 52 49 41 ENTER SERIA% g9 L6 ^# i/ m! E# F
1016CD85 4C 20 54 4F 20 43 4F 4E 54 49 4E 55 45 3A 00 41 L TO CONTINUE:.A, \& Z2 F3 I; m, S5 |
1016CD95 58 39 34 33 00 57 45 4C 4C 20 44 4F 4E 45 21 00 X943.WELL DONE!.$ W1 R; W$ i3 b
1016CDA5 57 52 4F 4E 47 20 53 45 52 49 41 4C WRONG SERIAL
: ^7 V; ]( @" B% D* B, p! z: k呵呵,很多字符串哦!AX943是什么,难道就是......按[F9]允许,然后输入AX943,成功了!
8 p) ^; {3 C; W8 G4 ~4 b两个外国人的方案都是到此为止了。如果是破解应用软件,到此也的确够了。此crackme的作者明确表示要求通过任意序列号(Note: Consider it cracked if it accept any serial, not finding the right one.)因此我们继续! ; B' O2 @0 y. t3 I
[Ctrl+F2]重新开始,按[F9]运行,出现了提示输入的界面。输个好记并且不容易在内存中存在的字符串,我这里输的是QWERTYUIOP(键盘第一行字母,都大写的)。回到OD,依然[Alt+M],然后[Ctrl+B]调出搜索窗口,输入QWERTYUIOP,按ok。很快OD就找到了
6 O2 x% w3 r# W3 \$ q00A5D321 51 57 45 52 54 59 55 49 4F 50 00 0D F0 AD BA QWERTYUIOP..瓠? 7 `( i: r7 d4 e/ c* Z
右击51(就是那个Q),选"Breakpoint","Memory,on access",这样当crackme读取这个序列号的时候就被中断了。回到crackme,按回车,OD把它中断在
: a/ j4 ^9 |* R1 i" j4 Z7 \- A: w10045B7E 0FBE00 MOVSX EAX,BYTE PTR DS:[EAX] ( G$ P7 Q" H T, v
先不要急,继续[F9]运行,看看它要被读多少次(为什么这样呢,因为很多时候序列号都要被重复读取的,但重要的比较或者运算很可能在最后那次才出现,否则,最后一次读来干嘛就很值得怀疑了) . N3 h( L+ L% ^" u+ D2 _
好了,让它运行都结束,出现WRONG SERIAL(当然的结果,浪费少少时间不要紧),发现一共读了5次!我决定从最后一次入手!!(前几次很可能是一些验空串、去空格等预处理)
. i( E) {! ?4 i1 M( F: F" |$ ^再一次[Ctrl+F2],再一次输入QWERTYUIOP,查找,并下断点,运行。跳过前4次的中断,我们来到最后那次读取的地方,是 - P0 A( y2 t: O1 f( G& ?$ e- D
10004DEB F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] ( \+ r7 Z* R8 `& V5 K; h% J% j
一看知道是比较了,右边寄存器的窗口还显示出 9 j8 D. J2 W# w. w
ESI 00A5D321 ASCII "QWERTYUIOP"
/ Y; g9 ?( K Y2 MEDI 00A59FC1 ASCII "AX943" ; ]' T. v. a" p% u
为了通过任意序列号,暴力改下面的跳转吧! ' c9 s& z( L4 C" [
10004DED 74 05 JE SHORT Zi__Crac.10004DF4 4 F, s( ?5 O5 @: c
原来是相等就跳,我把74改为EB,无条件跳转!
: ?5 D0 E$ {/ _" d$ i运行crackme,还是WRONG SERIAL!应该是跳转后还有判断吧...... # K8 [( J. S2 Y5 X6 l
再次运行,跟踪,来到10004DED,无条件跳转后,按[F8]跟下去,很快就发现又有比较了
$ [4 J8 V- C' i1 K3 z5 A0 w( ]10004DFB 3BD6 CMP EDX,ESI
2 @# g+ t2 C& ?; }( B+ O' M* I+ q3 w代码窗口下面还有提示:
! v, c5 K0 U) Q, B6 JESI=000000054 V; j; G. K! F
EDX=0000000A & `, a' w7 h& [( G
想一下,5应该是AX943的长度,0A就是QWERTYUIOP的长度10,好,继续改跳转 1 f) m$ u. a" Q" y" y& h
10004DFD 73 05 JNB SHORT Zi__Crac.10004E04 . U+ r, p, M" T ^; G/ b
将73改为EB,无条件跳转! 4 B1 R! A( m$ w" e0 v
细想原来的JNB这个指令有可疑,为什么不是JNE呢,难道下面还有JB指令?继续[F8]跟! # F4 l, E) a |" s0 N0 ^/ z
果然没有错,很快又来一个比较了 8 w1 S. S# O: N! X; O
10004E06 3BD6 CMP EDX,ESI + p9 i9 t+ \2 A( W7 l: i
而且下面紧接的是
. K6 F/ T2 {. B3 Z7 {10004E08 0F95C0 SETNE AL
0 ~0 B" t) }8 U1 a呵呵,终于来"NE"了(不相等就怎么怎么样)!!
T2 g# l% Y% i! Y再看下面
2 }" G4 }$ ~' c# {) ?10004E0B 8BF0 MOV ESI,EAX
1 _: a. L. G8 w0 b10004E0D 85DB TEST EBX,EBX
7 r4 E q7 v) Q% Y10004E0F BF 38AD1210 MOV EDI,Zi__Crac.1012AD38
' O, s0 x. L) ~0 f6 q. c10004E14 74 33 JE SHORT Zi__Crac.10004E49
$ ^, Y% `: O( M8 B f+ ] [& ?9 T10004E16 8BCB MOV ECX,EBX3 W1 E5 o8 M( M' W9 a
10004E18 E8 03FCFFFF CALL Zi__Crac.10004A20
) M3 w2 P# F* D/ a0 F# C; a6 f, r1 X! [2 I8 K4 L( C
ESI和EAX装的就是比较的结果,然后就是一个CALL!!决不能让你存!!改掉!!目的是要ESI的数值无条件是0(使10004E06处的比较结果一定相等)。考虑到10004E0B的指令有2字节,改为
k. g$ z- M/ j7 A3 z10004E0B 33F6 XOR ESI,ESI ; R/ T( `2 b2 A- f7 l8 L
运行......全部通过了^_^ " |- Q1 Q. E$ N( w, J- w: [
以后用16进制编辑器怎么改就不用多说了,基本工具使用的问题。
, v/ d& |/ f& N% c, _2 { s2 f/ w1 ^菜鸟一个,有意见或建议请不吝赐教,共同进步 : ) $ e3 m! K. P- H3 ?% U
5 Y* E0 K$ { d0 A) `
破解用时:18分钟 : (- z" q1 H" l0 }
* c# m/ w7 b0 k4 P6 @
) K- O' E# L* R- _+ B% Q, x8 L' p
|