好友
阅读权限100
听众
最后登录1970-1-1
|
苏紫方璇
发表于 2015-11-4 11:05
【文章标题】: 佳宜人事工资管理软件算法分析
【软件名称】: 佳宜人事工资管理软件
【使用工具】: OD,ExeinfoPE,IDR (Interactive Delphi Reconstructor)
【工具下载】: 爱盘啥都有
--------------------------------------------------------------------------------
【首先说明】
昨天看到@oo74521 发了一个内存注册机
佳宜人事工资管理软件(注册机)
http://www.52pojie.cn/thread-428125-1-1.html
(出处: 吾爱破解论坛)
我发现这个软件能追到码,并且比较简单,就想逆个算法试试。。。。于是就有了此文。
此文为逆算法的分析,就不说如何找到关键点了吧,有兴趣的可以试试,十分的简单。
【详细过程】
首先先查壳,发现时delphi编写的程序,拖入IDR生成map文件辅助分析。
拖入od,用插件加载map文件,用脚本下按钮事件断点或者断api MessageBoxA寻找关键点
在这里发现程序把机器码当做参数调用dll生成注册码。
所以跟进去看一下。
这个dll也是delphi编写的,所以同理,拖入idr生成map文件辅助分析。
然后单步跟下去。
[Asm] 纯文本查看 复制代码 00399024 >/$ 55 push ebp
00399025 |. 8BEC mov ebp,esp
00399027 |. B9 06000000 mov ecx,0x6
0039902C |> 6A 00 /push 0x0
0039902E |. 6A 00 |push 0x0
00399030 |. 49 |dec ecx
00399031 |.^ 75 F9 \jnz short PunUnitL.0039902C
00399033 |. 53 push ebx
00399034 |. 56 push esi
00399035 |. 33C0 xor eax,eax
00399037 |. 55 push ebp
00399038 |. 68 F2913900 push PunUnitL.003991F2
0039903D |. 64:FF30 push dword ptr fs:[eax]
00399040 |. 64:8920 mov dword ptr fs:[eax],esp
00399043 |. 8D45 EC lea eax,[local.5]
00399046 |. E8 65B5F8FF call <PunUnitL.System.@LStrClr>
0039904B |. 8D45 F0 lea eax,[local.4]
0039904E |. 8B55 08 mov edx,[arg.1]
00399051 |. E8 4AB7F8FF call <PunUnitL.System.@LStrFromPChar>
00399056 |. 8B45 F0 mov eax,[local.4]
00399059 |. E8 0AB8F8FF call <PunUnitL.System.@LStrLen>
0039905E |. 8BF0 mov esi,eax
00399060 |. 85F6 test esi,esi
00399062 |. 7E 26 jle short PunUnitL.0039908A ; 判断机器码长度不是0
00399064 |. BB 01000000 mov ebx,0x1
00399069 |> 8D4D E8 /lea ecx,[local.6]
0039906C |. 8B45 F0 |mov eax,[local.4]
0039906F |. 0FB64418 FF |movzx eax,byte ptr ds:[eax+ebx-0x1]
00399074 |. 33D2 |xor edx,edx
00399076 |. E8 F905F9FF |call <PunUnitL.SysUtils.IntToHex> ; 字符串转Ascii字串
0039907B |. 8B55 E8 |mov edx,[local.6]
0039907E |. 8D45 FC |lea eax,[local.1]
00399081 |. E8 EAB7F8FF |call <PunUnitL.System.@LStrCat> ; 字符串连接起来
00399086 |. 43 |inc ebx
00399087 |. 4E |dec esi
00399088 |.^ 75 DF \jnz short PunUnitL.00399069
0039908A |> 8B45 FC mov eax,[local.1]
0039908D |. E8 D6B7F8FF call <PunUnitL.System.@LStrLen>
00399092 |. 8BF0 mov esi,eax
00399094 |. 85F6 test esi,esi
00399096 |. 7E 2C jle short PunUnitL.003990C4 ; 判断生成的长度是否为空
00399098 |. BB 01000000 mov ebx,0x1
0039909D |> 8B45 FC /mov eax,[local.1]
003990A0 |. E8 C3B7F8FF |call <PunUnitL.System.@LStrLen>
003990A5 |. 2BC3 |sub eax,ebx
003990A7 |. 8B55 FC |mov edx,[local.1]
003990AA |. 8A1402 |mov dl,byte ptr ds:[edx+eax]
003990AD |. 8D45 E4 |lea eax,[local.7]
003990B0 |. E8 DBB6F8FF |call <PunUnitL.System.@LStrFromChar>
003990B5 |. 8B55 E4 |mov edx,[local.7]
003990B8 |. 8D45 F8 |lea eax,[local.2]
003990BB |. E8 B0B7F8FF |call <PunUnitL.System.@LStrCat>
003990C0 |. 43 |inc ebx
003990C1 |. 4E |dec esi
003990C2 |.^ 75 D9 \jnz short PunUnitL.0039909D ; 字符串反向处理
003990C4 |> 8D45 FC lea eax,[local.1]
003990C7 |. 50 push eax
003990C8 |. B9 04000000 mov ecx,0x4
003990CD |. BA 01000000 mov edx,0x1
003990D2 |. 8B45 F8 mov eax,[local.2]
003990D5 |. E8 E6B9F8FF call <PunUnitL.System.@LStrCopy> ; 取字符串1-4位,记为StrA
003990DA |. 8D45 F8 lea eax,[local.2]
003990DD |. 50 push eax
003990DE |. B9 04000000 mov ecx,0x4
003990E3 |. BA 05000000 mov edx,0x5
003990E8 |. 8B45 F8 mov eax,[local.2]
003990EB |. E8 D0B9F8FF call <PunUnitL.System.@LStrCopy> ; 取字符串5-8位,记为StrB
003990F0 |. 8B45 FC mov eax,[local.1]
003990F3 |. E8 70B7F8FF call <PunUnitL.System.@LStrLen>
003990F8 |. 83F8 04 cmp eax,0x4
003990FB |. 7D 2F jge short PunUnitL.0039912C
003990FD |. 8B45 FC mov eax,[local.1]
00399100 |. E8 63B7F8FF call <PunUnitL.System.@LStrLen>
00399105 |. 8BD8 mov ebx,eax
00399107 |. 83FB 03 cmp ebx,0x3
0039910A |. 7F 20 jg short PunUnitL.0039912C
0039910C |> 8D4D E0 /lea ecx,[local.8]
0039910F |. 8BC3 |mov eax,ebx
00399111 |. C1E0 02 |shl eax,0x2
00399114 |. 33D2 |xor edx,edx
00399116 |. E8 5905F9FF |call <PunUnitL.SysUtils.IntToHex>
0039911B |. 8B55 E0 |mov edx,[local.8]
0039911E |. 8D45 FC |lea eax,[local.1]
00399121 |. E8 4AB7F8FF |call <PunUnitL.System.@LStrCat>
00399126 |. 43 |inc ebx
00399127 |. 83FB 04 |cmp ebx,0x4
0039912A |.^ 75 E0 \jnz short PunUnitL.0039910C
0039912C |> 8B45 F8 mov eax,[local.2]
0039912F |. E8 34B7F8FF call <PunUnitL.System.@LStrLen>
00399134 |. 83F8 04 cmp eax,0x4
00399137 |. 7D 2F jge short PunUnitL.00399168
00399139 |. 8B45 F8 mov eax,[local.2]
0039913C |. E8 27B7F8FF call <PunUnitL.System.@LStrLen>
00399141 |. 8BD8 mov ebx,eax
00399143 |. 83FB 03 cmp ebx,0x3
00399146 |. 7F 20 jg short PunUnitL.00399168
00399148 |> 8D4D DC /lea ecx,[local.9]
0039914B |. 8BC3 |mov eax,ebx
0039914D |. C1E0 02 |shl eax,0x2
00399150 |. 33D2 |xor edx,edx
00399152 |. E8 1D05F9FF |call <PunUnitL.SysUtils.IntToHex>
00399157 |. 8B55 DC |mov edx,[local.9]
0039915A |. 8D45 F8 |lea eax,[local.2]
0039915D |. E8 0EB7F8FF |call <PunUnitL.System.@LStrCat>
00399162 |. 43 |inc ebx
00399163 |. 83FB 04 |cmp ebx,0x4
00399166 |.^ 75 E0 \jnz short PunUnitL.00399148
00399168 |> 8D45 D8 lea eax,[local.10]
0039916B |. 8B55 0C mov edx,[arg.2] ; jyHRMman.005EED64
0039916E |. E8 2DB6F8FF call <PunUnitL.System.@LStrFromPChar>
00399173 |. 8B45 D8 mov eax,[local.10] ; 出现读取特定注册码CRS5-J9E8
00399176 |. 8D55 F4 lea edx,[local.3]
00399179 |. E8 DE03F9FF call <PunUnitL.SysUtils.Trim>
0039917E |. 8D45 D4 lea eax,[local.11]
00399181 |. 50 push eax
00399182 |. B9 04000000 mov ecx,0x4
00399187 |. BA 01000000 mov edx,0x1
0039918C |. 8B45 F4 mov eax,[local.3]
0039918F |. E8 2CB9F8FF call <PunUnitL.System.@LStrCopy> ; 取特定注册码1-4位,记为CodA
00399194 |. FF75 D4 push [local.11]
00399197 |. 68 0C923900 push PunUnitL.0039920C ; UNICODE "-"
0039919C |. FF75 FC push [local.1]
0039919F |. 8D45 D0 lea eax,[local.12]
003991A2 |. 50 push eax
003991A3 |. B9 05000000 mov ecx,0x5
003991A8 |. BA 05000000 mov edx,0x5
003991AD |. 8B45 F4 mov eax,[local.3]
003991B0 |. E8 0BB9F8FF call <PunUnitL.System.@LStrCopy> ; 取特定注册码5-9位,记为CodB
003991B5 |. FF75 D0 push [local.12]
003991B8 |. 68 0C923900 push PunUnitL.0039920C ; UNICODE "-"
003991BD |. FF75 F8 push [local.2]
003991C0 |. 8D45 EC lea eax,[local.5]
003991C3 |. BA 06000000 mov edx,0x6
003991C8 |. E8 5BB7F8FF call <PunUnitL.System.@LStrCatN> ; 拼接字符CodA,-,StrA,CodB,-,StrB
003991CD |. 8B45 EC mov eax,[local.5]
003991D0 |. E8 8BB8F8FF call <PunUnitL.System.@LStrToPChar>
003991D5 |. 8BD8 mov ebx,eax
003991D7 |. 33C0 xor eax,eax
003991D9 |. 5A pop edx ; PunUnitL.003991F9
003991DA |. 59 pop ecx ; PunUnitL.003991F9
003991DB |. 59 pop ecx ; PunUnitL.003991F9
003991DC |. 64:8910 mov dword ptr fs:[eax],edx
003991DF |. 68 F9913900 push PunUnitL.003991F9
003991E4 |> 8D45 D0 lea eax,[local.12]
003991E7 |. BA 0C000000 mov edx,0xC
003991EC |. E8 E3B3F8FF call <PunUnitL.System.@LStrArrayClr>
003991F1 \. C3 retn
总结一下,注册码="CRS5" + "-"+取1-4位(反向(转ascii值(机器码)))+"-J9E8"+"-"+取5-8位(反向(转ascii值(机器码)))
这样就可以写算法注册机了,算法注册机可以有两种写法,
第一种,直接调用这个dll的函数,输入机器码,函数返回就是注册码了。
第二种,自己实现上面的算法即可。
附粗略代码:
[C++] 纯文本查看 复制代码 #include <windows.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
typedef char *(WINAPI *pGetRegPass)(char *Mac, char *Code);
void AscStr(char *Mac, char *Asc)
{
char ch[3];
int i = 0;
for (i = 0; i < strlen(Mac);i++)
{
sprintf(ch, "%02X", Mac[i]);
strcat(Asc, ch);
}
}
void swapStr(char *Str)
{
char tmp[122] = {0};
int i = 0,a=0;
for (i = strlen(Str) - 1; i >= 0; i--)
{
tmp[a++] = Str[i];
}
strcpy(Str, tmp);
}
int main()
{
char Mac[60] = {0};
char Code[122] = {0};
printf("请输入机器码:");
scanf("%s", Mac);
printf("第一种方法\n\n");
pGetRegPass GetRegPass = (pGetRegPass)GetProcAddress(LoadLibraryA("PunUnitLib.dll"), "GetRegPass");
char *a;
a = GetRegPass(Mac, "CRS5-J9E8");
printf("%s\n\n", a);
printf("第二种方法\n\n");
AscStr(Mac, Code);
swapStr(Code);
char Zhuce[60];
char tmp[5] = {0};
strcpy(Zhuce, "CRS5-");
memcpy(tmp, Code, 4);
strcat(Zhuce, tmp);
strcat(Zhuce, "-J9E8-");
memcpy(tmp, &Code[4], 4);
strcat(Zhuce, tmp);
printf("%s\n", Zhuce);
system("pause");
return 0;
}
--------------------------------------------------------------------------------
【版权声明】: 本文原创于吾爱破解,转载请注明作者并保持文章的完整,谢谢!
2015年11月04日
|
免费评分
-
查看全部评分
|