└文章标题┐:CrackMe(Keyfile)'算法分析
└破文作者┐:-=>大菜一号<=-
└破解对象┐:附件里有
└下载地址┐:也在附件
└对象大小┐:不知道
└加壳方式┐:没有
└保护方式┐:Keyfile
└编写语言┐:汇编
└使用工具┐:OD,Ue
└破解平台┐:D版XP
└破解声明┐:原来写个key也很容易```
----------------------------------------------------------------------------------
└破解过程┐:
呵呵``忘记在哪了!!突然看到这个CrackMe,拿来玩玩`Keyfile保护滴!!挺有意思的`
运行提示"Your time-trial has ended..Please register and copy the keyfile sent to you to this directory!"
->使用过期了!
OD载入,Ultra String Reference->只看到一个文件名了"due-cm2.dat"
手动做个假的,写入"121212",再运行,提示"Your current keyfile is invalid."->提示错误码内容.用OD载入,找到这个字符串,向上看,有一个Readfile,下断
F9运行,中断在下面了:
0040109A > \6A 00 push 0 ; /pOverlapped = NULL
0040109C . 68 73214000 push 00402173 ; |pBytesRead = due-cm2.00402173
004010A1 . 6A 46 push 46 ; |BytesToRead = 46 (70.)
004010A3 . 68 1A214000 push 0040211A ; |Buffer = due-cm2.0040211A
004010A8 . 50 push eax ; |hFile
004010A9 . E8 2F020000 call <jmp.&KERNEL32.ReadFile> ; \ReadFile
004010AE . 85C0 test eax, eax
004010B0 . 75 02 jnz short 004010B4 ; 内容为空出错
004010B2 . EB 43 jmp short 004010F7
004010B4 > 33DB xor ebx, ebx
004010B6 . 33F6 xor esi, esi
004010B8 . 833D 73214000>cmp dword ptr [402173], 12
004010BF . 7C 36 jl short 004010F7 ; 字节长度小于18位,出错
004010C1 > 8A83 1A214000 mov al, byte ptr [ebx+40211A] ; 取字符
004010C7 . 3C 00 cmp al, 0
004010C9 . 74 08 je short 004010D3 ; 为0就跳
004010CB . 3C 01 cmp al, 1 ; 字符和1比较
004010CD . 75 01 jnz short 004010D0 ; 不等跳到4010d0
004010CF . 46 inc esi ; 如果在循环当中遇到字节为01的,就跳
004010D0 > 43 inc ebx ; 文件读写位置指针编移1
004010D1 .^ EB EE jmp short 004010C1
004010D3 > 83FE 02 cmp esi, 2 ; 在循环当中如果遇到字节00的话就到这里(字符取完后就是00,不过手动写个00也是可以),我们知道在004010cb处al与01比较,如果是01esi就加1,这里esi和2比较
004010D6 7C 1F jl short 004010F7 ; 上面esi和2比较,如果小于2的话就直接出错了!
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
第一阶段就到这里,可以得到这个key文件的大致要求:
1、字节长度必须大于等于18,也就是要17个字节以上
2、所有字节里必须要有两个以上的01
3、强化第二个条件,在遇到字节00时esi必须要为2,也就是必须要有两个01(可以看004010c9处代码,如果有00就直接比较字节01的个数了!当然,在这18个字节的key里,也可以不写00,这个循环到最后+1次循环时就会取一个空字节,也就是00了)
AA:最重要的一点就是,这个key文件要用十六进制编辑工具来写了,呵!
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
004010D8 . 33F6 xor esi, esi
004010DA . 33DB xor ebx, ebx
004010DC > 8A83 1A214000 mov al, byte ptr [ebx+40211A] ; 取字符
004010E2 . 3C 00 cmp al, 0
004010E4 . 74 09 je short 004010EF ; 如果key文件内容里并没有00,则可以解释为是否已取完字符,取完就跳
004010E6 . 3C 01 cmp al, 1 ; 判断是否遇到为01的字节
004010E8 . 74 05 je short 004010EF ; 如果是01就跳
004010EA . 03F0 add esi, eax ; 否则累加
004010EC . 43 inc ebx ; 文件读写位置偏移1
004010ED .^ EB ED jmp short 004010DC
004010EF > 81FE D5010000 cmp esi, 1D5 ; esi是累加的结果,这里和1d5比较!在004010e4和004010e8处的跳转都跳到这,说明在程序遇到字节为00或01时前面的字节的累加和必须为1d5
004010F5 74 1D je short 00401114 ; 不等就出错
004010F7 > 6A 00 push 0 ; |/Style = MB_OK|MB_APPLMODAL
004010F9 . 68 01204000 push 00402001 ; ||duelist's crackme #2
004010FE . 68 86204000 push 00402086 ; ||your current keyfile is invalid... please obtain a valid one from the software author!
00401103 . 6A 00 push 0 ; ||hOwner = NULL
00401105 . E8 5D020000 call <jmp.&USER32.MessageBoxA> ; |\MessageBoxA
0040110A . E8 AA010000 call <jmp.&KERNEL32.ExitProcess> ; \ExitProcess
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
第二阶段:
可以得出,在key文件遇到第一个01前的所有字节的累加和必须为1d5
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
00401114 > \33F6 xor esi, esi ; 如果为1d5就跳到这
00401116 > 43 inc ebx ; 文件读写位置又向下一个字节了
00401117 . 8A83 1A214000 mov al, byte ptr [ebx+40211A] ; 取出字符
0040111D . 3C 00 cmp al, 0
0040111F . 74 18 je short 00401139 ; 又是这样,和上面差不多,不多分析了
00401121 . 3C 01 cmp al, 1
00401123 . 74 14 je short 00401139 ; 上面分析过了
00401125 . 83FE 0F cmp esi, 0F
00401128 . 73 0F jnb short 00401139
0040112A . 3286 1A214000 xor al, byte ptr [esi+40211A] ; 在第一个01后的字节和在第二个01前的字节分别异或,也就是两个01中间那一堆字节了
00401130 . 8986 60214000 mov dword ptr [esi+402160], eax ;异或出的字符放到esi+402160这个内存地址处
00401136 . 46 inc esi
00401137 .^ EB DD jmp short 00401116
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
第三阶段:
其实只是推出一个edit的内容,这个程序成功运行后,界面有一个不可编辑的edit,就是放这里算出来的字符的!没什么用``
不过要注意思的是:0040111f,00401123,00401128这三个里的代码,都跳到同一个地方,如果key文件里较验到这阶段,已经没有为00,01,或大于等于0f的字节的话,那这就是一个死循环了!
注意哦!!!
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
00401139 > 43 inc ebx ; 指向下一个字符
0040113A . 33F6 xor esi, esi
0040113C > 8A83 1A214000 mov al, byte ptr [ebx+40211A]
00401142 . 3C 00 cmp al, 0 ; 上面分析过了,这里也差不多
00401144 . 74 09 je short 0040114F
00401146 . 3C 01 cmp al, 1
00401148 .^ 74 F2 je short 0040113C ; 这里也是
0040114A . 03F0 add esi, eax ; 如果没遇到00或01的就话就累加
0040114C . 43 inc ebx ; 文件读写位置向下
0040114D .^ EB ED jmp short 0040113C ; 跳上去
0040114F > 81FE B2010000 cmp esi, 1B2 ; 累加结果和1b2比较
00401155 .^ 75 A0 jnz short 004010F7 ; 不等就出错
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
第四阶段:
可以得出在第二个01到第三个01(如果key里有多01的话)之后字节的累加和必须为1b2
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
经过分析,可以得出了key的写法,
一个正确的key文件:
|EA+EB=1D5| |这里是推出edit的内容的,随便写写| | 这几个3E的和为1B2 |
EA EB 01 15 15 15 15 15 15 15 01 3E 3E 3E 3E 3E 3E 3E
用ue可以写了!!呵呵,运行程序,已经可以用了,界面的edit中显示个"?"->呵,有兴趣自己算出个好看的名字!!!
----------------------------------------------------------------------------------
└经验总结┐:
嘿嘿``这个keyfile好玩!!不过还真累```汗~~~~~~
----------------------------------------------------------------------------------
└版权声明┐ 本文原创于看雪软件安全论坛, 转载请注明作者并保持文章的完整, 谢谢!
2007年4月9日 16:7:19
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!