欧姆龙C系列PLC解密软件的算法分析+注册机
欧姆龙C系列PLC解密软件的算法分析+注册机该程序用了ASPack压缩,将其脱壳后发现是用VB编写的,注册验证方式为重启验证,故使用VBExplorer软件打开它,然后得到其窗口的load事件地址为: 0x00404320,记下该地址后,便用OD将该程序载入,按Ctrl+G键后,输入上面记下的地址,来到该地址后,F2键下断,完成之后,便F9键运行,这时程序被断在了窗口的load事件处,代码如下:
>>>>>>
00404320 > \55 push ebp ;被断在了这里:
00404321 .8BEC mov ebp, esp
00404323 .83EC 0C sub esp, 0C
00404326 .68 86124000 push <欧姆龙C?__vbaExceptHandler> ;jmp 到 MSVBVM60.__vbaExceptHandler; SE 处理程序安装
0040432B .64:A1 0000000>mov eax, dword ptr fs:
(省略...)
00404494 .68 DC354000 push 欧姆龙C?004035DC ;定位到 C:\下
00404499 .51 push ecx
0040449A .FFD7 call edi
0040449C .50 push eax
0040449D .E8 0EF2FFFF call <欧姆龙C?GetVolumeInformationA> ;下面开始得到其卷标号
004044A2 .FF15 48104000 call dword ptr [<&MSVBVM60.__vbaSetS>;MSVBVM60.__vbaSetSystemError
004044A8 .8B55 C4 mov edx, dword ptr
004044AB .8B3D E0104000 mov edi, dword ptr [<&MSVBVM60.__vb>;MSVBVM60.__vbaStrToUnicode
004044B1 .8D45 C0 lea eax, dword ptr
004044B4 .52 push edx
004044B5 .50 push eax
004044B6 .FFD7 call edi ;<&MSVBVM60.__vbaStrToUnicode>
004044B8 .8B4D D0 mov ecx, dword ptr
004044BB .50 push eax
004044BC .51 push ecx
004044BD .53 push ebx
004044BE .FF15 44104000 call dword ptr [<&MSVBVM60.__vbaLset> ;MSVBVM60.__vbaLsetFixstr
004044C4 .8B55 BC mov edx, dword ptr
004044C7 .8D45 B8 lea eax, dword ptr
004044CA .52 push edx
004044CB .50 push eax
004044CC .FFD7 call edi
004044CE .8B4D CC mov ecx, dword ptr
004044D1 .50 push eax
004044D2 .51 push ecx
004044D3 .53 push ebx
004044D4 .FF15 44104000 call dword ptr [<&MSVBVM60.__vbaLset> ;MSVBVM60.__vbaLsetFixstr
004044DA .8D55 B8 lea edx, dword ptr
004044DD .8D45 BC lea eax, dword ptr
004044E0 .52 push edx
004044E1 .8D4D C0 lea ecx, dword ptr
004044E4 .50 push eax
004044E5 .8D55 C4 lea edx, dword ptr
004044E8 .51 push ecx
004044E9 .8D45 C8 lea eax, dword ptr
004044EC .52 push edx
004044ED .50 push eax
004044EE .6A 05 push 5
004044F0 .FF15 2C114000 call dword ptr [<&MSVBVM60.__vbaFree> ;MSVBVM60.__vbaFreeStrList
004044F6 .8B0D 34804000 mov ecx, dword ptr
004044FC .83C4 18 add esp, 18
004044FF .51 push ecx
00404500 .FF15 14104000 call dword ptr [<&MSVBVM60.__vbaStrI> ;将得到的C:\的卷标号转为UNICODE字符串 -> eax
(省略...)
00404888 .FF15 88114000 call dword ptr [<&MSVBVM60.rtcR8ValFrom>;MSVBVM60.rtcR8ValFromBstr
0040488E .8B03 mov eax, dword ptr ;前面读取的卷标号 -> eax
00404890 .8B56 4C mov edx, dword ptr ;注册表中读入的注册码 -> edx
00404893 .DD9D 28FFFFFF fstp qword ptr
00404899 .50 push eax
0040489A .8995 3CFFFFFF mov dword ptr , edx
004048A0 .C785 34FFFFFF>mov dword ptr , 8008
004048AA .FF15 88114000 call dword ptr [<&MSVBVM60.rtcR8ValFrom>;卷标号 -> ST0 (开始浮点运算)
004048B0 .DC0D B0114000 fmul qword ptr ;ST0 * 388.0000000000000;
004048B6 .8D4D 94 lea ecx, dword ptr
004048B9 .8D55 84 lea edx, dword ptr
004048BC .51 push ecx
004048BD .52 push edx
004048BE .DC05 A8114000 fadd qword ptr ;ST0 + 654987.0000000000;
004048C4 .C745 94 05000>mov dword ptr , 5
004048CB .DCA5 28FFFFFF fsub qword ptr ;ST0 - 706.0000000000000;
004048D1 .DD5D 9C fstp qword ptr ;ST0 -> ST7;
004048D4 .DFE0 fstsw ax
004048D6 .A8 0D test al, 0D ;是否为12位
004048D8 .0F85 63020000 jnz 欧姆龙C?00404B41 ;不是,跳走
004048DE .FF15 54114000 call dword ptr [<&MSVBVM60.rtcVarStrFro>;将上面 ST7 的结果转换为字符串(即为真正的注册码)
004048E4 .8D45 84 lea eax, dword ptr
004048E7 .8D8D 74FFFFFF lea ecx, dword ptr
004048ED .50 push eax
004048EE .51 push ecx
004048EF .FF15 88104000 call dword ptr [<&MSVBVM60.rtcTrimVar>] ;去除字符串的空格
004048F5 .8D95 34FFFFFF lea edx, dword ptr
004048FB .8D85 74FFFFFF lea eax, dword ptr
00404901 .52 push edx
00404902 .50 push eax
00404903 .FF15 3C114000 call dword ptr [<&MSVBVM60.__vbaVarTstN>;MSVBVM60.__vbaVarTstNe
00404909 .8D4D C8 lea ecx, dword ptr
0040490C .66:8985 24FFF>mov word ptr , ax
00404913 .FF15 84114000 call dword ptr [<&MSVBVM60.__vbaFreeStr>;MSVBVM60.__vbaFreeStr
00404919 .8D8D 74FFFFFF lea ecx, dword ptr
0040491F .8D55 84 lea edx, dword ptr
00404922 .51 push ecx
00404923 .8D45 94 lea eax, dword ptr
00404926 .52 push edx
00404927 .8D4D A4 lea ecx, dword ptr
0040492A .50 push eax
0040492B .51 push ecx
0040492C .6A 04 push 4
0040492E .FF15 28104000 call dword ptr [<&MSVBVM60.__vbaFreeVar>;MSVBVM60.__vbaFreeVarList
00404934 .8B16 mov edx, dword ptr
00404936 .83C4 14 add esp, 14
00404939 .66:83BD 24FFF>cmp word ptr , 0 ; 的数据是否为 0
00404941 .56 push esi
00404942 0F84 C8000000 je 欧姆龙C?00404A10 ;为0,则注册成功,便跳走了!
00404948 .FF92 1C030000 call dword ptr ;注册没有成功,便继续:
0040494E .50 push eax
0040494F .8D45 B4 lea eax, dword ptr
00404952 .50 push eax
00404953 .FFD7 call edi
00404955 .8B08 mov ecx, dword ptr
00404957 .68 80354000 push 欧姆龙C?00403580
0040495C .50 push eax
0040495D .8985 24FFFFFF mov dword ptr , eax
00404963 .FF51 54 call dword ptr
00404966 .85C0 test eax, eax
00404968 .DBE2 fclex
0040496A .7D 15 jge short 欧姆龙C?00404981
0040496C .8B95 24FFFFFF mov edx, dword ptr
00404972 .6A 54 push 54
00404974 .68 88354000 push 欧姆龙C?00403588
00404979 .52 push edx
0040497A .50 push eax
0040497B .FF15 4C104000 call dword ptr [<&MSVBVM60.__vbaHresult>;MSVBVM60.__vbaHresultCheckObj
00404981 >8D4D B4 lea ecx, dword ptr
00404984 .FF15 80114000 call dword ptr [<&MSVBVM60.__vbaFreeObj>;MSVBVM60.__vbaFreeObj
0040498A .8B06 mov eax, dword ptr
0040498C .56 push esi
0040498D .FF90 08030000 call dword ptr
00404993 .8D4D B4 lea ecx, dword ptr
00404996 .50 push eax
00404997 .51 push ecx
00404998 .FFD7 call edi
0040499A .8BF8 mov edi, eax
0040499C .8B03 mov eax, dword ptr ;前面读取的卷标号 -> eax
0040499E .50 push eax
0040499F .8B17 mov edx, dword ptr
004049A1 .8995 E4FEFFFF mov dword ptr , edx
004049A7 .FF15 88114000 call dword ptr [<&MSVBVM60.rtcR8ValFrom>;卷标号 -> ST0 (开始浮点运算)
004049AD .DC0D A0114000 fmul qword ptr ;ST0 * 18.00000000000000;
004049B3 .83EC 08 sub esp, 8
004049B6 .DFE0 fstsw ax
004049B8 .A8 0D test al, 0D ;是否为12位
004049BA .0F85 81010000 jnz 欧姆龙C?00404B41 ;不是,跳走
004049C0 .DD1C24 fstp qword ptr ;ST0 -> ST7;
004049C3 .FF15 CC104000 call dword ptr [<&MSVBVM60.__vbaStrR8>] ;将上面 ST7 的结果转换为字符串(即为软件的序号)
004049C9 .8BD0 mov edx, eax
(省略...)
>>>>>>
通过上面的分析,我们知道了软件的序号是这样得来的:
得到C:\的卷标号,将其转换为实数,然后和18.00000000000000相乘,得到的结果再转换为字符串,便是序号了;由此也就知道,将软件的序号转换为实数后除以18.00000000000000得结果再转换为字符串,便是该用户的C:\卷标号了;
而它的注册算法则为:
得到C:\的卷标号,将其转换为实数,然后和388.0000000000000相乘,得到的结果再和654987.0000000000相加,之后再减去706.0000000000000后,将该结果转换为字符串,便是真正的注册码了! 注册成功后,注册码保存在了:下的ZCM中.
附上注册机源码(Delphi + KOL/MCK):
//注册算法
function keygen(RegName: string): string; //定义string函数
var
temp : real;
begin
if (RegName = '') or (RegName = '呵呵,发现你没有输入序号哟!') then
begin
Result := '呵呵,发现你没有输入序号哟!';
Exit;
end;
//算法开始
temp := Str2Double(RegName) / 18.00000000000000;
temp := temp * 388.0000000000000;
temp := temp + 654987.0000000000;
temp := temp - 706.0000000000000;
//结果回传
Result := Double2Str(temp);
end;
//开始注册认证
procedure TForm1.BitBtnCountClick(Sender: PObj);
begin
EditCode.Text := keygen(EditName.Text); //注册算法
end;
好的,就到这里结束吧!分析难免有不当之处,还望大家给我指出来! 精典,谢谢看 完 真历害呀/:001 学习,不断提高自己 好东西,谢谢楼主 好东西真是不少呀 能贴出下载地址学习下吗? 总之要支持LZ/:good 好东西........看完了
页:
[1]