一種非明碼比較程式的註冊------NS-SHAFT註冊碼破解 (9千字)

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

NS-SHAFT的兩個小遊戲一個是向上逃命的,一個是向下逃命的。
暫且叫向上逃命的為“是男人就上100層”,向下逃命的就叫做“是男人就是100層”。
絕對有難度!!鬼子的東西就是變態。
這麼簡單的程式將然要500日元的註冊費(我漢化的把那個漢化掉了,原版上有提示)
向我這些窮人,只能拿它來研究了。
並且對破解“一種非明碼比較”程式的思路經驗進行總結,以饗讀者。

下載地址:http://202.102.229.61/zhima
保護方式:例外,異常
使用工具:OllyDbg1.09C漢化版,VC++6.0(寫序號產生器用)
作業系統:win2000
破解難度:有一定難度

      破解過程

一、解除軟體保護。
由於用的是例外,異常來進行保護,所以alt+O開啟OllyDbg的“除錯選項”,選擇“異常”標籤
把“忽略”的核取方塊選項除了最下邊的那一個不選其他統統選上。然後就可以放心的載入程式了。
OllyDbg就是強大,沒得說,對付鬼子的變態保護很有一套。感謝迎刃兄的指導。

二、對軟體註冊方式的分析。
這個軟體註冊時要求輸入使用者名稱和註冊號,使用者名稱不起任何作用,主要是對註冊碼進行檢驗。
兩個程式註冊碼之間的差別只有一條指令。這裡我拿“向上100層”舉例。那條指令我會特別註釋。
開啟程式-〉執行。
在反彙編框中,滑鼠右鍵-〉搜尋-〉當前模組中的名稱(其實也就是當前領空所有被呼叫的API函式)。
找到GetDlgItemTextA對著它點右鍵,選擇“查詢匯入參考”。全部設為斷點。
前期工作做完了。選擇“註冊”。輸入使用者名稱,輸入註冊碼(7位,後面有解釋)。確定。被斷下來了。
我們可以看到下面緊接著就是出錯的提示框的CALL,能跳過它的只有JNZ 120.0040302F這個。
00402FE1   . 8D85 FCFDFFFF  LEA EAX,DWORD PTR SS:[EBP-204]
00402FE7   . 50             PUSH EAX
00402FE8   . E8 C0010000    CALL 120.004031AD
00402FED   . 83C4 04        ADD ESP,4
00402FF0   . 85C0           TEST EAX,EAX
00402FF2   . 0F85 37000000  JNZ 120.0040302F
所以,比較的核心程式碼肯定在CALL 120.004031AD這個裡面,F7進入。
這裡就是比較位數的不能大於7位。
004031BB   . 8A48 07        MOV CL,BYTE PTR DS:[EAX+7]       //取第8個,
004031BE   . 85C9           TEST ECX,ECX      //ECX必須為零所以第8位必須位0x00也就是什麼都不能有
004031C0   . 0F84 07000000  JE 120.004031CD
往下看就是比較的核心了。
可以發現比較過程經常呼叫的一個函式就是CALL 120.00403317。看看裡面是什麼呢??
00403317  /$ 55             PUSH EBP
00403318  |. 8BEC           MOV EBP,ESP
0040331A  |. 53             PUSH EBX
0040331B  |. 56             PUSH ESI
0040331C  |. 57             PUSH EDI
0040331D  |. 33C0           XOR EAX,EAX
0040331F  |. 8A45 08        MOV AL,BYTE PTR SS:[EBP+8]   //取一個字元
00403322  |. 83F8 61        CMP EAX,61  //是小寫字母嗎???
00403325  |. 0F8C 0B000000  JL 120.00403336
0040332B  |. 33C0           XOR EAX,EAX
0040332D  |. 8A45 08        MOV AL,BYTE PTR SS:[EBP+8]
00403330  |. 83E8 20        SUB EAX,20  //是轉化為大寫,
00403333  |. 8845 08        MOV BYTE PTR SS:[EBP+8],AL
00403336  |> 33C0           XOR EAX,EAX
00403338  |. 8A45 08        MOV AL,BYTE PTR SS:[EBP+8]
0040333B  |. 83F8 41        CMP EAX,41 //是大寫字母嗎???
0040333E  |. 0F8C 0B000000  JL 120.0040334F
00403344  |. 33C0           XOR EAX,EAX
00403346  |. 8A45 08        MOV AL,BYTE PTR SS:[EBP+8]
00403349  |. 83E8 07        SUB EAX,7 //是大寫減0x07
0040334C  |. 8845 08        MOV BYTE PTR SS:[EBP+8],AL
0040334F  |> 33C0           XOR EAX,EAX
00403351  |. 8A45 08        MOV AL,BYTE PTR SS:[EBP+8]
00403354  |. 83E8 30        SUB EAX,30  //不管是數字還是字母統統減0x30
00403357  |. E9 00000000    JMP 120.0040335C
0040335C  |> 5F             POP EDI
0040335D  |. 5E             POP ESI
0040335E  |. 5B             POP EBX
0040335F  |. C9             LEAVE
00403360  \. C3             RETN
對這個函式的功能總結:
數字-0x30
小寫字母-0x20-0x07-0x30
大寫字母-0x07-0x30
好了讓我們在分析核心的程式碼:試煉碼:ljylhqn (這個試煉碼可是有一定的含義呦)
----------------第一個開始-----------------
00403211   > 8B45 08        MOV EAX,DWORD PTR SS:[EBP+8] //傳遞給EAX試煉碼,這裡下斷點是個不錯的注意
00403214   . 8A40 05        MOV AL,BYTE PTR DS:[EAX+5] //取註冊碼第6位
00403217   . 50             PUSH EAX
00403218   . E8 FA000000    CALL 120.00403317 //計算得到EAX=1A
0040321D   . 83C4 04        ADD ESP,4
00403220   . 33DB           XOR EBX,EBX
00403222   . 8AD8           MOV BL,AL //EBX=1A
00403224   . 8B45 08        MOV EAX,DWORD PTR SS:[EBP+8] //傳遞給EAX試煉碼
00403227   . 8A40 02        MOV AL,BYTE PTR DS:[EAX+2] //取註冊碼第3位
0040322A   . 50             PUSH EAX
0040322B   . E8 E7000000    CALL 120.00403317 //計算得到EAX=22
00403230   . 83C4 04        ADD ESP,4
00403233   . 33C9           XOR ECX,ECX
00403235   . 8AC8           MOV CL,AL //ECX=22
00403237   . BE 24000000    MOV ESI,24
0040323C   . 8D4459 1C      LEA EAX,DWORD PTR DS:[ECX+EBX*2+1C] //一個計算,結果EAX=72。下100層的計算是[ECX+EBX*2+1D]
00403240   . 99             CDQ
00403241   . F7FE           IDIV ESI //eax除以24,計算後EAX為商,EDX為餘數
00403243   . 8BDA           MOV EBX,EDX
00403245   . 8B45 08        MOV EAX,DWORD PTR SS:[EBP+8]
00403248   . 8A00           MOV AL,BYTE PTR DS:[EAX//取註冊碼第1位
0040324A   . 50             PUSH EAX
0040324B   . E8 C7000000    CALL 120.00403317 //計算得到EAX=15
00403250   . 83C4 04        ADD ESP,4
00403253   . 33C9           XOR ECX,ECX
00403255   . 8AC8           MOV CL,AL
00403257   . 3BD9           CMP EBX,ECX //一個是6一個是15肯定不一樣所以eax應該等於6根據
00403259   . 0F85 AC000000  JNZ 120.0040330B //CALL 120.00403317逆推註冊碼第一位應該是數字6也就是0x36
----------------第二個開始-----------------//和第一個類似區別,區別在於位置
0040325F   . 8B45 08        MOV EAX,DWORD PTR SS:[EBP+8]
00403262   . 8A40 04        MOV AL,BYTE PTR DS:[EAX+4]
00403265   . 50             PUSH EAX
00403266   . E8 AC000000    CALL 120.00403317
0040326B   . 83C4 04        ADD ESP,4
0040326E   . 33DB           XOR EBX,EBX
00403270   . 8AD8           MOV BL,AL
00403272   . 8B45 08        MOV EAX,DWORD PTR SS:[EBP+8]
00403275   . 8A40 01        MOV AL,BYTE PTR DS:[EAX+1]
00403278   . 50             PUSH EAX
00403279   . E8 99000000    CALL 120.00403317
0040327E   . 83C4 04        ADD ESP,4
00403281   . 33C9           XOR ECX,ECX
00403283   . 8AC8           MOV CL,AL
00403285   . BE 24000000    MOV ESI,24
0040328A   . 8D4459 1C      LEA EAX,DWORD PTR DS:[ECX+EBX*2+1C]
0040328E   . 99             CDQ
0040328F   . F7FE           IDIV ESI
00403291   . 8BDA           MOV EBX,EDX
00403293   . 8B45 08        MOV EAX,DWORD PTR SS:[EBP+8]
00403296   . 8A40 06        MOV AL,BYTE PTR DS:[EAX+6]
00403299   . 50             PUSH EAX
0040329A   . E8 78000000    CALL 120.00403317
0040329F   . 83C4 04        ADD ESP,4
004032A2   . 33C9           XOR ECX,ECX
004032A4   . 8AC8           MOV CL,AL
004032A6   . 3BD9           CMP EBX,ECX
004032A8   . 0F85 5D000000  JNZ 120.0040330B
----------------第三個開始-----------------//差不多一模一樣
004032AE   . 8B45 08        MOV EAX,DWORD PTR SS:[EBP+8]
004032B1   . 8A40 06        MOV AL,BYTE PTR DS:[EAX+6]
004032B4   . 50             PUSH EAX
004032B5   . E8 5D000000    CALL 120.00403317
004032BA   . 83C4 04        ADD ESP,4
004032BD   . 33DB           XOR EBX,EBX
004032BF   . 8AD8           MOV BL,AL
004032C1   . 8B45 08        MOV EAX,DWORD PTR SS:[EBP+8]
004032C4   . 8A00           MOV AL,BYTE PTR DS:[EAX]
004032C6   . 50             PUSH EAX
004032C7   . E8 4B000000    CALL 120.00403317
004032CC   . 83C4 04        ADD ESP,4
004032CF   . 33C9           XOR ECX,ECX
004032D1   . 8AC8           MOV CL,AL
004032D3   . BE 24000000    MOV ESI,24
004032D8   . 8D4459 1C      LEA EAX,DWORD PTR DS:[ECX+EBX*2+1C]
004032DC   . 99             CDQ
004032DD   . F7FE           IDIV ESI
004032DF   . 8BDA           MOV EBX,EDX
004032E1   . 8B45 08        MOV EAX,DWORD PTR SS:[EBP+8]
004032E4   . 8A40 03        MOV AL,BYTE PTR DS:[EAX+3]
004032E7   . 50             PUSH EAX
004032E8   . E8 2A000000    CALL 120.00403317
004032ED   . 83C4 04        ADD ESP,4
004032F0   . 33C9           XOR ECX,ECX
004032F2   . 8AC8           MOV CL,AL
004032F4   . 3BD9           CMP EBX,ECX
004032F6   . 0F85 0F000000  JNZ 120.0040330B
----------------結束-----------------
從程式碼看一共比較3次:
第一次比較:取第六位(ebx)和第三位(ecx)經CALL 120.00403317處理。然後經0040323c計算除0x24取餘數存入ebx
再取第一位經CALL 120.00403317處理存入eax。然後比較eax和ebx。相等則以,不等則死

第二次比較:取第五位(ebx)和第二位(ecx)經CALL 120.00403317處理。然後經0040323c計算除0x24取餘數存入ebx
再取第七位經CALL 120.00403317處理存入eax。然後比較eax和ebx。相等則以,不等則死

第三次比較:取第七位(ebx)和第一位(ecx)經CALL 120.00403317處理。然後經0040323c計算除0x24取餘數存入ebx
再取第四位經CALL 120.00403317處理存入eax。然後比較eax和ebx。相等則以,不等則死

三、製作序號產生器
透過推理這個軟體的註冊碼可以透過輸入任意一個7位字串猜測出來。下面是我寫的序號產生器的核心程式碼
void CNS_KGDlg::OnBnGetKey() 
{
// TODO: Add your control notification handler code here
int ctmp1,ctmp2,ctmp3;
LPCSTR testKey1;
char testKey[8];
testKey[7]='\0';
UpdateData();
if(m_strKey.IsEmpty()||m_strKey.GetLength()!=7)//m_strKey是使用者輸入的任意7位註冊碼
{
MessageBox("您的輸入有誤","提示");
return;
}
testKey1=(LPCSTR)m_strKey;
strncpy(testKey,testKey1,7);
ctmp1=changechartoint(testKey[5]);
ctmp2=changechartoint(testKey[2]);
ctmp3=suanfa(ctmp1, ctmp2, m_nChk);
testKey[0]=changeinttochar(ctmp3);

ctmp1=changechartoint(testKey[4]);
ctmp2=changechartoint(testKey[1]);
ctmp3=suanfa(ctmp1, ctmp2, m_nChk);
testKey[6]=changeinttochar(ctmp3);

ctmp1=changechartoint(testKey[6]);
ctmp2=changechartoint(testKey[0]);
ctmp3=suanfa(ctmp1, ctmp2, m_nChk);
testKey[3]=changeinttochar(ctmp3);

m_strKey.Format("%s",testKey); 
m_strNote.Format("幸福的芝麻製作");  //廣告
SetWindowText("http://zhimaxp.126.com");   //廣告
UpdateData(FALSE);

}

int CNS_KGDlg::changechartoint(char ch)
{
if(ch>=97)
{
ch-=32;
}
if(ch>=65)
{
ch-=7;
}
return ch-48;

}

int CNS_KGDlg::suanfa(char a, char b, int k)
{
int c;
if(k==0)
{
c=b+a*2+28;
return c%36;
}
else
{
c=b+a*2+29;
return c%36;
}
}

char CNS_KGDlg::changeinttochar(int nCh)
{
nCh+=48;
if(nCh>57)
nCh+=7;
if(nCh>90)
nCh+=32;
return nCh;
}
----------
程式下載:http://202.102.229.61/zhima

相關文章