Lambda Pro v2.0安裝序列號破解(1) (16千字)

看雪資料發表於2001-12-08

/////////////////////////////////////////////////////////////////////
//
//  目標軟體:Lambda Pro
//
//  軟體版本:v2.0-MAC-Limit-DEMO-0724
//
//  官方網站:http://www.coretek.com.cn/
//
//  軟體授權:商用軟體
//
//  作業系統:Win95/98/ME、WinNT/2000
//
//  軟體簡介:
//
//  中國擁有自己智慧財產權的實時作業系統 - Delta OS的IDE。因為是簡體中文
//
//  軟體,個人覺得很適合於初學實時作業系統(RTOS)的人們作為學習參考。
//
//  軟體保護:IntsallShield v6.x序列號保護(此序列號與網路卡MAC地址有關)
//
/////////////////////////////////////////////////////////////////////
//
//  使用工具:InstallShield Decompiler v1.00 beta 7
//            (用於反彙編SETUP.INX指令碼檔案)
//
//            Borland C++ v3.1
//            (用於編寫序列號生成器)
//
//            Our Brain...:-)
//
/////////////////////////////////////////////////////////////////////
//
//  關於本文:本文主要目的在於教學,讓初學者掌握InstallShoeld序列號分
//
//            析的一般方法,所以找了這個很不常見的軟體...請勿將此教程
//
//            用於商業目的。
//
//                              Always Your Best Friend: FiNALSErAPH
//
//  水平有限,難免疏漏...
//
//  Any Question?
//  Mail To: FiNALSErAPH@yahoo.com.cn
//
//                                                        2001-12-04
//
/////////////////////////////////////////////////////////////////////
//
//  第一部分:指令碼分析
//
/////////////////////////////////////////////////////////////////////
//
//  ISD SETUP.INX SETUP.TXT -O -E
//  (將SETUP.INX反編譯並將結果輸出至SETUP.TXT檔案)
//
/////////////////////////////////////////////////////////////////////
function program()
begin
/* 000055A5: 0006 */    g_str27 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

/* 000055D3: 0006 */    g_str28 = "YW9KV8IU7MT6DS5NQ4AP3LJ2EH1RG0OFZCBX";

/* 00005601: 0021 */    function_22();
                        //將安裝目錄下的TEST_001.EXE檔案複製到C:\並重新命名
                        //為GETMAC.EXE。執行C:\GETMAC.EXE(獲取網路卡MAC地址)
                        //生成C:\MACINFO.TXT(裡面就是網路卡的實體地址)
                        //在安裝正常完成後這些檔案會被刪除

/* 00005607: 0021 */    function_184(12);

/* 00005612: 0021 */    function_10();

/* 00005618: 0021 */    function_8();

/* 0000561E: 0021 */    function_9();

/* 00005624: 0006 */    g_number28 = 0;

/* 00005630: 0021 */    function_1();
                        //密碼驗證程式入口
  .
  .
  .
end;
/////////////////////////////////////////////////////////////////////
// : Call Referenced(1):
// :  00005630,
function NUMBER function_1()
    NUMBER n0;
    NUMBER n1;
begin

// : Jump Referenced(1):
// :  00005A82,
label_13:
/* 00005A4F: 0021 */    function_23();
                        //從C:\MACINFO.TXT中獲取網路卡資訊備用

// : Jump Referenced(1):
// :  00005AB8,
label_14:
/* 00005A57: 0021 */    function_11();
                        //顯示歡迎畫面
/* 00005A5D: 0006 */    n0 = LAST_RESULT;
/* 00005A67: 000D */    n1 = n0 == 12;
/* 00005A76: 0004 */    if(! n1) goto label_15;
/* 00005A82: 0005 */    goto label_13;

// : Jump Referenced(2):
// :  00005A76, 00005AEE,
label_15:
/* 00005A8D: 0021 */    function_12();
                        //顯示版權資訊
/* 00005A93: 0006 */    n0 = LAST_RESULT;
/* 00005A9D: 000D */    n1 = n0 == 12;
/* 00005AAC: 0004 */    if(! n1) goto label_16;
/* 00005AB8: 0005 */    goto label_14;

// : Jump Referenced(3):
// :  00005AAC, 00005B3F, 00005B83,
label_16:
/* 00005AC3: 0021 */    function_13();
                        //獲取使用者輸入的序列號(賦給g_str26)
/* 00005AC9: 0006 */    n0 = LAST_RESULT;
/* 00005AD3: 000D */    n1 = n0 == 12;
/* 00005AE2: 0004 */    if(! n1) goto label_17;
/* 00005AEE: 0005 */    goto label_15;

// : Jump Referenced(1):
// :  00005AE2,
label_17:
/* 00005AF9: 000D */    n1 = n0 == 1;
/* 00005B08: 0004 */    if(! n1) goto label_18;
/* 00005B14: 0021 */    function_24();
                        //序列號驗證程式的核心部分(即演算法驗證部分)
/* 00005B1A: 0006 */    n1 = LAST_RESULT;
/* 00005B24: 000D */    n1 = n1 == 1;
/* 00005B33: 0004 */    if(! n1) goto label_18;
/* 00005B3F: 0005 */    goto label_16;
                        //輸入序列號錯誤則陷入迴圈
  .
  .
  .
end;
/////////////////////////////////////////////////////////////////////
// : Call Referenced(1):
// :  00005B14,
function NUMBER function_24()
    STRING s0;
    STRING s1[13];
    STRING s2;
    NUMBER n0;
    NUMBER n1;
    NUMBER n2;
    NUMBER n3;
    NUMBER n4;
    NUMBER n5;
    NUMBER n6;
    NUMBER n7;
    NUMBER n8;
begin
/* 00007036: 0006 */    s2 = g_str26;
/* 00007040: 0021 */    function_455(s2);
/* 00007049: 0006 */    n7 = LAST_RESULT;
/* 00007053: 000E */    n7 = n7 != 52;
/* 00007062: 0004 */    if(! n7) goto label_82;
/* 0000706E: 0021 */    function_304("Invalid serial number!", -65535);
/* 00007092: 0027 */    // -- Start Return Code -- //
/* 00007096: 0023 */    return 1;
//判斷輸入的序列號是否為52位

// : Jump Referenced(1):
// :  00007062,
label_82:
/* 000070A1: 0006 */    n0 = 0;

// : Jump Referenced(1):
// :  00007106,
label_83:
/* 000070AF: 000B */    n7 = n0 <= 51;
/* 000070BE: 0004 */    if(! n7) goto label_84;
/* 000070CA: 001E */    n7 = s2[n0];
/* 000070D7: 0021 */    function_18(n7);
/* 000070E0: 0006 */    n7 = LAST_RESULT;
/* 000070EA: 001D */    s2[n0] = n7;
/* 000070F7: 0007 */    n0 = n0 + 1;
/* 00007106: 0005 */    goto label_83;
//將輸入序列號中的小寫字母全部換成大寫字母

// : Jump Referenced(1):
// :  000070BE,
label_84:
/* 00007111: 001E */    n7 = s2[0];
/* 00007120: 000C */    n7 = n7 >= 48;
/* 0000712F: 001E */    n8 = s2[0];
/* 0000713E: 000B */    n8 = n8 <= 52;
/* 0000714D: 0019 */    n7 = n7 && n8;
/* 0000715A: 0004 */    if(! n7) goto label_85;
/* 00007166: 0006 */    g_str28 = "YW9KV8IU7MT6DS5NQ4AP3LJ2EH1RG0OFZCBX";
/* 00007194: 0005 */    goto label_86;

// : Jump Referenced(1):
// :  0000715A,
label_85:
/* 0000719F: 0006 */    g_str28 = "IR6UQ5GP4MO3YN2SK1AJ0THZLFX9ECW8DBV7";

// : Jump Referenced(1):
// :  00007194,
label_86:
/* 000071CF: 0006 */    n0 = 1;
//根據輸入的第一個字元選擇“字元替換表”

// : Jump Referenced(1):
// :  00007244,
label_87:
/* 000071DD: 000B */    n7 = n0 <= 51;
/* 000071EC: 0004 */    if(! n7) goto label_88;
/* 000071F8: 001E */    n7 = s2[n0];
/* 00007205: 0021 */    function_19(g_str28, n7);
/* 00007211: 0006 */    n1 = LAST_RESULT;
/* 0000721B: 001E */    n7 = g_str27[n1];
/* 00007228: 001D */    s2[n0] = n7;
/* 00007235: 0007 */    n0 = n0 + 1;
/* 00007244: 0005 */    goto label_87;
//根據上面選擇的“字元替換表”對輸入字串進行變換(注意:[00]不變,只變換[01] - [51])
//由g_str28確定位置 - >對應於g_str27的字元

// : Jump Referenced(1):
// :  000071EC,
label_88:
/* 0000724F: 0006 */    n2 = 1;
/* 0000725B: 0006 */    n1 = 49;

// : Jump Referenced(1):
// :  000073AE,
label_89:
/* 00007269: 000B */    n7 = n1 <= 51;
/* 00007278: 0004 */    if(! n7) goto label_93;
/* 00007284: 001E */    n7 = s2[n2];
/* 00007291: 0021 */    function_20(n7);
/* 0000729A: 0006 */    n3 = LAST_RESULT;
/* 000072A4: 0007 */    n0 = n2 + 1;
/* 000072B3: 0007 */    n7 = n2 + 15;

// : Jump Referenced(1):
// :  00007319,
label_90:
/* 000072C4: 000B */    n8 = n0 <= n7;
/* 000072D1: 0004 */    if(! n8) goto label_91;
/* 000072DD: 001E */    n8 = s2[n0];
/* 000072EA: 0021 */    function_20(n8);
/* 000072F3: 0006 */    n8 = LAST_RESULT;
/* 000072FD: 0014 */    n3 = n3 ^ n8;
/* 0000730A: 0007 */    n0 = n0 + 1;
/* 00007319: 0005 */    goto label_90;

// : Jump Referenced(1):
// :  000072D1,
label_91:
/* 00007324: 0021 */    function_21(n3);
/* 0000732D: 0006 */    n3 = LAST_RESULT;
/* 00007337: 001E */    n7 = s2[n1];
/* 00007344: 000E */    n7 = n3 != n7;
/* 00007351: 0004 */    if(! n7) goto label_92;
/* 0000735D: 0021 */    function_304("Invalid Serial Number!", -65535);
/* 00007381: 0027 */    // -- Start Return Code -- //
/* 00007385: 0023 */    return 1;

// : Jump Referenced(1):
// :  00007351,
label_92:
/* 00007390: 0007 */    n2 = n2 + 16;
/* 0000739F: 0007 */    n1 = n1 + 1;
/* 000073AE: 0005 */    goto label_89;
//對新生成的字串進行初步校驗
//[00]
//[01] [02] [03] [04] [05] [06] [07] [08] [09] [10] [11] [12] [13] [14] [15] [16]  -  [49]
//[17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [31] [32]  -  [50]
//[33] [34] [35] [36] [37] [38] [39] [40] [41] [42] [43] [44] [45] [46] [47] [48]  -  [51]
//將[01] - [48]的字元分成3組:[01] - [16],[17] - [32],[33] - [48]
//分別作以下運算:
//將每一個字元進行變換(字元0 - 9 -> 數字0 - 9,字元A - F -> 數字10 - 15,字元G - Z ->其ASCII值)
//進行XOR -> 校驗數 -> 字元
//校驗數變換為字元規則(數字0 - 9 -> 字元0 - 9,數字10 - 15 -> 字元A - F,其他原樣返回)
//然後與校驗位比較,看是否相同。若相同則繼續

// : Jump Referenced(1):
// :  00007278,
label_93:
/* 000073B9: 0006 */    n1 = 1;
/* 000073C5: 0006 */    n0 = 40;

// : Jump Referenced(1):
// :  00007426,
label_94:
/* 000073D3: 000B */    n7 = n0 <= 48;
/* 000073E2: 0004 */    if(! n7) goto label_95;
/* 000073EE: 001E */    n7 = s2[n0];
/* 000073FB: 001D */    s0[n1] = n7;
/* 00007408: 0007 */    n1 = n1 + 1;
/* 00007417: 0007 */    n0 = n0 + 1;
/* 00007426: 0005 */    goto label_94;

// : Jump Referenced(1):
// :  000073E2,
label_95:
/* 00007431: 0006 */    n0 = 1;

// : Jump Referenced(1):
// :  00007492,
label_96:
/* 0000743F: 000B */    n7 = n0 <= 39;
/* 0000744E: 0004 */    if(! n7) goto label_97;
/* 0000745A: 001E */    n7 = s2[n0];
/* 00007467: 001D */    s0[n1] = n7;
/* 00007474: 0007 */    n1 = n1 + 1;
/* 00007483: 0007 */    n0 = n0 + 1;
/* 00007492: 0005 */    goto label_96;

// : Jump Referenced(1):
// :  0000744E,
label_97:
/* 0000749D: 0006 */    n0 = 1;

// : Jump Referenced(1):
// :  000074EF,
label_98:
/* 000074AB: 000B */    n7 = n0 <= 48;
/* 000074BA: 0004 */    if(! n7) goto label_99;
/* 000074C6: 001E */    n7 = s0[n0];
/* 000074D3: 001D */    s2[n0] = n7;
/* 000074E0: 0007 */    n0 = n0 + 1;
/* 000074EF: 0005 */    goto label_98;
//對字串進行“換位”,規則如下:
//[00]
//[01] [02] [03] [04] [05] [06] [07] [08] [09] [10] [11] [12] [13] [14] [15] [16]
//[17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [31] [32]
//[33] [34] [35] [36] [37] [38] [39] [40] [41] [42] [43] [44] [45] [46] [47] [48]
//[49] [50] [51]
//
//變為
//
//[00]
//[40] [41] [42] [43] [44] [45] [46] [47] [48] [01] [02] [03] [04] [05] [06] [07]
//[08] [09] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23]
//[24] [25] [26] [27] [28] [29] [30] [31] [32] [33] [34] [35] [36] [37] [38] [39]
//[49] [50] [51]

// : Jump Referenced(1):
// :  000074BA,
label_99:
/* 000074FA: 001E */    n7 = s2[1];
/* 00007509: 001D */    g_str24[0] = n7;
/* 00007518: 0006 */    n0 = 14;

// : Jump Referenced(1):
// :  00007579,
label_100:
/* 00007526: 000B */    n7 = n0 <= 32;
/* 00007535: 0004 */    if(! n7) goto label_101;
/* 00007541: 000F */    n7 = n0 - 13;
/* 00007550: 001E */    n8 = s2[n0];
/* 0000755D: 001D */    g_str24[n7] = n8;
/* 0000756A: 0007 */    n0 = n0 + 1;
/* 00007579: 0005 */    goto label_100;
//生成字串g_str24,規則如下:
//[00]
//[01] [02] [03] [04] [05] [06] [07] [08] [09] [10] [11] [12] [13] [14] [15] [16]
//[17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [31] [32]
//[33] [34] [35] [36] [37] [38] [39] [40] [41] [42] [43] [44] [45] [46] [47] [48]
//[49] [50] [51]
//
//[01] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28]
//[29] [30] [31] [32]

// : Jump Referenced(1):
// :  00007535,
label_101:
/* 00007584: 0006 */    n0 = 0;

// : Jump Referenced(1):
// :  000075E5,
label_102:
/* 00007592: 000B */    n7 = n0 <= 14;
/* 000075A1: 0004 */    if(! n7) goto label_103;
/* 000075AD: 0007 */    n7 = n0 + 14;
/* 000075BC: 001E */    n7 = s2[n7];
/* 000075C9: 001D */    g_str25[n0] = n7;
/* 000075D6: 0007 */    n0 = n0 + 1;
/* 000075E5: 0005 */    goto label_102;
//生成字串g_str25,規則如下:
//[00]
//[01] [02] [03] [04] [05] [06] [07] [08] [09] [10] [11] [12] [13] [14] [15] [16]
//[17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [31] [32]
//[33] [34] [35] [36] [37] [38] [39] [40] [41] [42] [43] [44] [45] [46] [47] [48]
//[49] [50] [51]
//
//[14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28]

// : Jump Referenced(1):
// :  000075A1,
label_103:
/* 000075F0: 001E */    n7 = s2[29];
/* 000075FF: 0009 */    n7 = n7 < 50;
/* 0000760E: 001E */    n8 = s2[29];
/* 0000761D: 000A */    n8 = n8 > 57;
/* 0000762C: 0018 */    n7 = n7 || n8;
/* 00007639: 0004 */    if(! n7) goto label_104;
/* 00007645: 0021 */    function_304("Invalid serial number!", -65535);
/* 00007669: 0027 */    // -- Start Return Code -- //
/* 0000766D: 0023 */    return 1;
//繼續校驗:
//[00]
//[01] [02] [03] [04] [05] [06] [07] [08] [09] [10] [11] [12] [13] [14] [15] [16]
//[17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [31] [32]
//[33] [34] [35] [36] [37] [38] [39] [40] [41] [42] [43] [44] [45] [46] [47] [48]
//[49] [50] [51]
//
//[29]必須為字元2 - 9

// : Jump Referenced(1):
// :  00007639,
label_104:
/* 00007678: 001E */    n7 = s2[31];
/* 00007687: 0021 */    function_20(n7);
/* 00007690: 0006 */    n3 = LAST_RESULT;
/* 0000769A: 0016 */    n3 = n3 << 4;
/* 000076A9: 001E */    n7 = s2[32];
/* 000076B8: 0021 */    function_20(n7);
/* 000076C1: 0006 */    n7 = LAST_RESULT;
/* 000076CB: 0013 */    n3 = n3 | n7;
/* 000076D8: 0012 */    n4 = n3 & 1;
/* 000076E7: 000D */    n7 = n4 == 0;
/* 000076F6: 0004 */    if(! n7) goto label_105;
/* 00007702: 0021 */    function_304("Invalid serial number!", -65535);
/* 00007726: 0027 */    // -- Start Return Code -- //
/* 0000772A: 0023 */    return 1;
//繼續校驗:
//[00]
//[01] [02] [03] [04] [05] [06] [07] [08] [09] [10] [11] [12] [13] [14] [15] [16]
//[17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [31] [32]
//[33] [34] [35] [36] [37] [38] [39] [40] [41] [42] [43] [44] [45] [46] [47] [48]
//[49] [50] [51]
//
//[31]進行變換(字元0 - 9 -> 數字0 - 9,字元A - F -> 數字10 - 15,字元G - Z ->其ASCII值)
//結果 *16
//與
//[32]進行變換(字元0 - 9 -> 數字0 - 9,字元A - F -> 數字10 - 15,字元G - Z ->其ASCII值)
//結果 按位或
//最低位必須為1
//
//下面的校驗已轉為明文,即MAC字串為最後生成的52位字串的前12位,詳見序號產生器程式

// : Jump Referenced(1):
// :  000076F6,
label_105:
/* 00007735: 0021 */    function_347(g_number33, s1);
/* 00007741: 0006 */    n6 = LAST_RESULT;

// : Jump Referenced(1):
// :  0000786B,
label_106:
/* 0000774D: 0001 */    // -- While -- //
/* 00007751: 000D */    n7 = n6 == 0;
/* 00007760: 0004 */    if(! n7) goto label_111;
/* 0000776C: 0006 */    n0 = 0;
/* 00007778: 0006 */    n5 = 1;

// : Jump Referenced(1):
// :  00007820,
label_107:
/* 00007786: 0001 */    // -- While -- //
/* 0000778A: 000D */    n7 = n5 == 1;
/* 00007799: 0009 */    n8 = n0 < 12;
/* 000077A8: 0019 */    n7 = n7 && n8;
/* 000077B5: 0004 */    if(! n7) goto label_109;
/* 000077C1: 0007 */    n7 = n0 + 2;
/* 000077D0: 001E */    n7 = s2[n7];
/* 000077DD: 001E */    n8 = s1[n0];
/* 000077EA: 000E */    n7 = n7 != n8;
/* 000077F7: 0004 */    if(! n7) goto label_108;
/* 00007803: 0006 */    n5 = 0;

// : Jump Referenced(1):
// :  000077F7,
label_108:
/* 00007811: 0007 */    n0 = n0 + 1;
/* 00007820: 0005 */    goto label_107;

// : Jump Referenced(1):
// :  000077B5,
label_109:
/* 0000782B: 000D */    n7 = n5 == 1;
/* 0000783A: 0004 */    if(! n7) goto label_110;
/* 00007846: 0027 */    // -- Start Return Code -- //
/* 0000784A: 0023 */    return 0;

// : Jump Referenced(1):
// :  0000783A,
label_110:
/* 00007855: 0021 */    function_349(g_number33, s1);
/* 00007861: 0006 */    n6 = LAST_RESULT;
/* 0000786B: 0005 */    goto label_106;

// : Jump Referenced(1):
// :  00007760,
label_111:
/* 00007876: 000D */    n7 = n5 == 0;
/* 00007885: 0004 */    if(! n7) goto label_112;
/* 00007891: 0021 */    function_304("Invalid Serial Number!", -65535);
/* 000078B5: 0027 */    // -- Start Return Code -- //
/* 000078B9: 0023 */    return 1;

// : Jump Referenced(1):
// :  00007885,
label_112:
/* 000078C4: 0027 */    // -- Start Return Code -- //
/* 000078C8: 0023 */    return 0;
end;
/////////////////////////////////////////////////////////////////////
//
//  第二部分:序列號生成器
//
//  為了便於初學者學習,全部使用陣列,只需有一點C的基礎...:-)
//
//  另:MACINFO.TXT可執行TEST_001.EXE獲得
//
/////////////////////////////////////////////////////////////////////
/*-------------------------------------------------------------*/
/*                        某某研究所                          */
/*                                                            */
/*                  版權所有(C) 19xx - 2001                    */
/*-------------------------------------------------------------*/
/*                  實時作業系統 - 輔助程式                    */
/*                                                            */
/*              REAL TIME OPERATING SYSTEM (RTOS)              */
/*-------------------------------------------------------------*/
/*                                                            */
/*-------------------------------------------------------------*/
/*              檔名    :    KeyGen.C                    */
/*                描述    :    Lambda Pro v2.0安裝序列號    */
/*                                生成器。                    */
/*            建立日期    :    2001-08-13                  */
/*        最後修改日期    :    2001-08-13                  */
/*              編制人    :    FiNALSErAPH                  */
/*-------------------------------------------------------------*/
/*                                                            */
/*-------------------------------------------------------------*/
/*  修改號  日期        修改人    修改描述                  */
/*-------------------------------------------------------------*/
/*  初始版本 2001-08-13    HZH      這是整理後的改寫版新增    */
/*                                  了註釋,比較易懂          */
/*-------------------------------------------------------------*/
/*  標頭檔案段                                                  */
/*-------------------------------------------------------------*/
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <process.h>
#include <dos.h>
#include <time.h>
/*-------------------------------------------------------------*/
/*  資料定義段                                                */
/*-------------------------------------------------------------*/
FILE *InMacInfo;
FILE *OutSerial;

int iCount = 0;
int iTemp = 0;

char cTable0[36] = {'A','B','C','D','E','F','G','H','I','J','K','L',
            'M','N','O','P','Q','R','S','T','U','V','W','X',
            'Y','Z','0','1','2','3','4','5','6','7','8','9'};
char cTable1[36] = {'Y','W','9','K','V','8','I','U','7','M','T','6',
            'D','S','5','N','Q','4','A','P','3','L','J','2',
            'E','H','1','R','G','0','O','F','Z','C','B','X'};
char cTable2[36] = {'I','R','6','U','Q','5','G','P','4','M','O','3',
            'Y','N','2','S','K','1','A','J','0','T','H','Z',
            'L','F','X','9','E','C','W','8','D','B','V','7'};
char cTarget[36];
/*-------------------------------------------------------------*/
/*  內部函式呼叫宣告段                                        */
/*-------------------------------------------------------------*/
void vCopyRightMsg(void);
void vKeyGenerate(void);
void vWaitFor(void);
char cCharToNum(char cInput);
char cNumToChar(char cInput);
int iCheckLocation(char cInput);
/*-------------------------------------------------------------*/
/*  程式碼段                                                    */
/*-------------------------------------------------------------*/
void main(void)
{
  vCopyRightMsg();
  vWaitFor();
  vKeyGenerate();
}

void vCopyRightMsg(void)
{
  printf("+----------------------------------------+\n");
  printf("|  LambdaPro v2.0-MAC-Limit-DEMO-0724  |\n");
  printf("|      Install Key Generator v1.0.1      |\n");
  printf("|        =- Proudly  Present -=        |\n");
  printf("|              2001-08-14              |\n");
  printf("|              FiNAL SErAPH              |\n");
  printf("+----------------------------------------+\n");
  printf("\n");
}

void vKeyGenerate()
{
//安裝序列號生成演算法 - 開始

  //從MACINFO.TXT中提取資訊
  if((InMacInfo = fopen("MACINFO.TXT","r")) == NULL)
  {
      printf("Can't Open \"MACINFO.TXT\"!\n");
      exit(0);
  }

  char cMacInfo[12];
  fgets(cMacInfo,13,InMacInfo);
  fclose(InMacInfo);

  //字元轉為數字
  for(iCount = 0;iCount < 12;iCount++)
  {
      cMacInfo[iCount] = cCharToNum(cMacInfo[iCount]);
  }

  //隨機生成長度為52的數字串
  char cOutSerial[52];
  srand(time(NULL));
  iCount = 0;
  while(iCount < 52)
  {
      cOutSerial[iCount] = rand()%16;
      iCount++;
  }

  //將網路卡MAC地址插入長度為52的數字串中
  for(iCount = 0;iCount < 12;iCount++)
  {
      cOutSerial[iCount + 2] = cMacInfo[iCount];
  }

  //使長度為52的數字串滿足兩種校驗條件
  //1 - 控制[29]在 2 - 9之間
  iTemp = rand()%10;
  if(iTemp < 2)
  {
      iTemp = 9 - iTemp;
  }
  cOutSerial[29] = iTemp;
  //2
  cOutSerial[31] = 0;
  cOutSerial[32] = 1;

  //調整長度為52的數字串中48位的順序
  char cTemp[9];
  for(iCount = 0;iCount < 9;iCount++)
  {
      cTemp[iCount]= cOutSerial[iCount+1];
  }
  for(iCount = 1;iCount < 40;iCount++)
  {
      cOutSerial[iCount] = cOutSerial[iCount+9];
  }
  for(iCount = 0;iCount < 9;iCount++)
  {
      cOutSerial[iCount+40] = cTemp[iCount];
  }

  //調整3個校驗位
  //1
  iTemp = cOutSerial[1];
  for(iCount = 2;iCount < 17;iCount++)
  {
      iTemp = iTemp ^ cOutSerial[iCount];
  }
  cOutSerial[49] = iTemp;
  //2
  iTemp = cOutSerial[17];
  for(iCount = 18;iCount < 33;iCount++)
  {
      iTemp = iTemp ^ cOutSerial[iCount];
  }
  cOutSerial[50] = iTemp;
  //3
  iTemp = cOutSerial[33];
  for(iCount = 34;iCount < 49;iCount++)
  {
      iTemp = iTemp ^ cOutSerial[iCount];
  }
  cOutSerial[51] = iTemp;

  //將長度為52的數字串轉為字串
  for(iCount = 0;iCount < 52;iCount++)
  {
      cOutSerial[iCount] = cNumToChar(cOutSerial[iCount]);
  }

  //根據字元替換表生成最終序列號,輸出結果到螢幕
  if((cOutSerial[0] >= '0') && (cOutSerial[0] <= '4'))
  {
      for(iCount = 0;iCount < 36;iCount++)
      {
        cTarget[iCount] = cTable1[iCount];
      }
  }
  else
  {
      for(iCount = 0;iCount < 36;iCount++)
      {
        cTarget[iCount] = cTable2[iCount];
      }
  }

  printf("Your Install Key:\n\n");
  printf("%c",cOutSerial[0]);
  for(iCount = 1;iCount < 52;iCount++)
  {
      cOutSerial[iCount] = cTarget[iCheckLocation(cOutSerial[iCount])];
      printf("%c",cOutSerial[iCount]);
  }

  //輸出結果到檔案
  if((OutSerial = fopen("SERIAL.TXT","w+")) == NULL)
  {
      printf("I Can't Create File \"SERIAL.TXT\" !!!\n");
      exit(0);
  }
  for(iCount = 0;iCount < 52;iCount++)
  {
      fputc(cOutSerial[iCount],OutSerial);
  }
  fclose(OutSerial);
//安裝序列號生成演算法 - 結束

}

void vWaitFor(void)
{
  delay(300);
  printf("Please wait");
  for(int i = 0;i < 6;i++)
  {
      printf(".");
      delay(400);
  }
  printf("\n\n");
}

char cCharToNum(char cInput)
{
  char cOutput;
  if((cInput >= '0') && (cInput <= '9'))
  {
      cOutput = cInput - 48;
  }
  if((cInput >= 'A') && (cInput <= 'F'))
  {
      cOutput = cInput - 55;
  }
  if((cInput >= 'a') && (cInput <= 'f'))
  {
      cOutput = cInput - 87;
  }
  return(cOutput);
}

char cNumToChar(char cInput)
{
  char cOutput;
  if((cInput >= 0) && (cInput <= 9))
  {
      cOutput = cInput + 48;
  }
  if((cInput >= 10) && (cInput <= 15))
  {
      cOutput = cInput + 55;
  }
  return(cOutput);
}

int iCheckLocation(char cInput)
{
  for(int i = 0;i < 36;i++)
  {
      if(cInput == cTable0[i])
      {
        return(i);
      }
  }
  return(-1);
}

相關文章