[原创]EditPlus v3.80详细分析+keygen
【文章标题】EditPlus v3.80详细分析+keygen
【文章作者】lacoucou
【软件名称】EditPlus Text Editor 3.80(805) 32位Evaluation Version?
【软件大小】 1.98 MB
【原版下载】https://www.editplus.com/download.html
【保护方式】用户名 序列号
【软件简介】一套功能强大,可取代记事本的文字编辑器,拥有无限制的 Undo/Redo、英文拼字检查、自动换行、列数标记、搜寻取代、同时编辑多文件。。。。。
【作者声明】本文仅供研究学习,本人对因这篇文章而导致的一切后果,不承担任何法律责任。本文中的不足之处请各位多多指教。
【分析过程】
老套路,弹出错误之后,F12暂停,然后栈回溯找到重点:
004D2B57 > \57 PUSH EDI 004D2B58 . 53 PUSH EBX 004D2B59 . E8 F2F8FFFF CALL editplus.004D2450 ; 注册名都传进去了
Sub_004D2450 :
004D2450 /$ 83EC 10 SUB ESP,0x10 ; 验证算法 004D2453 |. A1 744D5C00 MOV EAX,DWORD PTR DS:[0x5C4D74] 004D2458 |. 33C4 XOR EAX,ESP 004D245A |. 894424 0C MOV DWORD PTR SS:[ESP+0xC],EAX 004D245E |. 53 PUSH EBX 004D245F |. 55 PUSH EBP 004D2460 |. 8B6C24 1C MOV EBP,DWORD PTR SS:[ESP+0x1C] ; 参数 用户名 004D2464 |. 56 PUSH ESI 004D2465 |. 8B7424 24 MOV ESI,DWORD PTR SS:[ESP+0x24] ; 参数 注册码 004D2469 |. 8BC5 MOV EAX,EBP 004D246B |. 57 PUSH EDI 004D246C |. 8D50 01 LEA EDX,DWORD PTR DS:[EAX+0x1] 004D246F |. 90 NOP 004D2470 |> 8A08 /MOV CL,BYTE PTR DS:[EAX] 004D2472 |. 40 |INC EAX 004D2473 |. 84C9 |TEST CL,CL 004D2475 |.^ 75 F9 \JNZ SHORT editplus.004D2470 004D2477 |. 2BC2 SUB EAX,EDX ; 求用户名长度 004D2479 |. 8BD8 MOV EBX,EAX ; ebx 用户名长度 004D247B |. 8BC6 MOV EAX,ESI 004D247D |. 8D50 01 LEA EDX,DWORD PTR DS:[EAX+0x1] 004D2480 |> 8A08 /MOV CL,BYTE PTR DS:[EAX] 004D2482 |. 40 |INC EAX 004D2483 |. 84C9 |TEST CL,CL 004D2485 |.^ 75 F9 \JNZ SHORT editplus.004D2480 004D2487 |. 2BC2 SUB EAX,EDX 004D2489 |. 8BF8 MOV EDI,EAX ; edi注册码长度 004D248B |. E8 E0F6FFFF CALL <editplus.CreateTable> ; 5eb7b8填表 004D2490 |. 53 PUSH EBX ; ebx 用户名长度 004D2491 |. 55 PUSH EBP ; 用户名 004D2492 |. 6A 00 PUSH 0x0 004D2494 |. E8 37F7FFFF CALL <editplus.calcNum> 004D2499 |. 0FB7C0 MOVZX EAX,AX 004D249C |. 50 PUSH EAX ; /<%02X> 004D249D |. 8D4C24 20 LEA ECX,DWORD PTR SS:[ESP+0x20] ; | 004D24A1 |. 68 50105900 PUSH editplus.00591050 ; |format = "%02X" 004D24A6 |. 51 PUSH ECX ; |s 004D24A7 |. E8 44F9FFFF CALL <editplus.sprintf> ; \sprintf(szBuf(ecx),"%02x",eax) 004D24AC |. 0FB656 02 MOVZX EDX,BYTE PTR DS:[ESI+0x2] 004D24B0 |. 0FBE4C24 28 MOVSX ECX,BYTE PTR SS:[ESP+0x28] 004D24B5 |. 8D46 02 LEA EAX,DWORD PTR DS:[ESI+0x2] 004D24B8 |. 83C4 18 ADD ESP,0x18 004D24BB |. 3BD1 CMP EDX,ECX 004D24BD |. 74 15 JE SHORT editplus.004D24D4 004D24BF |> 5F POP EDI ; lable_end 004D24C0 |. 5E POP ESI 004D24C1 |. 5D POP EBP 004D24C2 |. 33C0 XOR EAX,EAX 004D24C4 |. 5B POP EBX 004D24C5 |. 8B4C24 0C MOV ECX,DWORD PTR SS:[ESP+0xC] 004D24C9 |. 33CC XOR ECX,ESP 004D24CB |. E8 C6760700 CALL editplus.00549B96 004D24D0 |. 83C4 10 ADD ESP,0x10 004D24D3 |. C3 RETN 004D24D4 |> 0FB656 03 MOVZX EDX,BYTE PTR DS:[ESI+0x3] 004D24D8 |. 0FBE4C24 11 MOVSX ECX,BYTE PTR SS:[ESP+0x11] 004D24DD |. 3BD1 CMP EDX,ECX 004D24DF |.^ 75 DE JNZ SHORT editplus.004D24BF 004D24E1 |. 83C7 FE ADD EDI,-0x2 004D24E4 |. 57 PUSH EDI 004D24E5 |. 50 PUSH EAX 004D24E6 |. 6A 00 PUSH 0x0 004D24E8 |. E8 E3F6FFFF CALL <editplus.calcNum> ; calcNum(0,(pass+2),strlen(pass)-2) 004D24ED |. 0FB7D0 MOVZX EDX,AX 004D24F0 |. 52 PUSH EDX ; /<%02X> 004D24F1 |. 8D4424 20 LEA EAX,DWORD PTR SS:[ESP+0x20] ; | 004D24F5 |. 68 50105900 PUSH editplus.00591050 ; |format = "%02X" 004D24FA |. 50 PUSH EAX ; |s 004D24FB |. E8 F0F8FFFF CALL <editplus.sprintf> ; \sprintf 004D2500 |. 0FB60E MOVZX ECX,BYTE PTR DS:[ESI] ; 第一位 004D2503 |. 0FBE5424 28 MOVSX EDX,BYTE PTR SS:[ESP+0x28] 004D2508 |. 83C4 18 ADD ESP,0x18 004D250B |. 3BCA CMP ECX,EDX 004D250D |.^ 75 B0 JNZ SHORT editplus.004D24BF 004D250F |. 0FB646 01 MOVZX EAX,BYTE PTR DS:[ESI+0x1] ; 第二位 004D2513 |. 0FBE4C24 11 MOVSX ECX,BYTE PTR SS:[ESP+0x11] 004D2518 |. 33D2 XOR EDX,EDX 004D251A |. 3BC1 CMP EAX,ECX 004D251C |. 8B4C24 1C MOV ECX,DWORD PTR SS:[ESP+0x1C] 004D2520 |. 5F POP EDI 004D2521 |. 0F94C2 SETE DL 004D2524 |. 5E POP ESI 004D2525 |. 5D POP EBP 004D2526 |. 5B POP EBX 004D2527 |. 33CC XOR ECX,ESP 004D2529 |. 8BC2 MOV EAX,EDX 004D252B |. E8 66760700 CALL editplus.00549B96 004D2530 |. 83C4 10 ADD ESP,0x10 004D2533 \. C3 RETN
说下流程:
1.计算传入的用户名和注册码的长度
2.Sub_004D1B70会创建一张表,表是固定的。
004D1B70 <CreateTable> $ 68 00020000 PUSH 0x200 ; /n = 200 (512.) 004D1B75 . 6A 00 PUSH 0x0 ; |c = 00 004D1B77 . 68 B8B75E00 PUSH editplus.005EB7B8 ; |s = editplus.005EB7B8 004D1B7C . E8 EF870700 CALL <editplus.memset> ; \memset 004D1B81 . 83C4 0C ADD ESP,0xC 004D1B84 . 33D2 XOR EDX,EDX 004D1B86 . EB 08 JMP SHORT editplus.004D1B90 004D1B88 . 8DA424 000000>LEA ESP,DWORD PTR SS:[ESP] 004D1B8F . 90 NOP 004D1B90 > B8 C1C00000 MOV EAX,0xC0C1 004D1B95 . B9 01000000 MOV ECX,0x1 004D1B9A . 8D9B 00000000 LEA EBX,DWORD PTR DS:[EBX] 004D1BA0 > 85CA TEST EDX,ECX 004D1BA2 . 74 08 JE SHORT editplus.004D1BAC 004D1BA4 . 66:310455 B8B>XOR WORD PTR DS:[EDX*2+0x5EB7B8],AX 004D1BAC > 03C0 ADD EAX,EAX 004D1BAE . 35 03400000 XOR EAX,0x4003 004D1BB3 . 03C9 ADD ECX,ECX 004D1BB5 . 81F9 00010000 CMP ECX,0x100 004D1BBB . 0FB7C0 MOVZX EAX,AX 004D1BBE .^ 7C E0 JL SHORT editplus.004D1BA0 004D1BC0 . 42 INC EDX 004D1BC1 . 81FA 00010000 CMP EDX,0x100 004D1BC7 .^ 7C C7 JL SHORT editplus.004D1B90 004D1BC9 . C3 RETN
对应C代码:
unsigned char g_szTable[0x200]={0};
void CreateTable() //4d1870
{
memset(g_szTable,0,0x200);
unsigned short* pSBuf=(unsigned short*)g_szTable;
int nCount1=0;
int nCount2=0;
int nTemp=0;
do
{
//LOWORD(nTemp) = 0xC0C1u;
nTemp = 0xC0C1;
nTemp &=0xffff;
nCount2 = 1;
do
{
if ( nCount2 & nCount1 )
{
pSBuf[nCount1] ^= nTemp;
}
nCount2 *= 2;
nTemp = (unsigned __int16)(2 * nTemp ^ 0x4003);
}
while ( nCount2 < 256 );
++nCount1;
}
while ( nCount1 < 256 );
}具体表的内容看附件。
3.之后有一个计算的函数:
004D1BD0 <calcNum> /$ 8B4C24 08 MOV ECX,DWORD PTR SS:[ESP+0x8] ; 用户名缓冲区 004D1BD4 |. 8B4424 0C MOV EAX,DWORD PTR SS:[ESP+0xC] ; 长度 004D1BD8 |. 8D1401 LEA EDX,DWORD PTR DS:[ECX+EAX] 004D1BDB |. 3BCA CMP ECX,EDX 004D1BDD |. 73 25 JNB SHORT editplus.004D1C04 004D1BDF |. 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+0x4] ; 第一个参数 004D1BE3 |. 56 PUSH ESI 004D1BE4 |. 57 PUSH EDI 004D1BE5 |> 0FB639 /MOVZX EDI,BYTE PTR DS:[ECX] 004D1BE8 |. 0FB6F0 |MOVZX ESI,AL 004D1BEB |. 66:C1E8 08 |SHR AX,0x8 004D1BEF |. 33F7 |XOR ESI,EDI 004D1BF1 |. 66:330475 B8B>|XOR AX,WORD PTR DS:[ESI*2+0x5EB7B8] 004D1BF9 |. 41 |INC ECX 004D1BFA |. 0FB7C0 |MOVZX EAX,AX 004D1BFD |. 3BCA |CMP ECX,EDX 004D1BFF |.^ 72 E4 \JB SHORT editplus.004D1BE5 004D1C01 |. 5F POP EDI 004D1C02 |. 5E POP ESI 004D1C03 |. C3 RETN 004D1C04 |> 66:8B4424 04 MOV AX,WORD PTR SS:[ESP+0x4] 004D1C09 \. C3 RETN
//原程序在 sub_4D1BD0
short CalcNum(int a1, char *pszName, int nNameLen)
{
unsigned short* psTable=(unsigned short*)g_szTable;
int v5=0;
char *pBuf=pszName;
int nTemp=a1;
for(int i=0;i<nNameLen;i++)
{
v5=(*pBuf)^nTemp;
nTemp=psTable[LOBYTE(v5)]^(nTemp>>8);
pBuf++;
}
return nTemp;
}算法就是根据传入的字符串和字符串长度进行某些运算后查表然后得到一个值。
4.程序会根据用户输入的用户名通过CalcNum计算出一个值,然后调用sprintf之类的函数把值转成字符串,然后用这个字符串的前两位与用户输入的注册的3,4位分别比较,相等则继续,不相等则结束。
5.接着程序根据用户输入注册码的第2-最后这个字符串通过CalcNum计算出一个值,然后调用sprintf之类的函数把值转成字符串,然后用这个字符串的前两位与用户输入的注册的1,2位分别比较,相等则继续,不相等则结束。
说的可能有点绕,举个例子可能就清楚了。
假如用户名是test ,注册码输入的是12345678
用户名是test用calcNum函数算出来并转成字符串是“F82E”,程序接着就会拿F8跟23这两位比较,不相等就结束了。
假如他们相等了,就用345678这一串调用calcNum函数算出来并转成字符串,然后跟12比较是否相等。
这个过程就是这样,在注册成功之后会保存这些注册信息:
004D1F40 <保存注册信息> /$ 81EC BC050000 SUB ESP,0x5BC ; 保存用户名注册码 004D1F46 |. A1 744D5C00 MOV EAX,DWORD PTR DS:[0x5C4D74] 004D1F4B |. 33C4 XOR EAX,ESP 004D1F4D |. 898424 B80500>MOV DWORD PTR SS:[ESP+0x5B8],EAX 004D1F54 |. 53 PUSH EBX 004D1F55 |. 8B9C24 C40500>MOV EBX,DWORD PTR SS:[ESP+0x5C4] ; 用户名 004D1F5C |. 55 PUSH EBP 004D1F5D |. 56 PUSH ESI 004D1F5E |. 57 PUSH EDI 004D1F5F |. 8BBC24 D40500>MOV EDI,DWORD PTR SS:[ESP+0x5D4] ; 注册码 004D1F66 |. 895C24 10 MOV DWORD PTR SS:[ESP+0x10],EBX ; [ESP+0x10] 用户名 004D1F6A |. 8D4B 01 LEA ECX,DWORD PTR DS:[EBX+0x1] 004D1F6D |. 8D49 00 LEA ECX,DWORD PTR DS:[ECX] 004D1F70 |> 8A03 /MOV AL,BYTE PTR DS:[EBX] 004D1F72 |. 43 |INC EBX 004D1F73 |. 84C0 |TEST AL,AL 004D1F75 |.^ 75 F9 \JNZ SHORT editplus.004D1F70 004D1F77 |. 8BC7 MOV EAX,EDI 004D1F79 |. 2BD9 SUB EBX,ECX ; 求用户名长度 004D1F7B |. 8D70 01 LEA ESI,DWORD PTR DS:[EAX+0x1] 004D1F7E |. 8BFF MOV EDI,EDI 004D1F80 |> 8A08 /MOV CL,BYTE PTR DS:[EAX] 004D1F82 |. 40 |INC EAX 004D1F83 |. 84C9 |TEST CL,CL 004D1F85 |.^ 75 F9 \JNZ SHORT editplus.004D1F80 004D1F87 |. 2BC6 SUB EAX,ESI ; 注册码长度 004D1F89 |. 8D7418 02 LEA ESI,DWORD PTR DS:[EAX+EBX+0x2] ; 两者长度相加+2 004D1F8D |. 56 PUSH ESI 004D1F8E |. 894424 24 MOV DWORD PTR SS:[ESP+0x24],EAX ; 注册码长度 [ESP+0x24] 004D1F92 |. E8 797B0300 CALL <editplus.new> ; ???、、、 004D1F97 |. 8BE8 MOV EBP,EAX 004D1F99 |. 8B4424 14 MOV EAX,DWORD PTR SS:[ESP+0x14] 004D1F9D |. 53 PUSH EBX 004D1F9E |. 50 PUSH EAX 004D1F9F |. 8D4E FF LEA ECX,DWORD PTR DS:[ESI-0x1] 004D1FA2 |. 51 PUSH ECX 004D1FA3 |. 8D55 01 LEA EDX,DWORD PTR SS:[EBP+0x1] 004D1FA6 |. 52 PUSH EDX 004D1FA7 |. 885D 00 MOV BYTE PTR SS:[EBP],BL 004D1FAA |. E8 F67B0700 CALL <editplus._memcpy_s> 004D1FAF |. 8B4C24 34 MOV ECX,DWORD PTR SS:[ESP+0x34] 004D1FB3 |. 51 PUSH ECX 004D1FB4 |. 884C2B 01 MOV BYTE PTR DS:[EBX+EBP+0x1],CL 004D1FB8 |. 8D43 01 LEA EAX,DWORD PTR DS:[EBX+0x1] 004D1FBB |. 40 INC EAX 004D1FBC |. 8BCE MOV ECX,ESI 004D1FBE |. 2BC8 SUB ECX,EAX 004D1FC0 |. 57 PUSH EDI 004D1FC1 |. 51 PUSH ECX 004D1FC2 |. 03C5 ADD EAX,EBP 004D1FC4 |. 50 PUSH EAX 004D1FC5 |. E8 DB7B0700 CALL <editplus._memcpy_s> 004D1FCA |. B8 1F85EB51 MOV EAX,0x51EB851F 004D1FCF |. F7EE IMUL ESI ; 除法运算 esi被除数 除数100 004D1FD1 |. C1FA 05 SAR EDX,0x5 004D1FD4 |. 8BC2 MOV EAX,EDX 004D1FD6 |. C1E8 1F SHR EAX,0x1F 004D1FD9 |. 03C2 ADD EAX,EDX 004D1FDB |. 8D4430 0C LEA EAX,DWORD PTR DS:[EAX+ESI+0xC] ; esi=用户名长度加上注册码长度+2 004D1FDF |. 50 PUSH EAX ; eax=esi/100 +esi +0xc 004D1FE0 |. 894424 3C MOV DWORD PTR SS:[ESP+0x3C],EAX 004D1FE4 |. E8 277B0300 CALL <editplus.new> 004D1FE9 |. 56 PUSH ESI ; 用户名+注册码+2 004D1FEA |. 55 PUSH EBP ; 用户名长度 用户名 004D1FEB |. 8D4C24 44 LEA ECX,DWORD PTR SS:[ESP+0x44] 004D1FEF |. 8BF8 MOV EDI,EAX 004D1FF1 |. 51 PUSH ECX ; 上边算出来的奇怪值eax=1a 004D1FF2 |. 57 PUSH EDI ; new 缓冲区 004D1FF3 |. 897C24 48 MOV DWORD PTR SS:[ESP+0x48],EDI 004D1FF7 |. E8 D41C0300 CALL editplus.00503CD0 ; 加密? 004D1FFC |. 83C4 38 ADD ESP,0x38 004D1FFF |. 85C0 TEST EAX,EAX 004D2001 |. 74 16 JE SHORT editplus.004D2019 004D2003 |. 55 PUSH EBP 004D2004 |. E8 FC7A0300 CALL <editplus.delete> 004D2009 |. 57 PUSH EDI 004D200A |. E8 F67A0300 CALL <editplus.delete> 004D200F |. 83C4 08 ADD ESP,0x8 004D2012 |. 33C0 XOR EAX,EAX 004D2014 |. E9 B5010000 JMP editplus.004D21CE 004D2019 |> 8B7C24 14 MOV EDI,DWORD PTR SS:[ESP+0x14] 004D201D |. 83C7 08 ADD EDI,0x8 004D2020 |. 57 PUSH EDI 004D2021 |. E8 EA7A0300 CALL <editplus.new> 004D2026 |. 6A 04 PUSH 0x4 004D2028 |. 68 A41D5C00 PUSH editplus.005C1DA4 ; 005C1DA4 DB 89 29 18 004D202D |. 8BD8 MOV EBX,EAX 004D202F |. 57 PUSH EDI 004D2030 |. 53 PUSH EBX 004D2031 |. E8 6F7B0700 CALL <editplus._memcpy_s> ; errno_t memcpy_s(void *dest, size_t numberOfElements, const void *src, size_t count); 004D2036 |. 8B15 A41D5C00 MOV EDX,DWORD PTR DS:[0x5C1DA4] ; 成功返回0 004D203C |. 52 PUSH EDX 004D203D |. E8 FA820700 CALL <editplus.srand> 004D2042 |. E8 07830700 CALL <editplus.rand> 004D2047 |. 03C6 ADD EAX,ESI 004D2049 |. 0FB7C0 MOVZX EAX,AX 004D204C |. 6A 02 PUSH 0x2 004D204E |. 8D4C24 34 LEA ECX,DWORD PTR SS:[ESP+0x34] 004D2052 |. 51 PUSH ECX 004D2053 |. 8D57 FC LEA EDX,DWORD PTR DS:[EDI-0x4] 004D2056 |. 894424 38 MOV DWORD PTR SS:[ESP+0x38],EAX 004D205A |. 52 PUSH EDX 004D205B |. 8D43 04 LEA EAX,DWORD PTR DS:[EBX+0x4] 004D205E |. 50 PUSH EAX 004D205F |. E8 417B0700 CALL <editplus._memcpy_s> 004D2064 |. 8B0D A41D5C00 MOV ECX,DWORD PTR DS:[0x5C1DA4] 004D206A |. 41 INC ECX 004D206B |. 51 PUSH ECX 004D206C |. E8 CB820700 CALL <editplus.srand> 004D2071 |. E8 D8820700 CALL <editplus.rand> 004D2076 |. 034424 40 ADD EAX,DWORD PTR SS:[ESP+0x40] 004D207A |. 6A 02 PUSH 0x2 004D207C |. 0FB7D0 MOVZX EDX,AX 004D207F |. 8D4424 48 LEA EAX,DWORD PTR SS:[ESP+0x48] 004D2083 |. 50 PUSH EAX 004D2084 |. 8D4F FA LEA ECX,DWORD PTR DS:[EDI-0x6] 004D2087 |. 895424 4C MOV DWORD PTR SS:[ESP+0x4C],EDX 004D208B |. 51 PUSH ECX 004D208C |. 8D53 06 LEA EDX,DWORD PTR DS:[EBX+0x6] 004D208F |. 52 PUSH EDX 004D2090 |. E8 107B0700 CALL <editplus._memcpy_s> 004D2095 |. 8B4424 50 MOV EAX,DWORD PTR SS:[ESP+0x50] 004D2099 |. 8B4C24 4C MOV ECX,DWORD PTR SS:[ESP+0x4C] 004D209D |. 50 PUSH EAX 004D209E |. 51 PUSH ECX 004D209F |. 8D57 F8 LEA EDX,DWORD PTR DS:[EDI-0x8] 004D20A2 |. 52 PUSH EDX 004D20A3 |. 8D43 08 LEA EAX,DWORD PTR DS:[EBX+0x8] 004D20A6 |. 50 PUSH EAX 004D20A7 |. E8 F97A0700 CALL <editplus._memcpy_s> 004D20AC |. 8B0D 80755C00 MOV ECX,DWORD PTR DS:[0x5C7580] ; editplus.005C7590 004D20B2 |. 83C4 4C ADD ESP,0x4C 004D20B5 |. 57 PUSH EDI 004D20B6 |. 53 PUSH EBX 004D20B7 |. 68 8C7B5800 PUSH editplus.00587B8C ; UNICODE "License" 004D20BC |. 68 A8DE5700 PUSH editplus.0057DEA8 ; UNICODE "Install" 004D20C1 |. E8 6FDC0400 CALL editplus.0051FD35 ; CWinApp::WriteProfileBinary(wchar_t const *,wchar_t const *,uchar *,uint) 004D20C6 |. 8B0D 80755C00 MOV ECX,DWORD PTR DS:[0x5C7580] ; editplus.005C7590 004D20CC |. 8B51 50 MOV EDX,DWORD PTR DS:[ECX+0x50] 004D20CF |. 68 A8DE5700 PUSH editplus.0057DEA8 ; UNICODE "Install" 004D20D4 |. 8BF0 MOV ESI,EAX 004D20D6 |. A1 68125C00 MOV EAX,DWORD PTR DS:[0x5C1268] 004D20DB |. 52 PUSH EDX 004D20DC |. 50 PUSH EAX 004D20DD |. 8D4C24 34 LEA ECX,DWORD PTR SS:[ESP+0x34] 004D20E1 |. 51 PUSH ECX 004D20E2 |. E8 D913F3FF CALL editplus.004034C0 ; wsprintf 004D20E7 |. 83C4 10 ADD ESP,0x10 004D20EA |. 8D5424 24 LEA EDX,DWORD PTR SS:[ESP+0x24] 004D20EE |. 52 PUSH EDX ; /pDisposition 004D20EF |. 8D4424 20 LEA EAX,DWORD PTR SS:[ESP+0x20] ; | 004D20F3 |. 50 PUSH EAX ; |pHandle 004D20F4 |. 6A 00 PUSH 0x0 ; |pSecurity = NULL 004D20F6 |. 68 1F000200 PUSH 0x2001F ; |Access = KEY_QUERY_VALUE|KEY_SET_VALUE|KEY_CREATE_SUB_KEY|KEY_ENUMERATE_SUB_KEYS|KEY_NOTIFY|20000 004D20FB |. 6A 00 PUSH 0x0 ; |Options = REG_OPTION_NON_VOLATILE 004D20FD |. 6A 00 PUSH 0x0 ; |Class = NULL 004D20FF |. 6A 00 PUSH 0x0 ; |Reserved = 0x0 004D2101 |. 8D4C24 44 LEA ECX,DWORD PTR SS:[ESP+0x44] ; | 004D2105 |. 51 PUSH ECX ; |Subkey 004D2106 |. 68 02000080 PUSH 0x80000002 ; |hKey = HKEY_LOCAL_MACHINE 004D210B |. FF15 7C905700 CALL DWORD PTR DS:[<&ADVAPI32.RegCreateK>; \RegCreateKeyExW 004D2111 |. 85C0 TEST EAX,EAX 004D2113 |. 75 20 JNZ SHORT editplus.004D2135 004D2115 |. 8B5424 1C MOV EDX,DWORD PTR SS:[ESP+0x1C] 004D2119 |. 57 PUSH EDI ; /BufSize 004D211A |. 53 PUSH EBX ; |Buffer 004D211B |. 6A 03 PUSH 0x3 ; |ValueType = REG_BINARY 004D211D |. 50 PUSH EAX ; |Reserved 004D211E |. 68 8C7B5800 PUSH editplus.00587B8C ; |ValueName = "License" 004D2123 |. 52 PUSH EDX ; |hKey 004D2124 |. FF15 50905700 CALL DWORD PTR DS:[<&ADVAPI32.RegSetValu>; \RegSetValueExW 004D212A |. 8B4424 1C MOV EAX,DWORD PTR SS:[ESP+0x1C] 004D212E |. 50 PUSH EAX ; /hKey 004D212F |. FF15 80905700 CALL DWORD PTR DS:[<&ADVAPI32.RegCloseKe>; \RegCloseKey 004D2135 |> 8B0D 80755C00 MOV ECX,DWORD PTR DS:[0x5C7580] ; editplus.005C7590 004D213B |. 8B91 E0000000 MOV EDX,DWORD PTR DS:[ECX+0xE0] 004D2141 |. 52 PUSH EDX 004D2142 |. 8D8424 BC0100>LEA EAX,DWORD PTR SS:[ESP+0x1BC] 004D2149 |. 68 08020000 PUSH 0x208 004D214E |. 50 PUSH EAX 004D214F |. E8 B8800700 CALL <editplus._wcscpy_s> 004D2154 |. 8B0D AC1D5C00 MOV ECX,DWORD PTR DS:[0x5C1DAC] ; DS:[005C1DAC]=00590EC8 (editplus.00590EC8), UNICODE "reg_u.ini" 004D215A |. 51 PUSH ECX 004D215B |. 8D9424 C80100>LEA EDX,DWORD PTR SS:[ESP+0x1C8] 004D2162 |. 68 08020000 PUSH 0x208 004D2167 |. 52 PUSH EDX 004D2168 |. E8 22800700 CALL <editplus._wcscat_s> 004D216D |. 8D8424 D00100>LEA EAX,DWORD PTR SS:[ESP+0x1D0] 004D2174 |. 50 PUSH EAX 004D2175 |. 57 PUSH EDI 004D2176 |. 53 PUSH EBX 004D2177 |. 68 8C7B5800 PUSH editplus.00587B8C ; UNICODE "License" 004D217C |. 68 A8DE5700 PUSH editplus.0057DEA8 ; UNICODE "Install" 004D2181 |. E8 AA1BF8FF CALL editplus.00453D30 ; license写入reg_u.ini 004D2186 |. 8D8C24 E40100>LEA ECX,DWORD PTR SS:[ESP+0x1E4] 004D218D |. 51 PUSH ECX 004D218E |. E8 9DFCFFFF CALL <editplus.读硬盘序列号并计算> ; 根据安装位置的色 004D2193 |. 6A 00 PUSH 0x0 004D2195 |. 0FB7C0 MOVZX EAX,AX 004D2198 |. 8D9424 EC0100>LEA EDX,DWORD PTR SS:[ESP+0x1EC] 004D219F |. 52 PUSH EDX 004D21A0 |. 50 PUSH EAX 004D21A1 |. 68 847B5800 PUSH editplus.00587B84 ; UNICODE "ID" 004D21A6 |. 68 A8DE5700 PUSH editplus.0057DEA8 ; UNICODE "Install" 004D21AB |. E8 F01AF8FF CALL editplus.00453CA0 ; Id写入reg_u.ini 004D21B0 |. 83C4 44 ADD ESP,0x44 004D21B3 |. 55 PUSH EBP 004D21B4 |. E8 4C790300 CALL <editplus.delete> 004D21B9 |. 8B4424 14 MOV EAX,DWORD PTR SS:[ESP+0x14] 004D21BD |. 50 PUSH EAX 004D21BE |. E8 42790300 CALL <editplus.delete> 004D21C3 |. 53 PUSH EBX 004D21C4 |. E8 3C790300 CALL <editplus.delete> 004D21C9 |. 83C4 0C ADD ESP,0xC 004D21CC |. 8BC6 MOV EAX,ESI 004D21CE |> 8B8C24 C80500>MOV ECX,DWORD PTR SS:[ESP+0x5C8] 004D21D5 |. 5F POP EDI 004D21D6 |. 5E POP ESI 004D21D7 |. 5D POP EBP 004D21D8 |. 5B POP EBX 004D21D9 |. 33CC XOR ECX,ESP 004D21DB |. E8 B6790700 CALL editplus.00549B96 004D21E0 |. 81C4 BC050000 ADD ESP,0x5BC 004D21E6 \. C3 RETN
这个算法比较长也比较蛋疼,不再写算法,只大致写下过程。
这个算法的前半部分是生成一个加密字符串,后半部分是保存这个加密的license。
加密字符串长度是固定的:
+0 固定值 //DB892918
+4 保存的是一个长度值
+6 保存的是一个长度值
+8 保存的是用户名和注册码加密后的字符串
nLen1=用户名长度+注册码长度+2
nLen2=nLen1/100+nLen1+0xC
+4 位置的数据算法:
取出g_dw0x5c1da4处的值【182989DB】也就是前四位转成DOUBLE值,然后把这个值作为srand函数的种子然后在调用rand()函数得到一个值A 然后用A+nlen1 再取低两位的值
+6 位置的数据算法:
取出g_dw0x5c1da4处的值【182989DB】也就是前四位转成DOUBLE值,然后把这个值+1作为srand函数的种子然后在调用rand()函数得到一个值B 然后用B+用户名和注册码加密后的长度 再取低两位的值
+8 :
加密函数sub_ 00503CD0(arg1,arg2,arg3,arg4)
参数1:new出来的空间 长度nLen2 存放加密后的字符串
参数2:int*指针 传入是new空间的长度 传出加密后字符串长度
参数3:用户名和注册码按照[用户名长度 用户名字符串 注册码长度 注册码长度]这样格式排列的字符串
参数4:参数3字符串的长度
具体加密算法太长就不跟了。
这么拼接的字符串最后保存在:(xp下其他系统可能有变化)
1.[HKEY_CURRENT_USER\Software\ES-Computing\EditPlus 3\Install] "License"字段
2.[HKEY_LOCAL_MACHINE\SOFTWARE\ES-Computing\EditPlus 3\Install] "License"字段
3.Reg_u.ini 的License字段中
PS:插播下Reg_u.ini 的ID字段是根据GetVolumeInformationW取得VolumeSerialNumber ,然后调用CalcNum算出来的。
这些程序完成之后程序就会提示你重启验证。
然后最狗血的地方来了。
验证时候就根据上边保存license的顺序取出加密后的字符串,然后再还原。这时候不知道是bug还是分析的时候漏了什么地方。





如果你用OD打开程序,然后输入keygen提供的用户名和注册码,然后运行注册的话,最后保存的license就是正确的。
如果直接打开程序输入keygen提供的用户名和注册码,再次打开程序你的注册码的第一个字节就被抹零,然后就注册失败了,很蛋疼,暂时没找到是什么原因。
所以提醒用注册机时,用OD加载程序然后再输入注册码,然后再运行(不用再用OD加载了)就OK了。
另外带一个林版主的注册机和一个在线注册的网站。
林斑竹的
http://bbs.pediy.com/showthread.php?t=198129&highlight=editplus
注册码在线生成的
http://demon.tw/my-work/editplus-regcode-online.html
这个在线的生成的是之前版本的注册码不过当前版本也可以用。
字节写的注册机:
EditPlus.zip
