-
-
[原创]WinImage 7.0 序列号算法
-
发表于:
2005-1-20 13:36
5882
-
TITLE : WinImage 7.0 序列号算法
AUTHOR : [email]lionel@nkbbs.org[/email]
WEBLOG : http://lionel.blogchina.com/
DATE : 01/19/2005
SOFTWARE : WinImage Version 7.0.7000
COMPANY : Gilles Vollant
HOMEPAGE : http://www.winimage.com/
CONTEXT : WinImage使用的序列号算法应该是自创的,所以算法比较简单,只是对用户
名进行了简单的四则运算,每一个用户名应该可以有10种不同的序列号可用,下面
是对用户名进行运算的代码:
初始化时,ECX = 0,[EBP - 4] = 0x47694C
0044883C /MOV EAX,ECX ; eax = 0
0044883E |PUSH 0E
00448840 |CDQ ; edx = 0
00448841 |POP EBX ; ebx = 0x0E
00448842 |IDIV EBX ; edx = eax % ebx
00448844 |TEST EDX,EDX ; eax = eax / ebx
00448846 |JNZ SHORT winimage.0044884B
00448848 |PUSH 27
0044884A |POP ESI ; esi = 0x27
0044884B |LEA EAX,DWORD PTR DS:[ECX+3] ; eax = ecx + 3
0044884E |MOVZX EDX,BYTE PTR DS:[EDI+EAX] ; edx = user_name[ecx]
00448852 |IMUL EDX,ESI ; edx = edx * esi
00448855 |ADD DWORD PTR SS:[EBP-4],EDX ; [EBP-4] += edx
00448858 |PUSH 0E
0044885A |CDQ ; edx = 0
0044885B |POP EBX ; ebx = 0x0E
0044885C |IDIV EBX ; edx = eax % ebx
0044885E |TEST EDX,EDX ; eax = eax / ebx
00448860 |JE SHORT winimage.00448867
00448862 |LEA ESI,DWORD PTR DS:[ESI+ESI*2] ; esi = esi * 3
00448865 |JMP SHORT winimage.0044886A
00448867 |IMUL ESI,ESI,7 ; esi = esi * 7
0044886A |INC ECX
0044886B |CMP ECX,DWORD PTR SS:[EBP-8] ; [ebp-8] = strlen(user_name)
0044886E \JL SHORT winimage.0044883C
经过上述运算,如果user_name = "lionel"的话,那么运算后[ebp-4] = 0x579453
程序在这里还有一处判断,就是[ebp-4] != 0xB8DCDD26,但我不清楚什么用户名能
算出来这种结果。
下面对刚算出来的结果进一步计算,总共有10步,但每一步的算法都是一样的:
这里我们把刚刚算出来的结果记作val0 = 0x579453
0044887F PUSH DWORD PTR SS:[EBP+C] ; /val0
00448882 MOV ESI,DWORD PTR SS:[EBP+8] ; |
00448885 LEA EAX,DWORD PTR SS:[EBP-10] ; |
00448888 PUSH winimage.0045A2D0 ; |Format = "%lX"
0044888D PUSH EAX ; |buf
0044888E CALL DWORD PTR DS:[<&USER32.wsprintfA>] ; \wsprintfA
00448894 MOV AL,BYTE PTR SS:[EBP-10]
00448897 ADD ESP,0C
0044889A TEST AL,AL
0044889C JE SHORT winimage.004488BB
0044889E LEA ECX,DWORD PTR SS:[EBP-10]
004488A1 SUB ECX,ESI
004488A3 /CMP AL,38 ; if(al == '8')
004488A5 |JNZ SHORT winimage.004488AB ; al += 0x0A;
004488A7 |ADD AL,0A
004488A9 |JMP SHORT winimage.004488B1
004488AB |CMP AL,42 ; else if(al == 0x42)
004488AD |JNZ SHORT winimage.004488B1 ; al -= 0x0A;
004488AF |ADD AL,0F6
004488B1 |MOV BYTE PTR DS:[ESI],AL
004488B3 |INC ESI
004488B4 |MOV AL,BYTE PTR DS:[ECX+ESI]
004488B7 |TEST AL,AL
004488B9 \JNZ SHORT winimage.004488A3
其实上面的运算就是把 val0中的 8替换成B,把 B换成 8,然后与输入的序列号进
行比较;如果不相等,那么val1 = val0 + 0x14051948,再进行上面的替换,然后
比较;如果还不相等,那么val2 = val1 + 0x17061954,再进行上面的替换,然后
比较;算上第一次,总共是比较了10次,这10次中,每次加上的常量分别是:
0x00000000 0x14051948 0x17061954 0x10051981 0x40111995
0x20611997 0x12091999 0x16062004 0x21042002 0x13062004
大家可以看出,后面 4位竟然都是年份!我觉得这很可能是对前几个版本序列号的
兼容,或者说着几个年份对Gilles Vollant公司有什么特别的意义,呵呵。
下面是我根据以上算法写的keygen,算出来的序列号是第一次比较就能通过的。
http://xs.blogchina.com/upload/2005-01-19/20050119141006881133.zip
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)