diff --git a/plugins/wacom-usb/fu-wac-firmware.c b/plugins/wacom-usb/fu-wac-firmware.c index 9a03b5544..ae5cf073e 100644 --- a/plugins/wacom-usb/fu-wac-firmware.c +++ b/plugins/wacom-usb/fu-wac-firmware.c @@ -253,6 +253,59 @@ fu_wac_firmware_parse (FuFirmware *firmware, return TRUE; } +static guint8 +fu_wac_firmware_calc_checksum (GByteArray *buf) +{ + guint8 csum = 0; + for (guint i = 0; i < buf->len; i++) + csum += buf->data[i]; + return csum ^ 0xFF; +} + +static GBytes * +fu_wac_firmware_write (FuFirmware *firmware, GError **error) +{ + g_autoptr(GPtrArray) images = fu_firmware_get_images (firmware); + g_autoptr(GString) str = g_string_new (NULL); + g_autoptr(GByteArray) buf_hdr = g_byte_array_new (); + + /* fw header */ + for (guint i = 0; i < images->len; i++) { + FuFirmware *img = g_ptr_array_index (images, i); + fu_byte_array_append_uint32 (buf_hdr, fu_firmware_get_addr (img), G_BIG_ENDIAN); + fu_byte_array_append_uint32 (buf_hdr, fu_firmware_get_size (img), G_BIG_ENDIAN); + } + g_string_append_printf (str, "WACOM%u", images->len); + for (guint i = 0; i < buf_hdr->len; i++) + g_string_append_printf (str, "%02X", buf_hdr->data[i]); + g_string_append_printf (str, "%02X\n", fu_wac_firmware_calc_checksum (buf_hdr)); + + /* payload */ + for (guint i = 0; i < images->len; i++) { + FuFirmware *img = g_ptr_array_index (images, i); + g_autoptr(GBytes) img_blob = NULL; + g_autoptr(GByteArray) buf_img = g_byte_array_new (); + + /* img header */ + g_string_append_printf (str, "WA%u", (guint) fu_firmware_get_idx (img) + 1); + fu_byte_array_append_uint32 (buf_img, fu_firmware_get_addr (img), G_BIG_ENDIAN); + for (guint j = 0; j < buf_img->len; j++) + g_string_append_printf (str, "%02X", buf_img->data[j]); + g_string_append_printf (str, "%02X\n", fu_wac_firmware_calc_checksum (buf_img)); + + /* srec */ + img_blob = fu_firmware_write (img, error); + if (img_blob == NULL) + return NULL; + g_string_append_len (str, + (const gchar *) g_bytes_get_data (img_blob, NULL), + g_bytes_get_size (img_blob)); + } + + /* success */ + return g_string_free_to_bytes (g_steal_pointer (&str)); +} + static void fu_wac_firmware_init (FuWacFirmware *self) { @@ -263,6 +316,7 @@ fu_wac_firmware_class_init (FuWacFirmwareClass *klass) { FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS (klass); klass_firmware->parse = fu_wac_firmware_parse; + klass_firmware->write = fu_wac_firmware_write; } FuFirmware * diff --git a/src/fuzzing/firmware/wacom.wac b/src/fuzzing/firmware/wacom.wac index 465c093ca..1e743dac4 100644 --- a/src/fuzzing/firmware/wacom.wac +++ b/src/fuzzing/firmware/wacom.wac @@ -1,9 +1,11 @@ -WACOM2080080000009414E080400000009414A3F -WA10800800067 -S00B00004F616B2E73726563FE -S70508038BD58F - -WA2080400001F -S00B00004F616B2E73726563FE -S70508070BD50B - +WACOM2080080000000000B080400000000000B55 +WA10800800077 +S0030000FC +S3100800800068656C6C6F20776F726C640B +S604000001FA +S70500000000FA +WA208040000F3 +S0030000FC +S3100804000068656C6C6F20776F726C6487 +S604000001FA +S70500000000FA diff --git a/src/fuzzing/wacom.builder.xml b/src/fuzzing/wacom.builder.xml new file mode 100644 index 000000000..0ca3d8f17 --- /dev/null +++ b/src/fuzzing/wacom.builder.xml @@ -0,0 +1,12 @@ + + + 0x0 + 0x8008000 + aGVsbG8gd29ybGQ= + + + 0x1 + 0x8040000 + aGVsbG8gd29ybGQ= + +