好友
阅读权限10
听众
最后登录1970-1-1
|
这个CM还是比较简单的,但是为什么会想要用这个CM写注册机,是因为我还没有写过注册机。。。额,第一次写,大神勿喷!
首先我们先运行下程序,程序的样子是这样子的
然后我们点击下OK,这个程序会先观点主对话框,然后再弹一个消息框出来,提示你
好的,这个程序是无壳的,那么就可以先去OD了吧。
先进OD,看到的是这样的,这个就可以看到它的对话框的回调函数的地址了。就是00403184,那么我们就直接去了。
我要下断点的话,就直接在GetDlgItemText这里下了。
然后我们继续向下,其实分析到后面就会发现这个对用户名和输入的密码根本没有要求,而且其实可以不要用户名的。。。嘿嘿
我们继续向下单步咯。。。这个下面就是在获取注册表里面的信息了,这个要获取的键值是“HKEY_LOCAL_MACHIN\\SOFTWARE\\Misrosoft\\Windows\\CurrentVersion"下面的一个
”ProductId“这样一个键值。
那么我机器上的这个值是”76481—640—8834005—23291“然后再在前面加上"WS",就是、、”WS76481—640—8834005—23291“,我在这里将这个称为”注册表码1",哈哈。
继续往下面走,看到这个call,注意这个call,嘿嘿。
我们可以进去看看。其实这里面是在对一个代码段进行解密,我觉得是解密吧,因为这个地址是00403052,可以再反汇编窗口跟一下,这个其实是代码段的代码,而且在没解密之前,这段代码,额。。看不懂,然后就是对他进行解密了。
我们可以看看解密之后的代码。,下面就是主要的解密之后的代码,一看就是关键代码,关键算法。。嘿嘿嘿。
[C] 纯文本查看 复制代码 00403038 |. 33C0 xor eax,eax
0040303A |. 68 93334000 push aescul.00403393
0040303F |. 64:FF30 push dword ptr fs:[eax]
00403042 |. 64:8920 mov dword ptr fs:[eax],esp
00403045 |. 9C pushfd
00403046 |. 9C pushfd
00403047 |. 58 pop eax ; kernel32.7C81776F
00403048 |. 0D 00010000 or eax,0x100
0040304D |. 50 push eax
0040304E |. 9D popfd
0040304F |. 90 nop
00403050 |. 33F6 xor esi,esi
00403052 |. 33FF xor edi,edi ; ntdll.7C930208
00403054 |. 33D2 xor edx,edx ; ntdll.KiFastSystemCallRet
00403056 |. 8B2D 124B4000 mov ebp,dword ptr ds:[0x404B12]
0040305C |. BF 02454000 mov edi,aescul.00404502
00403061 |> 55 /push ebp
00403062 |. 57 |push edi ; ntdll.7C930208
00403063 |. 56 |push esi ; 注意密钥的地址
00403064 |. BD C0444000 |mov ebp,aescul.004044C0 ; ASCII "0I5LZ7G123RXCV9OPAS6TBN48YUHJKDF0QWEM"
00403069 |. BB BA434000 |mov ebx,aescul.004043BA ; ASCII "WS76481-640-8834005-23291"
0040306E |. 8A0433 |mov al,byte ptr ds:[ebx+esi] ; 将注册码循环放入AL
00403071 |. C1F8 04 |sar eax,0x4
00403074 |. 83E0 0F |and eax,0xF ; 对注册码的ASCII的高位进行处理
00403077 |. E8 BF000000 |call aescul.0040313B ; 一样的对处理函数
0040307C |. 8807 |mov byte ptr ds:[edi],al ; 放正确的密码
0040307E |. 8A0C33 |mov cl,byte ptr ds:[ebx+esi]
00403081 |. 83E1 0F |and ecx,0xF
00403084 |. 8BC1 |mov eax,ecx
00403086 |. E8 B0000000 |call aescul.0040313B ; 对低位进行一样的处理
0040308B |. 8847 01 |mov byte ptr ds:[edi+0x1],al
0040308E |. 5E |pop esi ; kernel32.7C81776F
0040308F |. 5F |pop edi ; kernel32.7C81776F
00403090 |. 5D |pop ebp ; kernel32.7C81776F
00403091 |. 46 |inc esi
00403092 |. 83C7 02 |add edi,0x2
00403095 |. 3BEE |cmp ebp,esi
00403097 |.^ 75 C8 \jnz short aescul.00403061
00403099 |. 33F6 xor esi,esi ; 在00404501里面保存的是算好的
0040309B |. 8B86 BA424000 mov eax,dword ptr ds:[esi+0x4042>; 其实下面这就是在对我输入的密码和算出来的密码进行判断
004030A1 |. 8B9E 02454000 mov ebx,dword ptr ds:[esi+0x4045>; 下面就说明密码的位数必须的0x10位
004030A7 |. 3BC3 cmp eax,ebx
004030A9 |. 75 45 jnz short aescul.004030F0
004030AB |. 83C6 04 add esi,0x4
004030AE |. 8B86 BA424000 mov eax,dword ptr ds:[esi+0x4042>; 这里是我输入的注册码
004030B4 |. 8B9E 02454000 mov ebx,dword ptr ds:[esi+0x4045>
004030BA |. 3BC3 cmp eax,ebx
004030BC |. 75 32 jnz short aescul.004030F0
004030BE |. 83C6 04 add esi,0x4
004030C1 |. 8B86 BA424000 mov eax,dword ptr ds:[esi+0x4042>
004030C7 |. 8B9E 02454000 mov ebx,dword ptr ds:[esi+0x4045>
004030CD |. 3BC3 cmp eax,ebx
004030CF |. 75 1F jnz short aescul.004030F0
004030D1 |. 83C6 04 add esi,0x4
004030D4 |. 8B86 BA424000 mov eax,dword ptr ds:[esi+0x4042>
004030DA |. 8B9E 02454000 mov ebx,dword ptr ds:[esi+0x4045>
004030E0 |. 3BC3 cmp eax,ebx
004030E2 |. 75 0C jnz short aescul.004030F0
004030E4 |. C705 F2444000 01000000 mov dword ptr ds:[0x4044F2],0x1
004030EE |. EB 0A jmp short aescul.004030FA
004030F0 |> C705 F2444000 00000000 mov dword ptr ds:[0x4044F2],0x0
004030FA |> 9D popfd
004030FB |. 33C0 xor eax,eax
004030FD |. 64:8F00 pop dword ptr fs:[eax] ; kernel32.7C81776F
00403100 |. 83C4 04 add esp,0x4
00403103 |. 833D F2444000 01 cmp dword ptr ds:[0x4044F2],0x1
0040310A |. 75 15 jnz short aescul.00403121
0040310C |. 6A 40 push 0x40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
0040310E |. 68 3D404000 push aescul.0040403D ; |Title = "Congratulations..."
00403113 |. 68 AB414000 push aescul.004041AB ; |Text = "Registered to: "
00403118 |. 6A 00 push 0x0 ; |hOwner = NULL
0040311A |. E8 A8030000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA
0040311F |. EB 13 jmp short aescul.00403134
00403121 |> 6A 30 push 0x30 ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
00403123 |. 68 50404000 push aescul.00404050 ; |Title = "Error"
00403128 |. 68 56404000 push aescul.00404056 ; |Text = "Wrong Serial Number!"
0040312D |. 6A 00 push 0x0 ; |hOwner = NULL
0040312F |. E8 93030000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA
00403134 |> 6A 00 push 0x0 ; /ExitCode = 0
00403136 \. E8 C8030000 call <jmp.&KERNEL32.ExitProcess> ; \ExitProcess
0040313B /$ 8935 EE444000 mov dword ptr ds:[0x4044EE],esi
00403141 |. 8B15 EA444000 mov edx,dword ptr ds:[0x4044EA]
00403147 |. 8B0D E6444000 mov ecx,dword ptr ds:[0x4044E6] ; 这个是密钥的位数
0040314D |. 3BD1 cmp edx,ecx ; 判断有没有循环完毕,这个edx计数器是上次算完了之后的结果
0040314F |. 72 02 jb short aescul.00403153
00403151 |. 33D2 xor edx,edx ; ntdll.KiFastSystemCallRet
00403153 |> 0FBE7415 00 /movsx esi,byte ptr ss:[ebp+edx] ; 依次循环取出密钥中的字符
00403158 |. 81E6 0F000080 |and esi,0x8000000F ; 取低位
0040315E |. 79 05 |jns short aescul.00403165
00403160 |. 4E |dec esi
00403161 |. 83CE F0 |or esi,-0x10
00403164 |. 46 |inc esi
00403165 |> 3BF0 |cmp esi,eax ; 直到与注册表字符的高位相等就停止
00403167 |. 74 09 |je short aescul.00403172
00403169 |. 42 |inc edx ; ntdll.KiFastSystemCallRet
0040316A |. 3BD1 |cmp edx,ecx
0040316C |.^ 7C E5 |jl short aescul.00403153
0040316E |. 33D2 |xor edx,edx ; ntdll.KiFastSystemCallRet
00403170 |.^ EB E1 \jmp short aescul.00403153
00403172 |> 8915 EA444000 mov dword ptr ds:[0x4044EA],edx ; 将密钥计数器放回
00403178 |. 8B35 EE444000 mov esi,dword ptr ds:[0x4044EE]
0040317E |. 0FBE042A movsx eax,byte ptr ds:[edx+ebp] ; 将密钥中对应的算出来的正确密码放回正确密码的字符创
00403182 |. 42 inc edx ; ntdll.KiFastSystemCallRet
好的,那我们直接去到解密之后的关键代码处,下面这个循环就是关键,这段代码的主要含义,就是将刚刚的代号为”注册表码1“的每一位的SCAII取出来,然后高位做一个处理,低为做一个处理。
下面我们就来看看具体的处理代码,这个就是具体的。他的那个算法的思路,就是先存一个密钥,就是”0I5LZ7G123RXCV9OPAS6TBN48YUHJKDF0QWEM“,然后依次取出每一位密钥的低位,然后和我们”注册表码1“的高低位依次比较,如果相等,就可以讲这个密钥对应的那个字符选出来,作为真的注册码的一个字符、
最后算出来的那个真的注册码字符一共有0x30位,但是我们只需要前面0x10位。。。嘿嘿嘿。
所以这个我的机子的注册码就是
57U33W3VST3XCABM
下面是注册机的代码
[C] 纯文本查看 复制代码 #include <stdio.h>
#include <windows.h>
#include <tchar.h>
TCHAR cMiyao[] = "0I5LZ7G123RXCV9OPAS6TBN48YUHJKDF0QWEM";
void main()
{
TCHAR cbuffer[128] ;
TCHAR cGuodu[] = "WS";
TCHAR cPassword[48] = {0};
int reg = 0;
int regD = 0;
int regG = 0;
int miyao = 0;
int i;
static int j = 0, k = 0;
LONG ret;
DWORD regSize = 25;
HKEY hMainKey = HKEY_LOCAL_MACHINE;
HKEY hSubKey;
LONG ReturnValue = RegOpenKeyEx(hMainKey, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", 0L, KEY_QUERY_VALUE, &hSubKey);
if (ReturnValue == ERROR_SUCCESS)
{
ret = RegQueryValueEx(hSubKey, "ProductId", NULL, NULL, (unsigned char *)cbuffer, ®Size);
}
if (ret == ERROR_SUCCESS)
{
_tcscat(cGuodu, cbuffer);
for ( i = 0; i < 18; i++)
{
if (j >= 0x25)
{
j = 0;
}
//高位
reg = cGuodu[i];
regG = (reg&0xf0)/16;
for (j; j < 0x25; j++)
{
miyao = cMiyao[j];
miyao = miyao&0x0f;
if (miyao == regG)
{
cPassword[k] = cMiyao[j];
k++;
break;
}
if (j >= 0x24)
{
j = 0;
}
}
//低位
regD = reg&0x0f;
if (j >= 0x25)
{
j = 0;
}
for (j; j<0x25; j++)
{
miyao = cMiyao[j];
miyao = miyao&0x0f;
if (miyao == regD)
{
cPassword[k] = cMiyao[j];
k++;
break;
}
if (j >= 0x24)
{
j = 0;
}
}
}
for (int m = 0; m <16; m++)
{
printf("%c", cPassword[m]);
}
printf("\n");
}
}
我这个注册机写的确实有点差。。而且我还不知道有没有bug,大神不要喷,小菜第一次亮相。。。多多指导
|
免费评分
-
查看全部评分
|