public MapleStream(bool pOutbound, ushort pBuild, byte pLocale, byte[] pIV, byte pSubVersion) { mOutbound = pOutbound; Build = pBuild; Locale = pLocale; if (mOutbound) mAES = new MapleAES(Build, Locale, pIV, pSubVersion); else mAES = new MapleAES((ushort)(0xFFFF - Build), Locale, pIV, pSubVersion); if ((Locale == MapleLocale.TESPIA && Build == 40) || (Locale == MapleLocale.SOUTH_EAST_ASIA && Build == 15)) { // WvsBeta _transformMethod = TransformMethod.MAPLE_CRYPTO | TransformMethod.SHIFT_IV; _usesByteHeader = true; } else if (Locale == MapleLocale.KOREA_TEST && Build == 255) { // KMSB (Modified client) _transformMethod = TransformMethod.OLD_KMS_CRYPTO | TransformMethod.SHIFT_IV_OLD; _usesByteHeader = true; _usesOldHeader = true; } else if ( Locale == MapleLocale.TAIWAN || Locale == MapleLocale.CHINA || Locale == MapleLocale.TESPIA || Locale == MapleLocale.JAPAN || (Locale == MapleLocale.GLOBAL && (short)Build >= 149) || (Locale == MapleLocale.KOREA && Build >= 221) || (Locale == MapleLocale.SOUTH_EAST_ASIA && Build >= 144) || (Locale == MapleLocale.EUROPE && Build >= 115)) { // TWMS / CMS / CMST / JMS / GMS (>= 149) _transformMethod = TransformMethod.AES | TransformMethod.SHIFT_IV; } else if (Locale == MapleLocale.KOREA || Locale == MapleLocale.KOREA_TEST) { // KMS / KMST _transformMethod = TransformMethod.KMS_CRYPTO; } else { // All others lol _transformMethod = TransformMethod.AES | TransformMethod.MAPLE_CRYPTO | TransformMethod.SHIFT_IV; } Console.WriteLine("Using transform methods: {0}", _transformMethod); }
public MaplePacket Read(DateTime pTransmitted, bool bMaple2) { if (mCursor < _expectedDataSize) { return(null); } if (bMaple2) { if (DecodeSeqBase(IV) != Build) { //throw new Exception("Failed to confirm packet header"); Console.WriteLine("ERROR: Failed to confirm packet header!"); } } else { if (!mAES.ConfirmHeader(mBuffer, 0)) { throw new Exception("Failed to confirm packet header"); } } int headerLength = bMaple2 ? 6 : MapleAES.GetHeaderLength(mBuffer, mCursor, _usesOldHeader); _expectedDataSize = headerLength; if (mCursor < headerLength) { return(null); } int packetSize = MapleAES.GetPacketLength(mBuffer, mCursor, _usesOldHeader, bMaple2); _expectedDataSize = packetSize + headerLength; if (mCursor < (packetSize + headerLength)) { return(null); } byte[] packetBuffer = new byte[packetSize]; Buffer.BlockCopy(mBuffer, headerLength, packetBuffer, 0, packetSize); uint preDecodeIV; if (bMaple2) { preDecodeIV = IV; mCrypt.Decrypt(packetBuffer, packetSize, BlockIV, IV); ShiftIV(); } else { preDecodeIV = BitConverter.ToUInt32(mAES.mIV, 0); Decrypt(packetBuffer, _transformMethod); } var postDecodeIV = bMaple2 ? IV : BitConverter.ToUInt32(mAES.mIV, 0); mCursor -= _expectedDataSize; if (mCursor > 0) { Buffer.BlockCopy(mBuffer, _expectedDataSize, mBuffer, 0, mCursor); } ushort opcode; if (_usesByteHeader) { opcode = (ushort)(packetBuffer[0]); Buffer.BlockCopy(packetBuffer, 1, packetBuffer, 0, packetSize - 1); Array.Resize(ref packetBuffer, packetSize - 1); } else { opcode = (ushort)(packetBuffer[0] | (packetBuffer[1] << 8)); Buffer.BlockCopy(packetBuffer, 2, packetBuffer, 0, packetSize - 2); Array.Resize(ref packetBuffer, packetSize - 2); } _expectedDataSize = bMaple2 ? 6 : 4; Definition definition = Config.Instance.GetDefinition(Build, Locale, mOutbound, opcode); return(new MaplePacket(pTransmitted, mOutbound, Build, Locale, opcode, definition == null ? "" : definition.Name, packetBuffer, preDecodeIV, postDecodeIV)); }
public MaplePacket Read(DateTime pTransmitted) { if (mCursor < _expectedDataSize) { return(null); } if (!mAES.ConfirmHeader(mBuffer, 0)) { mCursor -= lastAddedLength; //return null; throw new Exception("Failed to confirm packet header"); } int headerLength = MapleAES.GetHeaderLength(mBuffer, mCursor, _usesOldHeader); _expectedDataSize = headerLength; if (mCursor < headerLength) { return(null); } int packetSize = MapleAES.GetPacketLength(mBuffer, mCursor, _usesOldHeader); _expectedDataSize = packetSize + headerLength; if (mCursor < (packetSize + headerLength)) { return(null); } byte[] packetBuffer = new byte[packetSize]; Buffer.BlockCopy(mBuffer, headerLength, packetBuffer, 0, packetSize); var preDecodeIV = BitConverter.ToUInt32(mAES.mIV, 0); Decrypt(packetBuffer, _transformMethod); var postDecodeIV = BitConverter.ToUInt32(mAES.mIV, 0); mCursor -= _expectedDataSize; if (mCursor > 0) { Buffer.BlockCopy(mBuffer, _expectedDataSize, mBuffer, 0, mCursor); } ushort opcode; if (_usesByteHeader) { opcode = (ushort)(packetBuffer[0]); Buffer.BlockCopy(packetBuffer, 1, packetBuffer, 0, packetSize - 1); Array.Resize(ref packetBuffer, packetSize - 1); } else { opcode = (ushort)(packetBuffer[0] | (packetBuffer[1] << 8)); Buffer.BlockCopy(packetBuffer, 2, packetBuffer, 0, packetSize - 2); Array.Resize(ref packetBuffer, packetSize - 2); } _expectedDataSize = 4; Definition definition = Config.Instance.GetDefinition(Build, Locale, mOutbound, opcode); return(new MaplePacket(pTransmitted, mOutbound, Build, Locale, opcode, definition == null ? "" : definition.Name, packetBuffer, preDecodeIV, postDecodeIV)); }
public MapleStream(bool pOutbound, ushort pBuild, byte pLocale, byte[] pIV, byte pSubVersion, bool bLoginSv) { mOutbound = pOutbound; mLoginSv = bLoginSv; Build = pBuild; Locale = pLocale; if (mOutbound) { mAES = new MapleAES(Build, Locale, pIV, pSubVersion); } else { mAES = new MapleAES((ushort)(0xFFFF - Build), Locale, pIV, pSubVersion); } if ((Locale == MapleLocale.TESPIA && Build == 40) || (Locale == MapleLocale.SOUTH_EAST_ASIA && Build == 15)) { // WvsBeta _transformMethod = TransformMethod.MAPLE_CRYPTO | TransformMethod.SHIFT_IV; _usesByteHeader = true; } else if (Locale == MapleLocale.KOREA_TEST && Build == 255) { // KMSB (Modified client) _transformMethod = TransformMethod.OLD_KMS_CRYPTO | TransformMethod.SHIFT_IV_OLD; _usesByteHeader = true; _usesOldHeader = true; } else if ( Locale == MapleLocale.TAIWAN || Locale == MapleLocale.CHINA || Locale == MapleLocale.TESPIA || Locale == MapleLocale.JAPAN || (Locale == MapleLocale.GLOBAL && (short)Build >= 149) || (Locale == MapleLocale.KOREA && Build >= 221) || (Locale == MapleLocale.SOUTH_EAST_ASIA && Build >= 144) || (Locale == MapleLocale.EUROPE && Build >= 115)) { // TWMS / CMS / CMST / JMS / GMS (>= 149) _transformMethod = TransformMethod.AES | TransformMethod.SHIFT_IV; // GMS (>= 186) if (Locale == MapleLocale.GLOBAL && Build >= 186) { _transformMethod |= TransformMethod.CIG; } } else if (Locale == MapleLocale.KOREA || Locale == MapleLocale.KOREA_TEST) { // KMS / KMST _transformMethod = TransformMethod.KMS_CRYPTO; } else { // All others lol _transformMethod = TransformMethod.AES | TransformMethod.MAPLE_CRYPTO | TransformMethod.SHIFT_IV; } Console.WriteLine("Using transform methods: {0}", _transformMethod); }
public MaplePacket Read(DateTime pTransmitted) { if (mCursor < _expectedDataSize) { return(null); } if (!mAES.ConfirmHeader(mBuffer, 0)) { throw new Exception("Failed to confirm packet header"); } int headerLength = MapleAES.GetHeaderLength(mBuffer, mCursor, _usesOldHeader); _expectedDataSize = headerLength; if (mCursor < headerLength) { return(null); } int packetSize = MapleAES.GetPacketLength(mBuffer, mCursor, _usesOldHeader); _expectedDataSize = packetSize + headerLength; if (mCursor < (packetSize + headerLength)) { return(null); } byte[] packetBuffer = new byte[packetSize]; Buffer.BlockCopy(mBuffer, headerLength, packetBuffer, 0, packetSize); var preDecodeIV = BitConverter.ToUInt32(mAES.mIV, 0); Decrypt(packetBuffer, _transformMethod); var postDecodeIV = BitConverter.ToUInt32(mAES.mIV, 0); mCursor -= _expectedDataSize; if (mCursor > 0) { Buffer.BlockCopy(mBuffer, _expectedDataSize, mBuffer, 0, mCursor); } ushort opcode; if (_usesByteHeader) { opcode = (ushort)(packetBuffer[0]); Buffer.BlockCopy(packetBuffer, 1, packetBuffer, 0, packetSize - 1); Array.Resize(ref packetBuffer, packetSize - 1); } else { opcode = (ushort)(packetBuffer[0] | (packetBuffer[1] << 8)); Buffer.BlockCopy(packetBuffer, 2, packetBuffer, 0, packetSize - 2); Array.Resize(ref packetBuffer, packetSize - 2); } _expectedDataSize = 4; Definition definition = null; // Detect OpcodeEncryption Packet if (packetBuffer.Length == (8 + 1 + short.MaxValue)) // 32776 { int blockSize = BitConverter.ToInt32(packetBuffer, 0); int bufferSize = BitConverter.ToInt32(packetBuffer, 4); if (blockSize == 4 && bufferSize == (1 + short.MaxValue)) { Console.WriteLine("Recv OpcodeEncryption Packet with Opcode:0x{0:X} | BlockSize:{1} | BufferSize:{2}", opcode, blockSize, bufferSize); OpcodeEncryptedEventArgs recvOpcodeEventArgs = new OpcodeEncryptedEventArgs(); recvOpcodeEventArgs.OpcodeEncrypted = true; recvOpcodeEventArgs.EncryptedOpcodes = PopulateEncryptedOpcode(packetBuffer, bufferSize); OnRecvOpcodeEncryptPacket(recvOpcodeEventArgs); // Generate OpcodeEncryption packet { definition = Config.Instance.GetDefinition(Build, Locale, mOutbound, opcode); if (definition == null) { definition = new Definition(); definition.Outbound = mOutbound; definition.Locale = Locale; definition.Opcode = opcode; definition.Name = "Opcode Encryption"; definition.Build = Build; DefinitionsContainer.Instance.SaveDefinition(definition); } var filename = Helpers.GetScriptPath(Locale, Build, mOutbound, opcode); Helpers.MakeSureFileDirectoryExists(filename); // Create main script if (!File.Exists(filename)) { string contents = @" using (ScriptAPI) { AddInt(""Block Size""); AddInt(""Buffer Size""); AddByte(""Unknown""); AddField(""Buffer With Encrypted Opcodes"", 32767); } "; File.WriteAllText(filename, contents); } } } } // Get the real opcode if (OpcodeEncrypted && mOutbound && EncryptedOpcodes != null && EncryptedOpcodes.ContainsKey(opcode)) { opcode = EncryptedOpcodes[opcode].RealOp; } definition = Config.Instance.GetDefinition(Build, Locale, mOutbound, opcode); return(new MaplePacket(pTransmitted, mOutbound, Build, Locale, opcode, definition == null ? "" : definition.Name, packetBuffer, preDecodeIV, postDecodeIV)); }
public MapleStream(bool pOutbound, ushort pBuild, byte pLocale, byte[] pIV) { mOutbound = pOutbound; mAES = new MapleAES(pBuild, pLocale, pIV); }