舉個簡單的例子說明下,以下就是軟件的注冊碼關鍵代碼,根據(jù)其生成注冊碼的函數(shù),分析其思路,寫出相應的程序生成注冊碼即可。

004011AE . 6A 51 PUSH 51 ; /Count = 51 (81.)
004011B0 . 50 PUSH EAX ; |Buffer
004011B1 . 6A 6E PUSH 6E ; |ControlID = 6E (110.)
004011B3 . 56 PUSH ESI ; |hWnd
004011B4 . FFD7 CALL EDI ; \GetDlgItemTextA
004011B6 . 8D8C24 9C0000>LEA ECX,DWORD PTR SS:[ESP+9C]
004011BD . 6A 65 PUSH 65 ; /Count = 65 (101.)
004011BF . 51 PUSH ECX ; |Buffer
004011C0 . 68 E8030000 PUSH 3E8 ; |ControlID = 3E8 (1000.)
004011C5 . 56 PUSH ESI ; |hWnd
004011C6 . 8BD8 MOV EBX,EAX ; |EBX存放用戶名的長度
004011C8 . FFD7 CALL EDI ; \GetDlgItemTextA
004011CA . 8A4424 4C MOV AL,BYTE PTR SS:[ESP+4C]
004011CE . 84C0 TEST AL,AL ; 是否結束
004011D0 . 74 76 JE SHORT TraceMe.00401248
004011D2 . 83FB 05 CMP EBX,5
004011D5 . 7C 71 JL SHORT TraceMe.00401248 ; 如果用戶名長度小于5,跳
004011D7 . 8D5424 4C LEA EDX,DWORD PTR SS:[ESP+4C] ; EDX指向用戶名
004011DB . 53 PUSH EBX ; 用戶名長度
004011DC . 8D8424 A00000>LEA EAX,DWORD PTR SS:[ESP+A0]
004011E3 . 52 PUSH EDX ; 用戶名
004011E4 . 50 PUSH EAX ; key
004011E5 . E8 56010000 CALL TraceMe.00401340 ; 判斷注冊碼是否正確,有三個參數(shù)[輸入key,用戶名,用戶名長度]
 
思路:
從用戶名的第4個字符開始分別與全局的一個長度為7的標識相乘最后和就為key
--注冊碼部分--
00401340 /$ 55 PUSH EBP ; 保存EBP
00401341 |. 8B6C24 0C MOV EBP,DWORD PTR SS:[ESP+C] ; 獲取第2個參數(shù),用戶名
00401345 |. 56 PUSH ESI ; 保護ESI,EDI
00401346 |. 57 PUSH EDI
00401347 |. 8B7C24 18 MOV EDI,DWORD PTR SS:[ESP+18] ; 取第一個參數(shù),用戶名長度
0040134B |. B9 03000000 MOV ECX,3
00401350 |. 33F6 XOR ESI,ESI
00401352 |. 33C0 XOR EAX,EAX
00401354 |. 3BF9 CMP EDI,ECX
00401356 |. 7E 21 JLE SHORT TraceMe.00401379 ; 如果用戶名長度小于等于3,跳
00401358 |. 53 PUSH EBX
00401359 |> 83F8 07 /CMP EAX,7
0040135C |. 7E 02 |JLE SHORT TraceMe.00401360 ; 如果EAX小于等于7,跳
0040135E |. 33C0 |XOR EAX,EAX
00401360 |> 33D2 |XOR EDX,EDX
00401362 |. 33DB |XOR EBX,EBX
00401364 |. 8A1429 |MOV DL,BYTE PTR DS:[ECX+EBP] ; DL存放從用戶名中取出的第ECX字符
00401367 |. 8A98 30504000 |MOV BL,BYTE PTR DS:[EAX+405030] ; BL存放某個全局變量
0040136D |. 0FAFD3 |IMUL EDX,EBX ; 某個用戶名×全局變量C
00401370 |. 03F2 |ADD ESI,EDX ; ESI似乎是這些值的統(tǒng)計
00401372 |. 41 |INC ECX
00401373 |. 40 |INC EAX
00401374 |. 3BCF |CMP ECX,EDI ; 如果ECX小于用戶名的長度則繼續(xù)循環(huán)
00401376 |.^ 7C E1 \JL SHORT TraceMe.00401359
00401378 |. 5B POP EBX ; 還原EBX,不需要使用了
00401379 |> 56 PUSH ESI ; /<%ld>
0040137A |. 68 78504000 PUSH TraceMe.00405078 ; |Format = "%ld"
0040137F |. 55 PUSH EBP ; |s
00401380 |. FF15 9C404000 CALL DWORD PTR DS:[<&USER32.wsprintfA>] ; \wsprintfA
00401386 |. 8B4424 1C MOV EAX,DWORD PTR SS:[ESP+1C]
0040138A |. 83C4 0C ADD ESP,0C ; C調用方式
0040138D |. 55 PUSH EBP ; /String2
0040138E |. 50 PUSH EAX ; |String1
0040138F |. FF15 04404000 CALL DWORD PTR DS:[<&KERNEL32.lstrcmpA>] ; \lstrcmpA
00401395 |. F7D8 NEG EAX
00401397 |. 1BC0 SBB EAX,EAX
00401399 |. 5F POP EDI
0040139A |. 5E POP ESI
0040139B |. 40 INC EAX
0040139C |. 5D POP EBP
0040139D \. C3 RETN

private string GetKey(string userName, int userNameLength)
{
int ecx = 3;
int sum = 0;
int eax = 0;
int[] flag = {0x0C0x0A0x130x090x0C0x0B0x0A0x08};
while (ecx < userNameLength)
{
if (eax >= flag.Length)
eax 
= eax % flag.Length;
sum 
+= userName[ecx] * flag[eax];
ecx
++;
eax
++;
}
return sum.ToString();
}