whosmatt / uvmod

Web-based firmware patcher for various Quansheng radios
https://whosmatt.github.io/uvmod/
268 stars 47 forks source link

mistake in write flash packet (size field) #41

Closed qrp73 closed 2 months ago

qrp73 commented 2 months ago

There is incorrect field Size send from your uvmod updater. k5prog flasher and original firmware updater sending correct Size field, while your uvmod updater sends incorrect Size field value.

Here is comparison for a packet sent from original UV-K5 updater and packet sent from uvtools:

Original updater:

[TRACE] RX: 19050c01945d6a2c0000e6000001000088130020d5000000d9000000db00000000000000000000000000000000000000000000000000000000000000dd0000000000000000000000df00000025c40000e3000000e5000000e7000000e9000000eb000000ed000000ef000000f1000000f3000000f5000000f7000000f9000000fb000000fd000000ff00000001010000030100000501000007010000090100000b0100000d0100000f01000011010000130100001501000017010000190100001b0100001d0100001f010000210100000348854600f058fb00480047edd100008813002013480047fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7
[TRACE] recv PacketFlashWriteReq {
  HdrSize=268
  Id=0x2c6a5d94
  Offset=0x0000
  OffsetFinal=0xe600
  Size=0x100
  Padding=0x0000
  Data=88130020d5000000d9000000db00000000000000000000000000000000000000000000000000000000000000dd0000000000000000000000df00000025c40000e3000000e5000000e7000000e9000000eb000000ed000000ef000000f1000000f3000000f5000000f7000000f9000000fb000000fd000000ff00000001010000030100000501000007010000090100000b0100000d0100000f01000011010000130100001501000017010000190100001b0100001d0100001f010000210100000348854600f058fb00480047edd100008813002013480047fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7
}

uvmod:

[TRACE] RX: 19050c018a8d9f1d0000e6000100000088130020d5000000d9000000db00000000000000000000000000000000000000000000000000000000000000dd0000000000000000000000df0000000dc40000e3000000e5000000e7000000e9000000eb000000ed000000ef000000f1000000f3000000f5000000f7000000f9000000fb000000fd000000ff00000001010000030100000501000007010000090100000b0100000d0100000f01000011010000130100001501000017010000190100001b0100001d0100001f010000210100000348854600f058fb00480047d5d100008813002013480047fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7fee7
[TRACE] recv PacketFlashWriteReq {
  HdrSize=268
  Id=0x1d9f8d8a
  Offset=0x0000
  OffsetFinal=0xe600
  Size=0x01
  Padding=0x0000
  Data=88
}

Notice, that original updater and k5prog sending Size=0x100 (the actual block size), while your uvmod updater sends Size-0x01 (just 1 byte).

For some reason UV-K5 bootloader ignores actual Size field value and uses all data transmitted with packet header. So your code still works, but it sends incorrect Size value and it may lead to failure.

Please fix it.

qrp73 commented 2 months ago

You can test your updater with my K5TOOL updater tool, which supports bootloader simulator mode, you can run it in the following way:

./k5tool -port /dev/ttyUSB1 -simula

where /dev/ttyUSB1 is a serial port used for UV-K5 device simulation.

Just make loopback with two USB-serial dongles (connect RX-TX and TX-RX on them) and run K5TOOL in simulator mode on one serial port and your uvmod updater on second serial port.

whosmatt commented 2 months ago

i had the decompiled the bootloader code to look at and verified that it was safe based on that. the bootloader implementation uses a fixed 0x100 byte size and completely ignores length. i believe crc was also ignored (curiously only by the bootloader, not by the application).

this is most likely swapped msb and lsb even though they should be in the correct order, ill take a look at it later

qrp73 commented 2 months ago

can you share bootloader code? Does it has some command to read flash memory?

whosmatt commented 2 months ago

i dont remember any function to read flash, bootloader was a basic implementation with most only the bare working minimum of features. i dont have the ghidra project anymore but you can ask oneofeleven, he did all of the decompiling work.

On Wed, Jun 12, 2024, 15:43 qrp73 @.***> wrote:

can you share bootloader code? Does it has some command to read flash memory?

— Reply to this email directly, view it on GitHub https://github.com/whosmatt/uvmod/issues/41#issuecomment-2163047414, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACSFI23SJXS266A3DP2QAV3ZHBGBBAVCNFSM6AAAAABJFZ7TQGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNRTGA2DONBRGQ . You are receiving this because you commented.Message ID: @.***>

qrp73 commented 2 months ago

Do you know what means Id field (offset 4,5,6,7 in decrypted packet) of write flash packet? Original firmware updater sends some random values in that field, and it's not timestamp like in Hello packet.

First I thought this is just a some unique id of the packet, I tried to use autoincremented value, but bootloader stops to respond on such packets. While using some constant taken from original updater packet works ok. So, I'm confused, what this field means?

Also there is not clear what data is sent in first 16 bytes of bootloader beacon packet?

How I can contact with oneofeleven regarding my questions? He has repository with cursom firmware, but I'm not sure if it's good way add issue about bootloader for discussion, because it's not related to his firmware project...

whosmatt commented 2 months ago

you can try to ask around in the telegram groups linked by amnemonic and dont worry about making an issue about the bootloader, it makes sense to include it in the firmware project

i dont remember what the id field was, but i remember that the command ids were just arbitrarily hardcoded and dont seem to match any patterns or ascii chars.

i dont remember the bootloader packet structure but 16 bytes sounds like the version string which is just a hardcoded string like the firmware version. the bootloader version has the same format as the firmware version and the first digit identifies the device (k5, k5(8)/k6, 5r-plus are 2,3 and 4 respectively). they reserved the ability to release device specific firmware but the hardware is essentially the same and fully interchangeable.

whosmatt commented 2 months ago

fair enough, i just had the byte order the same as with the other fields but it appears they didnt even use it consistently. ill swap the byte order of the length field around to make it the same behaviour as the official tool.

seems like you also had your fair share of confusion looking at their protocol: https://github.com/qrp73/K5TOOL/blob/f909513ed0380ae7fc981788cd5736fddcff1613/Packets/PacketFlashWriteReq.cs#L78-L79

you might want to update this comment: https://github.com/qrp73/K5TOOL/blob/f909513ed0380ae7fc981788cd5736fddcff1613/Packets/PacketFlashWriteReq.cs#L54

qrp73 commented 1 month ago

I analyzed official updater code and it appears that both variants are incorrect, see packet structure here for details: https://github.com/qrp73/K5TOOL/blob/main/Packets/PacketFlashWriteReq.cs

K5TOOL now has fixed packet structure to be compatible with official updater.