風雲CM - 算法分析 & genkey實現

// 風雲CM分析

// 計算用戶名
00402D8A  |> \8D45 F8       LEA EAX, [LOCAL.2]
00402D8D  |.  50            PUSH EAX
00402D8E  |.  E8 8B060000   CALL <Hash_md5>                          ;  // md5(用戶名)
00402D93  |.  8945 F4       MOV [LOCAL.3], EAX
00402D96  |.  8B5D F8       MOV EBX, [LOCAL.2]
00402D99  |.  85DB          TEST EBX, EBX
00402D9B  |.  74 09         JE SHORT 00402DA6
00402D9D  |.  53            PUSH EBX
00402D9E  |.  E8 0C060100   CALL 004133AF
00402DA3  |.  83C4 04       ADD ESP, 0x4
00402DA6  |>  8B45 F4       MOV EAX, [LOCAL.3]				// 2cbd779a6d41d9715d259a5d7e8bb93d
00402DBE  |.  A3 67D04100   MOV DWORD PTR DS:[0x41D067], EAX	     ; // [0x41D067] = md5(用戶名)



00402E29  |.  A3 6BD04100   MOV DWORD PTR DS:[0x41D06B], EAX         ;  // md5(註冊碼)

// 到字節集(md5(user)) 轉換成字節集
00402E71  |.  A3 6FD04100   MOV DWORD PTR DS:[0x41D06F], EAX 

// 字節集到文本
00402E76  |.  68 6FD04100   PUSH 0041D06F
00402E7B  |.  E8 18070000   CALL 00403598                            ;  字節集到文本
00402E9B  |.  A3 73D04100   MOV DWORD PTR DS:[0x41D073], EAX
0018F6C0   002DCBA8  ASCII "3263626437373961366434316439373135643235396135643765386262393364" aEnCode

// 保存長度 64
00402EFD  |.  A3 77D04100   MOV DWORD PTR DS:[0x41D077], EAX

// left(aEnCode,0,5)
00402F51  |.  A3 7BD04100   MOV DWORD PTR DS:[0x41D07B], EAX

// left(aEnCode, 10, 5)
00402FB1  |.  A3 7FD04100   MOV DWORD PTR DS:[0x41D07F], EAX

// left(aEnCode, 20, 5)
00403011  |.  A3 83D04100   MOV DWORD PTR DS:[0x41D083], EAX

// left(aEnCode, 30, 5)
00403071  |.  A3 87D04100   MOV DWORD PTR DS:[0x41D087], EAX

// left(aEnCode, 40, 5)
004030D1  |.  A3 8BD04100   MOV DWORD PTR DS:[0x41D08B], EAX

// left(aEnCode, 50, 5)
00403131  |.  A3 8FD04100   MOV DWORD PTR DS:[0x41D08F], EAX

// 再次MD5
00403170  |.  50            PUSH EAX                                 ;  // left(aEnCode,0,5)
00403171  |.  E8 A8020000   CALL <Hash_md5>

// left(MD5(left(aEnCode, 0, 5)), 0 , 5)
004031BB  |.  8945 F4       MOV [LOCAL.3], EAX

// left(aEnCode, 0, 5)
00403202  |.  8945 F0       MOV [LOCAL.4], EAX

// md5(left(aEnCode, 0, 5))
00403209  |.  E8 10020000   CALL <Hash_md5>
0040320E  |.  8945 EC       MOV [LOCAL.5], EAX

// right(md5(left(aEnCode, 0, 5)),0, 5)
00403253  |.  8945 E8       MOV [LOCAL.6], EAX

// L7 = left(MD5(left(aEnCode, 0, 5)), 0 , 5) + right(md5(left(aEnCode, 0, 5)),0, 5)
00403266  |> \FF75 E8       PUSH [LOCAL.6]
00403269  |.  FF75 F4       PUSH [LOCAL.3]
0040326C  |.  B9 02000000   MOV ECX, 0x2
00403271  |.  E8 98F9FFFF   CALL 00402C0E                            ;  組合
00403279  |.  8945 E4       MOV [LOCAL.7], EAX

// left(L7,0, 6)
004032DA  |.  8945 E0       MOV [LOCAL.8], EAX

// upcase(left(L7, 0, 6);
00403313  |.  8945 DC       MOV [LOCAL.9], EAX
0040333E  |.  A3 93D04100   MOV DWORD PTR DS:[0x41D093], EAX


// 到了關鍵的地方了 下面就是關鍵跳
00403343  |.  E8 67050000   CALL 004038AF                            ;  // 關鍵的倆個函數 into
00403348  |.  E8 E0090000   CALL 00403D2D			     ; //比較eax = 1成功
0040334D  |.  8945 F8       MOV [LOCAL.2], EAX
00403350  |.  837D F8 01    CMP [LOCAL.2], 0x1
00403354  |.  0F85 4F000000 JNZ 004033A9
0040335A  |.  68 04000080   PUSH 0x80000004
0040335F  |.  6A 00         PUSH 0x0
00403361  |.  68 C1924100   PUSH 004192C1
00403366  |.  68 01030080   PUSH 0x80000301
0040336B  |.  6A 00         PUSH 0x0
0040336D  |.  68 00000000   PUSH 0x0
00403372  |.  68 04000080   PUSH 0x80000004
00403377  |.  6A 00         PUSH 0x0
00403379  |.  68 C6924100   PUSH 004192C6                            ;  ASCII "註冊成功!"
0040337E  |.  68 03000000   PUSH 0x3
00403383  |.  BB 00030000   MOV EBX, 0x300
00403388  |.  E8 630E0100   CALL 004141F0
0040338D  |.  83C4 28       ADD ESP, 0x28
00403390  |.  68 64000000   PUSH 0x64
00403395  |.  68 63D04100   PUSH 0041D063
0040339A  |.  8B0424        MOV EAX, DWORD PTR SS:[ESP]
0040339D  |.  8B00          MOV EAX, DWORD PTR DS:[EAX]
0040339F  |.  8B00          MOV EAX, DWORD PTR DS:[EAX]
004033A1  |.  FF50 14       CALL DWORD PTR DS:[EAX+0x14]
004033A4  |.  E9 36000000   JMP 004033DF

// 先進 0x004038AF

// UPcase(LEFT(MD5(left(aEnCode,0,5)),2,5))
// UPcase(LEFT(MD5(left(aEnCode, 10, 5),3,5))
// UPcase(LEFT(MD5(left(aEnCode, 20, 5),4,5))
// UPcase(LEFT(MD5(left(aEnCode, 30, 5),5,5))
// UPcase(LEFT(MD5(left(aEnCode, 40, 5),6,5))
// UPcase(LEFT(MD5(left(aEnCode, 50, 5),7,5))
0041D07B  002E0450  ASCII "8F717"
0041D07F  002E03A0  ASCII "1DE45"
0041D083  002E04A0  ASCII "2F035"
0041D087  002E03E0  ASCII "2ED7B"
0041D08B  002E0470  ASCII "46F03"
0041D08F  002E0630  ASCII "DB200"



004038B8  |.  68 7BD04100   PUSH 0041D07B
004038BD  |.  E8 5CFBFFFF   CALL <Hash_md5>
004038C2  |.  8945 FC       MOV [LOCAL.1], EAX
004038C5  |.  68 01030080   PUSH 0x80000301
004038CA  |.  6A 00         PUSH 0x0
004038CC  |.  68 05000000   PUSH 0x5
004038D1  |.  68 01030080   PUSH 0x80000301
004038D6  |.  6A 00         PUSH 0x0
004038D8  |.  68 02000000   PUSH 0x2
004038DD  |.  68 04000080   PUSH 0x80000004
004038E2  |.  6A 00         PUSH 0x0
004038E4  |.  8B45 FC       MOV EAX, [LOCAL.1]                       ;  風雲CM.0040333A
004038E7  |.  85C0          TEST EAX, EAX
004038E9  |.  75 05         JNZ SHORT 004038F0
004038EB  |.  B8 37924100   MOV EAX, 00419237
004038F0  |>  50            PUSH EAX
004038F1  |.  68 03000000   PUSH 0x3
004038F6  |.  BB 3C010000   MOV EBX, 0x13C
004038FB  |.  E8 90070100   CALL 00414090
00403900  |.  83C4 28       ADD ESP, 0x28
00403903  |.  8945 F8       MOV [LOCAL.2], EAX
00403934  |.  E8 37080100   CALL 00414170                            ;  upcase
0040393C  |.  8945 F4       MOV [LOCAL.3], EAX
00403967  |.  A3 7BD04100   MOV DWORD PTR DS:[0x41D07B], EAX


// 後面已經懶得分析了  剩下的就是比對了

  

註冊機實現:

#include <iostream>
#include <string>
#include "md5.h"

using namespace std;

const string& ToUpcase(string &Text){
    for(string::size_type i = 0; i < Text.length(); ++i)
        if(Text[i] >= 'a' && Text[i] <= 'z') Text[i] = Text[i] & ~0x20;
    return Text;
}

string MD5ToAscii(const string &Binary){
    string HexTable = "0123456789ABCDEF";
    string Ascii;
    for(string::size_type i = 0; i < Binary.size(); ++i){
        char n = Binary.at(i);
        while(n){
            Ascii.insert(i*2, 1,HexTable.at(n % 16));
            n /= 16;
        }
    }
    return Ascii;
}

int main()
{
    string name;
    cout << "Input User Name:";
    cin >> name;

    // 第二部分
    string strSn1 = MD5ToAscii(MD5(name).toString());
    string strSn2 = MD5(strSn1.substr(0,5)).toString().substr(0,5);
    string strSn3 = MD5(strSn1.substr(64 - 5,5)).toString().substr(32 - 5,5);
    string strSn4 = strSn2 + strSn3;
    strSn4 = strSn4.substr(3,6);
    ToUpcase(strSn4);  // 轉到大寫

    // 第一部分
    string strSn5 = MD5(strSn1.substr(0,5)).toString().substr(1,5);
    ToUpcase(strSn5);
    string strSn6 = MD5(strSn1.substr(9,5)).toString().substr(2,5);
    ToUpcase(strSn6);
    string strSn7 = MD5(strSn1.substr(19,5)).toString().substr(3,5);
    ToUpcase(strSn7);
    string strSn8 = MD5(strSn1.substr(29,5)).toString().substr(4,5);
    ToUpcase(strSn8);
    string strSn9 = MD5(strSn1.substr(39,5)).toString().substr(5,5);
    ToUpcase(strSn9);
    string strSn10 = MD5(strSn1.substr(49,5)).toString().substr(6,5);
    ToUpcase(strSn10);

    char regCode[100] = {0};

    sprintf(regCode, "64-%s-%s-%s-%s-%s-%s-%s", strSn5.c_str(), strSn6.c_str(), strSn7.c_str(),
                strSn8.c_str(), strSn9.c_str(), strSn10.c_str(), strSn4.c_str());
    cout << "Your RegCode:" << regCode << endl;
    return 0;
}

  

 

風雲CM分析+md5算法庫+Source(genkey)

http://pan.baidu.com/s/1ntzG4m1

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章