Advertisement
Guest User

Untitled

a guest
Sep 23rd, 2016
403
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 17.19 KB | None | 0 0
  1. ///
  2. /// WoLfulus.com
  3. ///
  4.  
  5. using System;
  6. using System.IO;
  7. using System.Linq;
  8.  
  9.  
  10. namespace GameNetwork.Protocol
  11. {
  12.  
  13.     /// <summary>
  14.     /// Modulus
  15.     /// </summary>
  16.     class Modulus
  17.     {
  18.         /// <summary>
  19.         /// Constants
  20.         /// </summary>
  21.         const int KEYFILE_ALLKEY = 0x1111;
  22.         const int KEYFILE_ONEKEY = 0x1112;
  23.         const int ENCRYPTION_KEY_SIZE = 4;
  24.         const int ENCRYPTION_BLOCK_SIZE = 8;
  25.         const int ENCRYPTED_BLOCK_SIZE = 11;
  26.  
  27.         private static byte[] m_bXORKey = new byte[] {
  28.             0xE7, 0x6D, 0x3A, 0x89, 0xBC, 0xB2, 0x9F, 0x73, 0x23, 0xA8, 0xFE, 0xB6, 0x49, 0x5D, 0x39, 0x5D,
  29.             0x8A, 0xCB, 0x63, 0x8D, 0xEA, 0x7D, 0x2B, 0x5F, 0xC3, 0xB1, 0xE9, 0x83, 0x29, 0x51, 0xE8, 0x56
  30.         };
  31.  
  32.         /// <summary>
  33.         /// Variables
  34.         /// </summary>
  35.         private uint[] m_dwModulus = new uint[ENCRYPTION_KEY_SIZE] { 0, 0, 0, 0 };
  36.         private uint[] m_dwEncryptionKey = new uint[ENCRYPTION_KEY_SIZE] { 0, 0, 0, 0 };
  37.         private uint[] m_dwDecryptionKey = new uint[ENCRYPTION_KEY_SIZE] { 0, 0, 0, 0 };
  38.         private uint[] m_dwXORKey = new uint[ENCRYPTION_KEY_SIZE] { 0, 0, 0, 0 };
  39.  
  40.         /// <summary>
  41.         /// Embeded Keys
  42.         /// </summary>
  43.         ///
  44.         public static uint[,] ClientEncryptionKeys = new uint[,] {
  45.             { 23489, 11911, 19816, 13647 },
  46.             { 128079, 164742, 70235, 106898 },
  47.             { 48413, 46165, 15171, 37433 }
  48.         };
  49.  
  50.         public static uint[,] ClientDecryptionKeys = new uint[,] {
  51.             { 18035, 30340, 24701, 11141 },
  52.             { 73326, 109989, 98843, 171058 },
  53.             { 62004, 64409, 35374, 64599 }
  54.         };
  55.  
  56.         public static uint[,] ServerDecryptionKeys = new uint[,] {
  57.             { 31544, 2047, 57011, 10183 },
  58.             { 128079, 164742, 70235, 106898 },
  59.             { 48413, 46165, 15171, 37433 }
  60.         };
  61.  
  62.         public static uint[,] ServerEncryptionKeys = new uint[,] {
  63.             { 13169, 19036, 35482, 29587 },
  64.             { 73326, 109989, 98843, 171058 },
  65.             { 62004, 64409, 35374, 64599 }
  66.         };
  67.  
  68.         /// <summary>
  69.         /// Mask
  70.         /// </summary>
  71.         private static uint[] s_dwSaveLoadXOR = new uint[ENCRYPTION_KEY_SIZE] { 0x3F08A79B, 0xE25CC287, 0x93D27AB9, 0x20DEA7BF };
  72.  
  73.         /// <summary>
  74.         /// Encryption
  75.         /// </summary>
  76.  
  77.         public byte[] Encrypt(byte[] buffer)
  78.         {
  79.             int iTotalSize = ((buffer.Length + ENCRYPTION_BLOCK_SIZE - 1) / ENCRYPTION_BLOCK_SIZE) * ENCRYPTED_BLOCK_SIZE;
  80.             using (MemoryStream encrypted = new MemoryStream(iTotalSize))
  81.             {
  82.                 for (int i = 0; i < buffer.Length; i += ENCRYPTION_BLOCK_SIZE)
  83.                 {
  84.                     byte[] block = EncryptBlock(buffer.Skip(i).ToArray());
  85.                     encrypted.Write(block, 0, block.Length);
  86.                 }
  87.                 return encrypted.ToArray();
  88.             }
  89.         }
  90.  
  91.         private byte[] EncryptBlock(byte[] buffer)
  92.         {
  93.             int nSize = Math.Min(8, buffer.Length);
  94.  
  95.             uint[] dwEncBuffer = Enumerable.Repeat<uint>(0, ENCRYPTION_KEY_SIZE).ToArray();
  96.  
  97.             byte[] lpTarget = Enumerable.Repeat<byte>(0, ENCRYPTED_BLOCK_SIZE).ToArray();
  98.             byte[] lpSource = new byte[ENCRYPTION_BLOCK_SIZE];
  99.             Buffer.BlockCopy(buffer, 0, lpSource, 0, nSize);
  100.  
  101.             uint dwPrev = 0;
  102.  
  103.             int lpSrcOffset = 0;
  104.             for (int i = 0; i < ENCRYPTION_KEY_SIZE; i++, lpSrcOffset += 2)
  105.             {
  106.                 uint dwNext = BitConverter.ToUInt16(lpSource, lpSrcOffset);
  107.  
  108.                 dwEncBuffer[i] = ((dwNext ^ m_dwXORKey[i] ^ dwPrev) * m_dwEncryptionKey[i]) % m_dwModulus[i];
  109.                 dwPrev = dwEncBuffer[i] & 0xFFFF;
  110.             }
  111.  
  112.             dwPrev = dwEncBuffer[ENCRYPTION_KEY_SIZE - 1] & 0xFFFF;
  113.  
  114.             for (int i = 2; i >= 0; i--)
  115.             {
  116.                 uint dwSrc = dwEncBuffer[i] & 0xFFFF;
  117.                 dwEncBuffer[i] = dwEncBuffer[i] ^ m_dwXORKey[i] ^ dwPrev;
  118.                 dwPrev = dwSrc;
  119.             }
  120.  
  121.             int nTotalBits = 0;
  122.             for (int i = 0; i < ENCRYPTION_KEY_SIZE; i++)
  123.             {
  124.                 nTotalBits = AddBits(ref lpTarget, nTotalBits, KeysToBytes(dwEncBuffer, i), 0, 16);
  125.                 nTotalBits = AddBits(ref lpTarget, nTotalBits, KeysToBytes(dwEncBuffer, i), 22, 2);
  126.             }
  127.  
  128.             byte[] cCheckSum = new byte[2] { (byte)((nSize & 0xFF) ^ 0x3D), 0xF8 };
  129.             for (int i = 0; i < ENCRYPTION_BLOCK_SIZE; i++)
  130.             {
  131.                 cCheckSum[1] ^= lpSource[i];
  132.             }
  133.             cCheckSum[0] ^= cCheckSum[1];
  134.  
  135.             nTotalBits = AddBits(ref lpTarget, nTotalBits, cCheckSum, 0, 16);
  136.             return lpTarget;
  137.         }
  138.  
  139.         /// <summary>
  140.         /// Decryption
  141.         /// </summary>
  142.  
  143.         public byte[] Decrypt(byte[] buffer)
  144.         {
  145.             int iTotalSize = ((buffer.Length + ENCRYPTED_BLOCK_SIZE - 1) / ENCRYPTED_BLOCK_SIZE) * ENCRYPTION_BLOCK_SIZE;
  146.             using (MemoryStream decrypted = new MemoryStream(iTotalSize))
  147.             {
  148.                 for (int i = 0; i < buffer.Length; i += ENCRYPTED_BLOCK_SIZE)
  149.                 {
  150.                     var encryptedBlock = buffer.Skip(i).ToArray();
  151.                     byte[] block = DecryptBlock(encryptedBlock);
  152.                     if (block.Length == 0)
  153.                     {
  154.                         return block; // Error
  155.                     }
  156.                     decrypted.Write(block, 0, block.Length);
  157.                 }
  158.                 return decrypted.ToArray();
  159.             }
  160.         }
  161.  
  162.         private byte[] DecryptBlock(byte[] buffer)
  163.         {
  164.             //int nSize = Math.Min(8, buffer.Length);
  165.             uint[] dwDecBuffer = Enumerable.Repeat<uint>(0, ENCRYPTION_KEY_SIZE).ToArray();
  166.  
  167.             byte[] lpTarget = Enumerable.Repeat<byte>(0, ENCRYPTED_BLOCK_SIZE).ToArray();
  168.  
  169.             byte[] lpEncrypted = new byte[buffer.Length];
  170.             Buffer.BlockCopy(buffer, 0, lpEncrypted, 0, buffer.Length);
  171.  
  172.             int nTotalBits = 0;
  173.             for (int i = 0; i < ENCRYPTION_KEY_SIZE; i++)
  174.             {
  175.                 byte[] tempBuffer = new byte[4];
  176.                 AddBits(ref tempBuffer, 0, lpEncrypted, nTotalBits, 16);
  177.                 nTotalBits += 16;
  178.                 AddBits(ref tempBuffer, 22, lpEncrypted, nTotalBits, 2);
  179.                 nTotalBits += 2;
  180.                 dwDecBuffer[i] = BitConverter.ToUInt32(tempBuffer, 0);
  181.             }
  182.  
  183.             uint dwPrev = dwDecBuffer[ENCRYPTION_KEY_SIZE - 1] & 0xFFFF;
  184.             for (int i = 2; i >= 0; i--)
  185.             {
  186.                 dwDecBuffer[i] ^= m_dwXORKey[i];
  187.                 dwDecBuffer[i] ^= dwPrev;
  188.                 dwPrev = dwDecBuffer[i] & 0xFFFF;
  189.             }
  190.  
  191.             dwPrev = 0;
  192.             int offset = 0;
  193.             for (int i = 0; i < ENCRYPTION_KEY_SIZE; i++, offset += 2)
  194.             {
  195.                 uint dwResult = (dwDecBuffer[i] * m_dwDecryptionKey[i]) % m_dwModulus[i] ^ m_dwXORKey[i] ^ dwPrev;
  196.                 byte[] temp = BitConverter.GetBytes(dwResult);
  197.                 lpTarget[offset + 0] = temp[0];
  198.                 lpTarget[offset + 1] = temp[1];
  199.                 dwPrev = dwDecBuffer[i] & 0xFFFF;
  200.             }
  201.  
  202.             byte[] cCheckSum = { 0, 0 };
  203.  
  204.             AddBits(ref cCheckSum, 0, lpEncrypted, nTotalBits, 16);
  205.             nTotalBits += 16;
  206.  
  207.             cCheckSum[0] = (byte)((cCheckSum[1] ^ (cCheckSum[0] ^ 0x3D)) & 0xFF);
  208.  
  209.             byte cTempCheckSum = 0xF8;
  210.  
  211.             for (int i = 0; i < ENCRYPTION_BLOCK_SIZE; i++)
  212.             {
  213.                 cTempCheckSum ^= lpTarget[i];
  214.             }
  215.  
  216.             if (cCheckSum[1] != cTempCheckSum)
  217.             {
  218.                 return new byte[0];
  219.             }
  220.  
  221.             return lpTarget.Take(cCheckSum[0]).ToArray();
  222.         }
  223.  
  224.         /// <summary>
  225.         /// Helper functions
  226.         /// </summary>
  227.  
  228.         public int GetByteOfBit(int nBit)
  229.         {
  230.             return nBit >> 3;
  231.         }
  232.  
  233.         byte[] KeysToBytes(uint[] keys, int offset)
  234.         {
  235.             using (MemoryStream stream = new MemoryStream(keys.Length * sizeof(uint)))
  236.             {
  237.                 for (int i = offset; i < keys.Length; i++)
  238.                 {
  239.                     var bytes = BitConverter.GetBytes(keys[i]);
  240.                     stream.Write(bytes, 0, bytes.Length);
  241.                 }
  242.                 return stream.ToArray();
  243.             }
  244.         }
  245.  
  246.         private int AddBits(ref byte[] lpBuffer, int nNumBufferBits, byte[] lpBits, int nInitialBit, int nNumBits)
  247.         {
  248.             int nBufferSize = (GetByteOfBit((nNumBits + nInitialBit) - 1) - GetByteOfBit(nInitialBit)) + 1;
  249.  
  250.             byte[] lpTemp = Enumerable.Repeat<byte>(0, nBufferSize + 1).ToArray();
  251.             Buffer.BlockCopy(lpBits, GetByteOfBit(nInitialBit), lpTemp, 0, nBufferSize);
  252.  
  253.             int nLastBitMod8 = (nNumBits + nInitialBit) % ENCRYPTION_BLOCK_SIZE;
  254.             if (nLastBitMod8 != 0)
  255.             {
  256.                 lpTemp[nBufferSize - 1] &= (byte)(((nLastBitMod8 | 0xFF) << (ENCRYPTION_BLOCK_SIZE - nLastBitMod8)) & 0xFF);
  257.             }
  258.  
  259.             int nShiftLeft = (nInitialBit % ENCRYPTION_BLOCK_SIZE);
  260.             int nShiftRight = (nNumBufferBits % ENCRYPTION_BLOCK_SIZE);
  261.  
  262.             Shift(ref lpTemp, nBufferSize, -nShiftLeft);
  263.             Shift(ref lpTemp, nBufferSize + 1, nShiftRight);
  264.  
  265.             int nMax = ((nShiftRight <= nShiftLeft) ? 0 : 1) + nBufferSize;
  266.  
  267.             int offset = GetByteOfBit(nNumBufferBits);
  268.             for (int i = 0; i < nMax; i++)
  269.             {
  270.                 lpBuffer[i + offset] |= lpTemp[i];
  271.             }
  272.  
  273.             return nNumBufferBits + nNumBits;
  274.         }
  275.  
  276.         void Shift(ref byte[] lpBuffer, int nByte, int nShift)
  277.         {
  278.             if (nShift == 0)
  279.             {
  280.                 return;
  281.             }
  282.  
  283.             if (nShift > 0)
  284.             {
  285.                 int lpTemp = nByte - 1;
  286.                 for (int i = nByte - 1; i > 0; i--, lpTemp--)
  287.                 {
  288.                     lpBuffer[lpTemp] = (byte)(((lpBuffer[lpTemp - 1] << (ENCRYPTION_BLOCK_SIZE - nShift)) | (lpBuffer[lpTemp] >> nShift)) & 0xFF);
  289.                 }
  290.                 lpBuffer[lpTemp] = (byte)((lpBuffer[lpTemp] >> nShift) & 0xFF);
  291.             }
  292.             else
  293.             {
  294.                 int nRealShift = -nShift;
  295.  
  296.                 int lpTemp = 0;
  297.                 for (int i = 0; i < nByte - 1; i++, lpTemp++)
  298.                 {
  299.                     lpBuffer[lpTemp] = (byte)(((lpBuffer[lpTemp + 1] >> (ENCRYPTION_BLOCK_SIZE - nRealShift)) | (lpBuffer[lpTemp] << nRealShift)) & 0xFF);
  300.                 }
  301.                 lpBuffer[lpTemp] = (byte)((lpBuffer[lpTemp] << nRealShift) & 0xFF);
  302.             }
  303.         }
  304.  
  305.         /// <summary>
  306.         /// Keys
  307.         /// </summary>
  308.  
  309.         private int GetKeyFileSize(int x)
  310.         {
  311.             return (((x) * (sizeof(uint) * ENCRYPTION_KEY_SIZE)) + sizeof(uint) + sizeof(ushort));
  312.         }
  313.  
  314.         private bool LoadKey(string lpszFileName, ushort wFileHeader, bool bLoadModulus, bool bLoadEncKey, bool bLoadDecKey, bool bLoadXORKey)
  315.         {
  316.             //uint[] dwBuffer = new uint[ENCRYPTION_KEY_SIZE];
  317.             if (!File.Exists(lpszFileName))
  318.             {
  319.                 throw new FileNotFoundException("File doesn't exists.");
  320.             }
  321.  
  322.             var buffer = File.ReadAllBytes(lpszFileName);
  323.             var headerType = BitConverter.ToUInt16(buffer, 0);
  324.             var headerSize = BitConverter.ToUInt32(buffer, 2);
  325.  
  326.             //
  327.             // Make sure the Header it's fine.
  328.             //
  329.  
  330.             int keyFileSize = GetKeyFileSize(
  331.                 Convert.ToInt32(bLoadModulus) +
  332.                 Convert.ToInt32(bLoadEncKey) +
  333.                 Convert.ToInt32(bLoadDecKey) +
  334.                 Convert.ToInt32(bLoadXORKey)
  335.             );
  336.  
  337.             if (headerType != wFileHeader || headerSize != keyFileSize)
  338.             {
  339.                 throw new Exception("Key file header mismatch.");
  340.             }
  341.  
  342.             int offset = 6;
  343.  
  344.             if (bLoadModulus)
  345.             {
  346.                 for (int i = 0; i < ENCRYPTION_KEY_SIZE; i++)
  347.                 {
  348.                     m_dwModulus[i] = s_dwSaveLoadXOR[i] ^ BitConverter.ToUInt32(buffer, offset);
  349.                     offset += sizeof(uint);
  350.                 }
  351.             }
  352.  
  353.             if (bLoadEncKey)
  354.             {
  355.                 for (int i = 0; i < ENCRYPTION_KEY_SIZE; i++)
  356.                 {
  357.                     m_dwEncryptionKey[i] = s_dwSaveLoadXOR[i] ^ BitConverter.ToUInt32(buffer, offset);
  358.                     offset += sizeof(uint);
  359.                 }
  360.             }
  361.  
  362.             if (bLoadDecKey)
  363.             {
  364.                 for (int i = 0; i < ENCRYPTION_KEY_SIZE; i++)
  365.                 {
  366.                     m_dwDecryptionKey[i] = s_dwSaveLoadXOR[i] ^ BitConverter.ToUInt32(buffer, offset);
  367.                     offset += sizeof(uint);
  368.                 }
  369.             }
  370.  
  371.             if (bLoadXORKey)
  372.             {
  373.                 for (int i = 0; i < ENCRYPTION_KEY_SIZE; i++)
  374.                 {
  375.                     m_dwXORKey[i] = s_dwSaveLoadXOR[i] ^ BitConverter.ToUInt32(buffer, offset);
  376.                     offset += sizeof(uint);
  377.                 }
  378.             }
  379.  
  380.             return true;
  381.         }
  382.  
  383.         /// <summary>
  384.         /// Key setters
  385.         /// </summary>
  386.  
  387.         public bool SetEncryptionKey(uint[,] keys)
  388.         {
  389.             this.m_dwEncryptionKey[0] = keys[0, 0];
  390.             this.m_dwEncryptionKey[1] = keys[0, 1];
  391.             this.m_dwEncryptionKey[2] = keys[0, 2];
  392.             this.m_dwEncryptionKey[3] = keys[0, 3];
  393.  
  394.             this.m_dwDecryptionKey[0] = 0;
  395.             this.m_dwDecryptionKey[1] = 0;
  396.             this.m_dwDecryptionKey[2] = 0;
  397.             this.m_dwDecryptionKey[3] = 0;
  398.  
  399.             this.m_dwModulus[0] = keys[1, 0];
  400.             this.m_dwModulus[1] = keys[1, 1];
  401.             this.m_dwModulus[2] = keys[1, 2];
  402.             this.m_dwModulus[3] = keys[1, 3];
  403.  
  404.             this.m_dwXORKey[0] = keys[2, 0];
  405.             this.m_dwXORKey[1] = keys[2, 1];
  406.             this.m_dwXORKey[2] = keys[2, 2];
  407.             this.m_dwXORKey[3] = keys[2, 3];
  408.  
  409.             return true;
  410.         }
  411.  
  412.         public bool SetDecryptionKey(uint[,] keys)
  413.         {
  414.             this.m_dwEncryptionKey[0] = 0;
  415.             this.m_dwEncryptionKey[1] = 0;
  416.             this.m_dwEncryptionKey[2] = 0;
  417.             this.m_dwEncryptionKey[3] = 0;
  418.  
  419.             this.m_dwDecryptionKey[0] = keys[0, 0];
  420.             this.m_dwDecryptionKey[1] = keys[0, 1];
  421.             this.m_dwDecryptionKey[2] = keys[0, 2];
  422.             this.m_dwDecryptionKey[3] = keys[0, 3];
  423.  
  424.             this.m_dwModulus[0] = keys[1, 0];
  425.             this.m_dwModulus[1] = keys[1, 1];
  426.             this.m_dwModulus[2] = keys[1, 2];
  427.             this.m_dwModulus[3] = keys[1, 3];
  428.  
  429.             this.m_dwXORKey[0] = keys[2, 0];
  430.             this.m_dwXORKey[1] = keys[2, 1];
  431.             this.m_dwXORKey[2] = keys[2, 2];
  432.             this.m_dwXORKey[3] = keys[2, 3];
  433.  
  434.             return true;
  435.         }
  436.  
  437.         /// <summary>
  438.         /// Key loaders
  439.         /// </summary>
  440.  
  441.         public bool LoadEncryptionKey(string path)
  442.         {
  443.             return LoadKey(path, KEYFILE_ONEKEY, true, true, false, true);
  444.         }
  445.  
  446.         public bool LoadDecryptionKey(string path)
  447.         {
  448.             return LoadKey(path, KEYFILE_ONEKEY, true, false, true, true);
  449.         }
  450.  
  451.         ///
  452.         /// Simple
  453.         ///
  454.  
  455.         public static void XorEncode(ref byte[] buffer, int headerSize)
  456.         {
  457.             XorData(ref buffer, headerSize + 1, buffer.Length, 1);
  458.         }
  459.  
  460.         public static void XorDecode(ref byte[] buffer, int headerSize)
  461.         {
  462.             XorData(ref buffer, buffer.Length - 1, headerSize, -1);
  463.         }
  464.  
  465.         private static void XorData(ref byte[] buffer, int start, int end, int dir)
  466.         {
  467.             for (int i = start; i != end; i += dir)
  468.             {
  469.                 buffer[i] ^= (byte)(buffer[i - 1] ^ m_bXORKey[i % m_bXORKey.Length]);
  470.             }
  471.         }
  472.  
  473.         public static void XorEncodeInline(ref byte[] buffer, int headerSize)
  474.         {
  475.             var start = 1;
  476.             var length = buffer.Length - 1;
  477.             var pos = start;
  478.             for (int i = start; i < start + length; i++)
  479.             {
  480.                 buffer[pos] ^= (byte)(m_bXORKey[(pos + headerSize) % m_bXORKey.Length] ^ buffer[pos - 1]);
  481.                 pos++;
  482.             }
  483.         }
  484.  
  485.         public static void XorDecodeInline(ref byte[] buffer)
  486.         {
  487.             var k = buffer.Length;
  488.             for (int i = buffer.Length - 1; i >= 1; i--)
  489.             {
  490.                 buffer[i] ^= (byte)(m_bXORKey[k % m_bXORKey.Length] ^ buffer[i - 1]);
  491.                 k--;
  492.             }
  493.         }
  494.  
  495.         public static void Mask(ref byte[] buffer, int offset, int length)
  496.         {
  497.             int k = 0;
  498.             byte[] mask = new byte[] { 0xFC, 0xCF, 0xAB };
  499.             for (int i = offset; i < length; i++)
  500.             {
  501.                 buffer[i] = (byte)(buffer[i] ^ mask[k++ % mask.Length]);
  502.             }
  503.         }
  504.     }
  505. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement