C3 encryption

Results 1 to 7 of 7
  1. #1
    Apprentice jotpeaka is offline
    MemberRank
    Dec 2013 Join Date
    PolandLocation
    17Posts

    C3 encryption

    Hello guys. I've writing some useless things and now I need encrypt c1 to c3 join to map packet. I use simple modulus from gs90 and decrypt works good but encrypt not :-( I've been created two instances for decrypt and for encrypt, use dec1.dat and enc2.dat, as example I use gs90 encrypt function.

    Maybe someone could help me :-(
    Thanks.

    //Edit:
    Code:
    --- INPUT C1 to C3 ----
    0xC1 0x3B 0xF1 0x01 0xCD 0xFD 0x98 0xFC 0xCF 0xAB 0xFC 0xCF 0xAB 0xFC 0xCD 0xFD
    0x98 0xFC 0xCF 0xAB 0xFC 0xCF 0xAB 0xFC 0xCF 0xAB 0xFC 0xCF 0xAB 0xFC 0xCF 0xAB
    0xFC 0xCF 0xF7 0xC7 0x95 0x03 0x31 0x30 0x33 0x31 0x31 0x45 0x71 0x76 0x65 0x37
    0x4C 0x63 0x76 0x64 0x68 0x6B 0x33 0x52 0x79 0x73 0x71
    -------
    
    
    --- SHOULD BE C3 ----
    0xC3 0x5A 0x8B 0x78 0x24 0x48 0x2A 0xFB 0xF3 0xF0 0x2D 0xA6 0x93 0x93 0x3B 0x22
    0xE8 0x00 0x45 0xC3 0x9B 0x74 0xCB 0xFE 0x51 0x03 0x20 0x97 0x13 0x46 0x22 0xDD
    0x04 0xFB 0xCE 0x27 0x93 0x13 0x0A 0x59 0x22 0xF3 0xF3 0x74 0x66 0x53 0xAA 0x4C
    0x28 0x04 0xD4 0x17 0x93 0x37 0xE0 0x01 0x34 0x0A 0xDE 0x11 0xD2 0xD3 0x19 0x01
    0x17 0x18 0xA0 0x95 0x55 0xE2 0x60 0xAF 0x00 0xCD 0xD2 0x75 0x08 0xF8 0xCD 0xCB
    0x2D 0x05 0x7E 0x68 0x5F 0x51 0x08 0x0D 0x70 0x4F
    -------
    
    
    --- OUTPUT C3 ----
    0xC3 0x5A 0x7C 0x1B 0x08 0xFC 0x5C 0xF1 0xE1 0x93 0x14 0x9D 0xA8 0xED 0xFB 0x25
    0x40 0x9F 0x26 0x51 0x99 0x7E 0xAA 0x9F 0x22 0x36 0x1C 0xFC 0xDA 0xDF 0x92 0x1C
    0xDD 0xFE 0xCB 0xED 0xFB 0x03 0x6C 0x90 0x28 0x04 0x38 0x29 0x9A 0xAF 0x97 0x69
    0x57 0x9A 0xC6 0x5B 0x60 0x80 0x90 0x96 0xA3 0xAD 0x95 0x0E 0xA9 0x07 0xCB 0x27
    0x25 0x4D 0x91 0xA4 0x97 0xF8 0x30 0xE7 0x59 0x7F 0xE1 0xBE 0x26 0xA7 0x92 0xB1
    0xCB 0x01 0xE9 0x92 0x77 0x60 0xFC 0x92 0xC5 0xFA
    -------
    //Edit:
    My Encode:
    Code:
    this->SimpleModulusEnc.LoadEncryptionKey((char*)"data//Enc2.dat");
    int ret = this->SimpleModulusEnc.Encrypt(&byEnc[2], &buffer[1], size-1);
    byEnc[0] = 0xC3;
    byEnc[1] = ret+2;
    SimpleModulus.h:
    Code:
    #ifndef __SIMPLEMODULUS_H__
    #define __SIMPLEMODULUS_H__
    
    
    #pragma pack(1)
    struct ENCDEC_FILEHEADER
    {
        short sFileHeader;
        int dwSize;
    };
    typedef DWORD dwXORTable[4];
    #pragma pack()
    
    
    class CSimpleModulus
    {
    public:
        CSimpleModulus();
        virtual ~CSimpleModulus();
    
    
        void Init();
    
    
        DWORD m_dwModulus[4];
        DWORD m_dwEncryptionKey[4];
        DWORD m_dwDecryptionKey[4];
        DWORD m_dwXORKey[4];
    
    
    protected:
        static DWORD s_dwSaveLoadXOR[4];
    
    
    public:
        int Encrypt(void * lpDest, void * lpSource, int iSize);
        int Decrypt(void * lpDest, void * lpSource, int iSize);
    
    
    protected:
        int EncryptBlock(void*, void*, int);
        int DecryptBlock(void*, void*);
        int AddBits(void* lpDest, int iDestBitPos, void* lpSource, int iBitSourcePos, int iBitLen);
        void Shift(void* lpBuff, int iSize, int ShiftLen);
        int GetByteOfBit(int);
    
    
    public:
        BOOL SaveAllKey(LPSTR lpszFileName);
        BOOL LoadAllKey(LPSTR lpszFileName);
        BOOL SaveEncryptionKey(LPSTR lpszFileName);
        BOOL LoadEncryptionKey(LPSTR lpszFileName);
        BOOL SaveDecryptionKey(LPSTR lpszFileName);
        BOOL LoadDecryptionKey(LPSTR lpszFileName);
    
    
    protected:
        BOOL SaveKey(LPSTR lpszFileName, WORD wFileHeader, BOOL bSaveModulus, BOOL bSaveEncKey, BOOL bSaveDecKey, BOOL bSaveXORKey);
        BOOL LoadKey(LPSTR lpszFileName, WORD wFileHeader, BOOL bLoadModulus, BOOL bLoadEncKey, BOOL bLoadDecKey, BOOL bLoadXORKey);
    
    
    };
    
    
    #endif
    SimpleModulus.cpp:
    Code:
    // SimpleModulus.cpp : Defines the entry point for the application.
    //
    
    
    #include "StdAfx.h"
    #include "SimpleModulus.h"
    
    
    DWORD CSimpleModulus::s_dwSaveLoadXOR[4]={0x3F08A79B, 0xE25CC287, 0x93D27AB9, 0x20DEA7BF};
    
    
    CSimpleModulus::CSimpleModulus()
    { 
        this->Init(); 
    }
    
    
    CSimpleModulus::~CSimpleModulus()
    {
        return;
    }
    
    
    VOID CSimpleModulus::Init()
    {
        memset(this->m_dwEncryptionKey, 0, sizeof(this->m_dwEncryptionKey));
        memset(this->m_dwModulus, 0, sizeof(this->m_dwModulus));
        memset(this->m_dwDecryptionKey, 0, sizeof(this->m_dwDecryptionKey));
    } 
    
    
    int CSimpleModulus::Encrypt(void* lpDest, void* lpSource, int iSize)
    {
        int iTempSize = iSize;
        int iTempSize2;
        int iOriSize ;
        unsigned char* lpTempDest = (LPBYTE)lpDest;
        unsigned char* lpTempSource = (LPBYTE)lpSource;
        
        int iDec = ((iSize+7)/8);
        iSize = (iDec + iDec*4)*2 + iDec;
    
    
        if (lpDest != NULL)
        {
            iOriSize = iTempSize;
    
    
            for (int i = 0; i < iTempSize; i += 8, iOriSize -= 8, lpTempDest +=11)
            {
                iTempSize2 = iOriSize;
                if (iOriSize >= 8)
                    iTempSize2 = 8;
    
    
                this->EncryptBlock(lpTempDest, lpTempSource+i, iTempSize2);
            }
        }
    
    
        return iSize;
    }
    
    
    int CSimpleModulus::Decrypt(void* lpDest, void* lpSource, int iSize)
    {
        if (lpDest == NULL)
        {
            return iSize*8/11;
        }
    
    
        LPBYTE lpTempDest = (LPBYTE)lpDest;
        LPBYTE lpTempSrc = (LPBYTE)lpSource;
    
    
        int iResult = 0;
        int iDecLen = 0;
    
    
        if ( iSize > 0 )
        {
            while ( iDecLen < iSize )
            {
                int iTempResult = this->DecryptBlock(lpTempDest, lpTempSrc);
    
    
                if ( iResult < 0 )
                {
                    return iResult;
                }
    
    
                iResult += iTempResult;
                iDecLen += 11;
                lpTempSrc += 11;
                lpTempDest += 8;
    
    
            }
        }
    
    
        return iResult;
    }
    
    
    
    
    
    
    int CSimpleModulus::EncryptBlock(void*lpDest,void*lpSource,int iSize)
    {
        DWORD dwEncBuffer[4];
        DWORD dwEncValue=0;    // TempVar1
    
    
        LPBYTE lpEncDest = (LPBYTE)lpDest;
        LPBYTE lpEncSource = (LPBYTE)lpSource;
    
    
        memset(lpEncDest, 0, 11);
    
    
        for ( int i=0;i<4;i++)
        {
            dwEncBuffer[i]=((this->m_dwXORKey[i]^((WORD*)lpEncSource)[i]^dwEncValue)*this->m_dwEncryptionKey[i])%this->m_dwModulus[i];
            dwEncValue=dwEncBuffer[i]&0xFFFF;
        }
    
    
        for (int i=0;i<3;i++)
        {
            dwEncBuffer[i] = dwEncBuffer[i] ^ this->m_dwXORKey[i] ^ ( dwEncBuffer[i+1] & 0xFFFF );
        }
    
    
        int iBitPos = 0;
    
    
        for (int i=0;i<4;i++)
        {
            iBitPos = this->AddBits(lpDest, iBitPos, &dwEncBuffer[i], 0, 16);
            iBitPos = this->AddBits(lpDest, iBitPos, &dwEncBuffer[i], 22, 2);
        }
    
    
        BYTE btCheckSum = 0xF8;
        
        for (int i=0;i<8;i++)
            btCheckSum ^= lpEncSource[i];
    
    
        ((LPBYTE)&dwEncValue)[1] = btCheckSum ; 
        ((LPBYTE)&dwEncValue)[0] = btCheckSum ^ iSize ^ 0x3D; 
    
    
        return this->AddBits(lpDest, iBitPos, &dwEncValue, 0, 16);
    }
    
    
    
    
    int CSimpleModulus::DecryptBlock(void*lpDest,void*lpSource)
    {
        memset(lpDest, 0, 8);
        DWORD dwDecBuffer[4]= {0};
        int iBitPosition = 0;
    
    
        LPBYTE lpDecDest = (LPBYTE)lpDest;
        LPBYTE lpDecSource = (LPBYTE)lpSource;
    
    
        for(int i=0;i<4;i++)
        {
            this->AddBits(&dwDecBuffer[i], 0, lpDecSource, iBitPosition, 16);
            iBitPosition += 16;
            this->AddBits(&dwDecBuffer[i], 22, lpDecSource, iBitPosition, 2);
            iBitPosition += 2;
        }
    
    
        for(int i=2;i>=0;i--)
        {
            dwDecBuffer[i] = dwDecBuffer[i] ^ this->m_dwXORKey[i] ^ (dwDecBuffer[i+1]&0xFFFF);
        }
    
    
        DWORD Temp=0,Temp1;
    
    
        for(int i=0;i<4;i++)
        {
            Temp1 = (( this->m_dwDecryptionKey[i] * (dwDecBuffer[i])) % ( this->m_dwModulus[i])) ^ this->m_dwXORKey[i]^Temp;
            Temp = dwDecBuffer[i]&0xFFFF;
            ((WORD*)lpDecDest)[i] = (WORD)(Temp1);
        }
    
    
        dwDecBuffer[0]=0;
        this->AddBits(&dwDecBuffer[0], 0, lpDecSource, iBitPosition, 16);
        ((LPBYTE)dwDecBuffer)[0]=((LPBYTE)dwDecBuffer)[1]^ ((LPBYTE)dwDecBuffer)[0]^0x3D;
    
    
        BYTE btCheckSum=0xF8;
    
    
        for(int i=0;i<8;i++)
            btCheckSum ^= lpDecDest[i];
    
    
        if( btCheckSum != ((LPBYTE)dwDecBuffer)[1] )
            return -1;
        
        return ((LPBYTE)dwDecBuffer)[0];
    }
    
    
    
    
    int CSimpleModulus::AddBits(void*lpDest,int iDestBitPos,void*lpSource,int iBitSourcePos,int iBitLen)    // Completed Emulated
    {
        // Get Buffer Lens
        int iSourceBufferBitLen = iBitLen + iBitSourcePos ;
        int iTempBufferLen = this->GetByteOfBit(iSourceBufferBitLen-1);
        iTempBufferLen += 1 - this->GetByteOfBit(iBitSourcePos);
    
    
        // Copy the Source Buffer
        unsigned char * pTempBuffer = new unsigned char[iTempBufferLen+1];
        memset(pTempBuffer, 0, iTempBufferLen+1);
        memcpy(pTempBuffer, (unsigned char *)lpSource+ this->GetByteOfBit(iBitSourcePos), iTempBufferLen);
    
    
        // Save the Last ibt if exist
        if ( (iSourceBufferBitLen%8 ) != 0 )
        {
            pTempBuffer[iTempBufferLen - 1] &= 255 << (8 - (iSourceBufferBitLen%8));
        }
    
    
        // Get the Values to Shift
        int iShiftLeft = (iBitSourcePos%8);
        int iShiftRight = (iDestBitPos%8);
    
    
        // Shift the Values to Add the right space of the desired bits
        this->Shift(pTempBuffer, iTempBufferLen, -iShiftLeft);
        this->Shift(pTempBuffer, iTempBufferLen+1, iShiftRight);
    
    
        // Copy the the bits of Source to the Dest
        int iNewTempBufferLen = (( iShiftRight <= iShiftLeft )?0:1) + iTempBufferLen;
        unsigned char * TempDist = (unsigned char *)lpDest + this->GetByteOfBit(iDestBitPos);
    
    
        for ( int i=0;i<iNewTempBufferLen;i++)
        {
            TempDist[i] |= pTempBuffer[i];
        }
    
    
        // Delete the temp Buffer
        delete [] pTempBuffer;
    
    
        // Return the number of bits of the new Dest Buffer
        return iDestBitPos + iBitLen;
    }
    
    
    
    
    
    
    VOID CSimpleModulus::Shift(void*lpBuff,int iSize,int ShiftLen) // Need To be Checked
    {
        unsigned char * TempBuff = (unsigned char *)lpBuff;
    
    
        // Case no Shift Len
        if ( ShiftLen != 0  )    
        {
            // Shift Right
            if ( ShiftLen > 0 )
            {
                if ( (iSize -1 ) > 0 )
                {
                    for ( int i=(iSize-1); i>0 ; i--)
                    {
                        TempBuff[i] = (TempBuff[i-1]<<((8 - ShiftLen))) | (TempBuff[i]>>ShiftLen );
                    }
                }
    
    
                TempBuff[0] >>=  ShiftLen;
            }
            else    // Shift Left
            {
                ShiftLen = - ShiftLen;
    
    
                if ( (iSize-1) > 0 )
                {
                    for ( int i=0; i<(iSize-1) ;i++)
                    {
                        TempBuff[i] = (TempBuff[i+1]>>((8 - ShiftLen))) | (TempBuff[i]<<ShiftLen );
                    }
                }
    
    
                TempBuff[iSize-1] <<= ShiftLen;
            }
        }
    }
    
    
    int CSimpleModulus::GetByteOfBit(int btByte)
    {
        return btByte >> 3;
    }
    
    
    BOOL CSimpleModulus::SaveAllKey(LPSTR lpszFileName )
    {
        return this->SaveKey(lpszFileName, 4370, TRUE, TRUE, TRUE, TRUE);
    }
    
    
    BOOL CSimpleModulus::LoadAllKey(LPSTR lpszFileName)
    {
        return this->LoadKey(lpszFileName, 4370, TRUE, TRUE, TRUE, TRUE);
    }
    
    
    BOOL CSimpleModulus::SaveEncryptionKey(LPSTR lpszFileName)
    {
        return this->SaveKey(lpszFileName, 4370, TRUE, TRUE, FALSE, TRUE);
    }
    
    
    
    
    BOOL CSimpleModulus::LoadEncryptionKey(LPSTR lpszFileName)
    {
        return this->LoadKey(lpszFileName, 4370, TRUE, TRUE, FALSE ,TRUE);
    }
    
    
    BOOL CSimpleModulus::SaveDecryptionKey(LPSTR lpszFileName)
    {
        return this->SaveKey(lpszFileName, 4370, TRUE, FALSE, TRUE, TRUE);
    }
    
    
    
    
    BOOL CSimpleModulus::LoadDecryptionKey(LPSTR lpszFileName)
    {
        return this->LoadKey(lpszFileName, 4370, TRUE, FALSE ,TRUE ,TRUE);
    }
    
    
    
    
    BOOL CSimpleModulus::SaveKey(LPSTR lpszFileName, WORD wFileHeader, BOOL bSaveModulus, BOOL bSaveEncKey, BOOL bSaveDecKey, BOOL bSaveXORKey)
    {
        // MAde by Deathway
        ENCDEC_FILEHEADER HeaderBuffer;
        int iSize;
        DWORD XORTable[4];
        HANDLE hFile = CreateFile(lpszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0x80, NULL);
    
    
        if ( hFile == INVALID_HANDLE_VALUE )
        {
            return FALSE;
        }
    
    
        HeaderBuffer.sFileHeader = wFileHeader;
        HeaderBuffer.dwSize = ( bSaveModulus + bSaveEncKey + bSaveDecKey + bSaveXORKey ) * sizeof(XORTable) + sizeof(ENCDEC_FILEHEADER);
    
    
        WriteFile( hFile, &HeaderBuffer, sizeof(ENCDEC_FILEHEADER), (ULONG*)&iSize, NULL);
    
    
        if ( bSaveModulus != FALSE )
        {
            for ( int n = 0 ; n < 4 ; n++ )
            {
                XORTable[n] = this->m_dwModulus[n] ^ s_dwSaveLoadXOR[n];
            }
            WriteFile(hFile, &XORTable, sizeof(XORTable), (ULONG*)&iSize, NULL);
        }
    
    
        if ( bSaveEncKey != FALSE )
        {
            for ( int n = 0 ; n < 4 ; n++ )
            {
                XORTable[n] = this->m_dwEncryptionKey[n] ^ s_dwSaveLoadXOR[n];
            }
            WriteFile(hFile, &XORTable, sizeof(XORTable), (ULONG*)&iSize, NULL);
        }
    
    
        if ( bSaveDecKey != FALSE )
        {
            for ( int n = 0 ; n < 4 ; n++ )
            {
                XORTable[n] = this->m_dwDecryptionKey[n] ^ s_dwSaveLoadXOR[n];
            }
            WriteFile(hFile, &XORTable, sizeof(XORTable), (ULONG*)&iSize, NULL);
        }
    
    
        if ( bSaveXORKey != FALSE )
        {
            for ( int n = 0 ; n < 4 ; n++ )
            {
                XORTable[n] = this->m_dwXORKey[n] ^ s_dwSaveLoadXOR[n];
            }
            WriteFile(hFile, &XORTable, sizeof(XORTable), (ULONG*)&iSize, NULL);
        }
    
    
        CloseHandle(hFile);
    
    
        return TRUE;
    }
    
    
    
    
    
    
    BOOL CSimpleModulus::LoadKey(LPSTR lpszFileName, WORD wFileHeader, BOOL bLoadModulus, BOOL bLoadEncKey, BOOL bLoadDecKey, BOOL bLoadXORKey)
    {
        ENCDEC_FILEHEADER HeaderBuffer;
        int iSize;
        DWORD XORTable[4];
        HANDLE hFile = CreateFile(lpszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0x80, NULL);
    
    
        if ( hFile != INVALID_HANDLE_VALUE )
        {
            ReadFile( hFile, &HeaderBuffer, sizeof(ENCDEC_FILEHEADER), (ULONG*)&iSize, NULL);
        }
    
    
        if ( HeaderBuffer.sFileHeader == wFileHeader  )
        {
            if ( (HeaderBuffer.dwSize) == (int)((( bLoadModulus + bLoadEncKey + bLoadDecKey + bLoadXORKey )*sizeof(XORTable))+sizeof(ENCDEC_FILEHEADER)) )
            {
                if ( bLoadModulus != FALSE )
                {
                    ReadFile(hFile, XORTable, sizeof(XORTable) , (ULONG*)&iSize, NULL);
                    for ( int n = 0 ; n<4;n++)
                    {
                        this->m_dwModulus[n] = s_dwSaveLoadXOR[n] ^ XORTable[n];
                    }
                }
                if ( bLoadEncKey != FALSE )
                {
                    ReadFile(hFile, XORTable, sizeof(XORTable) , (ULONG*)&iSize, NULL);
                    for ( int n = 0 ; n<4;n++)
                    {
                        this->m_dwEncryptionKey[n] = s_dwSaveLoadXOR[n] ^ XORTable[n];
                    }
                }
                if ( bLoadDecKey != FALSE )
                {
                    ReadFile(hFile, XORTable, sizeof(XORTable) , (ULONG*)&iSize, NULL);
                    for ( int n = 0 ; n<4;n++)
                    {
                        this->m_dwDecryptionKey[n] = s_dwSaveLoadXOR[n] ^ XORTable[n];
                    }
                }
                if ( bLoadXORKey != FALSE )
                {
                    ReadFile(hFile, XORTable,sizeof(XORTable) , (ULONG*)&iSize, NULL);
                    for ( int n = 0 ; n<4;n++)
                    {
                        this->m_dwXORKey[n] = s_dwSaveLoadXOR[n] ^ XORTable[n];
                    }
                }
    
    
                CloseHandle(hFile);
                return TRUE;
            }
        }
        else
        {
            CloseHandle(hFile);
        }
        return FALSE;
    }
    Last edited by jotpeaka; 22-12-13 at 09:19 AM.


  2. #2
    Developer nevS is offline
    MemberRank
    Aug 2005 Join Date
    GermanyLocation
    534Posts

    Re: C3 encryption

    I didn't read your code completely, and I guess your packet is from client to server. Then your packet has to be encrypted by the 32-byte XOR-Key like a normal C1-Packet before applying SimpleModulus.
    So, this way:
    packet -> C1-Encryption -> C3-Encryption -> encrypted packet

  3. #3
    Apprentice jotpeaka is offline
    MemberRank
    Dec 2013 Join Date
    PolandLocation
    17Posts

    Re: C3 encryption

    Yeah, but GS90 have no method for encrypt c1. It's look like C1 not encrypted change header to C3 and use SimpleModulus.Encrypt()

  4. #4
    Kingdom of Shadows [RCZ]ShadowKing is offline
    MemberRank
    Jul 2007 Join Date
    1,644Posts

    Re: C3 encryption

    Look in spe.h file in gameserver and you'll find the xor encryption.

  5. #5
    Apprentice jotpeaka is offline
    MemberRank
    Dec 2013 Join Date
    PolandLocation
    17Posts

    Re: C3 encryption

    OK, I've add spe.h xor encrypt for this packet. I'm sending response for C1:size:F3:03(joining to map). This response is encrypted C3, but how I can confirm is this good encrypt etc? Client froozen on "Mu Continent Map"...

  6. #6
    Kingdom of Shadows [RCZ]ShadowKing is offline
    MemberRank
    Jul 2007 Join Date
    1,644Posts

    Re: C3 encryption

    Dump the packet in server and if you can read good values then it's good encryption else it isn't. The encryption process should be like this: first xor, second simple modulus. For errors in client you can check muerror.log file.

  7. #7
    Apprentice jotpeaka is offline
    MemberRank
    Dec 2013 Join Date
    PolandLocation
    17Posts

    Re: C3 encryption

    Dumping this packet give Simple Moduls error, but client read good =] Thanks bro!



Advertisement