예제 #1
0
파일: CMFile.cs 프로젝트: minish0/GK6X
        public static byte[] Encrypt(byte[] fileData, CMFileType fileType)
        {
            using (MemoryStream stream = new MemoryStream())
                using (BinaryWriter writer = new BinaryWriter(stream))
                {
                    byte[] fileTypeStrBuffer = new byte[8];
                    Buffer.BlockCopy(fileTypes[fileType], 0, fileTypeStrBuffer, 0, fileTypes[fileType].Length);
                    string fileTypeStr   = Encoding.ASCII.GetString(fileTypeStrBuffer).TrimEnd('\0');
                    ushort encryptionKey = Crc16.GetCrc(Encoding.ASCII.GetBytes(fileTypeStr));
                    encryptionKey = Crc16.GetCrc(fileTypeStrBuffer, 0, encryptionKey);

                    byte[] encryptedData = new byte[fileData.Length];
                    Buffer.BlockCopy(fileData, 0, encryptedData, 0, fileData.Length);
                    ushort dataCrc = Encrypt(encryptedData, encryptionKey);

                    // Offset 0 (file signature)
                    writer.Write(fileSignature);

                    // Offset 4 (header crc - to be built after the header is fully formed)
                    writer.Write((int)0);

                    // Offset 8 (timestamp)
                    writer.Write(GetTimeStamp(DateTime.Now));

                    // Offset 12 (data length)
                    writer.Write(fileData.Length);

                    // Offset 16 (data crc)
                    writer.Write((int)dataCrc);

                    // Offset 20 (file type)
                    writer.Write((int)fileType);

                    // Offset 24-32 (file type string)
                    for (int i = 0; i < 8; i++)
                    {
                        writer.Write((byte)(i < fileTypeStrBuffer.Length ? fileTypeStrBuffer[i] : 0));
                    }

                    writer.Write(encryptedData);

                    // Get the header bytes, calculate the crc, and insert the crc into the header
                    long tempPos = stream.Position;
                    stream.Position = 0;
                    byte[] header = new byte[32];
                    stream.Read(header, 0, header.Length);
                    ushort headerCrc = Crc16.GetCrc(header);
                    stream.Position = 4;
                    writer.Write(headerCrc);
                    stream.Position = tempPos;

                    return(stream.ToArray());
                }
        }
예제 #2
0
파일: CMFile.cs 프로젝트: minish0/GK6X
        private static byte[] Decrypt(byte[] buffer, string file)
        {
            using (MemoryStream stream = new MemoryStream(buffer))
                using (BinaryReader reader = new BinaryReader(stream))
                {
                    if (reader.ReadUInt32() != fileSignature)
                    {
                        Log("Bad file signature", buffer, file);
                        return(null);
                    }

                    // Header crc is at offset 4, written as 4 bytes (but still a crc16)
                    // (this is a crc of the first 32 bytes (where the crc bytes are 0)
                    stream.Position = 4;
                    ushort headerCrc = reader.ReadUInt16();

                    // Timestamp is never used
                    // Timestamp is at offset 8, written as 4 bytes
                    // stream.Position = 8;
                    // int timestamp = reader.ReadInt32();

                    // Length is at offset 12, written as 4 bytes
                    stream.Position = 12;
                    int dataLength = reader.ReadInt32();

                    // Data crc is at offset 16, written as 4 bytes (but still a crc16)
                    stream.Position = 16;
                    ushort dataCrc = reader.ReadUInt16();

                    // File type is never used
                    // File type is at offset 20, written as 4 bytes
                    // stream.Position = 20;
                    // int fileType = reader.ReadInt32();

                    // File type (string) is at offset 24, written as 8 bytes, padded with 00
                    stream.Position = 24;
                    byte[] fileTypeStrBuffer = reader.ReadBytes(8);
                    uint   intFileType       = BitConverter.ToUInt32(fileTypeStrBuffer, 0);
                    if (unknownMaps.ContainsKey(intFileType))
                    {
                        byte[] newType = BitConverter.GetBytes(unknownMaps[intFileType]);
                        fileTypeStrBuffer = new byte[8];
                        Buffer.BlockCopy(newType, 0, fileTypeStrBuffer, 0, newType.Length);
                    }
                    List <byte> blob = new List <byte>();
                    for (int i = 0; i < fileTypeStrBuffer.Length; i++)
                    {
                        if (fileTypeStrBuffer[i] == 0)
                        {
                            break;
                        }
                        blob.Add(fileTypeStrBuffer[i]);
                    }
                    // First crc the file type name, then get crc the file type name (including zeroed bytes)
                    ushort encryptionKey = Crc16.GetCrc(blob.ToArray());
                    encryptionKey = Crc16.GetCrc(fileTypeStrBuffer, 0, encryptionKey);

                    // Data is at offset 32
                    stream.Position = 32;
                    byte[] data = reader.ReadBytes(dataLength);
                    ushort calculatedDataCrc = Decrypt(data, encryptionKey);

                    if (dataCrc != calculatedDataCrc)
                    {
                        Log("File has an invalid data crc", buffer, file);
                    }

                    if (stream.Position != stream.Length)
                    {
                        Log("File has trailing bytes", buffer, file);
                    }

                    stream.Position = 0;
                    byte[] header = reader.ReadBytes(32);
                    header[4] = 0;
                    header[5] = 0;
                    header[6] = 0;
                    header[7] = 0;
                    ushort calculatedHeaderCrc = Crc16.GetCrc(header);
                    if (headerCrc != calculatedHeaderCrc)
                    {
                        Log("File has an invalid header crc", buffer, file);
                    }

                    return(data);
                }
        }
예제 #3
0
        public void SetMacros(KeyboardLayer layer, UserDataFile userData)
        {
            WritePacketNoResponse(OpCodes.LayerResetDataType, (byte)layer, null, (byte)KeyboardLayerDataType.Macros);
            // The following check has been disabled so that the WebGUI can assign macros without having to setup the keys

            /*if (userData.GetNumMacros(layer) == 0)
             * {
             *  return;
             * }*/
            using (Packet packet = new Packet())
            {
                // TODO: This should be improved to only send the macros to the layers that require the macro
                foreach (UserDataFile.Macro macro in userData.Macros.Values)
                {
                    if (macro.Id < 0)
                    {
                        continue;
                    }
                    if (macro.Actions.Count * 2 > byte.MaxValue)
                    {
                        Program.Log("Macro '" + macro.Name + "' has too many actions (" + macro.Actions.Count +
                                    ", limit is " + (byte.MaxValue / 2) + ")");
                        continue;
                    }
                    if (macro.Actions.Count == 0 && macro.Id >= 0)
                    {
                        Program.Log("Macro '" + macro.Name + "' doesn't have any actions!");
                        continue;
                    }

                    packet.WriteUInt16(0x55AA);// Macro magic (21930 / 0x55AA / AA 55)

                    // Crc to be filled out once all data is written
                    int crcIndex = packet.Index;
                    packet.WriteUInt16(0);

                    byte numActionInts = (byte)((macro.Actions.Count * 2) - (macro.UseTrailingDelay ? 0 : 1));
                    packet.WriteByte(numActionInts);
                    packet.WriteByte((byte)macro.Id);
                    packet.WriteByte((byte)macro.RepeatType);
                    packet.WriteByte(macro.RepeatCount);

                    int crcDataStartIndex = packet.Index;
                    int crcDataEndIndex   = packet.Index + (numActionInts * 4);

                    for (int i = 0; i < 63; i++)
                    {
                        if (i < macro.Actions.Count)
                        {
                            UserDataFile.Macro.Action action = macro.Actions[i];
                            packet.WriteByte(action.KeyCode);
                            packet.WriteByte((byte)action.Modifier);
                            packet.WriteByte((byte)action.State);
                            packet.WriteByte((byte)action.Type);

                            if (i < macro.Actions.Count - 1 || (macro.UseTrailingDelay && i == macro.Actions.Count - 1))
                            {
                                packet.WriteUInt16(action.Delay); //TODO: Investigate! (ushort)(action.Delay == 0 ? 0 : action.Delay / 2));// Delay seems to be doubled?
                                packet.WriteByte(0);              // Always 0?
                                packet.WriteByte(3);              // Always 3? (1/2 use no delay, 0/4 (and maybe others) seem to never stop pressing the key)
                            }
                            else
                            {
                                packet.WriteInt32(0);
                            }
                        }
                        else
                        {
                            packet.WriteInt64(0);
                        }
                    }

                    byte[] buffer     = packet.GetBuffer();
                    byte[] bytesToCrc = new byte[crcDataEndIndex - crcDataStartIndex];
                    Buffer.BlockCopy(buffer, crcDataStartIndex, bytesToCrc, 0, bytesToCrc.Length);
                    ushort crc = Crc16.GetCrc(bytesToCrc);

                    // Always 0?
                    packet.WriteByte(0);

                    int tempIndex = packet.Index;
                    packet.Index = crcIndex;
                    packet.WriteUInt16(crc);
                    packet.Index = tempIndex;
                }
                WritePacketNoResponse(OpCodes.LayerSetMacros, (byte)layer, packet);
            }
        }
예제 #4
0
        private static KeyboardState Handshake(HidStream stream)
        {
            try
            {
                byte bufferSizeA;
                byte bufferSizeB;
                uint firmwareId;
                byte firmwareMinorVersion;
                byte firmwareMajorVersion;
                uint modelId;
                using (Packet packet = WriteSimplePacket(stream, 0x0901))
                {
                    if (packet == null)
                    {
                        LogHandshakeFailed(stream.Device, "opcode 01 09");
                        return(null);
                    }
                    bufferSizeA = packet.ReadByte();
                    bufferSizeB = packet.ReadByte();
                    if (bufferSizeA == 0 || bufferSizeB == 0)
                    {
                        LogHandshakeFailed(stream.Device, "Bad buffer size");
                        return(null);
                    }
                }
                using (Packet packet = WriteSimplePacket(stream, 0x0101))
                {
                    if (packet == null)
                    {
                        LogHandshakeFailed(stream.Device, "opcode 01 01");
                        return(null);
                    }
                    firmwareId           = packet.ReadUInt32();
                    firmwareMinorVersion = packet.ReadByte();
                    firmwareMajorVersion = packet.ReadByte();
                    if (firmwareId == 0 || (firmwareMinorVersion == 0 && firmwareMajorVersion == 0))
                    {
                        LogHandshakeFailed(stream.Device, "Bad firmware id");
                        return(null);
                    }
                }
                using (Packet packet = WriteSimplePacket(stream, 0x0801))
                {
                    if (packet == null)
                    {
                        LogHandshakeFailed(stream.Device, "opcode 01 08");
                        return(null);
                    }
                    byte[] crcBytes             = packet.ReadBytes(6);
                    ushort calculatedModelIdCrc = Crc16.GetCrc(crcBytes);
                    packet.Index -= 6;
                    modelId       = packet.ReadUInt32();
                    if (modelId == 0)
                    {
                        LogHandshakeFailed(stream.Device, "Bad keyboard model id");
                        return(null);
                    }
                    ushort crcValidation1 = packet.ReadUInt16();
                    ushort modelIdCrc     = packet.ReadUInt16();
                    if (calculatedModelIdCrc != modelIdCrc)
                    {
                        LogHandshakeFailed(stream.Device, "Bad keyboard model crc");
                        return(null);
                    }
                }
                // OpCodes_Info.Unk_02 should probably also be sent? Not sure what it's used for though...

                KeyboardState result = KeyboardState.GetKeyboardState(modelId);
                if (result == null || result.FirmwareId != firmwareId)
                {
                    LogHandshakeFailed(stream.Device, "Couldn't find data for keyboard");
                    return(null);
                }
                result.FirmwareMinorVersion = firmwareMinorVersion;
                result.FirmwareMajorVersion = firmwareMajorVersion;
                result.InitializeBuffers(bufferSizeA, bufferSizeB);
                return(result);
            }
            catch (Exception e)
            {
                LogHandshakeFailed(stream.Device, "Exception occured. " + e);
                return(null);
            }
        }
예제 #5
0
        private static byte[] Decrypt(byte[] buffer, string file)
        {
            using (MemoryStream stream = new MemoryStream(buffer))
            using (BinaryReader reader = new BinaryReader(stream))
            {
                if (reader.ReadUInt32() != fileSignature)
                {
                    Log("Bad file signature", buffer, file);
                    return null;
                }

                // Header crc is at offset 4, written as 4 bytes (but still a crc16)
                // (this is a crc of the first 32 bytes (where the crc bytes are 0)
                stream.Position = 4;
                ushort headerCrc = reader.ReadUInt16();

                // Timestamp is at offset 8, written as 4 bytes
                stream.Position = 8;
                int timestamp = reader.ReadInt32();

                // Length is at offset 12, written as 4 bytes
                stream.Position = 12;
                int dataLength = reader.ReadInt32();

                // Data crc is at offset 16, written as 4 bytes (but still a crc16)
                stream.Position = 16;
                ushort dataCrc = reader.ReadUInt16();

                // File type is at offset 20, written as 4 bytes
                stream.Position = 20;
                int fileType = reader.ReadInt32();

                // File type (string) is at offset 24, written as 8 bytes, padded with 00
                stream.Position = 24;
                byte[] fileTypeStrBuffer = reader.ReadBytes(8);
                // First crc the file type name, then get crc the file type name (including zeroed bytes)
                string fileTypeStr = Encoding.ASCII.GetString(fileTypeStrBuffer).TrimEnd('\0');
                ushort encryptionKey = Crc16.GetCrc(Encoding.ASCII.GetBytes(fileTypeStr));
                encryptionKey = Crc16.GetCrc(fileTypeStrBuffer, 0, encryptionKey);

                // Data is at offset 32
                stream.Position = 32;
                byte[] data = reader.ReadBytes(dataLength);
                ushort calculatedDataCrc = Decrypt(data, encryptionKey);

                if (dataCrc != calculatedDataCrc)
                {
                    Log("File has an invalid data crc", buffer, file);
                }

                if (stream.Position != stream.Length)
                {
                    Log("File has trailing bytes", buffer, file);
                }

                stream.Position = 0;
                byte[] header = reader.ReadBytes(32);
                header[4] = 0;
                header[5] = 0;
                header[6] = 0;
                header[7] = 0;
                ushort calculatedHeaderCrc = Crc16.GetCrc(header);
                if (headerCrc != calculatedHeaderCrc)
                {
                    Log("File has an invalid header crc", buffer, file);
                }

                return data;
            }
        }