新手破解练习Crackme160之107 - Crackmex01e
程序无法在xp以上运行, 98下正常~ 随便输入提示错误信息"Please Restart the Porogram to Check your regist code."
OD载入程序, 搜索关键词, 定位到0040169F处, 同时也看到了成功关键词 "REGISTED, Email to wocy@263.net"定位到004014AF, 分别在他们上面方法入口下断(004013C0, 00401660), 直接F9运行试一下, 结果在004013C0处停下了, 有点小意外, 正常程序不会直接进入验证算法的, 这个程序可能有什么不一样的写法吧, 反正不能运行, 能停下真的算是意外之喜~, F8单步跟踪~
-
暴力破解
来到004013F5这第一个关键跳, 直接改为 jmp 00401492 到成功分支, 另存~ 复制到98下运行, 测试成功~ 其实这时在OD中继续F9直接运行, 程序竟然能成功运行了, 说明中间跳过的某些操作有异常~ 导致程序不能正常运行的~, 接下来我们正常破解, 看是否能解决这个小bug~
-
正常破解
我们OD重新载入程序~, F9运行~ 入口成功停下后, F8单步跟踪~ 我们发现程序在0040148600401488处异常 out, in两个命令, 是不是这两个命令低版本的系统才有, 所以我们把这两个命令nop掉, 程序运行正常了~ 我们输入abcde点ok, 程序来到了第二个断点处~, 向下运行又发现两处out命令(0040168D, 004016A8) , 把两个都先nop掉, 继续运行, 程序弹出注册失败信息~ 我们重新点ok~ 开始具体来分析算法~
1). 00401667 获取框内容
2). 0040167B 判断是否空
3). 0040167D ~ 00401687 cl = 每一位Asc相加+i
4). eax = cl, 高位补F,
5). eax /= 0x7F
6). al = dl(余数低位)
7). 弹错误信息, 是不是懵了~ 对的, 这里算法是没用的, 直接就失败了~
所以, 代码中的out, in命令应该是有用的, ~ 不然程序永远无法进入成功分支~ 我们把几处的out, in命令都列出, 如下:
0040168D out 0x70, al (入口是00401660) //无用
004016A8 out 0x71, al (入口是00401660) //此处应该有用~
00401486 out 0x70, al (入口是004013C0) //无用
00401488 in al, 0x71 (入口是004013C0) //此处下面有成功分支
由上面4处分析大概能知道这几句的功能了~ 即是, 将上面的算法结果传到0x71端口, 再判断低位是否等于0x51, 那么注册机的思路是这样的
char * code = "??????"; //某个正确串
int len = strlen(code);
int cl = 0;
for(int i=0; i<len; i++){
cl += code[i] + i;
cl &= 0xFF; //只取低位
}
unsigned int eax = 0xFFFFFFFF & cl;
eax %= 0x7F; //结果的低位=0x51就成功了
现在我们需要反过来推算出这个(或这些)正确串
cl = 0x51 或 cl = 0x7F + 0x51 & 0xFF = 0xD0, 两位数的只能是这两个了~
如果code只有1位, 那就是0xD0(非符号区), 不行~ 0x51(Q), 验证也不行~
如果是2位: 0xD0 = 0x67+0+0x68+1, 两个字母(gh), 验证也是不行的~ 奇怪了~
认真看错误提示, 作者是要我们重新启动程序才能验证~ 现在终于明白了~ 作者是把结果先保存在端口0x71上, 启动时获取这个端口内容, 这样验证的~ 难怪前面暴破时一启动程序就能在算法中停下这就解释通了 端口只能存一位数, 所以gh不行~ 只能是Q, 98下验证成功~(输入Q后点ok, 关闭程序, 再运行程序就看到注册成功了), 前面还想去掉out in命令, 看来作者已经预判了你的预判~ 牛X的作者~
- 修正程序
如果xp以上要能运行, 算法部分得到结果后, 利用现在的弹框代码, 做个判断实现成功与失败分支(刚好下面还有很多空间)
00401698 . 68 F8804100 push Crackmex.004180F8 ; ASCII "Waring..."
0040169D . F7F9 idiv ecx ; Crackmex.<ModuleEntryPoint>
0040169F . 68 C0804100 push Crackmex.004180C0 ; ASCII "Please Restart the Porogram to Check your regist code."
004016A4 . 8BCD mov ecx,ebp
004016A6 . 8AC2 mov al,dl
004016A8 . 90 nop
004016A9 . 90 nop
004016AA . E8 8CBE0000 call Crackmex.0040D53B
004016AF . 5F pop edi ; kernel32.76A8FCC9
004016B0 . 5E pop esi ; kernel32.76A8FCC9
004016B1 . 5D pop ebp ; kernel32.76A8FCC9
004016B2 . C3 retn
004016B3 90 nop
004016B4 90 nop
004016B5 90 nop
004016B6 90 nop
004016B7 90 nop
004016B8 90 nop
004016B9 90 nop
004016BA 90 nop
004016BB 90 nop
004016BC 90 nop
004016BD 90 nop
004016BE 90 nop
004016BF 90 nop
004016C0 . C2 0400 retn 0x4
对应修改为下面的, 保存即可完成修正~
0040169F /EB 12 jmp short Crackmex.004016B3
004016A1 |68 C0804100 push Crackmex.004180C0 ; ASCII "Please Restart the Porogram to Check your regist code."
004016A6 |8BCD mov ecx,ebp
004016A8 |90 nop
004016A9 |90 nop
004016AA |E8 8CBE0000 call Crackmex.0040D53B
004016AF |5F pop edi ; user32.74FF3DF5
004016B0 |5E pop esi ; user32.74FF3DF5
004016B1 |5D pop ebp ; user32.74FF3DF5
004016B2 |C3 retn
004016B3 \80FA 51 cmp dl,0x51
004016B6 ^ 75 E9 jnz short Crackmex.004016A1
004016B8 68 A0804100 push Crackmex.004180A0 ; ASCII "REGISTED,Email to wocy@263.net"
004016BD ^ EB E7 jmp short Crackmex.004016A6
修正后, 逻辑关系已经没问题了, 我们还需要手动修改掉错误提示信息"Please Restart the Porogram to Check your regist code.", 我们现在不需要重启程序了, 而是直接提示验证失败~, 重新载入修正后程序, 改动如下(内存区直接修改, 记得保存)
004180C0 43 68 65 63 6B 20 72 65 67 69 73 74 20 63 6F 64 Check regist cod
004180D0 65 20 65 72 72 6F 72 2E 20 50 6C 65 61 73 65 20 e error. Please
004180E0 74 72 79 20 61 67 61 69 6E 2E 00 00 00 00 00 00 try again.......
004180F0 00 00 00 00 00 00 00 00 57 61 72 69 6E 67 2E 2E ........Waring..
经过上面修改后, 不需要端口存储数据了, 所以答案就不限制1位了~ 先前的Q还是可以正常验证通过~ , gh验证失败~ 输入gh单步跟踪得到eax不是0xD0而是变成了0xFFFFFFD0, 这个%0x7F != 0x51, 反复跟踪了几次, 最终应该是发现dl, cl应该都是byte型, 最大值是127, D0=208所以转大数后变负数0xFFFFFFD0了, 所以最终还是只有唯一解Q
1~160每个破解过程,在吾爱破解论坛都有高手破解过了,也有整理好现成的, 我这边主要就是自己动手操作的过程,与他们的不太一样
附上高手们的连接: 点击前往查看
使用的工具连接(工具有点多有点大,可以先下OD,其它的后面慢慢下) 点击前往下载
新人入门教程"玩玩破解,写给新人看" 点击前往查看
我就是从这里开始的,对我这样的小白感觉超级友好~
下面是我的OD的界面布局,我觉得这4个是最常用的界面,其它的我基本上没用到~