很久没玩OD,正好机器上试用版的LeapFTP过期了,于是心血来潮准备写个注册机,LeapFTP版本v2.76
记得以前跟过LeapFTP,注册码分为两段,是明文存放在内存中,但是没有去细看算法,今天决定把算法搞定以后升级也方便^_^.
用OD,载入,下注册表断点(为什么下注册表断点?因为我跟过^_^),关键部分0x00484d89处停下,程序去读取”Software/LeapWare/Registry/”下有没有UserName和UserKey两个东西,往下看,这两个东西都必须有否则就直接跳走了.这个版本的Leap似乎有点改进,记得以前好像是无论成功失败都会去写注册表,现在是只有注册成功了里面才有东西,不管那么多,先手工添加方便分析-_-#.
走啊走啊走啊走,走到了一个地方
00484FB2 | . E8 B1FDFFFF call 00484D68
00484FB7 | > 807E 35 00 cmp byte ptr [esi + 35 ] , 0
00484FBB | . 75 33 jnz short 00484FF0
00484FBD | . 807E 36 00 cmp byte ptr [esi + 36 ] , 0
00484FC1 | . 74 13 je short 00484FD6
00484FC3 | . A1 94C14B00 mov eax , dword ptr [4BC194]
00484FC8 | . 8B00 mov eax , dword ptr [eax]
00484FCA | . 8B56 28 mov edx , dword ptr [esi + 28 ]
00484FCD | . E8 22F8FFFF call 004847F4 ; 这个CALL比较长度是否合格
00484FD2 | . 84C0 test al , al
00484FD4 75 1A jnz short 00484FF0
00484FD6 | > 8B46 2C mov eax , dword ptr [esi + 2C]
00484FD9 | . 50 push eax
00484FDA | . A1 94C14B00 mov eax , dword ptr [4BC194]
00484FDF | . 8B00 mov eax , dword ptr [eax]
00484FE1 | . 8B4E 28 mov ecx , dword ptr [esi + 28 ]
00484FE4 | . 8B56 24 mov edx , dword ptr [esi + 24 ]
00484FE7 | . E8 60F6FFFF call 0048464C ; 比较
00484FEC | . 84C0 test al , al ; 不能跳
00484FEE | . 74 04 je short 00484FF4
00484FF0 | > B3 01 mov bl , 1 ; 标志位
00484FF2 | . EB 0F jmp short 00485003 
大致流程就全在这了,先看第一个CALL,484FCD,F7跟入,里面似乎没什么特别的,只是有个比较注册码长度是不是0x13的情况,不是直接就回来了,是的话要经过一定算法的变形,大概就是比较某些位上是不是指定的值,继续往下看
关键CALL 484FE7,F7跟进去看看
0048469A |. 8BD0 mov edx , eax
0048469C |. 85D2 test edx , edx
0048469E |. 7E 33 jle short 004846D3
004846A0 |. B8 01000000 mov eax , 1
004846A5 |> 8B4D FC /mov ecx , dword ptr [ ebp-4 ]
004846A8 |. 0FB64C01 FF |movzx ecx , byte ptr [ ecx+eax-1 ]
004846AD |. 0FAFC8 |imul ecx , eax
004846B0 |. 8BD9 |mov ebx , ecx
004846B2 |. C1E1 04 |shl ecx , 4
004846B5 |. 2BCB |sub ecx , ebx
004846B7 |. 894D E8 |mov dword ptr [ ebp-18 ] , ecx
004846BA |. DB45 E8 |fild dword ptr [ ebp-18 ]
004846BD |. DC45 F0 |fadd qword ptr [ ebp-10 ]
004846C0 |. 8D0C80 |lea ecx , dword ptr [ eax+eax*4 ]
004846C3 |. 894D E4 |mov dword ptr [ ebp-1C ] , ecx
004846C6 |. DB45 E4 |fild dword ptr [ ebp-1C ]
004846C9 |. DEC1 |faddp st( 1 ) , st
004846CB |. DD5D F0 |fstp qword ptr [ ebp-10 ]
004846CE |. 9B |wait
004846CF |. 40 |inc eax
004846D0 |. 4A |dec edx
004846D1 |.^ 75 D2 jnz short 004846A5
004846D3 |> 8B45 08 mov eax , dword ptr [ ebp+8 ]
004846D6 |. E8 3945F8FF call 00408C14 ; 还不知道
004846DB |. 8945 E8 mov dword ptr [ ebp-18 ] , eax
004846DE |. DB45 E8 fild dword ptr [ ebp-18 ]
004846E1 |. DD45 F0 fld qword ptr [ ebp-10 ]
004846E4 |. DC4D F0 fmul qword ptr [ ebp-10 ]
004846E7 |. DEC1 faddp st( 1 ) , st
004846E9 |. DD5D F0 fstp qword ptr [ ebp-10 ] 
前面这一段是根据输入的用户名来算注册码的核心部分,先比较用户名的长度如果不为0的话,就循环取用户名的char值,乘上序号,乘上个0x10,再减去个char值乘序号,加上序号乘个5,这部分的循环最后就简化为:
(User[i] * (i+1)) * 9 + 5* (i+1)
最后循环得到的值来个平方,再加上一个常数,就算完了,接下来看程序用这个得到的数字做什么样的比较规则:
后面比较简单就不在贴代码,只是判断前面6位是不是常数,第7位是不是-,后面一堆是不是算到的数,最后用自己的KeyGenMaker写了个注册机,代码如下:
long result = 0 ;
for ( int i = 0 ;i < para1.Length;i ++ )
… {
result = result + para1[i]*(i+1)*15;
result = result + 5 * (i+1);
}
result = result * result + 214065 ;
return “ 214065- “ + result.ToString();
给出一组注册码 UserName: Red_angelX
UserKey: –
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/223651.html原文链接:https://javaforall.net
