|
作者:vifun http://bbs.pediy.com/
! A2 `9 m3 [ c" U1 t, m工具:* e% N6 C% a& d2 j! U
OllyDbg 1.10
! I* |+ l4 w! s" V( y9 h. r( c) U' u' h1 c* V
crackme: 0 |0 M r2 p4 r* a( |
___crakme/download">http://www.crackmes.de/users/zionz/crackmes/zi___crakme/download
. p1 \2 u2 M) Y# t( S总结:
+ t- e$ \+ B5 a) a7 V1. 不要一开始就用工具,先试运行一下,感觉一下可疑的地方,获取一些重要的信息,如错误提示。
% s* K: V) l) E2 R9 ]6 r6 _2. 从内存中查找字符串,输入的信息肯定在内存中的,一定找得到! # z8 a* Y E4 y! e) |
3. 大部分软件是等字符串全部输入了再处理的,内存跟踪,死盯着它!
) ^4 J& o& q5 ~+ I& n4. 有些程序是把字符串复制几份放不同地方的,每次被断的时候可以考虑重新搜索一次内存,在所有找到的字符串上下断点。 ; G6 q# ~3 d7 q) C6 P2 p
5. 后发先致,先从最后一次读取入手,先分析最后的处理算法,以免在前面一直浪费时间还影响信心。
) e( g {. R* e6. 细心、耐心、信心!!
/ ]4 m! W3 Z( F8 ?; b为什么先写总结呢?个人觉得这次破解的体会比获得的知识更重要。这个crackme难度不大,但能给刚入门的cracker一点启示。 & c a2 C2 z, [, B/ I* j9 O" t
1 n( {& m+ ~0 a& L/ @3 P
提议: 6 B7 h& a6 J; ]3 |
作为老鸟,或许感到很多事是必然的,但对我等菜鸟就不是那么明确了。以后破解文章能不能不单是过程的记录(比如突然冒出一个来到这里),最好还能是一种思想的启示(为什么你要来这里,怎么使你来这里)。
4 |7 H" h( v2 T最好再加上破解时间,因为一篇文章,看起来那么几百字,感觉像3、5分钟就破完一个程序一样,给初学者信心比较大的打击:"怎么我破了整天都没有搞定呢?"。加上时间,大家就可以看出差距了:"原来××牛人都用了半天,我还不太蠢^_^"。
) o2 t) i' E r* e, F) j. q" P6 Q老鸟看到这里就基本上不用看下去了,下面的破解实在是见笑^_^
. l( R$ b5 K$ |' j) H/ f |) }8 c/ @! q: _, x& H; t8 S( a
正文:
9 g8 P. _, ^& Y; s1 r. v有感于自己也曾经是菜菜鸟(现在是菜鸟^_^),也碰到过不少菜菜鸟级的问题,藉完成一简单破解之际,特发此文,谈谈菜菜鸟最想问的问题--"为什么这样做啊","为什么决定来这里看看",希望能给未来的菜鸟一点教益。老鸟如果看烦了,小的先陪个罪^_^
) }% q; q% |6 @5 I昨天在http://www.crackmes.de/ 随手down了个解决了的crackme(___crakme">http://www.crackmes.de/users/zionz/crackmes/zi___crakme)打算学习学习外国人的先进经验(我也是菜鸟啊),没想到两方案都是违背了作者初衷的,自己破吧! * C8 [5 ]$ E" X7 c" l0 n
先运行一下那个crackme(还是有个总体的印象好,不要什么都不清楚就用工具破解)。好了,发现是命令行界面的,随便输个号进去,回车,显示"WRONG SERIAL"(注意大小写,这个很重要,把提示都记准确一点)。
+ C* i: D/ y6 ~# Z9 w用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。好了这次有了!向上滚动看看上文(通常都要上下结合的啦),发现了
$ V$ ^$ x7 i7 I2 ?3 L# x1016CD75 45 4E 54 45 52 20 53 45 52 49 41 ENTER SERIA
; o* z, b5 j+ v0 d1 R6 d1016CD85 4C 20 54 4F 20 43 4F 4E 54 49 4E 55 45 3A 00 41 L TO CONTINUE:.A
2 u- [1 |+ l! ]1016CD95 58 39 34 33 00 57 45 4C 4C 20 44 4F 4E 45 21 00 X943.WELL DONE!.
. P! N% P, b0 n3 w0 ~2 _1016CDA5 57 52 4F 4E 47 20 53 45 52 49 41 4C WRONG SERIAL 8 E- Q: V7 f- Y0 V2 J
呵呵,很多字符串哦!AX943是什么,难道就是......按[F9]允许,然后输入AX943,成功了! / u9 }3 i1 h K$ Q7 C
两个外国人的方案都是到此为止了。如果是破解应用软件,到此也的确够了。此crackme的作者明确表示要求通过任意序列号(Note: Consider it cracked if it accept any serial, not finding the right one.)因此我们继续! - [6 O: j. A) _4 I2 K" J3 W
[Ctrl+F2]重新开始,按[F9]运行,出现了提示输入的界面。输个好记并且不容易在内存中存在的字符串,我这里输的是QWERTYUIOP(键盘第一行字母,都大写的)。回到OD,依然[Alt+M],然后[Ctrl+B]调出搜索窗口,输入QWERTYUIOP,按ok。很快OD就找到了 3 S1 R$ e& ~" x$ }# P E
00A5D321 51 57 45 52 54 59 55 49 4F 50 00 0D F0 AD BA QWERTYUIOP..瓠? . h$ J7 ]# }& m& T( K5 d) C
右击51(就是那个Q),选"Breakpoint","Memory,on access",这样当crackme读取这个序列号的时候就被中断了。回到crackme,按回车,OD把它中断在
9 q! ^: ?; K+ Y' Z* J; B. d3 D10045B7E 0FBE00 MOVSX EAX,BYTE PTR DS:[EAX]
) k+ ^; y6 V2 ]: @- M h# c- o! {先不要急,继续[F9]运行,看看它要被读多少次(为什么这样呢,因为很多时候序列号都要被重复读取的,但重要的比较或者运算很可能在最后那次才出现,否则,最后一次读来干嘛就很值得怀疑了)
5 C* g+ R+ B& `4 @" c$ q- I* N好了,让它运行都结束,出现WRONG SERIAL(当然的结果,浪费少少时间不要紧),发现一共读了5次!我决定从最后一次入手!!(前几次很可能是一些验空串、去空格等预处理)
' M' Z3 V& ?# s再一次[Ctrl+F2],再一次输入QWERTYUIOP,查找,并下断点,运行。跳过前4次的中断,我们来到最后那次读取的地方,是 ) ?9 F0 I4 Z2 a
10004DEB F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] 2 l5 ?( I$ T8 \, O' a
一看知道是比较了,右边寄存器的窗口还显示出
) r* i, H' R7 g/ j2 xESI 00A5D321 ASCII "QWERTYUIOP"
/ @6 s2 R9 a4 a8 y9 XEDI 00A59FC1 ASCII "AX943"
9 Q1 |9 q) j( j为了通过任意序列号,暴力改下面的跳转吧! 2 m: v5 T5 g9 ]4 S6 Q5 k% z
10004DED 74 05 JE SHORT Zi__Crac.10004DF4
. Y. Y9 P9 C* x6 h5 d0 Z: Z原来是相等就跳,我把74改为EB,无条件跳转!
( Z: r8 g, X' ?% ~: ?6 H4 X1 _运行crackme,还是WRONG SERIAL!应该是跳转后还有判断吧......
6 `6 g2 n. }& B U) {0 F再次运行,跟踪,来到10004DED,无条件跳转后,按[F8]跟下去,很快就发现又有比较了 {* W t3 Y% h
10004DFB 3BD6 CMP EDX,ESI
. z1 i: H( K( t* g$ _: K `7 C. t代码窗口下面还有提示:
& a" [0 W* ~9 Z9 C% R2 VESI=00000005. Y2 G8 _' Z! {
EDX=0000000A 8 J9 q4 C! i' T7 ]+ a
想一下,5应该是AX943的长度,0A就是QWERTYUIOP的长度10,好,继续改跳转
+ x! l! M' T9 n7 B) p+ c% T/ p0 ~2 x10004DFD 73 05 JNB SHORT Zi__Crac.10004E04 ( T8 k# \4 S0 L7 [5 U3 r L
将73改为EB,无条件跳转! 5 [( E0 A7 M' V! t
细想原来的JNB这个指令有可疑,为什么不是JNE呢,难道下面还有JB指令?继续[F8]跟!
* `5 }7 s9 F/ c7 S8 v8 [ F果然没有错,很快又来一个比较了
3 p+ P) m3 c8 Z+ b10004E06 3BD6 CMP EDX,ESI
# T5 {+ S. N7 {) S; m+ p/ k而且下面紧接的是 r( c8 h @& b }, T" L
10004E08 0F95C0 SETNE AL . G) I- ~3 C- y* {; s
呵呵,终于来"NE"了(不相等就怎么怎么样)!! - \8 }; Z9 z$ a) W+ ~
再看下面 ' K8 @& }- \# ?, R$ M! B' O
10004E0B 8BF0 MOV ESI,EAX
3 A. j2 k+ b/ b: ^% Z, R10004E0D 85DB TEST EBX,EBX4 w6 j( \ ] t. I, w
10004E0F BF 38AD1210 MOV EDI,Zi__Crac.1012AD38
' V6 ^& X$ {" V8 |% c9 f9 p/ E/ @10004E14 74 33 JE SHORT Zi__Crac.10004E49
- j+ U8 D/ d \. X5 K+ p! V, k10004E16 8BCB MOV ECX,EBX
4 S6 o( i; {. n% C10004E18 E8 03FCFFFF CALL Zi__Crac.10004A20
" w+ D; V1 X+ I/ B$ A# ? q9 D4 h- r" `! q( D
ESI和EAX装的就是比较的结果,然后就是一个CALL!!决不能让你存!!改掉!!目的是要ESI的数值无条件是0(使10004E06处的比较结果一定相等)。考虑到10004E0B的指令有2字节,改为 + r2 j% L5 T4 D) O; u1 x2 J
10004E0B 33F6 XOR ESI,ESI
7 A5 P; F' ~) K% \- A: p, C运行......全部通过了^_^ 8 X. l9 x: k8 X& ]- T
以后用16进制编辑器怎么改就不用多说了,基本工具使用的问题。
; N/ l# X6 Q& d* _; H. @, C5 B, F5 O菜鸟一个,有意见或建议请不吝赐教,共同进步 : ) 3 ~' z. N5 [4 K
: C1 h4 U0 i" B7 {6 X
破解用时:18分钟 : (( B9 C! A. P3 q" a. ^( m3 }
' s3 y5 Z0 S2 l0 a3 a7 K; r! e7 D9 a1 e) q) _1 V+ e* i! E
|