Last active
March 17, 2024 16:20
-
-
Save Doliman100/c4d22766c4288ad0e025fb3eba066289 to your computer and use it in GitHub Desktop.
Xiaomi Smart Band 8 firmware and watchface package template for 010 Editor.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //------------------------------------------------ | |
| //--- 010 Editor v14.0 Binary Template | |
| // | |
| // File: updata_pack.bin.bt | |
| // Authors: | |
| // Version: | |
| // Purpose: | |
| // Category: | |
| // File Mask: *.bin | |
| // ID Bytes: 78 56 34 12 | |
| // History: | |
| //------------------------------------------------ | |
| uint magic <format=hex, comment="0x12345678">; | |
| uint unknown; | |
| uint type <comment="1 - diff, 2 - full">; | |
| char new_version[64]; | |
| char old_version[64]; | |
| uint components_offset; | |
| uint size; // file_size excluding sign | |
| uint components_count; | |
| uint unknown; | |
| local uint component_offset = components_offset; | |
| struct ComponentInfo { | |
| uint patch_size; | |
| uint size; | |
| ushort id; | |
| uchar flag <comment="1">; | |
| uchar patch_type <comment="1 - diff, 2 - full">; | |
| char new_version[64]; // "", "2.2.12" | |
| char old_version[64]; // "2.1.8" | |
| uint patch_crc <format=hex, comment="CRC-32">; | |
| if (flag == 1) { | |
| Printf("%08x - %08x %08x %2d\r\n", component_offset, component_offset + patch_size, patch_size, id); | |
| local uint pos = FTell(); | |
| FSeek(component_offset); | |
| if (patch_type == 1) { | |
| struct { | |
| // https://patents.google.com/patent/CN105786563B/zh | |
| struct { | |
| char header[8] <comment="ROCKDIFF">; | |
| uint source_rom_len; | |
| uint target_rom_len; | |
| uint source_hash <format=hex, comment="Adler-32">; | |
| uint target_hash <format=hex, comment="Adler-32">; | |
| int chunk_number; | |
| uchar unknown[44]; | |
| } IOT_DELTA_HEADER; | |
| struct { | |
| int type; // CHUNK_DIFF, CHUNK_RAW | |
| uint source_base; | |
| uint source_len; | |
| uint target_base; | |
| uint target_len; | |
| uint patch_len; | |
| uint patch_offset; | |
| uint source_hash <format=hex, comment="Adler-32">; | |
| uint target_hash <format=hex, comment="Adler-32">; | |
| uchar unknown[8]; | |
| } IOT_DELTA_CHUNK[IOT_DELTA_HEADER.chunk_number]; | |
| } patch <size=patch_size>; | |
| } else { | |
| uchar patch[patch_size]; | |
| } | |
| FSeek(pos); | |
| component_offset += patch_size; | |
| } | |
| } component_info[25] <optimize=false, read=PrintComponentInfo>; | |
| string PrintComponentInfo(ComponentInfo &component_info) { | |
| local string s; | |
| switch (component_info.id) { | |
| case 1: | |
| s = "#bootloader"; | |
| break; | |
| case 2: | |
| s = "/yaffs2_mount/safemode/safe.bin"; | |
| break; | |
| case 3: | |
| s = "#rom"; | |
| break; | |
| case 4: | |
| s = "/yaffs2_mount/ui/img_s.bin"; | |
| break; | |
| case 5: | |
| s = "/yaffs2_mount/ui/img_d.bin"; | |
| break; | |
| case 6: | |
| s = "/yaffs2_mount/ui/dynamic_font.bin"; | |
| break; | |
| case 7: | |
| s = "/yaffs2_mount/ui/static_font.bin"; | |
| break; | |
| case 8: | |
| s = "/yaffs2_mount/ui/static_word.bin"; | |
| break; | |
| case 9: | |
| s = "/yaffs2_mount/ui/watchface/base/watchface_01.bin"; | |
| break; | |
| case 10: | |
| s = "/yaffs2_mount/ui/watchface/base/watchface_02.bin"; | |
| break; | |
| case 11: | |
| s = "/yaffs2_mount/ui/watchface/base/watchface_03.bin"; | |
| break; | |
| case 12: | |
| s = "/yaffs2_mount/ui/watchface/base/watchface_04.bin"; | |
| break; | |
| case 13: | |
| s = "/yaffs2_mount/ui/watchface/base/watchface_05.bin"; | |
| break; | |
| case 14: | |
| s = "/yaffs2_mount/ui/watchface/base/watchface_06.bin"; | |
| break; | |
| case 15: | |
| s = "/yaffs2_mount/ui/watchface/base/watchface_07.bin"; | |
| break; | |
| case 16: | |
| s = "/yaffs2_mount/ui/watchface/base/event.js"; | |
| break; | |
| case 17: | |
| s = "/yaffs2_mount/gps/gps.bin"; | |
| break; | |
| case 18: | |
| s = "/yaffs2_mount/firmware/tpfw.bin"; | |
| break; | |
| case 19: | |
| s = "/yaffs2_mount/monkey/monkey_json.bin"; | |
| break; | |
| case 20: | |
| s = "/yaffs2_mount/firmware/xip_code.bin"; | |
| break; | |
| default: | |
| s = ""; | |
| break; | |
| } | |
| return s; | |
| } | |
| uint unknown; | |
| FSeek(size); | |
| struct RSA_sign_S { | |
| uint head <format=hex, comment="0xF0F1F2F3">; | |
| uint size; | |
| char data[512] <comment="Base64">; | |
| uint end <format=hex, comment="0xF4F5F6F7">; | |
| } sign; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 1 date | |
| 1 time | |
| 1 hours | |
| 2 minutes | |
| 3 seconds | |
| 4 centiseconds | |
| 5 hours in 12-hour format | |
| 2 date | |
| 1 year | |
| 2 month | |
| 3 day of the month | |
| 4 day of the week | |
| 3 misc | |
| 1 is AM; AM = 0; PM = 8 or 7 | |
| 2 ?; AM = 0; PM = month | |
| 3 is 12-hour format; AM = 0; PM = day of the month | |
| 2 stats | |
| 1 steps | |
| 1 count | |
| 2 percents | |
| 2 heart rate | |
| 1 BPM | |
| 3 calories | |
| 1 kcal | |
| 2 percents | |
| 4 standing | |
| 1 hrs | |
| 2 percents | |
| 6 stress | |
| 1 score | |
| 8 sleep | |
| 1 score | |
| 9 moving | |
| 1 mins | |
| 2 percents | |
| 3 weather | |
| 1 current | |
| 1 temperature unit | |
| 4 temperature | |
| 5 humidity | |
| 6 icon | |
| 10 Air Quality Index | |
| 4 system | |
| 1 status | |
| 1 battery percents | |
| 2 on charge | |
| 3 Do Not Disturb | |
| 4 Bluetooth | |
| 6 PIN lock |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //------------------------------------------------ | |
| //--- 010 Editor v14.0 Binary Template | |
| // | |
| // File: watchface_01.bin.bt | |
| // Authors: | |
| // Version: | |
| // Purpose: | |
| // Category: | |
| // File Mask: *.bin | |
| // ID Bytes: 5A A5 34 12 | |
| // History: | |
| //------------------------------------------------ | |
| // firmware: Global 2.2.12 | |
| // MD5: ab2cc595b8bdf53d16b17a43071695d7 | |
| typedef struct { | |
| string buffer; | |
| } String <read=StringToWString(this.buffer, CHARSET_UTF8), write=true>; | |
| enum <uchar> Alignment { | |
| None, | |
| Left, | |
| Center, | |
| Right | |
| }; | |
| enum <uint> ObjectType { | |
| ObjectType_Element, | |
| ObjectType_Bitmap = 2, | |
| ObjectType_BitmapList, | |
| ObjectType_Animation, // unsupported: 140BAC38 | |
| ObjectType_App, | |
| ObjectType_Widget = 7, | |
| ObjectType_Option, // 0 or 1 | |
| ObjectType_ActionButton | |
| }; | |
| struct RLEImage (uint size) { | |
| uint signature <format=hex, comment="0x5AA521E0">; | |
| uint alpha_flag : 4; | |
| uint uncompressed_size : 28; | |
| uchar buffer[size - 8]; // size calculation: 140BA496 | |
| }; | |
| struct Bitmap { | |
| uchar unknown; | |
| uchar unknown : 2; | |
| uchar compression : 2; | |
| uchar unknown : 4; | |
| uchar unknown; | |
| uchar unknown; | |
| ushort width; | |
| ushort height; | |
| uint size; | |
| if (compression) { | |
| RLEImage image(size); | |
| } else { | |
| uchar image[size]; | |
| } | |
| }; | |
| struct Index { | |
| uint id : 24; | |
| ObjectType type : 8; | |
| }; | |
| uint signature <format=hex, comment="0x12345AA5">; | |
| uchar unknown1[12]; | |
| uint version <format=hex>; // 0x0701 or 0x0800 | |
| uchar unknown2[8]; | |
| uchar display_length; | |
| // [0] - Home screen | |
| // [1] - Always-on display | |
| uchar unknown4_length; | |
| ushort unknown; // bitfield | |
| // 2 - has AOD (4, 6) | |
| uint preview_offset; // bitmap | |
| uchar unknown3[4]; | |
| char id[64]; | |
| // id[4] == 6 (App) or 1 (others); 140BCD44 | |
| String title <size=64, comment="UTF-8">; | |
| // header size: 168 | |
| if (unknown4_length > 0) { | |
| uint unknown4[unknown4_length]; | |
| } | |
| struct { | |
| //uchar unknown[88]; | |
| uint unknown; | |
| uint unknown; | |
| struct { | |
| uint length; | |
| uint offset; | |
| //Printf("%08x - %08x %08x\r\n", offset, offset + 16 * count, 16 * count); | |
| if (length > 0) { | |
| local uint pos = FTell(); | |
| FSeek(offset); | |
| struct { | |
| Index index; | |
| uint unknown3; | |
| uint offset; | |
| uint size; | |
| //Printf("%08x - %08x %d %d\r\n", offset, offset + size, index.type, size); | |
| //Printf("%d\t%d\t%d\t%d\t%d\t%d\r\n", offset, offset + size, unknown[1] == 2024, index.type, index.id, size); | |
| local int pos = FTell(); | |
| FSeek(offset); | |
| switch (index.type) { | |
| case ObjectType_Element: | |
| struct { | |
| Index target_index; | |
| ushort pos_x; | |
| ushort pos_y; | |
| uchar unknown[8]; | |
| //Printf(" %d %d %d %d\r\n", target_index.type, target_index.id, pos_x, pos_y); | |
| } data; | |
| break; | |
| case ObjectType_Bitmap: | |
| Bitmap data; | |
| break; | |
| case ObjectType_BitmapList: | |
| struct BitmapList { | |
| uchar unknown; | |
| uchar image_length; // max: 40 | |
| uchar unknown : 2; | |
| uchar compression : 2; | |
| uchar unknown : 4; | |
| uchar unknown; | |
| ushort width; | |
| ushort height; | |
| uint size; | |
| if (compression) { | |
| uint image_size[image_length]; | |
| local int i; | |
| for (i = 0; i < image_length; i++) { | |
| RLEImage image(image_size[i]); | |
| } | |
| } else { | |
| uint images[width * height * image_length]; | |
| } | |
| } data; // C++ struct size: 184 | |
| break; | |
| // case ObjectType_App: // C++ struct size: 8 | |
| case ObjectType_Widget: | |
| struct { | |
| struct { | |
| ushort digit : 3; // 0 - all | |
| ushort subtype : 5; | |
| ushort type : 4; | |
| ushort category : 4; | |
| //Printf("%d %d %d %d\r\n", category, type, subtype, digit); | |
| } value_source <read=Str("%d.%d.%d (%d)", category, type, subtype, digit)>; | |
| uchar digits; | |
| Alignment alignment : 2; | |
| uchar pad : 1; // left-pad with zeroes | |
| uchar unknown : 1; | |
| uchar type_id : 4; | |
| // 1 number box | |
| // 2 image list | |
| // 4 circular progress bar | |
| // 5 linear progress bar | |
| uint unknown; | |
| switch (type_id) { | |
| case 1: | |
| Index digit_list_index; | |
| uint unknown; | |
| Index symbol_index; | |
| break; | |
| case 2: | |
| Index image_list_index; | |
| uint unknown : 9; | |
| uint overwrite_index : 1; | |
| uint unknown : 22; | |
| if (overwrite_index) { | |
| uint index[(size - 16) / 4]; | |
| } | |
| break; | |
| case 4: | |
| Index foreground_index; | |
| Index background_index; | |
| break; | |
| default: | |
| Index target_index; | |
| break; | |
| } | |
| //Printf(" %d %d\r\n", target_index.type, target_index.id); | |
| } data <size=size>; | |
| /*Printf(" "); | |
| struct { | |
| local int i; | |
| for (i = 0; i < size; i++) { | |
| uchar data; | |
| Printf("%02X", data); | |
| } | |
| } data; | |
| Printf("\r\n");*/ | |
| break; | |
| case ObjectType_Option: | |
| struct { | |
| uchar length; | |
| uchar __padding__[3]; | |
| Index target_index[length]; | |
| } data; | |
| break; | |
| case ObjectType_ActionButton: | |
| struct { | |
| uchar unknown_1[40]; | |
| ushort length; | |
| ushort unknown; | |
| //Printf(" "); | |
| struct { | |
| ushort pos_x; | |
| ushort pos_y; | |
| Index widget_index; | |
| //Printf("%d %d, ", widget_index.type, widget_index.id); | |
| } unknown1[length] <optimize=false>; | |
| //Printf("\r\n"); | |
| } data; | |
| break; | |
| default: | |
| uchar data[size]; | |
| break; | |
| } | |
| FSeek(pos); | |
| } object[length] <optimize=false>; // size: 16 | |
| FSeek(pos); | |
| } | |
| } object_by_type[10] <optimize=false>; | |
| } display[display_length] <optimize=false>; // size: 88 | |
| // memset | |
| // 168 | |
| // 88 * file[28] | |
| // 16 * accumulate | |
| FSeek(preview_offset); | |
| Bitmap preview; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment