kopia lustrzana https://github.com/sq5bpf/k5prog
commit
990eeb60aa
58
README
58
README
|
@ -1,14 +1,14 @@
|
||||||
k5prog - Quansheng UV-K5 EEPROM and flash programmer v0.9
|
k5prog - Quansheng UV-K5 EEPROM and flash programmer v0.9
|
||||||
(c) 2023 Jacek Lipkowski <sq5bpf@lipkowski.org>
|
(c) 2023 Jacek Lipkowski <sq5bpf@lipkowski.org>
|
||||||
|
|
||||||
This program can read and write the eeprom of Quansheng UV-K5.
|
This program can read and write the EEPROM of Quansheng UV-K5.
|
||||||
It can read/write arbitrary data, and might be useful for making backups of
|
It can read/write arbitrary data, and might be useful for making backups of
|
||||||
the configuration, mass programming of radios or reverse engineering of
|
the configuration, mass programming of radios or reverse engineering of
|
||||||
the radio configuration. Please note that it is probably possible to break
|
the radio configuration. Please note that it is probably possible to break
|
||||||
your radio by writing a bad configuration to it, so please use at your own
|
your radio by writing a bad configuration to it, so please use at your own
|
||||||
risk.
|
risk.
|
||||||
|
|
||||||
Note that this program does not edit the contents of the eeprom. Use an
|
Note that this program does not edit the contents of the EEPROM. Use an
|
||||||
external hex editor.
|
external hex editor.
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ here:
|
||||||
https://github.com/fagci/qs-uvk5-firmware-modder
|
https://github.com/fagci/qs-uvk5-firmware-modder
|
||||||
An example decrypted file is provided in k5_flash_test.raw, this is the vendor
|
An example decrypted file is provided in k5_flash_test.raw, this is the vendor
|
||||||
2.01.23 firmware without any modifications.
|
2.01.23 firmware without any modifications.
|
||||||
Please use extreme caution, as reprogramming the radioflash can potentially i
|
Please use extreme caution, as reprogramming the radioflash can potentially
|
||||||
brick your radio. If unsure, please use the vendor flashing software.
|
brick your radio. If unsure, please use the vendor flashing software.
|
||||||
|
|
||||||
The flashing support in k5prog was used in at least 2 cases to recover radios
|
The flashing support in k5prog was used in at least 2 cases to recover radios
|
||||||
|
@ -31,38 +31,38 @@ To compile, please see the compiling section at the end.
|
||||||
|
|
||||||
|
|
||||||
The program is written to (hopefully) run on POSIX systems. Testing was done
|
The program is written to (hopefully) run on POSIX systems. Testing was done
|
||||||
on GNU/Linux, but MacOS X and windows under cygwin should work too.
|
on GNU/Linux, but macOS and Windows under Cygwin should work too.
|
||||||
|
|
||||||
For licensing see the file LICENSE.
|
For licensing see the file LICENSE.
|
||||||
|
|
||||||
|
|
||||||
---- Usage ----
|
---- Usage ----
|
||||||
|
|
||||||
for help run the programwithout arguments, or with the -h option.
|
to display help run the program without arguments, or with the -h option.
|
||||||
|
|
||||||
The configuration options are:
|
The configuration options are:
|
||||||
Quansheng UV-K5 EEPROM programmer v0.8 (c) 2023 Jacek Lipkowski <sq5bpf@lipkowski.org>
|
Quansheng UV-K5 EEPROM programmer v0.8 (c) 2023 Jacek Lipkowski <sq5bpf@lipkowski.org>
|
||||||
|
|
||||||
cmdline opts:
|
cmdline opts:
|
||||||
-f <file> filename that contains the eeprom dump (default: k5_eeprom.raw)
|
-f <file> filename that contains the EEPROM dump (default: k5_eeprom.raw)
|
||||||
-b <file> filename that contains the raw flash image (default k5_flash.raw)
|
-b <file> filename that contains the raw flash image (default k5_flash.raw)
|
||||||
-Y increase "I know what i'm doing" value, to enable functionality likely to break the radio
|
-Y increase "I know what I'm doing" value, to enable functionality likely to break the radio
|
||||||
-D wait for the message from the radio flasher, print it's version
|
-D wait for the message from the radio flasher, print it's version
|
||||||
-F flash firmware, WARNING: this will likely brick your radio!
|
-F flash firmware, WARNING: this will likely brick your radio!
|
||||||
-M <ver> Set the firmware major version to <ver> during the flash process (default: *.01.23)
|
-M <ver> Set the firmware major version to <ver> during the flash process (default: *.01.23)
|
||||||
-r read eeprom
|
-r read EEPROM
|
||||||
-w write eeprom like the original software does
|
-w write EEPROM like the original software does
|
||||||
-W write most of the eeprom (but without what i think is calibration data)
|
-W write most of the EEPROM (but without what I think is calibration data)
|
||||||
-B write ALL of the eeprom (the "brick my radio" mode)
|
-B write ALL of the EEPROM (the "brick my radio" mode)
|
||||||
-p <port> device name (default: /dev/ttyUSB0)
|
-p <port> device name (default: /dev/ttyUSB0)
|
||||||
-s <speed> serial speed (default: 38400, the UV-K5 doesn't accept any other speed)
|
-s <speed> serial speed (default: 38400, the UV-K5 doesn't accept any other speed)
|
||||||
-h print this help
|
-h print this help
|
||||||
-v be verbose, use multiple times for more verbosity
|
-v be verbose, use multiple times for more verbosity
|
||||||
|
|
||||||
|
|
||||||
---- Reading/writing the configuration eeprom ----
|
---- Reading/writing the configuration EEPROM ----
|
||||||
|
|
||||||
For a basic usage use -r to read eeprom, -w to write eeprom. The -v option
|
For a basic usage use -r to read EEPROM, -w to write EEPROM. The -v option
|
||||||
gives more verbosity.
|
gives more verbosity.
|
||||||
|
|
||||||
Read configuration:
|
Read configuration:
|
||||||
|
@ -72,10 +72,10 @@ Quansheng UV-K5 EEPROM programmer v0.5 (c) 2023 Jacek Lipkowski <sq5bpf@lipkowsk
|
||||||
|
|
||||||
k5_prepare: try 0
|
k5_prepare: try 0
|
||||||
****** Connected to firmware version: [k5_2.01.23]
|
****** Connected to firmware version: [k5_2.01.23]
|
||||||
Sucessfuly read eeprom
|
Successfully read EEPROM
|
||||||
|
|
||||||
|
|
||||||
The eeprom contents are written to the file k5_eeprom.raw, this can be
|
The EEPROM contents are written to the file k5_eeprom.raw, this can be
|
||||||
changed with the -f option.
|
changed with the -f option.
|
||||||
|
|
||||||
|
|
||||||
|
@ -87,14 +87,14 @@ Quansheng UV-K5 EEPROM programmer v0.5 (c) 2023 Jacek Lipkowski <sq5bpf@lipkowsk
|
||||||
k5_prepare: try 0
|
k5_prepare: try 0
|
||||||
****** Connected to firmware version: [k5_2.01.23]
|
****** Connected to firmware version: [k5_2.01.23]
|
||||||
Read file k5_eeprom.raw success
|
Read file k5_eeprom.raw success
|
||||||
Sucessfuly wrote eeprom
|
Successfully wrote EEPROM
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The -w option writes only the memory blocks which are written by the original
|
The -w option writes only the memory blocks which are written by the original
|
||||||
radio software, in the same order.
|
radio software, in the same order.
|
||||||
|
|
||||||
The -W option is a bit more brave, it writes all memory upto 0x1d00. I _think_
|
The -W option is a bit braver as it writes all memory upto 0x1d00. I _think_
|
||||||
that the radio has calibration data above this address, but of course this is
|
that the radio has calibration data above this address, but of course this is
|
||||||
not certain, because this knowledge is a result of reverse engineering, and not
|
not certain, because this knowledge is a result of reverse engineering, and not
|
||||||
information from the manufacturer.
|
information from the manufacturer.
|
||||||
|
@ -105,7 +105,7 @@ allowing overwriting of calibration data (if there is any) or other data which
|
||||||
may be critical to the proper functioning of your radio. I have used this on
|
may be critical to the proper functioning of your radio. I have used this on
|
||||||
my radio, and it still works but please be extra-careful.
|
my radio, and it still works but please be extra-careful.
|
||||||
|
|
||||||
I have written the radio eeprom with the -W option tens of times, and others
|
I have written the radio EEPROM with the -W option tens of times, and others
|
||||||
have too. So far it hasn't produced any bad results. But of course beware.
|
have too. So far it hasn't produced any bad results. But of course beware.
|
||||||
|
|
||||||
|
|
||||||
|
@ -114,14 +114,14 @@ have too. So far it hasn't produced any bad results. But of course beware.
|
||||||
The flashing support is for the really brave people who know what they are
|
The flashing support is for the really brave people who know what they are
|
||||||
doing (hence the -Y flag is needed).
|
doing (hence the -Y flag is needed).
|
||||||
|
|
||||||
It is possible to read the bootloder version using the -D option. This option
|
It is possible to read the bootloader version using the -D option. This option
|
||||||
is safe, but needs the -Y value. Put the radio into flash mode and:
|
is safe, but needs the -Y value. Put the radio into flash mode and:
|
||||||
|
|
||||||
./k5prog -Y -D
|
./k5prog -Y -D
|
||||||
|
|
||||||
Quansheng UV-K5 EEPROM programmer v0.5 (c) 2023 Jacek Lipkowski <sq5bpf@lipkowski.org>
|
Quansheng UV-K5 EEPROM programmer v0.5 (c) 2023 Jacek Lipkowski <sq5bpf@lipkowski.org>
|
||||||
|
|
||||||
"I know what i'm doing" value set to 1
|
"I know what I'm doing" value set to 1
|
||||||
******** k5 command hexdump [obf_len:44 clear_len:36 crc_ok:1 **********
|
******** k5 command hexdump [obf_len:44 clear_len:36 crc_ok:1 **********
|
||||||
## obfuscated ##
|
## obfuscated ##
|
||||||
|
|
||||||
|
@ -143,13 +143,13 @@ Flasher version is: [2.00.06]
|
||||||
The radio can also be flashed with the raw unencrypted binary.
|
The radio can also be flashed with the raw unencrypted binary.
|
||||||
An example binary is provided in the k5_flash.raw file (this is the 2.01.23
|
An example binary is provided in the k5_flash.raw file (this is the 2.01.23
|
||||||
firmware). The binary file can be specified with the -b option.
|
firmware). The binary file can be specified with the -b option.
|
||||||
Flashing the radio requires the "i know what i'm doing value" of at least 5.
|
Flashing the radio requires the "I know what I'm doing value" of at least 5.
|
||||||
|
|
||||||
./k5prog -b k5_flash.raw -YYYYYY -F
|
./k5prog -b k5_flash.raw -YYYYYY -F
|
||||||
|
|
||||||
Quansheng UV-K5 EEPROM programmer v0.5 (c) 2023 Jacek Lipkowski <sq5bpf@lipkowski.org>
|
Quansheng UV-K5 EEPROM programmer v0.5 (c) 2023 Jacek Lipkowski <sq5bpf@lipkowski.org>
|
||||||
|
|
||||||
"I know what i'm doing" value set to 6
|
"I know what I'm doing" value set to 6
|
||||||
******** k5 command hexdump [obf_len:44 clear_len:36 crc_ok:1 **********
|
******** k5 command hexdump [obf_len:44 clear_len:36 crc_ok:1 **********
|
||||||
## obfuscated ##
|
## obfuscated ##
|
||||||
|
|
||||||
|
@ -190,19 +190,19 @@ simple makefile:
|
||||||
sq5bpf@dellix:~/k5prog-0.1$ make
|
sq5bpf@dellix:~/k5prog-0.1$ make
|
||||||
gcc -O2 k5prog.c -o k5prog
|
gcc -O2 k5prog.c -o k5prog
|
||||||
|
|
||||||
Other POSIX platforms should work also, including MacOS X.
|
Other POSIX platforms should work also, including macOS.
|
||||||
|
|
||||||
The software compiles under Cygwin/Microsoft Windows, but has not been tested.
|
The software compiles under Cygwin/Microsoft Windows, but has not been tested.
|
||||||
According to the cygwin documentation you should use /dev/comX to use port comX
|
According to the Cygwin documentation you should use /dev/comX to use port comX
|
||||||
(for example using com6: k5prog.exe -v -r -p /dev/com6)
|
(for example using com6: k5prog.exe -v -r -p /dev/com6)
|
||||||
|
|
||||||
|
|
||||||
If port this to another platform, or do anything interesting with this
|
If you port this to another platform, or do anything interesting with this
|
||||||
software, tell me about it.
|
software, tell me about it.
|
||||||
|
|
||||||
---- Other uses ----
|
---- Other uses ----
|
||||||
|
|
||||||
The file uvk5_original_eeprom.raw contains an eeprom downloaded from a UV-K5
|
The file uvk5_original_eeprom.raw contains an EEPROM downloaded from an UV-K5
|
||||||
radio. Maybe it can be used to resurrect another radio of the same type
|
radio. Maybe it can be used to resurrect another radio of the same type
|
||||||
if it was broken (perhaps by the use of this software :).
|
if it was broken (perhaps by the use of this software :).
|
||||||
|
|
||||||
|
@ -220,13 +220,13 @@ The format of the datagram sent to the radio is:
|
||||||
|
|
||||||
0xAB 0xCD len 0x00 <data bytes> <2 bytes CRC> 0xDC 0xBA
|
0xAB 0xCD len 0x00 <data bytes> <2 bytes CRC> 0xDC 0xBA
|
||||||
|
|
||||||
The length is the length od the data bytes.
|
The length is the length of the data bytes.
|
||||||
|
|
||||||
The data is protected by a typical CRC-16 xmodem algorithm.
|
The data is protected by a typical CRC-16 xmodem algorithm.
|
||||||
The data bytes and the CRC are obfuscated by xor-in it with an 8-byte
|
The data bytes and the CRC are obfuscated by xor-in it with an 8-byte
|
||||||
sequence.
|
sequence.
|
||||||
|
|
||||||
Fortunately the eeprom data contains a lot of 0xFF and 0x00 bytes, so the XOR
|
Fortunately the EEPROM data contains a lot of 0xFF and 0x00 bytes, so the XOR
|
||||||
sequence is easy to find by observing the traffic.
|
sequence is easy to find by observing the traffic.
|
||||||
|
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ The datagram sent from the radio is the same, but the CRC field is set to
|
||||||
obfuscation (same as the XOR).
|
obfuscation (same as the XOR).
|
||||||
|
|
||||||
|
|
||||||
I intend to publish a further description of the protocol, and the eeprom
|
I intend to publish a further description of the protocol, and the EEPROM
|
||||||
contents, meanwhile the sources can be used as documentation.
|
contents, meanwhile the sources can be used as documentation.
|
||||||
|
|
||||||
|
|
||||||
|
|
26
k5prog.c
26
k5prog.c
|
@ -1,7 +1,7 @@
|
||||||
/* Quansheng UV-K5 EEPROM programmer v0.9
|
/* Quansheng UV-K5 EEPROM programmer v0.9
|
||||||
* (c) 2023 Jacek Lipkowski <sq5bpf@lipkowski.org>
|
* (c) 2023 Jacek Lipkowski <sq5bpf@lipkowski.org>
|
||||||
*
|
*
|
||||||
* This program can read and write the eeprom of Quansheng UVK5 Mark II
|
* This program can read and write the EEPROM of Quansheng UVK5 Mark II
|
||||||
* and probably other similar radios via the serial port.
|
* and probably other similar radios via the serial port.
|
||||||
*
|
*
|
||||||
* It can read/write arbitrary data, and might be useful for reverse
|
* It can read/write arbitrary data, and might be useful for reverse
|
||||||
|
@ -110,8 +110,8 @@ unsigned char uvk5_hello2[]={0x14, 0x05, 0x04, 0x00, 0x9f, 0x25, 0x5a, 0x64};
|
||||||
|
|
||||||
/* commands:
|
/* commands:
|
||||||
* 0x14 - hello
|
* 0x14 - hello
|
||||||
* 0x1b - read eeprom
|
* 0x1b - read EEPROM
|
||||||
* 0x1d - write eeprom
|
* 0x1d - write EEPROM
|
||||||
* 0xdd - reset radio
|
* 0xdd - reset radio
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -465,7 +465,7 @@ struct k5_command *k5_receive(int fd,int tmout) {
|
||||||
return(cmd);
|
return(cmd);
|
||||||
}
|
}
|
||||||
/******************************/
|
/******************************/
|
||||||
/* eeprom read/write support */
|
/* EEPROM read/write support */
|
||||||
/******************************/
|
/******************************/
|
||||||
int k5_readmem(int fd, unsigned char *buf, unsigned char maxlen, int offset)
|
int k5_readmem(int fd, unsigned char *buf, unsigned char maxlen, int offset)
|
||||||
{
|
{
|
||||||
|
@ -552,7 +552,7 @@ int k5_reset(int fd)
|
||||||
r=k5_send_buf(fd,uvk5_reset,sizeof(uvk5_reset));
|
r=k5_send_buf(fd,uvk5_reset,sizeof(uvk5_reset));
|
||||||
return(r);
|
return(r);
|
||||||
}
|
}
|
||||||
/* end of eeprom read/write support */
|
/* end of EEPROM read/write support */
|
||||||
|
|
||||||
|
|
||||||
/******************************/
|
/******************************/
|
||||||
|
@ -759,14 +759,14 @@ void helpme()
|
||||||
"cmdline opts:\n"
|
"cmdline opts:\n"
|
||||||
"-f <file>\tfilename that contains the eeprom dump (default: " DEFAULT_FILE_NAME ")\n"
|
"-f <file>\tfilename that contains the eeprom dump (default: " DEFAULT_FILE_NAME ")\n"
|
||||||
"-b <file>\tfilename that contains the raw flash image (default " DEFAULT_FLASH_NAME ")\n"
|
"-b <file>\tfilename that contains the raw flash image (default " DEFAULT_FLASH_NAME ")\n"
|
||||||
"-Y \tincrease \"I know what i'm doing\" value, to enable functionality likely to break the radio\n"
|
"-Y \tincrease \"I know what I'm doing\" value, to enable functionality likely to break the radio\n"
|
||||||
"-D \twait for the message from the radio flasher, print it's version\n"
|
"-D \twait for the message from the radio flasher, print it's version\n"
|
||||||
"-F \tflash firmware, WARNING: this will likely brick your radio!\n"
|
"-F \tflash firmware, WARNING: this will likely brick your radio!\n"
|
||||||
"-M <ver> \tSet the firmware major version to <ver> during the flash process (default: " DEFAULT_FLASH_VERSION ")\n"
|
"-M <ver> \tSet the firmware major version to <ver> during the flash process (default: " DEFAULT_FLASH_VERSION ")\n"
|
||||||
"-r \tread eeprom\n"
|
"-r \tread eeprom\n"
|
||||||
"-w \twrite eeprom like the original software does\n"
|
"-w \twrite eeprom like the original software does\n"
|
||||||
"-W \twrite most of the eeprom (but without what i think is calibration data)\n"
|
"-W \twrite most of the EEPROM (but without what I think is calibration data)\n"
|
||||||
"-B \twrite ALL of the eeprom (the \"brick my radio\" mode)\n"
|
"-B \twrite ALL of the EEPROM (the \"brick my radio\" mode)\n"
|
||||||
"-p <port>\tdevice name (default: " DEFAULT_SERIAL_PORT ")\n"
|
"-p <port>\tdevice name (default: " DEFAULT_SERIAL_PORT ")\n"
|
||||||
"-s <speed>\tserial speed (default: 38400, the UV-K5 doesn't accept any other speed)\n"
|
"-s <speed>\tserial speed (default: 38400, the UV-K5 doesn't accept any other speed)\n"
|
||||||
"-h \tprint this help\n"
|
"-h \tprint this help\n"
|
||||||
|
@ -1009,7 +1009,7 @@ int main(int argc,char **argv)
|
||||||
|
|
||||||
/* arbitrary limit do that someone doesn't flash some random short file */
|
/* arbitrary limit do that someone doesn't flash some random short file */
|
||||||
if ((i_know_what_im_doing<5)&&(flash_length<50000)) {
|
if ((i_know_what_im_doing<5)&&(flash_length<50000)) {
|
||||||
fprintf(stderr,"Failed to read whole eeprom from file %s (read %i), file too short or some other error\n",file,flash_length);
|
fprintf(stderr,"Failed to read whole EEPROM from file %s (read %i), file too short or some other error\n",file,flash_length);
|
||||||
if (flash_length>0) {
|
if (flash_length>0) {
|
||||||
fprintf(stderr,"This failsafe is here so that people don't mistake config files with flash.\nIt can be ignored with an 'i know what i'm doing' value of at least 5\n");
|
fprintf(stderr,"This failsafe is here so that people don't mistake config files with flash.\nIt can be ignored with an 'i know what i'm doing' value of at least 5\n");
|
||||||
}
|
}
|
||||||
|
@ -1090,7 +1090,7 @@ int main(int argc,char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
if (verbose>0) { printf("\rSucessfuly read eeprom\n"); }
|
if (verbose>0) { printf("\rSuccessfully read EEPROM\n"); }
|
||||||
if (verbose>2) { hdump((unsigned char *)&eeprom,UVK5_EEPROM_SIZE); }
|
if (verbose>2) { hdump((unsigned char *)&eeprom,UVK5_EEPROM_SIZE); }
|
||||||
|
|
||||||
write_file(file,(unsigned char *)&eeprom,UVK5_EEPROM_SIZE);
|
write_file(file,(unsigned char *)&eeprom,UVK5_EEPROM_SIZE);
|
||||||
|
@ -1101,7 +1101,7 @@ int main(int argc,char **argv)
|
||||||
case MODE_WRITE_MOST:
|
case MODE_WRITE_MOST:
|
||||||
case MODE_WRITE_ALL:
|
case MODE_WRITE_ALL:
|
||||||
if ((mode==MODE_WRITE_ALL)&&(i_know_what_im_doing<1)) {
|
if ((mode==MODE_WRITE_ALL)&&(i_know_what_im_doing<1)) {
|
||||||
printf("ERROR: the \"I know what i'm doing\" value has to be at least 1 to confirm that you know what you're doing\n");
|
printf("ERROR: the \"I know what I'm doing\" value has to be at least 1 to confirm that you know what you're doing\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1113,7 +1113,7 @@ int main(int argc,char **argv)
|
||||||
}
|
}
|
||||||
r=read(ffd,(unsigned char *)&eeprom[i],UVK5_EEPROM_SIZE);
|
r=read(ffd,(unsigned char *)&eeprom[i],UVK5_EEPROM_SIZE);
|
||||||
if (r!=UVK5_EEPROM_SIZE) {
|
if (r!=UVK5_EEPROM_SIZE) {
|
||||||
fprintf(stderr,"Failed to read whole eeprom from file %s, file too short?\n",file);
|
fprintf(stderr,"Failed to read whole EEPROM from file %s, file too short?\n",file);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
close(ffd);
|
close(ffd);
|
||||||
|
@ -1157,7 +1157,7 @@ int main(int argc,char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
k5_reset(fd);
|
k5_reset(fd);
|
||||||
if (verbose>0) { printf("\rSucessfuly wrote eeprom\n"); }
|
if (verbose>0) { printf("\rSuccessfully wrote EEPROM\n"); }
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
2
uvk5.h
2
uvk5.h
|
@ -1,4 +1,4 @@
|
||||||
/* UV-K5 eeprom programmer */
|
/* UV-K5 EEPROM programmer */
|
||||||
|
|
||||||
#ifndef UVK5_INCLUDE_H
|
#ifndef UVK5_INCLUDE_H
|
||||||
#define UVK5_INCLUDE_H
|
#define UVK5_INCLUDE_H
|
||||||
|
|
Ładowanie…
Reference in New Issue