【文章作者】: 黃仁來
【 關鍵詞 】: MSN聊天記錄查看器,破解,算法,分析,綠色,注冊機,注冊碼;
【下載地址】: http://nj.onlinedown.Net/soft/48652.htm
【保護方式】: 序列號
【編寫語言】: VC6
【使用工具】: OD,計算器,記事本
【作者聲明】: 只是感興趣,沒有其他目的。失誤之處敬請諸位大俠賜教!
--------------------------------------------------------------------------------
【詳細過程】
好久沒有練破解,退步了。這個看似很簡單的家伙,花了我大半天時間才徹底搞定它,汗 ~~~~,
通過查找ASCII字符串可以定位到關鍵算法如下:
00401CE0 . 6A FF PUSH -1
00401CE2 . 68 48754200 PUSH msn聊天?00427548 ; SE 處理程序安裝
00401CE7 . 64:A1 0000000>MOV EAX,DWord PTR FS:[0]
00401CED . 50 PUSH EAX
00401CEE . 64:8925 00000>MOV DWord PTR FS:[0],ESP
00401CF5 . 83EC 08 SUB ESP,8
00401CF8 . 56 PUSH ESI
00401CF9 . 8BF1 MOV ESI,ECX
00401CFB . 6A 01 PUSH 1
00401CFD . E8 FFAA0100 CALL msn聊天?0041C801 ; 假碼
00401D02 . A1 8C464300 MOV EAX,DWord PTR DS:[43468C]
00401D07 . 894424 04 MOV DWord PTR SS:[ESP+4],EAX
00401D0B . 8D8E 1C010000 LEA ECX,DWord PTR DS:[ESI+11C]
00401D11 . C74424 14 000>MOV DWord PTR SS:[ESP+14],0
00401D19 . 51 PUSH ECX
00401D1A . 8D4C24 08 LEA ECX,DWord PTR SS:[ESP+8]
00401D1E . E8 E9C00100 CALL msn聊天?0041DE0C
00401D23 . 6A 08 PUSH 8
00401D25 . 68 28414300 PUSH msn聊天?00434128 ; 1163659294813585
00401D2A . 6A 08 PUSH 8
00401D2C . 8D4C24 10 LEA ECX,DWord PTR SS:[ESP+10]
00401D30 . E8 2DC30100 CALL msn聊天?0041E062 ; 和黑名單進行比較
00401D35 . 50 PUSH EAX
00401D36 . E8 D5A00000 CALL msn聊天?0040BE10
00401D3B . 83C4 0C ADD ESP,0C
00401D3E . 85C0 TEST EAX,EAX ; 相同則有下面的提示
00401D40 . 75 10 JNZ SHORT msn聊天?00401D52
00401D42 . 50 PUSH EAX
00401D43 . 68 8C414300 PUSH msn聊天?0043418C ; ngnsss
00401D48 . 68 68414300 PUSH msn聊天?00434168 ; 這是個盜版的注冊號,請注冊正式版本
00401D4D . E9 96000000 JMP msn聊天?00401DE8
00401D52 > 6A 08 PUSH 8
00401D54 . 68 54414300 PUSH msn聊天?00434154 ; 0386848021608060
00401D59 . 6A 08 PUSH 8
00401D5B . 8D4C24 10 LEA ECX,DWord PTR SS:[ESP+10]
00401D5F . E8 FEC20100 CALL msn聊天?0041E062
00401D64 . 50 PUSH EAX
00401D65 . E8 A6A00000 CALL msn聊天?0040BE10
00401D6A . 83C4 0C ADD ESP,0C
00401D6D . 85C0 TEST EAX,EAX
00401D6F . 75 0D JNZ SHORT msn聊天?00401D7E
00401D71 . 50 PUSH EAX
00401D72 . 68 8C414300 PUSH msn聊天?0043418C ; ngnsss
00401D77 . 68 68414300 PUSH msn聊天?00434168 ; 這是個盜版的注冊號,請注冊正式版本
00401D7C . EB 6A JMP SHORT msn聊天?00401DE8
00401D7E > 6A 08 PUSH 8
00401D80 . 68 14414300 PUSH msn聊天?00434114 ; 1191759292915277
00401D85 . 6A 08 PUSH 8
00401D87 . 8D4C24 10 LEA ECX,DWord PTR SS:[ESP+10]
00401D8B . E8 D2C20100 CALL msn聊天?0041E062
00401D90 . 50 PUSH EAX
00401D91 . E8 7AA00000 CALL msn聊天?0040BE10
00401D96 . 83C4 0C ADD ESP,0C
00401D99 . 85C0 TEST EAX,EAX
00401D9B . 75 0D JNZ SHORT msn聊天?00401DAA
00401D9D . 50 PUSH EAX
00401D9E . 68 8C414300 PUSH msn聊天?0043418C ; ngnsss
00401DA3 . 68 68414300 PUSH msn聊天?00434168 ; 這是個盜版的注冊號,請注冊正式版本
00401DA8 . EB 3E JMP SHORT msn聊天?00401DE8
00401DAA > 51 PUSH ECX
00401DAB . 8D5424 08 LEA EDX,DWord PTR SS:[ESP+8]
00401DAF . 8BCC MOV ECX,ESP
00401DB1 . 896424 0C MOV DWord PTR SS:[ESP+C],ESP
00401DB5 . 52 PUSH EDX
00401DB6 . E8 D1BC0100 CALL msn聊天?0041DA8C
00401DBB . E8 B0FDFFFF CALL msn聊天?00401B70 ; 關鍵算法,F7進入
00401DC0 . 83C4 04 ADD ESP,4
00401DC3 . 85C0 TEST EAX,EAX
00401DC5 . 6A 00 PUSH 0
00401DC7 . 68 8C414300 PUSH msn聊天?0043418C ; ngnsss
00401DCC . 74 15 JE SHORT msn聊天?00401DE3
00401DCE . 68 48414300 PUSH msn聊天?00434148 ; 注冊成功
00401DD3 . 8BCE MOV ECX,ESI
00401DD5 . E8 46A00100 CALL msn聊天?0041BE20
00401DDA . 8BCE MOV ECX,ESI
00401DDC . E8 19CB0100 CALL msn聊天?0041E8FA
00401DE1 . EB 0C JMP SHORT msn聊天?00401DEF
00401DE3 > 68 3C414300 PUSH msn聊天?0043413C ; 注冊號無效
00401DE8 > 8BCE MOV ECX,ESI
……省略幾行代碼……
00401E0C . 83C4 14 ADD ESP,14
00401E0F . C3 RETN
輸入假碼 1982032512345678 馬上被中斷到以上過程,注意關鍵算法過程處:
00401DBB . E8 B0FDFFFF CALL msn聊天?00401B70 ; 關鍵算法,F7進入
接下來就有好東西分析了。
00401B70 /$ 6A FF PUSH -1 ; 關鍵算法
00401B72 |. 68 28754200 PUSH msn聊天?00427528 ; SE 處理程序安裝
00401B77 |. 64:A1 0000000>MOV EAX,DWord PTR FS:[0]
00401B7D |. 50 PUSH EAX
00401B7E |. 64:8925 00000>MOV DWord PTR FS:[0],ESP
00401B85 |. 83EC 18 SUB ESP,18
00401B88 |. 53 PUSH EBX
00401B89 |. 6A 08 PUSH 8
00401B8B |. 33DB XOR EBX,EBX ; 以下出現幾串數字是注冊碼黑名單
00401B8D |. 68 28414300 PUSH msn聊天?00434128 ; 1163659294813585
00401B92 |. 6A 08 PUSH 8
00401B94 |. 8D4C24 38 LEA ECX,DWord PTR SS:[ESP+38]
00401B98 |. 895C24 30 MOV DWord PTR SS:[ESP+30],EBX
00401B9C |. E8 C1C40100 CALL msn聊天?0041E062 ; 讀取假碼
00401BA1 |. 50 PUSH EAX ; 入棧
00401BA2 |. E8 69A20000 CALL msn聊天?0040BE10 ; 和上述黑名單一致嗎?
00401BA7 |. 83C4 0C ADD ESP,0C
00401BAA |. 85C0 TEST EAX,EAX
00401BAC |. 0F84 06010000 JE msn聊天?00401CB8 ; 一致則OVER
00401BB2 |. 6A 08 PUSH 8
00401BB4 |. 68 14414300 PUSH msn聊天?00434114 ; 1191759292915277
00401BB9 |. 6A 08 PUSH 8
00401BBB |. 8D4C24 38 LEA ECX,DWord PTR SS:[ESP+38]
00401BBF |. E8 9EC40100 CALL msn聊天?0041E062
00401BC4 |. 50 PUSH EAX
00401BC5 |. E8 46A20000 CALL msn聊天?0040BE10 ; 和上述黑名單一致嗎?
00401BCA |. 83C4 0C ADD ESP,0C
00401BCD |. 85C0 TEST EAX,EAX
00401BCF |. 0F84 E3000000 JE msn聊天?00401CB8 ; 一致則OVER
00401BD5 |. 8B4C24 2C MOV ECX,DWord PTR SS:[ESP+2C]
00401BD9 |. 33C0 XOR EAX,EAX
00401BDB |. 894424 05 MOV DWord PTR SS:[ESP+5],EAX
00401BDF |. 885C24 04 MOV BYTE PTR SS:[ESP+4],BL
00401BE3 |. 66:894424 09 MOV Word PTR SS:[ESP+9],AX
00401BE8 |. 884424 0B MOV BYTE PTR SS:[ESP+B],AL
00401BEC |. 8B41 F8 MOV EAX,DWord PTR DS:[ECX-8] ; 假碼長度
00401BEF |. 83F8 10 CMP EAX,10 ; 和16比較
00401BF2 |. 0F8C C0000000 JL msn聊天?00401CB8 ; 小於則OVER
00401BF8 |. 56 PUSH ESI
00401BF9 |. 68 04010000 PUSH 104 ; $104=260
00401BFE |. 8D4C24 34 LEA ECX,DWord PTR SS:[ESP+34]
00401C02 |. E8 5BC40100 CALL msn聊天?0041E062 ; 假碼
00401C07 |. 8B10 MOV EDX,DWord PTR DS:[EAX] ; 字符串轉十六進制
00401C09 |. 33F6 XOR ESI,ESI ; ESI=0
00401C0B |. 895424 10 MOV DWord PTR SS:[ESP+10],EDX ; EDX=[ESP+10]=前四位倒序轉十六進制
00401C0F |. 8B48 04 MOV ECX,DWord PTR DS:[EAX+4] ; ECX=[ESP+4]=5到8位倒序十六進制
00401C12 |. 894C24 14 MOV DWord PTR SS:[ESP+14],ECX ; [ESP+14]=ECX
00401C16 |. 8B50 08 MOV EDX,DWord PTR DS:[EAX+8] ; [EAX+8]=EDX
00401C19 |. 895424 18 MOV DWord PTR SS:[ESP+18],EDX ; EDX=[ESP+18]=9至13位倒序十六進制
00401C1D |. 8B40 0C MOV EAX,DWord PTR DS:[EAX+C] ; EAX=[EAX+C]=最後四位倒序十六進制
00401C20 |. 894424 1C MOV DWord PTR SS:[ESP+1C],EAX ; [ESP+1C] = EAX
00401C24 |> 8A4C34 10 /MOV CL,BYTE PTR SS:[ESP+ESI+10] ; for i:=1 to 16 do begin CL=ord(假碼[i]);
00401C28 |. 51 |PUSH ECX
00401C29 |. E8 22FFFFFF |CALL msn聊天?00401B50 ; 對每一位假碼進行過濾,F7進入
================= F7進入這個過程,過濾非法字符串================
00401B50 /$ 8A4424 04 MOV AL,BYTE PTR SS:[ESP+4] ; 取該位注冊碼
00401B54 |. 3C 30 CMP AL,30 ; 是否大於0
00401B56 |. 7C 07 JL SHORT msn聊天?00401B5F
00401B58 |. 3C 39 CMP AL,39 ; 是否小於9,即判斷是否為數字
00401B5A |. 7F 03 JG SHORT msn聊天?00401B5F
00401B5C |. 2C 30 SUB AL,30 ; 減$30後返回,就是注冊碼假如是數字就減$30
00401B5E |. C3 RETN
00401B5F |> 3C 41 CMP AL,41 ; 是否大於$41,即A
00401B61 |. 7C 07 JL SHORT msn聊天?00401B6A
00401B63 |. 3C 46 CMP AL,46 ; 是否小於$46,即F
00401B65 |. 7F 03 JG SHORT msn聊天?00401B6A
00401B67 |. 2C 37 SUB AL,37 ; 如果該注冊碼是A-F之間的就減$37
00401B69 |. C3 RETN
00401B6A |> 0C FF OR AL,0FF ; 非數字或A-F,進程 OR $FF 運算
00401B6C \. C3 RETN
=============
Delphi描述為:
function Filter(Str: string): string;
var
i: integer;
Len: integer;
res: string;
begin
res := '';
for i := 1 to Length(Str) do
begin
case ord(Str[i]) of
$30..$39: res := res + inttostr(ord(Str[i]) - $30);
$41..$46: res := res + inttostr(ord(Str[i]) - $37);
else res := res + inttostr(ord(Str[i]) or $FF);
end;
end;
result := res;
end;
================= 跳出這以上過程,回到核心過程繼續分析================
00401C2E |. 83C4 04 |ADD ESP,4
00401C31 |. 884434 10 |MOV BYTE PTR SS:[ESP+ESI+10],AL
00401C35 |. 46 |INC ESI
00401C36 |. 83FE 10 |CMP ESI,10 ; 循環16次
00401C39 |.^ 7C E9 \JL SHORT msn聊天?00401C24 ; end;
00401C3B |. 33C0 XOR EAX,EAX
00401C3D |. 8D4C24 10 LEA ECX,DWord PTR SS:[ESP+10]
00401C41 |. 5E POP ESI
00401C42 |> 8A51 01 /MOV DL,BYTE PTR DS:[ECX+1] ; for i:=1 to 8 do begin [ECX+1]指向2.4.6.8.10.12.14.16位
00401C45 |. 8A19 |MOV BL,BYTE PTR DS:[ECX] ; [ECX]指向第1.3.5.7.9.11.13.15位
00401C47 |. C0E2 04 |SHL DL,4 ; DL:=DL shl 4
00401C4A |. 02D3 |ADD DL,BL ; DL:=DL + BL
00401C4C |. 83C1 02 |ADD ECX,2 ; (不用理)
00401C4F |. 885404 04 |MOV BYTE PTR SS:[ESP+EAX+4],DL ; 結果保存在DL
00401C53 |. 40 |INC EAX ; 計數器+1
00401C54 |. 83F8 08 |CMP EAX,8 ; 循環8次
00401C57 |.^ 7C E9 \JL SHORT msn聊天?00401C42 ; end;
00401C59 |. 8A4424 07 MOV AL,BYTE PTR SS:[ESP+7] ; 第四組 (下面有介紹分組)
00401C5D |. 8A5C24 04 MOV BL,BYTE PTR SS:[ESP+4] ; 第一組
00401C61 |. 8A4C24 0B MOV CL,BYTE PTR SS:[ESP+B] ; 第八組
00401C65 |. 8A5424 05 MOV DL,BYTE PTR SS:[ESP+5] ; 第二組
00401C69 |. 32C3 XOR AL,BL ; XOR運行得到AL
00401C6B |. 8A5C24 06 MOV BL,BYTE PTR SS:[ESP+6] ; 第三組
00401C6F |. 32CA XOR CL,DL ; XOR運行得到CL
00401C71 |. 8A5424 09 MOV DL,BYTE PTR SS:[ESP+9] ; 第六組
00401C75 |. 32D3 XOR DL,BL ; XOR運行得到DL
00401C77 |. 8A5C24 08 MOV BL,BYTE PTR SS:[ESP+8] ; 第五組
00401C7B |. 325C24 0A XOR BL,BYTE PTR SS:[ESP+A] ; 第七組,XOR運行得到BL
00401C7F |. 3C 38 CMP AL,38 ; AL=$38嗎?
00401C81 |. 75 35 JNZ SHORT msn聊天?00401CB8
00401C83 |. 80F9 6E CMP CL,6E ; CL=$6E嗎?
00401C86 |. 75 30 JNZ SHORT msn聊天?00401CB8
00401C88 |. 80FA 4E CMP DL,4E ; DL=$4E嗎?
00401C8B |. 75 2B JNZ SHORT msn聊天?00401CB8
00401C8D |. 80FB 0C CMP BL,0C ; BL=$0C嗎?
00401C90 |. 75 26 JNZ SHORT msn聊天?00401CB8 ; 只要有一個不相等就OVER
00401C92 |. 8D4C24 2C LEA ECX,DWord PTR SS:[ESP+2C]
……省略幾行代碼……
00401CDA \. C3 RETN
---------------------------------
簡單地總結一注冊碼的驗證過程吧:
這個過程一開始排除一些黑名單,然後開始檢測用戶輸入的注冊碼了
1、注冊碼長度必須 >=16位。
2、將假碼進行一系列倒序並循環過濾非法字符,保證為數字或A-F字母。
3、再進行循環把假碼進行位置對調,順序是 1-2對調,3-4對調,5-6對調,……
比如假碼:19 82 03 25 12 34 56 78 被對調成 91 28 30 52 21 43 65 87
(暫且把對調後的18位分成8組,加空格方便查看)
4、最後把對調後的數字進行下列判斷:
第四組(52) XOR 第一組(91) = $38 嗎?
第八組(87) XOR 第二組(28) = $4E 嗎?
第三組(30) XOR 第六組(43) = $4E 嗎?
第五組(21) XOR 第七組(65) = $0C 嗎?
如果上述有條件全部符合,則注冊碼被通過驗證。
看懂了過程就覺得比較簡單,至於如何寫注冊機必須要逆向推算了,這個覺得十分有趣。
仔細理解了上述驗證過程後,你會發現,驗證過程中的幾個步驟根本是不用過問的,比如,設計注冊機的時候,無需
判斷注冊碼是否有非法數字,還有,那個奇偶位數字對調的過程,其實也不用在注冊機中還原出來,只需把生成出來的
注冊碼進行奇偶位對調即可。呵呵,看懂了沒有,本人表達有問題啊,還是用Delphi來幫我表達吧!
Delphi算法注冊機(用窮舉法)——這叫窮舉法嗎???
function GenerateSN:string;
var
SN: array[1..16] of Char;
r1, r2: integer;
S1, S2: string;
begin
Randomize;
repeat
r1 := RandomRange(10, 99); //隨機生成
r2 := RandomRange(10, 99); //隨機生成
S1 := inttohex(r1, 2); //取六進制形式
S2 := inttohex(r2, 2); //取六進制形式
until (r1 xor r2 = $38); //不斷重復,直到符合條件,
SN[8] := S1[1]; SN[7] := S1[2]; //生成對應位置的注冊碼;第8第7位
SN[2] := S2[1]; SN[1] := S2[2]; //生成對應位置的注冊碼; 第2第1位
//以下過程基本一樣,生成應注冊碼對應的位置不同而已。
repeat
r1 := RandomRange(10, 99);
r2 := RandomRange(10, 99);
S1 := inttohex(r1, 2);
S2 := inttohex(r2, 2);
until (r1 xor r2 = $6E);
SN[16] := S1[1]; SN[15] := S1[2]; //第16第15位
SN[4] := S2[1]; SN[3] := S2[2]; //第4第3位
repeat
r1 := RandomRange(10, 99);
r2 := RandomRange(10, 99);
S1 := inttohex(r1, 2);
S2 := inttohex(r2, 2);
until (r1 xor r2 = $4E);
SN[12] := S1[1]; SN[11] := S1[2]; //第12第11位
SN[6] := S2[1]; SN[5] := S2[2]; //第6第5位
repeat
r1 := RandomRange(10, 99);
r2 := RandomRange(10, 99); /
S1 := inttohex(r1, 2);
S2 := inttohex(r2, 2);
until (r1 xor r2 = $0C);
SN[10] := S1[1]; SN[9] := S1[2]; //第10第9位
SN[14] := S2[1]; SN[13] := S2[2]; //第14第13位
Result := SN;
end;
最後給出幾組可生成的注冊碼吧,沒有去驗證,希望可以通過
7245E0F1850445A3
0645E0852304E3A3
A242452183A143A4
235495A0B47174B2
235495A0B47174B2
--------------------------------------------------------------------------------
【經驗總結】
逆向推算,非常有趣。
--------------------------------------------------------------------------------
【版權聲明】: 本文原創於http://www.unpack.cn, 轉載請注明作者並保持文章的完整, 謝謝!
2008年07月16日 15:27:38