昨天太困了 搞完就跑去睡觉了 先补上分析~
CM一开始通过DLL 的导出函数 null 进行MD5算法
大概就是 KEY1=MD5(用户名+年+日)
按钮事件跟进后
00401E7C . E8 7F010000 call CrackMe.00402000 ; 此call获取null函数地址然后跳进去DLL指向MD5算法
然后就是此call
00401EAC . E8 5F020000 call CrackMe.00402110 ; ?????
简单对注册码进行 加法运算然后后面对字符串success 比较 (其实这里应该是迷惑的,不过从中可以看出解出来的key应该满足0-9 A-F 还有个分割字符用的"|")
然后就是ShowWindow
然后就是到这里了 00403FA0 /. 55 push ebp
要留意大概是这里
[C++] 纯文本查看 复制代码 004040A8 |. 50 push eax
004040A9 |. 51 push ecx
004040AA |. 6A 7C push 0x7C
004040AC |. 68 70765B00 push CrackMe.005B7670
004040B1 |. 8D4D E4 lea ecx,[local.7]
004040B4 |. C745 E8 00000>mov [local.6],0x0
004040BB |. E8 A0EFFFFF call CrackMe.00403060
004040C0 |. 50 push eax ; //通过"|"分割文本
004040C1 |. FF75 E8 push [local.6] ; // eax==数组长度,local.6=&str
004040C4 |. E8 17000000 call CrackMe.004040E0 ; //重要call
然后就是004040C4 |. E8 17000000 call CrackMe.004040E0
里面大概就是通过0040340D |. FF15 E8745500 call dword ptr ds:[<&SHLWAPI.StrToIntExA>; \StrToIntExA
将str 转为int 然后
然后通过00404175 |. E8 E6040000 |call CrackMe.00404660 ; //生成一个buf[0x50]
001ACFF0 00 08 00 08 00 08 00 08 00 00 00 00 00 00 00 00 ............
001AD000 08 00 08 00 08 6A 08 42 08 00 00 00 00 00 00 00 ..jB.......
001AD010 00 00 4D 00 4E 00 08 43 08 00 00 00 00 00 00 00 ..M.N.C.......
001AD020 08 00 08 00 08 00 08 50 00 00 00 00 00 00 00 00 ...P........
001AD030 00 08 00 08 00 08 00 00 00 00 00 00 00 00 00 00 .............
后面大概是这样
1+2位 == 0|8|42|4d|4e|6a|43|50 要在buf里出现的
1位==42|4d| 分支跳转
3位==1|2|3 在分支42时第三位控制(在buf寻找到的1+2位)进行上移(-0x10),左移(-1)右移(+1) ,4D时控制进行特定跳动
还有一个50分支没有进去看过,还有其他一些限制
然后就是
00404246 |> \56 |push esi
00404247 |. E8 14040000 |call CrackMe.00404660
0040424C |. 56 |push esi
0040424D |. E8 6E060000 |call CrackMe.004048C0 ; //关键call
00404252 |. 84C0 |test al,al
然后就是0040424D |. E8 6E060000 |call CrackMe.004048C0
里面大概就是控制6A的移动和比较6A是否是正确位置,如果是就跳向成功
通过前面他对注册码字符串的判断,貌似步数不能多于4步~~~~
这里我用笨方法, 写个脚本 把0x6a放在buf的位置中一次次尝试,
发现buf[4|6] =====OK (貌似还有其他的办法)
然后再尝试逆推出路线,
最后得出“420E0244|4D1D0144”
所以前面通过注册码解除的key 应该是“420E0244|4D1D0144”
有了它 注册机就好办了
附上源码
复件 2.rar
(108.3 KB, 下载次数: 10)
|