3DAxy貪吃蛇 AxySnake 破解與序號產生器 (21千字)

看雪資料發表於2015-11-15


下載地址
http://download.pchome.net/game/action/7879.html

說實在的,不容易,你得有老好的耐心
SoftICE 與 W32DASM 配合
註冊檢查程式碼被分放在 proton.dll與axysnake.exe兩個模組中
而且 在axysnake中檢查程式碼被分放在五個不同的地方,哎害得我
好慘

在破解時作的筆記 與序號產生器的程式碼

DWORD g_dwUserNameLen;  //0x1003a498  儲存使用者名稱長度
DWORD g_dwSNLen;  //0x1003a49c  序列號長度
BYTE g_strUserPro[14h]  //0x1012f918  初步轉換後的使用者名稱 0x14h Bytes
char* g_strUser //0x1003a438  儲存使用者名稱
char* g_strSN  //0x1003a478  儲存SN
BYTE g_strSNPro[]  //0x1012f8f8  初步轉換後的序列號
char g_strProTable[20]  //0x1002cbb0  轉換字典表 0x20 Bytes
BOOL g_bRegistered //0x1012F938  註冊完成的標誌
//BYTE g_byUnk1; //0x1012f909 未知用途
//序列號轉換字典表內容
“23456789ABCDEFGH
JKLMNPQRSTUVWXYZ”

///////////////////////////////////////////////////////////////
/******************************************************************
:100107E0 55                      push ebp
:100107E1 8B6C2408                mov ebpdword ptr [esp+08]
:100107E5 8BCD                    mov ecxebp
:100107E7 8A4500                  mov albyte ptr [ebp+00]
:100107EA 84C0                    test alal
:100107EC 7410                    je 100107FE

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100107FC(C)
|
:100107EE 3C20                    cmp al, 20
:100107F0 7404                    je 100107F6
:100107F2 A880                    test al, 80
:100107F4 740C                    je 10010802

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100107F0(C)
|
:100107F6 8A4101                  mov albyte ptr [ecx+01]
:100107F9 41                      inc ecx
:100107FA 84C0                    test alal
:100107FC 75F0                    jne 100107EE

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100107EC(C)
|
:100107FE 33C0                    xor eaxeax
:10010800 5D                      pop ebp
:10010801 C3                      ret
******************************************************************/
Sub 0x100107e0  判斷使用者名稱是否合法,並作初步轉換
使用者名稱轉換子程式C偽碼
BOOL CheckAndProcessUserName(strUser , strUserPro) :
//PSTR strUser 使用者名稱緩衝
//PSTR strUserPro 初步轉換後的使用者名稱

//使用者名稱處理
/////////////////////////////////////////
char szUserPro[0x100];
int i = 0;
puc = szUser;
char* ppuc = szUserPro;
int nCount = 0;
//////////////////////////////////////////////////////
//產生處理後使用者名稱資料
ZeroMemory(szUserPro , sizeof(szUserPro));
for (i = 0  i < 0x6f  i ++)
{
if (*puc == '\0')
{
puc = szUser;
ppuc ++;
}

if (*puc != '\x20' && (*puc & 0x80) == 0)
{
*ppuc = *ppuc + *puc;
ppuc ++;
nCount ++;
if (nCount == 0x10)
{
nCount = 0;
ppuc = szUserPro;
}
}
else
i --;
puc ++;
}


////////////////////////////////////////////////////////////////////




/////////////////////////////////////////////////////////////////////////////
CheckSN(char* szSN):

/************************************************************
* Referenced by a CALL at Address:
|:100108A1   
|
:10010790 8B4C2404                mov ecxdword ptr [esp+04]
:10010794 56                      push esi
:10010795 33F6                    xor esiesi
:10010797 803900                  cmp byte ptr [ecx], 00
:1001079A 742A                    je 100107C6
:1001079C 53                      push ebx
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100107BE(C)
|
:1001079D 33C0                    xor eaxeax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100107B6(C)
|
:1001079F 8A90B0CB0210            mov dlbyte ptr [eax+g_strProTable]
:100107A5 8A19                    mov blbyte ptr [ecx]
:100107A7 3AD3                    cmp dlbl
:100107A9 7507                    jne 100107B2

:100107AB 8886F8F81210            mov byte ptr [esi+g_strSNPro], al
:100107B1 46                      inc esi
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100107A9(C)
|
:100107B2 40                      inc eax
:100107B3 83F820                  cmp eax, 00000020
:100107B6 7CE7                    jl 1001079F
:100107B8 8A4101                  mov albyte ptr [ecx+01]
:100107BB 41                      inc ecx
:100107BC 84C0                    test alal
:100107BE 75DD                    jne 1001079D
:100107C0 83FE14                  cmp esi, 00000014
:100107C3 5B                      pop ebx
:100107C4 7404                    je 100107CA

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1001079A(C)
|
:100107C6 33C0                    xor eaxeax
:100107C8 5E                      pop esi
:100107C9 C3                      ret
************************************************************/

if (szSN[0] != '\0')
{
DWORD dwCount;
int i = 0 , j = 0; //I = EAX  J = ESI
char* c = strSN; // c = ECX
where(true)
{
for (i = 0  i <= 0x20; i++)
{
if (eax+g_strProTable[i] == c)
{
g_strSNPro[j] = i;
j ++;
}
}

if ( *(c + 1) == '\0')
{
if ( J == 0x14)
return TRUE;
}
else
break;
}
}
return FALSE;


/////////////////////////////////////////////////////////////////////////////

Sub 0x10010790 //通用轉換表找到至少0x14個合法字元,找到返回真,否則返回假

At 0x100108a1  Call Sub 0x100107e0 檢查序列號是否合法,並作初步轉換
At 0x1001088c  Call Sub 0x10010790 檢查使用者是否合法,並作初步轉換

///////////////////////////////////////////////////////////////////
At 0x1000fa03  Call Sub 0x10010860  測試輸入的註冊碼是否正確
C偽碼:
CheckReg():
// g_dwUserNameLen; 使用者名稱長度
// g_dwSNLen; 序列號長度

DWORD dwSum; //累加器
DWORD dwIndex;

/*************************************************************************
:10010860 A198A40310              mov eaxdword ptr [g_dwUserNameLen]
:10010865 85C0                    test eaxeax
:10010867 0F84E1000000            je 1001094E
:1001086D 8B0D9CA40310            mov ecxdword ptr [g_dwSNLen]
:10010873 85C9                    test ecxecx
:10010875 0F84D3000000            je 1001094E
:1001087B 6818F91210              push g_strUserPro
:10010880 6838A40310              push g_strUser
:10010885 C68038A4031000          mov byte ptr [eax+g_strUser], 00
:1001088C E84FFFFFFF              call 100107E0 CheckAndProcessUserName
:10010891 83C408                  add esp, 00000008
:10010894 85C0                    test eaxeax
:10010896 0F84B2000000            je 1001094E
:1001089C 6878A40310              push g_strSN
:100108A1 E8EAFEFFFF              call 10010790 CheckSN
:100108A6 83C404                  add esp, 00000004
:100108A9 85C0                    test eaxeax
:100108AB 0F849D000000            je 1001094E
**************************************************************************/
if (g_dwUserNameLen > 0 && g_dwSNLen > 0 && 
CheckAndProcessUserName(g_strUser , g_strUserPro) && 
CheckSN(g_strSN))
{
/**************************************************************************
:100108B1 B949000000              mov ecx, 00000049
:100108B6 33C0                    xor eaxeax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100108C5(C)
|
:100108B8 0FBE9018F91210          movsx edxbyte ptr [eax+g_strUserPro]
:100108BF 03CA                    add ecxedx
:100108C1 40                      inc eax
:100108C2 83F810                  cmp eax, 00000010
:100108C5 7CF1                    jl 100108B8
:100108C7 33C0                    xor eaxeax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100108DD(C)
|
:100108C9 0FBE90F8F81210          movsx edxbyte ptr [eax+g_strSNPro]
:100108D0 0FBE92B0CB0210          movsx edxbyte ptr [edx+g_strProTable]
:100108D7 03CA                    add ecxedx
:100108D9 40                      inc eax
:100108DA 83F811                  cmp eax, 00000011
:100108DD 7CEA                    jl 100108C9
:100108DF A009F91210              mov albyte ptr [1012F909]
:100108E4 83E11F                  and ecx, 0000001F
:100108E7 3AC1                    cmp alcl
:100108E9 7563                    jne 1001094E
**************************************************************************/
dwSum = 0x49;
for(int i = 0  i < 0x10  i ++)
dwSum += g_strUserPro[i];

for(int i = 0  i < 0x11  i ++)
{
dwIndex = g_strSNPro[i];
dwSum += g_strProTable[dwIndex];
}

dwSum &= 0x1f;
if (g_strSNPro[0x11] == (BYTE)dwSum)
{
/***************************************************************************
:100108EB B932000000              mov ecx, 00000032
:100108F0 33C0                    xor eaxeax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100108FF(C)
|
:100108F2 0FBE9018F91210          movsx edxbyte ptr [eax+g_strUserPro]
:100108F9 2BCA                    sub ecxedx
:100108FB 40                      inc eax
:100108FC 83F810                  cmp eax, 00000010
:100108FF 7CF1                    jl 100108F2
:10010901 33C0                    xor eaxeax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10010917(C)
|
:10010903 0FBE90F8F81210          movsx edxbyte ptr [eax+g_strSNPro]
:1001090A 0FBE92B0CB0210          movsx edxbyte ptr [edx+g_strProTable]
:10010911 03CA                    add ecxedx
:10010913 40                      inc eax
:10010914 83F812                  cmp eax, 00000012
:10010917 7CEA                    jl 10010903
:10010919 A00AF91210              mov albyte ptr [1012F90A]
:1001091E 83E11F                  and ecx, 0000001F
:10010921 3AC1                    cmp alcl
:10010923 7529                    jne 1001094E
****************************************************************************

//DWORD dwT2 = 0x32;
dwSum = 0x32;
for (int i = 0  i < 0x10; i++)
dwSum -= g_strUserPro[i];

for (int i = 0  i < 0x12; i ++)
{
dwIndex = g_strSNPro[i];
dwSum += g_strProTable[dwIndex];
}

dwSum &= 0x1f;
if (g_strSNPro[0x12] == (BYTE)dwSum) //0x10010921
{

/***************************************************************************
:10010925 B979000000              mov ecx, 00000079
:1001092A 33C0                    xor eaxeax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10010940(C)
|
:1001092C 0FBE90F8F81210          movsx edxbyte ptr [eax+g_strSNPro]
:10010933 0FBE92B0CB0210          movsx edxbyte ptr [edx+g_strProTable]
:1001093A 2BCA                    sub ecxedx
:1001093C 40                      inc eax
:1001093D 83F813                  cmp eax, 00000013
:10010940 7CEA                    jl 1001092C
****************************************************************************/

dwSum = 0x79;
for (int i = 0  i < 0x13; i ++)
{
dwIndex = g_strSNPro[i];
dwSum -= g_strProTable[dwIndex];
}
/****************************************************************************
:10010942 A00BF91210              mov albyte ptr [1012F90B]
:10010947 83E11F                  and ecx, 0000001F
:1001094A 3AC1                    cmp alcl
:1001094C 7416                    je 10010964
****************************************************************************/
dwSum &= 0x1f;
if (g_strSNPro[0x13] == (BYTE)dwSum)
{

/****************************************************************************
:10010964 B801000000              mov eax, 00000001
:10010969 A338F91210              mov dword ptr [1012F938], eax
:1001096E C3                      ret
****************************************************************************/

//g_bRegistered addr 1012F938
return g_bRegistered = TRUE;

}
else
{
/****************************************************************************
:1001094E 57                      push edi
:1001094F B91A000000              mov ecx, 0000001A
:10010954 33C0                    xor eaxeax
:10010956 BF38A40310              mov edi, g_strUser
:1001095B F3                      repz
:1001095C AB                      stosd
:1001095D A338F91210              mov dword ptr [1012F938], eax
:10010962 5F                      pop edi
:10010963 C3                      ret
****************************************************************************/
//錯誤處理
_ZeroMemory(g_strUser , sizeof(g_strUser));
return g_bRegistered = FALSE;
}

}

}

}




////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////
//004745DC 的比較 00410857
/*********************************************************************
:00410857 B94D000000              mov ecx, 0000004D
:0041085C 5E                      pop esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041086B(C)
|
:0041085D 0FBE90B4454700          movsx edxbyte ptr [eax+g_szUserPro]
:00410864 40                      inc eax
:00410865 83F810                  cmp eax, 00000010
:00410868 8D0C51                  lea ecxdword ptr [ecx+2*edx]
:0041086B 7CF0                    jl 0041085D
:0041086D A0DC454700              mov albyte ptr [g_szSNPro]
:00410872 83E11F                  and ecx, 0000001F
:00410875 3AC1                    cmp alcl
:00410877 7408                    je 00410881
*********************************************************************/

_asm
{
push eax
push ecx
push edx
xor eax , eax
L_Loop1:
movsx edx , byte ptr [eax + g_szUserPro]
inc eax
cmp eax , 00000010h
lea ecx , dword ptr [ecx + 2* edx]
jl L_Loop1;
and ecx , 0000001fh
mov dwSum , ecx
}
//////////////////////////////////////

//////////////////////////////////////
004745DD 的比較 00410B8C
/********************************************************************
:00410B8C B907030000              mov ecx, 00000307

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00410B9E(C)
|
:00410B91 0FBE90B4454700          movsx edxbyte ptr [eax+g_szUserPro]
:00410B98 2BCA                    sub ecxedx
:00410B9A 40                      inc eax
:00410B9B 83F810                  cmp eax, 00000010
:00410B9E 7CF1                    jl 00410B91
:00410BA0 A0DD454700              mov albyte ptr [004745DD]
:00410BA5 83E11F                  and ecx, 0000001F
********************************************************************/
dwSum = 0x307;
for (i = 0  i < 0x10  i++)
dwSum -= szUserPro[i];
//////////////////////////////////////

//////////////////////////////////////
004745DE 的比較 0041331A
/********************************************************************
:0041331A B986000000              mov ecx, 00000086
:0041331F 33C0                    xor eaxeax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00413339(C)
|
:00413321 0FBE90B4454700          movsx edxbyte ptr [eax+g_szUserPro]
:00413328 A801                    test al, 01
:0041332A 7404                    je 00413330
:0041332C 03CA                    add ecxedx
:0041332E EB05                    jmp 00413335

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041332A(C)
|
:00413330 F7DA                    neg edx
:00413332 8D0C51                  lea ecxdword ptr [ecx+2*edx]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041332E(U)
|
:00413335 40                      inc eax
:00413336 83F810                  cmp eax, 00000010
:00413339 7CE6                    jl 00413321
:0041333B A0DE454700              mov albyte ptr [004745DE]
:00413340 83E11F                  and ecx, 0000001F

********************************************************************/
//////////////////////////////////////

//////////////////////////////////////
004745DF 的比較 0040D75E
/********************************************************************
:0040D75E BA07000000              mov edx, 00000007
:0040D763 33C0                    xor eaxeax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D785(C)
L_Label1:
:0040D765 0FBE88B4454700          movsx ecxbyte ptr [eax+g_szUserPro]
:0040D76C 83F808                  cmp eax, 00000008
:0040D76F 7D04                    jge L_Label2
:0040D771 8BF1                    mov esiecx
:0040D773 EB07                    jmp L_Label3

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D76F(C)
L_Label2:
:0040D775 BE01000000              mov esi, 00000001
:0040D77A 2BF1                    sub esiecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D773(U)
L_Label3:
:0040D77C 0FAFF1                  imul esiecx
:0040D77F 03D6                    add edxesi
:0040D781 40                      inc eax
:0040D782 83F810                  cmp eax, 00000010
:0040D785 7CDE                    jl L_Label1
:0040D787 A0DF454700              mov albyte ptr [004745DF]
:0040D78C 83E21F                  and edx, 0000001F
********************************************************************/
//////////////////////////////////////

//////////////////////////////////////
004745E0 的比較 0040CFF4
/********************************************************************
:0040CFF4 B98C030000              mov ecx, 0000038C
:0040CFF9 33C0                    xor eaxeax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D020(C)
L_Label7:
:0040CFFB 0FBE90B4454700          movsx edxbyte ptr [eax+g_szUserPro]
:0040D002 83F809                  cmp eax, 00000009
:0040D005 7D08                    jge L_Label8
:0040D007 8D1452                  lea edxdword ptr [edx+2*edx]
:0040D00A 8D0C51                  lea ecxdword ptr [ecx+2*edx]
:0040D00D EB0D                    jmp L_Label9

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D005(C)
|
L_Label8:
:0040D00F 8D349500000000          lea esidword ptr [4*edx+00000000]
:0040D016 2BF2                    sub esiedx
:0040D018 F7DE                    neg esi
:0040D01A 03CE                    add ecxesi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D00D(U)
|
L_Label9:
:0040D01C 40                      inc eax
:0040D01D 83F810                  cmp eax, 00000010
:0040D020 7CD9                    jl L_Label7
:0040D022 A0E0454700              mov albyte ptr [004745E0]
:0040D027 83E11F                  and ecx, 0000001F

********************************************************************/
//////////////////////////////////////



//有的地方很難轉成C程式碼,可能本來就是ASM寫的
//所以直接嵌入ASM

BOOL GenSN(LPCSTR szUser , LPSTR lpSN)
{
if (strlen(szUser) <= 0)
return FALSE;
const char* puc = szUser;
while (*puc != '\0')
{
if (*puc == '\x14' || (*puc & 0x80) != 0)
return FALSE;
puc ++;
}

char szProTable[] = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
char szUserPro[0x100];
char szSNPro[0x15];

int i = 0;
puc = szUser;
char* ppuc = szUserPro;
int nCount = 0;
//////////////////////////////////////////////////////
//產生處理後使用者名稱資料
ZeroMemory(szUserPro , sizeof(szUserPro));
for (i = 0  i < 0x6f  i ++)
{
if (*puc == '\0')
{
puc = szUser;
ppuc ++;
}

if (*puc != '\x20' && (*puc & 0x80) == 0)
{
*ppuc = *ppuc + *puc;
ppuc ++;
nCount ++;
if (nCount == 0x10)
{
nCount = 0;
ppuc = szUserPro;
}
}
else
i --;
puc ++;
}

srand(::GetTickCount());
for (i = 5  i < 0x11  i ++)
{
szSNPro[i] = (char)(rand() % 0x20);
}


//0
DWORD dwSum = 0x4d;
_asm
{
push eax
push ecx
push edx
xor eax , eax
mov ecx , 0000004dh
L_Loop1:
movsx edx , byte ptr [eax + szUserPro]
inc eax
cmp eax , 00000010h
lea ecx , dword ptr [ecx + 2* edx]
jl L_Loop1;
and ecx , 0000001fh
mov dwSum , ecx
pop edx
pop ecx
pop eax
}
szSNPro[0x0] = (char)dwSum;

//1
dwSum = 0x307;
for (i = 0  i < 0x10  i++)
dwSum -= szUserPro[i];
szSNPro[0x1] = (char)(dwSum & 0x1f);

//2
_asm
{
push eax
push ecx
push edx

mov ecx, 00000086h
xor eaxeax

L_Label1:
movsx edxbyte ptr [eax+szUserPro]
test al, 01
je L_Label3
add ecxedx
jmp L_Label2

L_Label3:
neg edx
lea ecxdword ptr [ecx+2*edx]

L_Label2:
inc eax
cmp eax, 00000010h
jl L_Label1
and ecx, 0000001Fh
mov dwSum , ecx
pop edx
pop ecx
pop eax
}
szSNPro[0x2] = (char)dwSum;


_asm
{
push eax
push ecx
push edx
push esi

mov edx, 00000007h
xor eaxeax

L_Label4:
movsx ecxbyte ptr [eax+szUserPro]
cmp eax, 00000008h
jge L_Label5
mov esiecx
jmp L_Label6


L_Label5:
mov esi, 00000001h
sub esiecx

L_Label6:
imul esiecx
add edxesi
inc eax
cmp eax, 00000010h
jl L_Label4
and edx, 0000001Fh
mov dwSum , edx
pop esi
pop edx
pop ecx
pop eax
}
szSNPro[0x3] = (char)dwSum;

_asm
{
push eax
push ecx
push edx
push esi

mov ecx, 0000038Ch
xor eaxeax

L_Label7:
movsx edxbyte ptr [eax+szUserPro]
cmp eax, 00000009h
jge L_Label8
lea edxdword ptr [edx+2*edx]
lea ecxdword ptr [ecx+2*edx]
jmp L_Label9

L_Label8:
lea esidword ptr [4*edx+00000000h]
sub esiedx
neg esi
add ecxesi

L_Label9:
inc eax
cmp eax, 00000010h
jl L_Label7
and ecx, 0000001Fh
mov dwSum , ecx
pop esi
pop edx
pop ecx
pop eax

}
szSNPro[0x4] = (char)dwSum;

dwSum = 0x49;
for (i = 0  i < 0x10  i ++)
dwSum += szUserPro[i];

for (i = 0  i < 0x11  i ++)
{
dwSum += szProTable[szSNPro[i]];
}


szSNPro[0x11] = (char)(dwSum & 0x1f);

dwSum = 0x32;

for (i = 0  i < 0x10; i++)
dwSum -= szUserPro[i];

for (i = 0  i < 0x12; i ++)
dwSum += szProTable[szSNPro[i]];
szSNPro[0x12] = (char)(dwSum & 0x1f);

dwSum = 0x79;
for (i = 0  i < 0x13; i ++)
dwSum -= szProTable[szSNPro[i]];
szSNPro[0x13] = (char)(dwSum & 0x1f);


for (int k = 0x0  k < 0x14  k++)
lpSN[k] = szProTable[szSNPro[k]];
lpSN[0x14] = '\0';
return TRUE;

}

相關文章