Bootloader unlock for Kyocera KY-42C on firmware 1.090XX+ https://itssho.my/blog/article/unlocking-kyocera-ky42c
  • Python 57.3%
  • C 27.8%
  • Makefile 7%
  • Assembly 3%
  • Linker Script 3%
  • Other 1.9%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-08-15 07:26:03 +02:00
bin ky42c: Add files 2026-06-29 23:22:47 +02:00
lib ky42c: Improve preloader diagnostic messages (#1) 2026-08-15 07:26:03 +02:00
payload ky42c: Add files 2026-06-29 23:22:47 +02:00
.gitignore ky42c: Add files 2026-06-29 23:22:47 +02:00
.gitmodules ky42c: Add files 2026-06-29 23:22:47 +02:00
build.sh ky42c: Add files 2026-06-29 23:22:47 +02:00
flake.lock ky42c: Add files 2026-06-29 23:22:47 +02:00
flake.nix ky42c: Add files 2026-06-29 23:22:47 +02:00
LICENSE ky42c: Add files 2026-06-29 23:22:47 +02:00
main.py ky42c: Improve preloader diagnostic messages (#1) 2026-08-15 07:26:03 +02:00
Makefile ky42c: Add files 2026-06-29 23:22:47 +02:00
README.md ky42c: Rephrase README introduction 2026-07-06 18:41:54 +02:00
requirements.txt ky42c: Add files 2026-06-29 23:22:47 +02:00
ruff.toml ky42c: Add files 2026-06-29 23:22:47 +02:00

Bootloader unlock for Kyocera DIGNO Keitai 4 (KY-42C)

This is a bootloader unlock "exploit" for the Kyocera KY-42C, working on newer firmware versions (tested on 112.0.0153). Furthermore, it unlocks fastboot (bootloader) cmds that were previously locked out by a "Forbidden" message.

On newer firmware versions, the Preloader has been patched against the crash to BROM method, and bootrom usbdl has been disabled via the BROM SECCFG GFH. This means that BROM USBDL is not available, and no DA is available for this device.

Warning

This is for educational purposes only. I am not responsible for any damage caused by using this code. Use at your own risk.

If you only care about unlocking the bootloader, jump to the Usage section.

How does it work?

On older preloaders, MediaTek devices had a compile flag called CFG_PRELOADER_AS_DA, which enabled two cmds in the Preloader: CMD_SEND_IMAGE (0x70) and CMD_BOOT_IMAGE (0x71).

These cmds don't perform any sort of verification whatsoever, allowing anyone to run arbitrary code on the device.

static void usbdl_send_image(void) {
	u32 img_addr = 0;
	u32 img_len = 0;
	image_index_t id;
	u16 status = 0;
	u8 img_name[64] = {0};
	u32 checksum32 = 0;
	u32 my_checksum32 = 0;

	usbdl_get_data(img_name, 64);
	usbdl_get_dword(&img_len);

  /* 
   *  For loop checking for a valid image name, we just pass "lk"
   * and the check will pass
   * ...
   */

	usbdl_put_word(status);

	// receive Image data
	usbdl_get_data((u8 *)img_addr, img_len);

	my_checksum32 = checksum_plain((u8 *)img_addr, img_len);
	usbdl_get_dword(&checksum32);

	if (my_checksum32 != checksum32) {
		pal_log_err("%s checksum mismatch!\n", MOD);
		return;
	}

  if(id == IMAGE_ATF_ID) {
      // Relocate ATF and TEE
  }
}
static void usbdl_boot_image(void) {
	extern void bldr_jump(u32 addr, u32 arg1, u32 arg2);

	u8 img_name[64] = {0};
	u32 jump_arg;
	u16 status = 0;

	usbdl_get_data(img_name, 64);

	trustzone_pre_init();

	g_boot_mode = FASTBOOT;
	platform_set_boot_args();

	trustzone_post_init();

	jump_arg = (u32)&bootarg;

	if (!strcmp(img_name, lk)) {
		usbdl_put_word(status);
		pal_log_err("%s Jump to LK\n", MOD);
		bldr_jump(g_image_list[IMAGE_LK_ID].start_addr + PART_HDR_BUF_SIZE, jump_arg, sizeof(boot_arg_t));
	} else if (!strcmp(img_name, atf)) {
		usbdl_put_word(status);
		pal_log_err("%s Jump to ATF\n", MOD);
		bldr_jump64(g_image_list[IMAGE_LK_ID].start_addr + PART_HDR_BUF_SIZE, jump_arg, sizeof(boot_arg_t));
	} else {
		status = 1;
		usbdl_put_word(status);
		pal_log_err("%s Unknown Jump\n", MOD);
	}
}

This means, by crafting a payload with the correct layout (in this case, just prepending a 512 bytes empty header), we can get EL3 code execution on the device.

This method has been already used in the past to unlock other devices, such as the LG K10 in Preloader mode.

Usage

You'll need to install python3 and the required dependencies. Creating a venv is recommended.

Linux

$ python3 -m venv venv
$ source venv/bin/activate
$ pip install -r requirements.txt

Make sure you are in the dialout

$ sudo usermod -aG dialout $USER

Windows

> python -m venv venv
> .\venv\Scripts\activate
> pip install -r requirements.txt

You might also need to install MediaTek USB VCOM drivers.


Then, run the script:

$ python main.py unlock

Power off the device, and plug it in to connect into Preloader mode (port 0E8D:2000).

The device will automatically reboot and you should see a "Orange state" warning on the screen.

This will not automatically wipe your data, but it is recommended to perform a factory reset right after. If you get a permission denied error, make sure to configure udev rules for the device, or run the script as root.

Backup firmware

To perform a full backup, you'll need to install penumbra. Once installed, you can run the following commands:

$ mkdir backup
$ python main.py patch
$ antumbra rl backup --skip userdata --da MTK_DA_V5.bin

You can get MTK_DA_V5.bin from mtkclient repo.

Note

mtkclient is currently not compatible with this method, because of how it handles connecting on an already handshaked device. Any issue related to penumbra, should be reported to the penumbra repo.

Building

For building the payload, you'll need to install arm-none-eabi- toolchain and make. If needed, export the CROSS_COMPILE variable to point to the toolchain.

$ export CROSS_COMPILE=arm-none-eabi-
$ ./build.sh

License

This project is licensed under AGPL-3.0-or-later. See LICENSE for details.

This project also includes third party code: