acafeel 发表于 2007-11-10 16:12:56

欧姆龙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;

好的,就到这里结束吧!分析难免有不当之处,还望大家给我指出来!

sjclch 发表于 2007-11-14 19:03:59

精典,谢谢看 完

东方明珠 发表于 2007-11-17 16:13:03

真历害呀/:001

fengasdf 发表于 2007-11-19 16:57:51

学习,不断提高自己

sdprtf 发表于 2007-11-21 17:02:37

好东西,谢谢楼主

clh1979cmh 发表于 2007-11-22 10:59:24

好东西真是不少呀

剑客之道 发表于 2008-1-26 13:50:51

能贴出下载地址学习下吗?

szwein 发表于 2008-2-11 16:29:49

总之要支持LZ/:good

jamiezheng 发表于 2008-2-12 09:13:09

好东西........看完了
页: [1]
查看完整版本: 欧姆龙C系列PLC解密软件的算法分析+注册机