Skip to content

Commit f336660

Browse files
committed
Add moto g23 unlocking article
1 parent 35e813b commit f336660

5 files changed

+261
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
---
2+
layout: post
3+
author: Shomy
4+
title: "Unlocking the Motorola G23"
5+
date: 2025-02-13
6+
categories: posts
7+
tags:
8+
- Android Modding
9+
- Bootloader Unlocking
10+
---
11+
12+
Unlocking the Motorola G23 was not an easy task, but we finally did it!
13+
14+
In this article, I'll explain how I and a team of enthusiasts managed to unlock the bootloader of the Motorola G23, a device that was previously thought to be unlockable.
15+
16+
## The Motorola G23
17+
18+
The Motorola Moto G23 is a smartphone that was released in January 2023.
19+
Out of the box, the device might seem quite clean and minimal, but that all changed when Android 14 came.
20+
21+
I've been looking for to mod the device when Android 13 was still the latest version, but I couldn't find any information on XDA developers, or any other forums.
22+
23+
So I started my own research.
24+
25+
## The first tries
26+
27+
I started by looking for known ways to unlock previous Motorola phones, starting by G22.<br>
28+
29+
Here, I found out about how [mtkclient](https://github.com/bkerler/mtkclient) was used to unlock the bootloader on G22, so I thought giving it a try.<br>
30+
Unfortunately, the G23 BROM was blocked compared to G22, and only the preloader port was accessible.<br>
31+
This wouldn't be a problem, if only the preloader wasn't patched! Crash DA wasn't available, and the device would just reboot into preloader mode.<br><br>
32+
33+
Just like that, I was stuck.<br><br>
34+
35+
So, I tried extracting the firmware from the official rescue software, RSA, and I was able to find both the stock firmware and the flash tool, the latter being an encrypted zip file.<br>
36+
In the firmware I found a file named `MT6768_USER.bin`, which seemed to work at some extent.I tried using mtkclient's `da unlock` command, and it failed.<br>
37+
I knew RSA was able to flash stock firmware somehow, so tried getting the flash tool RSA used, and I was able to get the Flash Tool unencrypted by making RSA start a rescue, in which the tool had to be extracted beforehand.<br>
38+
In the Flash Tool, I've found another Download Agent, which I used with mtkclient, and this one booted too! Unfortunately, it seemed like the DA wasn't able to read partitions or flash anything.<br><br>
39+
40+
Some months later, thanks to [@DiabloSat](https://github.com/progzone122), we were able to use this DA file to dump the firmware.<br><br>
41+
42+
These tries were all made in early 2024, and I decided to just not bother with the device anymore, until Android 14 came.
43+
44+
## The Helio G85 telegram group
45+
46+
In late 2024, I once again tried to look up for an unlocking method for the device, because of how laggy the device became with Android 14.
47+
I searched for `penangf` (Moto G23 codename) on GitHub, and I found that someone was able to extract the Flash Tool from RSA, the same way I did.<br><br>
48+
49+
I looked at the Flash Tool files once again, and thought about how I could use it to unlock the bootloader.<br>
50+
Unfortunately, as already said before, the Download Agent was not able to read partitions or flash anything that wasn't signed.<br>
51+
I decided to look up on telegram, and I found a group where people were discussing on ways to unlock the bootloader, and found out that [DiabloSat](https://github.com/progzone122), the same person which uploaded the flash tool on GitHub, was on the group.<br><br>
52+
53+
For some time, I occasionally checked the group to see if someone managed to unlock the bootloader. Unfortunately, no one did.<br><br>
54+
55+
Near Novemeber 2024, I decided to open an issue on the Flash Tool repository, after I've found out we could use other flash tools to flash the firmware.<br><br>
56+
57+
Unfortunately, this concluded nothing, and I was stuck once again, and decided to once again occasionally check the group.
58+
59+
## The testpoints
60+
61+
Around December 2024, I found another repository popup with the schematics for the phone, and I found out that the device had testpoints, which could be used to force BROM.
62+
63+
I decided to open an issue on the schematics repository, and I was able to get in touch with the DiabloSat, who uploaded the schematics.
64+
65+
From that day to until February 2025, we decided to team up to finally unlock the bootloader of the phone.<br>
66+
We shared ideas, possible testpoints and more, but unfortunately, we couldn't find a way to force BROM.
67+
68+
We started to document all the discoveries we made, which can be accessed [here](https://penangf.fuckyoumoto.xyz).
69+
70+
In the meantime, I decided to decompile the bootloader and the preloader, to find out how the device worked, and I found out that the preloader should be able to.
71+
72+
```c
73+
#define KPDL1 KPCOL0 // 0
74+
#define KPDL2 PWRKEY_HW // 8
75+
#define KPDL3 HOMEKEY_RST // 17
76+
77+
bool are_dl_keys_pressed()
78+
{
79+
if(mtk_detect_key(KPDL1) && mtk_detect_key(KPDL2) && mtk_detect_key(KPDL3))
80+
{
81+
pr_debug("dl keys are pressed\n");
82+
return true;
83+
}
84+
85+
return false;
86+
}
87+
```
88+
89+
```c
90+
#define MODULE "[PLFM]"
91+
92+
void platform_emergency_download(int timeout)
93+
{
94+
pr_debug("%S emergency download mode(timeout=%d)\n", MODULE, timeout);
95+
96+
platform_safe_mode(1, timeout);
97+
98+
mtk_arch_reset(0);
99+
100+
while(1);
101+
}
102+
```
103+
104+
One of these keys is the KPCOL0 testpoint, which was tested thanks to DiabloSat.
105+
106+
![Moto G23 Testpoints](/media/posts/2025/penangf_mb_front_tp.png)
107+
_Photo by DiabloSat_
108+
109+
We were able to find the logs in the `expdb` partition, in which the phone seemed to indeed call the `platform_emergency_download` function, but unfortunately, the device would just reboot into preloader mode.
110+
111+
## Decompiling the bootloader
112+
113+
While DiabloSat was testing the testpoints and trying to force mtkclient to send the device to BROM, I decided to decompile **lk.img**, the bootloader of the device.<br>
114+
115+
There I found something really interesting, our device was indeed able to be unlocked, compared to what official sources said.<br>
116+
117+
The problem was, the device needed a key to be unlocked.<br>
118+
We were blocked again.<br>
119+
120+
But, one day Diablo found out about two important commands for us: `fastboot oem get_key` and `fastboot oem key <KEY>`.<br>
121+
122+
We had it, we thought.<br>
123+
The key from the first command, unfortunately, was not the one we were looking for.<br>
124+
Or so, we thought at first.<br><br>
125+
126+
I tried looking back at LK, and I found out the function that generates the key, which used a SHA256, and for a few days, we tried to reverse engineer the key, but we couldn't.<br>
127+
128+
Then for another week or two, we focused on trying again to force BROM, and Diablo contacted [R0rt1z2](https://github.com/R0rt1z2), who apparently had experience with MediaTek devices.<br>
129+
130+
Roger bought a Moto G13, and he tried to try some of the testpoints we found, but unfortunately, BROM was apparently blocked by efuse, and unfortunately, his device broke.
131+
132+
We thought about exploiting a buffer overflow, but then..<br><br>
133+
134+
I decided to finally reverse engineer how the key was generated from the phone.
135+
136+
```c
137+
#define UNLOCK_KEY_SIZE 32
138+
#define SOC_ID "0123456789ABCDEF0123456789ABCDEF" // Generic SOC ID
139+
140+
int fastboot_flashing_unlock_chk_key(void)
141+
{
142+
char unlock_key[UNLOCK_KEY_SIZE + 1];
143+
unsigned char thing_to_hash[65] = {0};
144+
unsigned char hashed_value[64] = {0};
145+
int len;
146+
147+
memset(thing_to_hash, 0, 65);
148+
149+
len = strlen(SOC_ID);
150+
if (len == UNLOCK_KEY_SIZE) {
151+
fastboot_info(SOC_ID);
152+
mtk_memcpy(thing_to_hash, SOC_ID, UNLOCK_KEY_SIZE);
153+
mtk_memcpy(thing_to_hash + 32, thing_to_hash, 32);
154+
155+
fastboot_info("start fastboot unlock");
156+
fastboot_info(fb_unlock_key_str);
157+
158+
printf("To hash: %s\n", thing_to_hash);
159+
160+
// This calculates the hash of the SOC_ID and stores it in hashed_value
161+
sha256(thing_to_hash, 64, hashed_value);
162+
163+
164+
printf("Hash is: ");
165+
for (int i = 0; i < 32; i++) printf("%02x", hashed_value[i]);
166+
167+
printf("\n");
168+
169+
len = compare_strings_until_length(fb_unlock_key_str, (char*)hashed_value, UNLOCK_KEY_SIZE);
170+
if (len != 0) {
171+
fastboot_fail("Unlock key code is incorrect!");
172+
return 0x7001;
173+
}
174+
175+
fastboot_info("Unlock Success");
176+
len = 0;
177+
}
178+
else {
179+
len = 0x7000;
180+
fastboot_fail("Unlock key length is incorrect!");
181+
}
182+
183+
return len;
184+
}
185+
```
186+
187+
<img src="/media/posts/2025/unlock_key_algorithm.png" style="width: 50%; heigth: 50%"/>
188+
189+
And just like that, I made a python script and asked the other members of the team to try it out.
190+
191+
```python
192+
193+
def oem_keygen(key: str) -> str:
194+
to_hash: str = key * 2
195+
196+
hash: str = sha256(to_hash.encode()).hexdigest()
197+
198+
print("Unlock key: %s" % (hash[:32]))
199+
return hash
200+
```
201+
202+
```bash
203+
➜ fuckyoumoto git:(main) ✗ python oem_keygen.py 061A757D042B2A378D9761E60C9D3FBC
204+
Unlock key: 87f3aef774eb3edbcdef39e2e94d05c9
205+
206+
➜ fuckyoumoto git:(main) ✗ fastboot oem key 87f3aef774eb3edbcdef39e2e94d05c9
207+
(bootloader) open fastboot unlock
208+
OKAY [ 0.000s]
209+
Finished. Total time: 0.000s
210+
➜ fuckyoumoto git:(main) ✗ fastboot flashing unlock
211+
(bootloader) Start unlock flow
212+
213+
(bootloader) 061A757D042B2A378D9761E60C9D3FBC
214+
(bootloader) start fastboot unlock
215+
(bootloader) 87f3aef774eb3edbcdef39e2e94d05c9
216+
(bootloader) Unlock Success
217+
(bootloader) fastboot unlock success
218+
OKAY [ 5.320s]
219+
Finished. Total time: 5.320s
220+
➜ fuckyoumoto git:(main) ✗ fastboot oem lks
221+
(bootloader) lks = 0
222+
OKAY [ 0.005s]
223+
Finished. Total time: 0.005s
224+
```
225+
226+
> We did it.<br>
227+
> The bootloader got unlocked!
228+
229+
## Moving forward
230+
231+
We were able to unlock the bootloader of the Motorola G23, and thanks to [Roger](https://github.com/R0rt1z2), who got another G13 with UART too, we were able to confirm that the same method worked on the G13.
232+
233+
The days later were spent on trying to find a way to boot TWRP (thanks [@GitFASTBOOT](https://github.com/GitFASTBOOT) for making it), and testing GSIs.<br>
234+
235+
<img src="/media/posts/2025/twrp_mainscreen.jpg" alt="TWRP main screen" style="width: 30%; heigth: 30%"/>
236+
237+
238+
The plans for the future are to try to port LineageOS, and spread the word about the device, and how it can be unlocked.
239+
240+
## Chouchou (Custom bootloader)
241+
242+
Now that the phone got unlocked, Roger decided to build a payload to inject code into LK, to be able to add new features to fastboot.
243+
244+
![chouchou injection](/media/posts/2025/chouchou_injection.png)
245+
246+
This payload protects the device from being relocked and blocks flashing of protected partitions that might hard brick the device.
247+
248+
249+
## Video Guide
250+
251+
<iframe height="315" src="https://www.youtube-nocookie.com/embed/3fHfiqM7UUg" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
252+
253+
## Conclusion
254+
255+
We finally were able to unlock the bootloader of the phone, after 2 years from its release date, finally making the device fully ours.
256+
257+
Special thanks to DiabloSat, R0rt1z2 (Roger) for helping me out with this project, GitFASTBOOT for making TWRP, and everyone else who helped us out.<br><br>
258+
259+
260+
261+
Check [our documentation](https://penangf.fuckyoumoto.xyz) for more information on the device!
20.6 KB
Loading
11.9 MB
Loading

media/posts/2025/twrp_mainscreen.jpg

35.8 KB
Loading
43.6 KB
Loading

0 commit comments

Comments
 (0)