[C++ / Delphi - Source] decrypt gameguard *.ini, *.cfg files

Results 1 to 2 of 2
  1. #1
    NN - Nord & Noob mauka is offline
    MemberRank
    Jul 2004 Join Date
    1,735Posts

    shout [C++ / Delphi - Source] decrypt gameguard *.ini, *.cfg files

    This example show how to decrypt config files of GameGuard
    eg: MuEng.ini, Mu.ini, Update.cfg etc.

    Code:
    unit Unit6;
    
    {
     C:\Program Files (x86)\WEBZEN\Mu\GameGuard\MuEng.ini
    
    [GAMEMON]
    GAME_NAME=MuEng
    UPDATE_SERVER=nprotect.muonline.webzen.net
    UPDATE_PATH=/GameGuard/MUGlobal/RealServer/
    BACKUP_SERVER=
    BACKUP_PATH=
    OPTION_VALUE=0
    SPEEDCHECK_INTERVAL=1000
    GAMECRC=1
    USE_GGSCAN=1
    SENDERRLOG=3
    LOG_SERVER=211.215.21.138
    LIMIT_TYAVPDOWN=10
    CHECK_GAMEBLOCK=1
    USB_EJECT=1
    
    
    C:\Program Files (x86)\WEBZEN\Mu\MuEngTest.ini
    [GAMEMON]
    GAME_NAME=MuEngTest
    UPDATE_SERVER=nprotect.muonline.webzen.net
    UPDATE_PATH=/GameGuard/MUGlobal/TestServer/
    BACKUP_SERVER=
    BACKUP_PATH=
    OPTION_VALUE=0
    SPEEDCHECK_INTERVAL=1000
    SENDERL=1
    GAMECRC=1
    USE_GGSCAN=1
    SENDERRLOG=3
    USE_PROXY=1
    REVISION=47
    LOG_SERVER=211.233.43.45
    
    
    C:\Games\MU1_08A+_Full\Mu.ini
    [GAMEMON]
    GAME_NAME=Mu
    UPDATE_SERVER=npro-mu.nefficient.co.kr
    UPDATE_PATH=/nProtect/GameGuard/MU/RealServer/
    BACKUP_SERVER=
    BACKUP_PATH=
    OPTION_VALUE=0
    SPEEDCHECK_INTERVAL=1000
    SENDERL=1
    GAMECRC=1
    SENDERRLOG=1
    USE_GGSCAN=1
    REVISION=47
    *)
    
    interface
    
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
      System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, wcrypt2;
    
    type
      TForm6 = class(TForm)
        Button1: TButton;
        Memo1: TMemo;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form6: TForm6;
    
    implementation
    
    {$R *.dfm}
    
    {
    Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F
    
    00000190                                  4D 75 2E 69 6E 69             Mu.ini
    000001A0   00 6E A1 09 59 E6 56 30  CE 02 65 3C 32 5E 44 FE    n YęV0Ī e<2^Dž
    000001B0   2F 67 47 8C FA A8 C8 BC  5F 1D 46 1D F4 A5 57 67   /gGŒśØČ¼_ F ōWg
    000001C0   AC 7E CB 7B 47 D4 64 F9  4D 26 5B C0 CD 92 D9 17   ¬~Ė{GŌdłM&[ĄĶ’Ł
    000001D0   AE E2 06 14 94 54 69 0A  9F 9E 30 AF A2 F4 B3 B2   ®ā  ”Ti Ÿ˛0Æ¢ō³²
    000001E0   68 22 26 81 32 07 00 00  00 40 00 00 00 21 26 81   h"& 2    @   !&
    000001F0   32                                                 2
    }
    
    procedure TForm6.Button1Click(Sender: TObject);
    type
      TGameGuard_Header = packed record
       FirstSignature: Cardinal;
       FileNameSize: Cardinal;
       SignatureSize: Cardinal;
       SecondSignature: Cardinal;
      end;
      PGameGuard_Header = ^TGameGuard_Header;
    
    const
     FPUBKEY: array [0 .. 83] of Byte = (
      $06, $02, $00, $00, $00, $24, $00, $00, $52, $53, $41, $31, $00, $02, $00,
      $00, $01, $00, $01, $00, $FB, $E3, $FC, $09, $AF, $AE, $65, $8C, $96, $4C,
      $C5, $37, $D2, $A4, $77, $E7, $4C, $41, $C2, $CF, $F2, $FE, $2D, $9C, $80,
      $94, $0C, $88, $6D, $B3, $84, $9F, $8C, $22, $A0, $C9, $CD, $C0, $AB, $30,
      $65, $82, $42, $3C, $EE, $3C, $A8, $B7, $11, $D6, $22, $FA, $FB, $23, $F7,
      $72, $CD, $E7, $D0, $6F, $6A, $8E, $96, $E3);
    
     KEY: array [0 .. 9] of Byte = ($65, $63, $74, $47, $61, $6D, $65, $4D, $6F, $6E);
    
    (*
        DataHdr: array[0 .. 89] of byte = (
      	$4D, $75, $45, $6E, $67, $2E, $69, $6E, $69, $00, // name
        $35, $3C, $05, $11, $01, $07, $24, $B5, $6A, $19, $B2, $A8, $38, $F6, $BD, $E3, // sig
        $21, $7A, $03, $20, $5B, $97, $72, $71, $1F, $36, $48, $B5, $E1, $CB, $9C, $01, // na
        $AA, $21, $DE, $CA, $B4, $6E, $D0, $DD, $53, $0B, $11, $A8, $67, $EC, $CD, $E4, // tu
        $8D, $BA, $E2, $23, $9C, $74, $E7, $33, $BF, $F6, $9D, $3A, $66, $BC, $1B, $D6, // re
    
        $22, $26, $81, $32,  //keyF
        $0A, $00, $00, $00,  //FileName - 10
        $40, $00, $00, $00,  //Signatures len - 64
        $21, $26, $81, $32   //KeyS
      );
    *)
    
     SIGNATURE1 = $32812622;
     SIGNATURE2 = $32812621;
    var
     Fs: TStream;
     Buffer: TBytes;
     Header: TGameGuard_Header;
    
     Len: DWORD;
     Signature: TBytes;
     i: Integer;
     Result: string;
    
     hProv: HCRYPTPROV;
     hHash: HCRYPTHASH;
     hKey: HCRYPTKEY;
    begin
     try
      Fs := TFileStream.Create('C:\Users\Ronaldo\Downloads\update(1).cfg', fmOpenRead);
       try
        SetLength(Buffer, Fs.Size);
        Fs.ReadBuffer(Buffer[0], Length(Buffer));
       finally
        Fs.Free;
       end;
     except
    
     end;
    
      Len := Length(Buffer);
      Len := Len - SizeOf(TGameGuard_Header);
      Header := PGameGuard_Header(@Buffer[Len])^;
      Len := Len - (Header.FileNameSize  + Header.SignatureSize);
    
    
    
      if not (SIGNATURE1 = Header.FirstSignature) or not (SIGNATURE2 = Header.SecondSignature) then
       MessageDlg('0', mtWarning, [mbOK], 0);
    
      SetLength(Signature, Header.SignatureSize);
      Move(Buffer[Len + Header.FileNameSize], Signature[0], Length(Signature));
    
     if not CryptAcquireContext(@hProv, nil, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) then
      MessageDlg('1', mtWarning, [mbOK], 0);
    
     if not CryptCreateHash(hProv, CALG_MD5, 0, 0, @hHash) then
      MessageDlg('2', mtWarning, [mbOK], 0);
    
     if not CryptImportKey(hProv, @FPUBKEY[0], SizeOf(FPUBKEY), 0, 0, @hKey) then
      MessageDlg('3', mtWarning, [mbOK], 0);
    
     if not CryptHashData(hHash, @Buffer[0], len + Header.FileNameSize, 0) then
      MessageDlg('4', mtWarning, [mbOK], 0);
    
     if not CryptVerifySignature(hHash, @Signature[0], Header.SignatureSize, hKey, nil, 0) then
      MessageDlg('5', mtWarning, [mbOK], 0);
    
     CryptDestroyKey(hKey);
     CryptDestroyHash(hHash);
    
     if not CryptCreateHash(hProv, CALG_MD5, 0, 0, @hHash) then
      MessageDlg('6', mtWarning, [mbOK], 0);
    
     if not CryptHashData(hHash, @KEY[0], SizeOf(KEY), 0) then
      MessageDlg('7', mtWarning, [mbOK], 0);
    
     if not CryptDeriveKey(hProv, CALG_RC4, hHash, 0, @hKey)  then
      MessageDlg('8', mtWarning, [mbOK], 0);
    
     if not CryptDecrypt(hKey, 0, True, 0, @Buffer[0], @Len) then
      MessageDlg('9', mtWarning, [mbOK], 0);
    
     CryptDestroyKey(hKey);
     CryptDestroyHash(hHash);
     CryptReleaseContext(hProv, 0);
    
     for i := 0 to Len -1  do
      Result := Result + Chr(Buffer[i]);
    
     Memo1.Clear;
     Memo1.Lines.Add(Result)
    end;
    
    end.
    Original code was in C++, i converted it to Delphi and share as it is ( i dont rember author of C++ code )

    Encryption uses Private key.. so i believe there is not posible to modify file and encrypt it back T_T

    C++
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/stat.h>
    #include <windows.h>
    #include <wincrypt.h>
    
    #include <winsock.h>
    
    #define VER     "0.1"
    #define KEY     "ectGameMon"
    #define SIGN1   0x32812622
    #define SIGN2   0x32812621
    #define PUBKEY  "\x06\x02\x00\x00\x00\x24\x00\x00\x52\x53\x41\x31\x00\x02\x00\x00" \
                    "\x01\x00\x01\x00\xFB\xE3\xFC\x09\xAF\xAE\x65\x8C\x96\x4C\xC5\x37" \
                    "\xD2\xA4\x77\xE7\x4C\x41\xC2\xCF\xF2\xFE\x2D\x9C\x80\x94\x0C\x88" \
                    "\x6D\xB3\x84\x9F\x8C\x22\xA0\xC9\xCD\xC0\xAB\x30\x65\x82\x42\x3C" \
                    "\xEE\x3C\xA8\xB7\x11\xD6\x22\xFA\xFB\x23\xF7\x72\xCD\xE7\xD0\x6F" \
                    "\x6A\x8E\x96\xE3"
    
    
    void std_err(int type);
    
    
    int main(int argc, char *argv[]) {
        FILE        *fd;
        struct stat xstat;
        HCRYPTPROV  hProv;
        HCRYPTHASH  hHash;
        HCRYPTKEY   hKey;
        DWORD       len;
        u_int      buffsz;
        u_char      *buff,
                    *input,
                    *output,
                    *filename,
                    *signature;
    
        struct gameguard_header {
            u_int  sign1;
            u_int  filename_size;
            u_int  signature_size;
            u_int  sign2;
        } *gh = NULL;
    
    
        setbuf(stdout, NULL);
    
        fputs("\n"
            "GameGuard files decrypter "VER"\n"
            "by Luigi Auriemma\n"
            "e-mail: aluigi@autistici.org\n"
            "web:    aluigi.org\n"
            "\n", stdout);
    
        if(argc < 3) {
            printf("\n"
                "Usage: %s <input_file> <output_file>\n"
                "\n", argv[0]);
            exit(1);
        }
    
        input  = argv[1];
        output = argv[2];
    
        printf("- open input file:     %s\n", input);
        fd = fopen(input, "rb");
        if(!fd) std_err(0);
    
        fstat(fileno(fd), &xstat);
        buffsz = xstat.st_size;
        printf("  filesize:            %u\n", buffsz);
    
        buff = malloc(buffsz);
        if(!buff) std_err(0);
        len = fread(buff, 1, buffsz, fd);
        fclose(fd);
    
        len -= sizeof(struct gameguard_header);
        gh = (struct gameguard_header *)(buff + len);
        len -= (gh->filename_size + gh->signature_size);
    
        if((gh->sign1 != SIGN1) ||
           (gh->sign2 != SIGN2)) {
            printf("\n"
                "Alert: the signs in the file don't match the default signs, I try to continue:\n"
                "       0x%08x (should be 0x%08x) and 0x%08x (should be 0x%08x)\n"
                "\n",
                gh->sign1, SIGN1,
                gh->sign2, SIGN2);
        }
    
        filename  = buff + len;
        printf("- built-in filename:   %s\n", filename);
        signature = buff + len + gh->filename_size;
    
        if(!CryptAcquireContext(
            &hProv,
            NULL,
            MS_DEF_PROV,
            PROV_RSA_FULL,
            CRYPT_VERIFYCONTEXT)) std_err(1);
    
                /* VERIFY SIGNATURE */
    
        fputs("- verify signature:", stdout);
    
        if(!CryptCreateHash(
            hProv,
            CALG_MD5,
            0,
            0,
            &hHash)) std_err(1);
    
        if(!CryptImportKey(
            hProv,
            PUBKEY,
            sizeof(PUBKEY) - 1,
            0,
            0,
            &hKey)) std_err(1);
    
        if(!CryptHashData(
            hHash,
            buff,
            len + gh->filename_size,
            0)) std_err(1);
    
        if(!CryptVerifySignature(
            hHash,
            signature,
            gh->signature_size,
            hKey,
            NULL,
            0)) {
            fputs("    WRONG!\n", stdout);
        } else {
            fputs("    OK\n", stdout);
        }
    
        CryptDestroyKey(hKey);
        CryptDestroyHash(hHash);
    
                /* DECRYPT DATA */
    
        if(!CryptCreateHash(
            hProv,
            CALG_MD5,
            0,
            0,
            &hHash)) std_err(1);
    
        if(!CryptHashData(
            hHash,
            KEY,
            sizeof(KEY) - 1,
            0)) std_err(1);
    
        if(!CryptDeriveKey(
            hProv,
            CALG_RC4,
            hHash,
            0,
            &hKey)) std_err(1);
    
        if(!CryptDecrypt(
            hKey,
            0,
            TRUE,
            0,
            buff,
            &len)) std_err(1);
    
        printf("- write output file:   %s\n", output);
        fd = fopen(output, "wb");
        if(!fd) std_err(0);
        fwrite(buff, len, 1, fd);
        fclose(fd);
    
        CryptDestroyKey(hKey);
        CryptDestroyHash(hHash);
        CryptReleaseContext(hProv, 0);
        free(buff);
        fputs("- Finished\n", stdout);
        return(0);
    }
    
    
    
    void std_err(int type) {
        if(type) {
            printf("\n"
                "Error: error during the usage of the cryptography (0x%lx)\n"
                "       If you received a sign error before means this is not a valid GameGuard\n"
                "       INI file\n"
                "\n", GetLastError());
        } else {
            perror("\nError");
        }
        exit(1);
    }


  2. #2
    Member DeathArmy is offline
    MemberRank
    Dec 2009 Join Date
    84Posts

    Re: [C++ / Delphi - Source] decrypt gameguard *.ini, *.cfg files

    long time ago I release something like this :D



Advertisement