昨天看了@zhaozdy 大神的追码帖子,(指路:https://www.52pojie.cn/thread-689921-1-1.html),感觉这软件的算法应该不会太难,今天闲着没事,神舞幻想也通关了,于是就来看一看。
正如原帖所说,这软件貌似vc6编写的,无壳,重启验证,对我这种小白比较友好。
下面进入正题,用OD打开这软件。
呃。。。下一步该干啥了,忘记了。好长时间不做逆向,我都忘记了。
不过没关系,我会抄,大神的帖子不是说了么,关键Call在0x42558F这里,Ctrl+G转到这条地址,回车进去然后下断,慢慢跟。
具体算法解释见注释(反汇编看不下去可以试试看最后的注册机代码):
[Asm] 纯文本查看 复制代码 003E1200 > 81EC 68080000 sub esp,0x868
003E1206 53 push ebx
003E1207 55 push ebp
003E1208 B0 F2 mov al,0xF2
003E120A 56 push esi
003E120B 8BB424 78080000 mov esi,dword ptr ss:[esp+0x878] ; PtdWin.00425594
003E1212 884424 2F mov byte ptr ss:[esp+0x2F],al
003E1216 884424 3C mov byte ptr ss:[esp+0x3C],al
003E121A B3 BA mov bl,0xBA
003E121C B2 9B mov dl,0x9B
003E121E B1 BE mov cl,0xBE
003E1220 B0 C1 mov al,0xC1
003E1222 57 push edi
003E1223 85F6 test esi,esi ; 注册名不为空
003E1225 C74424 14 04C46>mov dword ptr ss:[esp+0x14],0xAA6BC404
003E122D 66:C74424 18 1E>mov word ptr ss:[esp+0x18],0xC61E
003E1234 66:C74424 1A 7F>mov word ptr ss:[esp+0x1A],0x4E7F
003E123B C64424 1C A6 mov byte ptr ss:[esp+0x1C],0xA6
003E1240 C64424 1D 1A mov byte ptr ss:[esp+0x1D],0x1A
003E1245 885C24 1E mov byte ptr ss:[esp+0x1E],bl
003E1249 C64424 1F E9 mov byte ptr ss:[esp+0x1F],0xE9
003E124E 885424 20 mov byte ptr ss:[esp+0x20],dl
003E1252 C64424 21 20 mov byte ptr ss:[esp+0x21],0x20
003E1257 C64424 22 1B mov byte ptr ss:[esp+0x22],0x1B
003E125C C64424 23 67 mov byte ptr ss:[esp+0x23],0x67
003E1261 C74424 24 DAA6A>mov dword ptr ss:[esp+0x24],0x62A9A6DA
003E1269 66:C74424 28 46>mov word ptr ss:[esp+0x28],0x7546
003E1270 66:C74424 2A 33>mov word ptr ss:[esp+0x2A],0x4333
003E1277 C64424 2C A2 mov byte ptr ss:[esp+0x2C],0xA2
003E127C C64424 2D AA mov byte ptr ss:[esp+0x2D],0xAA
003E1281 C64424 2E 3E mov byte ptr ss:[esp+0x2E],0x3E
003E1286 C64424 2F FC mov byte ptr ss:[esp+0x2F],0xFC
003E128B C64424 30 15 mov byte ptr ss:[esp+0x30],0x15
003E1290 884C24 31 mov byte ptr ss:[esp+0x31],cl
003E1294 C64424 32 78 mov byte ptr ss:[esp+0x32],0x78
003E1299 C74424 34 C0B91>mov dword ptr ss:[esp+0x34],0xC417B9C0
003E12A1 66:C74424 38 63>mov word ptr ss:[esp+0x38],0x6863
003E12A8 66:C74424 3A 3F>mov word ptr ss:[esp+0x3A],0x493F
003E12AF C64424 3C A7 mov byte ptr ss:[esp+0x3C],0xA7
003E12B4 C64424 3D CC mov byte ptr ss:[esp+0x3D],0xCC
003E12B9 884C24 3E mov byte ptr ss:[esp+0x3E],cl
003E12BD C64424 3F C8 mov byte ptr ss:[esp+0x3F],0xC8
003E12C2 C64424 41 17 mov byte ptr ss:[esp+0x41],0x17
003E12C7 C64424 42 83 mov byte ptr ss:[esp+0x42],0x83
003E12CC C64424 43 9C mov byte ptr ss:[esp+0x43],0x9C
003E12D1 C74424 44 3BD0A>mov dword ptr ss:[esp+0x44],0x5DA3D03B
003E12D9 66:C74424 48 4E>mov word ptr ss:[esp+0x48],0x134E
003E12E0 66:C74424 4A 3A>mov word ptr ss:[esp+0x4A],0x4D3A
003E12E7 885C24 4C mov byte ptr ss:[esp+0x4C],bl
003E12EB C64424 4D 2B mov byte ptr ss:[esp+0x4D],0x2B
003E12F0 C64424 4E 91 mov byte ptr ss:[esp+0x4E],0x91
003E12F5 C64424 4F DA mov byte ptr ss:[esp+0x4F],0xDA
003E12FA C64424 50 EA mov byte ptr ss:[esp+0x50],0xEA
003E12FF C64424 51 73 mov byte ptr ss:[esp+0x51],0x73
003E1304 C64424 52 3B mov byte ptr ss:[esp+0x52],0x3B
003E1309 884424 53 mov byte ptr ss:[esp+0x53],al
003E130D C74424 54 D98C7>mov dword ptr ss:[esp+0x54],0xC6738CD9
003E1315 66:C74424 58 1B>mov word ptr ss:[esp+0x58],0x9D1B
003E131C 66:C74424 5A 25>mov word ptr ss:[esp+0x5A],0x4825
003E1323 885424 5C mov byte ptr ss:[esp+0x5C],dl
003E1327 C64424 5D FE mov byte ptr ss:[esp+0x5D],0xFE
003E132C 884424 5E mov byte ptr ss:[esp+0x5E],al
003E1330 C64424 5F 57 mov byte ptr ss:[esp+0x5F],0x57
003E1335 C64424 60 9A mov byte ptr ss:[esp+0x60],0x9A
003E133A C64424 61 CB mov byte ptr ss:[esp+0x61],0xCB
003E133F C64424 62 E4 mov byte ptr ss:[esp+0x62],0xE4
003E1344 C64424 63 18 mov byte ptr ss:[esp+0x63],0x18
003E1349 0F84 08020000 je hd06.003E1557
003E134F 8B8424 80080000 mov eax,dword ptr ss:[esp+0x880]
003E1356 85C0 test eax,eax ; 注册码不为空
003E1358 0F84 F9010000 je hd06.003E1557
003E135E 8BFE mov edi,esi
003E1360 83C9 FF or ecx,-0x1 ; |
003E1363 33C0 xor eax,eax ; |
003E1365 F2:AE repne scas byte ptr es:[edi] ; |strlen
003E1367 F7D1 not ecx ; |
003E1369 49 dec ecx ; |
003E136A 81F9 FD030000 cmp ecx,0x3FD ; 注册名长度小于3FD
003E1370 0F87 E1010000 ja hd06.003E1557
003E1376 8BFE mov edi,esi
003E1378 83C9 FF or ecx,-0x1
003E137B F2:AE repne scas byte ptr es:[edi]
003E137D F7D1 not ecx
003E137F 49 dec ecx ; 取注册名长度
003E1380 8D8424 78040000 lea eax,dword ptr ss:[esp+0x478]
003E1387 8BE9 mov ebp,ecx
003E1389 894424 64 mov dword ptr ss:[esp+0x64],eax
003E138D 8BFE mov edi,esi
003E138F 83C9 FF or ecx,-0x1
003E1392 33C0 xor eax,eax
003E1394 32D2 xor dl,dl
003E1396 33DB xor ebx,ebx
003E1398 885424 10 mov byte ptr ss:[esp+0x10],dl
003E139C F2:AE repne scas byte ptr es:[edi]
003E139E F7D1 not ecx
003E13A0 2BF9 sub edi,ecx
003E13A2 8BC1 mov eax,ecx
003E13A4 8BF7 mov esi,edi
003E13A6 8B7C24 64 mov edi,dword ptr ss:[esp+0x64]
003E13AA C1E9 02 shr ecx,0x2
003E13AD F3:A5 rep movs dword ptr es:[edi],dword ptr ds>
003E13AF 8BC8 mov ecx,eax
003E13B1 83E1 03 and ecx,0x3
003E13B4 F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[>; 把注册名放进esp+478
003E13B6 33F6 xor esi,esi
003E13B8 85ED test ebp,ebp
003E13BA 7E 1C jle short hd06.003E13D8
003E13BC 029434 78040000 add dl,byte ptr ss:[esp+esi+0x478] ; for循环
003E13C3 885424 10 mov byte ptr ss:[esp+0x10],dl
003E13C7 8B4C24 10 mov ecx,dword ptr ss:[esp+0x10] ; [esp+0x10](计算B)=注册名ascii相加(8bit)
003E13CB 81E1 FF000000 and ecx,0xFF
003E13D1 03D9 add ebx,ecx ; ebx(计算A)=上面结果相加
003E13D3 46 inc esi
003E13D4 3BF5 cmp esi,ebp
003E13D6 ^ 7C E4 jl short hd06.003E13BC
003E13D8 B9 80000000 mov ecx,0x80
003E13DD 33C0 xor eax,eax
003E13DF 8DBC24 78020000 lea edi,dword ptr ss:[esp+0x278]
003E13E6 F3:AB rep stos dword ptr es:[edi]
003E13E8 8B8424 80080000 mov eax,dword ptr ss:[esp+0x880]
003E13EF 8D8C24 78020000 lea ecx,dword ptr ss:[esp+0x278]
003E13F6 51 push ecx
003E13F7 8B10 mov edx,dword ptr ds:[eax]
003E13F9 8B40 04 mov eax,dword ptr ds:[eax+0x4]
003E13FC 899424 7C020000 mov dword ptr ss:[esp+0x27C],edx
003E1403 898424 80020000 mov dword ptr ss:[esp+0x280],eax ; push注册码前八位
003E140A E8 A1FCFFFF call hd06.#4111 ; 查表转数字(16进制文本转为数字)
003E140F 8BE8 mov ebp,eax
003E1411 33D2 xor edx,edx
003E1413 8A9434 77040000 mov dl,byte ptr ss:[esp+esi+0x477] ; 取注册码最后一位
003E141A 8B4424 10 mov eax,dword ptr ss:[esp+0x10] ; kernel32.7C8024BC
003E141E 8BCD mov ecx,ebp
003E1420 25 FF000000 and eax,0xFF
003E1425 03CA add ecx,edx ; ecx=返回结果+注册名最后一位
003E1427 03DD add ebx,ebp ; ebx=返回结果+计算A
003E1429 03C1 add eax,ecx ; eax=计算B+ecx
003E142B 33D2 xor edx,edx
003E142D 03C3 add eax,ebx ; eax=eax+ebx
003E142F B9 05000000 mov ecx,0x5
003E1434 F7F1 div ecx ; eax/5
003E1436 8D7C24 78 lea edi,dword ptr ss:[esp+0x78]
003E143A 55 push ebp ; call返回数据
003E143B 68 20303E00 push hd06.003E3020 ; % 8x-
003E1440 C1E2 04 shl edx,0x4 ; edx=左移四位(上面计算eax/5的余数 即 eax%5)
003E1443 8D4414 1C lea eax,dword ptr ss:[esp+edx+0x1C] ; eax=查表地址(edx+0x1c)
003E1447 8B5414 28 mov edx,dword ptr ss:[esp+edx+0x28] ; edx=查表数据(edx+0x28)
003E144B 8B48 04 mov ecx,dword ptr ds:[eax+0x4] ; ecx=查表数据(eax+4)
003E144E 33D3 xor edx,ebx ; edx^=ebx
003E1450 33CB xor ecx,ebx ; ecx^=ebx
003E1452 895424 70 mov dword ptr ss:[esp+0x70],edx
003E1456 8B50 08 mov edx,dword ptr ds:[eax+0x8] ; edx=查表数据eax+8
003E1459 8B00 mov eax,dword ptr ds:[eax] ; eax=查表数据eax
003E145B 894C24 74 mov dword ptr ss:[esp+0x74],ecx
003E145F 33C3 xor eax,ebx ; eax^=ebx
003E1461 B9 80000000 mov ecx,0x80
003E1466 894424 7C mov dword ptr ss:[esp+0x7C],eax
003E146A 33C0 xor eax,eax
003E146C F3:AB rep stos dword ptr es:[edi]
003E146E 8D8C24 80000000 lea ecx,dword ptr ss:[esp+0x80]
003E1475 33D3 xor edx,ebx ; edx^=ebx
003E1477 51 push ecx
003E1478 895424 7C mov dword ptr ss:[esp+0x7C],edx
003E147C FF15 0C213E00 call dword ptr ds:[<&MSVCRT.sprintf>] ; msvcrt.sprintf
003E1482 83C4 0C add esp,0xC
003E1485 8D5C24 68 lea ebx,dword ptr ss:[esp+0x68]
003E1489 BD 04000000 mov ebp,0x4 ; 按储存顺序输出字符串即为注册码
003E148E 8B13 mov edx,dword ptr ds:[ebx]
003E1490 8D8424 78040000 lea eax,dword ptr ss:[esp+0x478]
003E1497 52 push edx
003E1498 68 20303E00 push hd06.003E3020
003E149D 50 push eax
003E149E FF15 0C213E00 call dword ptr ds:[<&MSVCRT.sprintf>] ; msvcrt.sprintf
003E14A4 8DBC24 84040000 lea edi,dword ptr ss:[esp+0x484]
003E14AB 83C9 FF or ecx,-0x1
003E14AE 33C0 xor eax,eax
003E14B0 83C4 0C add esp,0xC
003E14B3 F2:AE repne scas byte ptr es:[edi]
003E14B5 F7D1 not ecx
003E14B7 2BF9 sub edi,ecx
003E14B9 8D5424 78 lea edx,dword ptr ss:[esp+0x78]
003E14BD 8BF7 mov esi,edi
003E14BF 8BFA mov edi,edx
003E14C1 8BD1 mov edx,ecx
003E14C3 83C9 FF or ecx,-0x1
003E14C6 F2:AE repne scas byte ptr es:[edi]
003E14C8 8BCA mov ecx,edx
003E14CA 4F dec edi
003E14CB C1E9 02 shr ecx,0x2
003E14CE F3:A5 rep movs dword ptr es:[edi],dword ptr ds>
003E14D0 8BCA mov ecx,edx
003E14D2 83C3 04 add ebx,0x4
003E14D5 83E1 03 and ecx,0x3
003E14D8 4D dec ebp
003E14D9 F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[>
003E14DB ^ 75 B1 jnz short hd06.003E148E
003E14DD 8D4424 78 lea eax,dword ptr ss:[esp+0x78]
003E14E1 50 push eax
003E14E2 FF15 34213E00 call dword ptr ds:[<&MSVCRT._strupr>] ; strupr转为大写
003E14E8 8D7C24 7C lea edi,dword ptr ss:[esp+0x7C]
003E14EC 83C9 FF or ecx,-0x1
003E14EF 33C0 xor eax,eax
003E14F1 83C4 04 add esp,0x4
003E14F4 F2:AE repne scas byte ptr es:[edi]
003E14F6 8BB424 80080000 mov esi,dword ptr ss:[esp+0x880]
003E14FD F7D1 not ecx
003E14FF 49 dec ecx
003E1500 8BFE mov edi,esi
003E1502 88440C 77 mov byte ptr ss:[esp+ecx+0x77],al
003E1506 83C9 FF or ecx,-0x1
003E1509 F2:AE repne scas byte ptr es:[edi]
003E150B F7D1 not ecx
003E150D 49 dec ecx
003E150E 8D7C24 78 lea edi,dword ptr ss:[esp+0x78]
003E1512 8BD1 mov edx,ecx
003E1514 83C9 FF or ecx,-0x1
003E1517 F2:AE repne scas byte ptr es:[edi]
003E1519 F7D1 not ecx
003E151B 49 dec ecx
003E151C 3BCA cmp ecx,edx
003E151E 75 37 jnz short hd06.003E1557
003E1520 33FF xor edi,edi
003E1522 33ED xor ebp,ebp
003E1524 85D2 test edx,edx
003E1526 7E 1B jle short hd06.003E1543
003E1528 8D4C24 78 lea ecx,dword ptr ss:[esp+0x78]
003E152C 8BC6 mov eax,esi
003E152E 2BCE sub ecx,esi
003E1530 8BF2 mov esi,edx
003E1532 33D2 xor edx,edx
003E1534 8A1401 mov dl,byte ptr ds:[ecx+eax]
003E1537 03FA add edi,edx
003E1539 33D2 xor edx,edx
003E153B 8A10 mov dl,byte ptr ds:[eax]
003E153D 03EA add ebp,edx
003E153F 40 inc eax
003E1540 4E dec esi
003E1541 ^ 75 EF jnz short hd06.003E1532
003E1543 33C0 xor eax,eax
003E1545 3BFD cmp edi,ebp
003E1547 5F pop edi ; 0012FABC
003E1548 5E pop esi ; 0012FABC
003E1549 5D pop ebp ; 0012FABC
003E154A 5B pop ebx ; 0012FABC
003E154B 0F94C0 sete al
003E154E 81C4 68080000 add esp,0x868
003E1554 C2 0800 retn 0x8
003E1557 5F pop edi ; 0012FABC
003E1558 5E pop esi ; 0012FABC
003E1559 5D pop ebp ; 0012FABC
003E155A 33C0 xor eax,eax
003E155C 5B pop ebx ; 0012FABC
003E155D 81C4 68080000 add esp,0x868
003E1563 C2 0800 retn 0x8
这里总结下,注册码主要利用注册名和注册码的前八位作为钥匙与自身所带的数据异或生成各组注册码。没有涉及到复杂的大型加解密算法
附注册机源码一份,需要的自行编译(本机win10 64 1709+VS2015编译成功)(代码写的烂)
[C] 纯文本查看 复制代码 #include <stdio.h>
#include <string.h>
#include <stdlib.h>
unsigned char data[80] = {
0x04, 0xC4, 0x6B, 0xAA, 0x1E, 0xC6, 0x7F, 0x4E, 0xA6, 0x1A, 0xBA, 0xE9, 0x9B, 0x20, 0x1B, 0x67,
0xDA, 0xA6, 0xA9, 0x62, 0x46, 0x75, 0x33, 0x43, 0xA2, 0xAA, 0x3E, 0xFC, 0x15, 0xBE, 0x78, 0xF2,
0xC0, 0xB9, 0x17, 0xC4, 0x63, 0x68, 0x3F, 0x49, 0xA7, 0xCC, 0xBE, 0xC8, 0xF2, 0x17, 0x83, 0x9C,
0x3B, 0xD0, 0xA3, 0x5D, 0x4E, 0x13, 0x3A, 0x4D, 0xBA, 0x2B, 0x91, 0xDA, 0xEA, 0x73, 0x3B, 0xC1,
0xD9, 0x8C, 0x73, 0xC6, 0x1B, 0x9D, 0x25, 0x48, 0x9B, 0xFE, 0xC1, 0x57, 0x9A, 0xCB, 0xE4, 0x74 };
int main()
{
char szName[1024];
char szCode[1024];
printf("输入注册名:");
scanf("%s", szName);
getchar();
printf("输入注册码前八位:");
scanf("%s", szCode);
getchar();
int calcA=0, calcB = 0;
int nlen = strlen(szName);
for (int i = 0; i < nlen; i++)
{
calcB += szName[i];
calcB &= 0xff;
calcA += calcB;
}
int nCode = strtol(szCode, NULL, 16);
int eax, ebx, ecx, edx;
int outA, outB, outC, outD;
ebx = nCode + calcA;
eax = calcB + nCode + szName[nlen - 1];
eax += ebx;
edx = (eax % 5)<<4;
int nBase = edx;
memcpy(&edx, &data[nBase + 0x28 - 0x1c], 4);
memcpy(&ecx,&data[nBase + 4], 4);
edx ^= ebx;
ecx ^= ebx;
outA = edx;
outB = ecx;
memcpy(&edx, &data[nBase + 8], 4);
memcpy(&eax, &data[nBase], 4);
eax ^= ebx;
outD = eax;
edx ^= ebx;
outC = edx;
sprintf(szCode,"%8x-%8x-%8x-%8x-%8x", nCode, outA, outB, outC, outD);
strupr(szCode);
printf("注册码:%s\n", szCode);
getchar();
return 0;
}
最后附一张成功的图
最后的最后,先感谢小赵大神的帖子为我指引方向,找到的最关键的算法call(跪求小赵大神别打我)。
真的是好长时间没做逆向了,最开始算法看的一脸懵逼,后来静下心来慢慢看才有所收获。
真·最后,如果觉得此贴对你有帮助,请给我评个分,评分不减自己的分数。如果有什么疑问或者本贴所述有错误,还请各位回帖指出,谢谢。
|