LAF (Download mode) What is it, and how can we root with it?

Search This thread

runningnak3d

Recognized Developer
Nov 10, 2010
2,649
7,227
Largo
EDIT: 2018-08-14

Wow -- re-reading this, whoa, what a bunch of assumptions / misinformation.

Note to self, update this post with the ACTUAL findings, and the ACTUAL way that the *current* (as of Nougat and Oreo) works. Also, add in the way that Google is going to F**K us all in the A** by adding AVB to the boot, and recovery, (and then LG can very easily add it to laf) in 9.0 (Pie). Pie in the face. A**holes.


LAF Is the LG Advanced Flash. When you hold vol up and insert your USB cable to get into download mode, aboot loads a partition called LAF.

It is just a boot image, but instead of the ramdisk (initrd) doing things like mounting system, so Android boots, it loads download mode.

As part of my research on the Boot Chain of Trust (BCT), it occurred to me that if you have an unlocked boot loader, you can flash whatever you want to the recovery partition. The only LG V20s that have unlockable boot loaders WITHOUT using the engineering aboot are the US996 (unlock.bin from LG), and the H918 (fastboot oem unlock). This wouldn't really be needed by the US996 since it has all fastboot commands available, the H918 however, does not.

In the thread about rooting the H918, I came up with the idea of patching LG UP to ignore ARB (Anti-RollBack). When a phone has an unlocked boot loader, aboot (applications boot) doesn't do RSA verification on the boot image. In addition, the boot image doesn't talk to the QFPROM to increment ARB. Heck, the boot image doesn't even have the code needed to write to QFPROM (ARB qfuse). So, the only thing stopping us from flashing an older kernel and system image is that LG UP checks the KDZ to see what ARB version it is at, and it checks QFPROM to see what ARB version the phone is at. If the KDZ is less -- it fails.

So, that is one way. Patch LG UP to ignore ARB, and then flash boot and system from an older KDZ. Unfortunately, my reverse engineering skills aren't great. On the other hand, my ability to read packet dumps and figure out protocols is much better (worked on -- and still work on World of Warcraft emulation). So I got to thinking, LG UP talks to LAF, so time to load up some wireshark, and start sniffing the USB bus to figure out what exactly is being said.

After working on this for a couple of days, I thought that there HAS to be someone else out there that thought of this same thing. Turns out I was correct: link.

As you can see it is a little old, but it put me much farther ahead than I would have been. I think the project was dropped, because as stated above, you need an unlocked boot loader -- and I think T-Mobile is the only one that still does.

BUT we have an engineering aboot. So, this tool is of use to ALL V20s, since we can just push the engineering aboot, and twrp just like back when dirtycow worked.

Finally to the point of this post. I would like some help updating the protocol. It appears that dmesg works no matter what:


Code:
<snip>
 pseudo_chg_ui[0]
<3>[ 3132.160144 / 01-01 01:06:45.539][1] LGE charging scenario : state 0 -> 0(0-0), temp=31, volt=3804, BTM=0, charger=1, cur_set=0/0, chg_cur = -232
<6>[ 3132.160154 / 01-01 01:06:45.539][1] [LGE-CC] lge_monitor_batt_temp_work : otp_ibat_current=0
<6>[ 3132.160177 / 01-01 01:06:45.539][1] [LGE-CC] lge_monitor_batt_temp_work : Reported Capacity : 17 / voltage : 3804
<6>[ 3133.448127 / 01-01 01:06:46.819][3] FG: update_sram_data: soc:[17], soc_raw[1863], voltage:[3804909], ocv:[3749062], current:[-232542], batt_temp:[310], charge_raw [374287 / 3167000]
<12>[ 3136.173937 / 01-01 01:06:49.549][3] [LAF] protocol version mismatch. rcv = 1000001, dev = 1000004 
<12>[ 3136.174137 / 01-01 01:06:49.549][3] [LAF] read property item = ATT
<12>[ 3136.289486 / 01-01 01:06:49.659][2] [LAF] execvp failed. error = 2
<6>[ 3136.560128 / 01-01 01:06:49.939][3] pet_watchdog [enable : 1, jiffies : 4295250952, delay_time : 1000]
<6>[ 3137.006156 / 01-01 01:06:50.379][2] SMBCHG: lgcc_charger_reginfo: [STATUS] USB_PRESENT[1], PARALLEL_STATUS[2], USB_TYPE[SDP]
<6>[ 3137.006165 / 01-01 01:06:50.379][2] SMBCHG: lgcc_charger_reginfo: [STATUS] TOTAL_IUSB[500], PMI_IUSB[1700], SMB_IUSB[0]
<6>[ 3137.006172 / 01-01 01:06:50.379][2] SMBCHG: lgcc_charger_reginfo: [STATUS] TOTAL_IBAT[3100/3100(vote)], PMI_IBAT[3000], SMB_IBAT[1000]
<6>[ 3137.006179 / 01-01 01:06:50.379][2] SMBCHG: lgcc_charger_reginfo: [STATUS] CABLE_ID [OPEN], CABLE_INFO[SDP], USBIN_VOL[4973]
<6>[ 3137.006185 / 01-01 01:06:50.379][2] SMBCHG: lgcc_charger_reginfo: [STATUS] BATT_SOC[17], BATT_VOL[3804], BATT_TEMP[310], BATT_CUR[-232542]
<6>[ 3137.006193 / 01-01 01:06:50.379][2] SMBCHG: lgcc_charger_reginfo: [STATUS] CHG_EN[Enable], CHG_STATE[CHARGING/500MA/CC], SAFTY_STATE[Set/Not yet]
<6>[ 3137.006199 / 01-01 01:06:50.379][2] SMBCHG: lgcc_charger_reginfo: [STATUS] XO_tHERM[36], PA_THERM[33], BOARD_THERM[32] VTS[333]
<6>[ 3142.000053 / 01-01 01:06:55.379][2] [bm] monitoring
<12>[ 3142.384450 / 01-01 01:06:55.759][3] [LAF] protocol version mismatch. rcv = 1000001, dev = 1000004 
<12>[ 3142.384664 / 01-01 01:06:55.759][3] [LAF] read property item = ATT
<12>[ 3142.498642 / 01-01 01:06:55.869][3] [LAF] dmesg!!


Enough to let me know that at the very least, the protocol version has changed.

So, once the missing pieces are back in place, we will be able to once again root any model, on any security patch.

Why can't they plug this hole? They could actually. They could force all phones to require OTA updates -- no more download mode. Until they do, they can change the protocol all they want, but as long as LG UP can talk to the phone, then it can be figured out once again. As for the engineering aboot. That can of worms can't be closed -- they have no way of updating the RSA key in the CPU. Well they could have, if they didn't decide to go the full on / locked down / method. There are slots for 4 keys in QFPROM, but they made the mistake of locking the CPU so that no new keys can be written. The advantage to them was that people like myself can't write my own key. The disadvantage is that if something like the eng aboot leaks, they can't do a thing about it.

So -- WHO'S WITH ME?!? :)

-- Brian
 
Last edited:

JerichoAbles

Senior Member
Jun 26, 2017
59
9
You bet your gosh dang angus beef I'm with you, but I've got a US996UCL so bootloader unlocking is a nono, but I hope this works... That said, I'm not a developer, but you have all my moral support and potentially monetary if needed and if possible.
 
Last edited:

askermk2000

Senior Member
Jul 9, 2015
1,229
2,669
Moto G
LG G5
Hey Brian

It's great that you're doing this and I really hope you'll get some help from other able computer geniuses :)
I myself don't have the skills for this sort of thing.

On another note; I now using a G5, so I'm back sort of :)
 

me2151

Senior Member
Apr 12, 2012
2,189
4,496
Jacksonville, FL
LAF Is the LG Advanced Flash. When you hold vol up and insert your USB cable to get into download mode, aboot loads a partition called LAF.

It is just a boot image, but instead of the ramdisk (initrd) doing things like mounting system, so Android boots, it loads download mode.

As part of my research on the Boot Chain of Trust (BCT), it occurred to me that if you have an unlocked boot loader, you can flash whatever you want to the recovery partition. The only LG V20s that have unlockable boot loaders WITHOUT using the engineering aboot are the US996 (unlock.bin from LG), and the H918 (fastboot oem unlock). This wouldn't really be needed by the US996 since it has all fastboot commands available, the H918 however, does not.

In the thread about rooting the H918, I came up with the idea of patching LG UP to ignore ARB (Anti-RollBack). When a phone has an unlocked boot loader, aboot (applications boot) doesn't do RSA verification on the boot image. In addition, the boot image doesn't talk to the QFPROM to increment ARB. Heck, the boot image doesn't even have the code needed to write to QFPROM (ARB qfuse). So, the only thing stopping us from flashing an older kernel and system image is that LG UP checks the KDZ to see what ARB version it is at, and it checks QFPROM to see what ARB version the phone is at. If the KDZ is less -- it fails.

So, that is one way. Patch LG UP to ignore ARB, and then flash boot and system from an older KDZ. Unfortunately, my reverse engineering skills aren't great. On the other hand, my ability to read packet dumps and figure out protocols is much better (worked on -- and still work on World of Warcraft emulation). So I got to thinking, LG UP talks to LAF, so time to load up some wireshark, and start sniffing the USB bus to figure out what exactly is being said.

After working on this for a couple of days, I thought that there HAS to be someone else out there that thought of this same thing. Turns out I was correct: link.

As you can see it is a little old, but it put me much farther ahead than I would have been. I think the project was dropped, because as stated above, you need an unlocked boot loader -- and I think T-Mobile is the only one that still does.

BUT we have an engineering aboot. So, this tool is of use to ALL V20s, since we can just push the engineering aboot, and twrp just like back when dirtycow worked.

Finally to the point of this post. I would like some help updating the protocol. It appears that dmesg works no matter what:


Code:
<snip>
 pseudo_chg_ui[0]
<3>[ 3132.160144 / 01-01 01:06:45.539][1] LGE charging scenario : state 0 -> 0(0-0), temp=31, volt=3804, BTM=0, charger=1, cur_set=0/0, chg_cur = -232
<6>[ 3132.160154 / 01-01 01:06:45.539][1] [LGE-CC] lge_monitor_batt_temp_work : otp_ibat_current=0
<6>[ 3132.160177 / 01-01 01:06:45.539][1] [LGE-CC] lge_monitor_batt_temp_work : Reported Capacity : 17 / voltage : 3804
<6>[ 3133.448127 / 01-01 01:06:46.819][3] FG: update_sram_data: soc:[17], soc_raw[1863], voltage:[3804909], ocv:[3749062], current:[-232542], batt_temp:[310], charge_raw [374287 / 3167000]
<12>[ 3136.173937 / 01-01 01:06:49.549][3] [LAF] protocol version mismatch. rcv = 1000001, dev = 1000004 
<12>[ 3136.174137 / 01-01 01:06:49.549][3] [LAF] read property item = ATT
<12>[ 3136.289486 / 01-01 01:06:49.659][2] [LAF] execvp failed. error = 2
<6>[ 3136.560128 / 01-01 01:06:49.939][3] pet_watchdog [enable : 1, jiffies : 4295250952, delay_time : 1000]
<6>[ 3137.006156 / 01-01 01:06:50.379][2] SMBCHG: lgcc_charger_reginfo: [STATUS] USB_PRESENT[1], PARALLEL_STATUS[2], USB_TYPE[SDP]
<6>[ 3137.006165 / 01-01 01:06:50.379][2] SMBCHG: lgcc_charger_reginfo: [STATUS] TOTAL_IUSB[500], PMI_IUSB[1700], SMB_IUSB[0]
<6>[ 3137.006172 / 01-01 01:06:50.379][2] SMBCHG: lgcc_charger_reginfo: [STATUS] TOTAL_IBAT[3100/3100(vote)], PMI_IBAT[3000], SMB_IBAT[1000]
<6>[ 3137.006179 / 01-01 01:06:50.379][2] SMBCHG: lgcc_charger_reginfo: [STATUS] CABLE_ID [OPEN], CABLE_INFO[SDP], USBIN_VOL[4973]
<6>[ 3137.006185 / 01-01 01:06:50.379][2] SMBCHG: lgcc_charger_reginfo: [STATUS] BATT_SOC[17], BATT_VOL[3804], BATT_TEMP[310], BATT_CUR[-232542]
<6>[ 3137.006193 / 01-01 01:06:50.379][2] SMBCHG: lgcc_charger_reginfo: [STATUS] CHG_EN[Enable], CHG_STATE[CHARGING/500MA/CC], SAFTY_STATE[Set/Not yet]
<6>[ 3137.006199 / 01-01 01:06:50.379][2] SMBCHG: lgcc_charger_reginfo: [STATUS] XO_tHERM[36], PA_THERM[33], BOARD_THERM[32] VTS[333]
<6>[ 3142.000053 / 01-01 01:06:55.379][2] [bm] monitoring
<12>[ 3142.384450 / 01-01 01:06:55.759][3] [LAF] protocol version mismatch. rcv = 1000001, dev = 1000004 
<12>[ 3142.384664 / 01-01 01:06:55.759][3] [LAF] read property item = ATT
<12>[ 3142.498642 / 01-01 01:06:55.869][3] [LAF] dmesg!!


Enough to let me know that at the very least, the protocol version has changed.

So, once the missing pieces are back in place, we will be able to once again root any model, on any security patch.

Why can't they plug this hole? They could actually. They could force all phones to require OTA updates -- no more download mode. Until they do, they can change the protocol all they want, but as long as LG UP can talk to the phone, then it can be figured out once again. As for the engineering aboot. That can of worms can't be closed -- they have no way of updating the RSA key in the CPU. Well they could have, if they didn't decide to go the full on / locked down / method. There are slots for 4 keys in QFPROM, but they made the mistake of locking the CPU so that no new keys can be written. The advantage to them was that people like myself can't write my own key. The disadvantage is that if something like the eng aboot leaks, they can't do a thing about it.

So -- WHO'S WITH ME?!? :)

-- Brian

Btw engineering BL dont work on TMO. insta brick. This method had already been figured out. Look in the G5 forums. I believe the guys name is fluffymittens or something.
 

runningnak3d

Recognized Developer
Nov 10, 2010
2,649
7,227
Largo
Been sick as crap for a few days so this project (and pretty much everything else) got put on hold.
@me2151 I know the eng aboot doesn't work on H918. Those have a different key. The H918 doesn't need the eng aboot since they are able to unlock their boot loaders. I looked in the G5 forums, and I couldn't find anything that pertains to this. A link would sure be nice so that efforts aren't duplicated.

-- Brian
 

JerichoAbles

Senior Member
Jun 26, 2017
59
9
How can we use the eng aboot?

---------- Post added at 03:53 AM ---------- Previous post was at 03:43 AM ----------

I found something. *#546368#*996# (Use the number after your US/VS/H) and type that into your dialer, Go to SVC Menu and let's compare some things and see if there's anything we can use there.

---------- Post added at 04:01 AM ---------- Previous post was at 03:53 AM ----------

Oh, and what's this LGODM thing? Is there anything we can use from there?

---------- Post added at 04:03 AM ---------- Previous post was at 04:01 AM ----------

Is the US Open Market codename also Elsa_Nao? Or just Elsa
 

runningnak3d

Recognized Developer
Nov 10, 2010
2,649
7,227
Largo
@JerichoAbles If you have a rooted v20 other than a US996 or H918 then you are using the engineering aboot. In order to root a modern Android phone, you need to be able to unlock the boot loader because if it isn't unlocked, then it does all kinds of nasty things like verify the integrity of the boot partition, and the recovery partition. So, if you have a locked boot loader, and you can't unlock it, you can't root your phone. The closest you are going to be able to come, is a root shell IF you can disable dm-verity without having the kernel stop booting. With an unlocked boot loader, you can flash whatever you want to your boot partition, and the phone will at least TRY to boot it. With a locked boot loader, the boot process would halt the minute the boot partition fails the RSA check.

So, what about the poor shmoes that can't unlock their boot loaders (everyone besides H918 and US996 owners raise your hands) -- well -- that is where the engineering boot loader comes into play. It is unlocked "from the factory".
Also, LG made a huge mistake and used the same RSA key in just about every variant of the V20. So, that is why the LS997, VS995, H910, H915, H990, H990DS can all use the engineering aboot. So the rest of us get to flash the eng aboot, and then we are free to flash twrp, a custom kernel, etc -- because it is unlocked, and does no verification.

If you have one of the above mentioned models that doesn't have a KDZ, and are still on ARB 0, dump your phone, flash a KDZ from one of the other models that is still rootable, and have fun. See my thread on how to root the H910 on v10m for an example.

Bottom line though -- it doesn't need to be that hard. We crack the LAF protocol, and we can send whatever we want, so for an H918 with an unlocked boot loader, only need to send TWRP to recovery and viola -- root (or possibility of root). Right now the only thing that is preventing that is the fact that we don't understand the LAF protocol.

So what about the other model. Well, we send the eng aboot and TWRP -- and viola -- root (or the possibility).

So with that said -- back to sniffing I go.

-- Brian
 

runningnak3d

Recognized Developer
Nov 10, 2010
2,649
7,227
Largo
Oh -- now this is interesting. Massive qfuse debug incoming:


[QFUSE]qfusing_show start
[QFUSE]qfprom_verify_data start
[QFUSE]qfprom_secdat_read start
[QFUSE]qfprom_secdat_read : secdata file already loaded
[QFUSE]qfprom_result_check_data start
[QFUSE]qfprom_result_check_data: 0x70150 check complete
[QFUSE]qfprom_result_check_data: 10 fusing_verification
[QFUSE]qfprom_result_check_data: 0x70158 check complete
[QFUSE]qfprom_result_check_data: 10 fusing_verification
[QFUSE]qfprom_result_check_data: 0x70160 check complete
[QFUSE]qfprom_result_check_data: 50 fusing_verification
[QFUSE]qfprom_result_check_data: 0x70188 check complete
[QFUSE]qfprom_result_check_data: 54 fusing_verification
[QFUSE]qfprom_result_check_data: 0x70190 check complete
[QFUSE]qfprom_result_check_data: 55 fusing_verification
[QFUSE]qfprom_result_check_data: 0x70190 check complete
[QFUSE]qfprom_result_check_data: 55 fusing_verification
[QFUSE]qfprom_result_check_data: 0x70190 check complete
[QFUSE]qfprom_result_check_data: 75 fusing_verification
[QFUSE]qfprom_result_check_data: 0x701c8 check complete
[QFUSE]qfprom_result_check_data: f5 fusing_verification
[QFUSE]qfprom_result_check_data: 0x70378 check complete
[QFUSE]qfprom_result_check_data: f7 fusing_verification
[QFUSE]qfprom_result_check_data: 0x703b0 check complete
[QFUSE]qfprom_result_check_data: ff fusing_verification
[QFUSE]qfprom_result_check_data end
[QFUSE]qfprom_verification_blow_data start
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x70150, value:0xe000000
[QFUSE]qfprom_read end
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x70154, value:0x0
[QFUSE]qfprom_read end
[QFUSE]qfprom_verification_blow_data: 0x70150 check complete
[QFUSE]qfprom_verification_blow_data: 10 fusing_verification
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x70158, value:0x6f007c3c
[QFUSE]qfprom_read end
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x7015c, value:0x0
[QFUSE]qfprom_read end
[QFUSE]qfprom_verification_blow_data: 0x70158 check complete
[QFUSE]qfprom_verification_blow_data: 10 fusing_verification
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x70160, value:0xf000000
[QFUSE]qfprom_read end
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x70164, value:0x0
[QFUSE]qfprom_read end
[QFUSE]qfprom_verification_blow_data: 0x70160 check complete
[QFUSE]qfprom_verification_blow_data: 50 fusing_verification
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x70188, value:0x104000
[QFUSE]qfprom_read end
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x7018c, value:0xf7bfbde0
[QFUSE]qfprom_read end
[QFUSE]qfprom_verification_blow_data: 0x70188 check complete
[QFUSE]qfprom_verification_blow_data: 54 fusing_verification
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x70194, value:0x26c0031
[QFUSE]qfprom_read end
[QFUSE]qfprom_verification_blow_data: 0x70190 check complete
[QFUSE]qfprom_verification_blow_data: 55 fusing_verification
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x70194, value:0x26c0031
[QFUSE]qfprom_read end
[QFUSE]qfprom_verification_blow_data: 0x70190 check complete
[QFUSE]qfprom_verification_blow_data: 75 fusing_verification
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x70198, value:0x0
[QFUSE]qfprom_read end
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x7019c, value:0xf
[QFUSE]qfprom_read end
[QFUSE]qfprom_verification_blow_data: 0x70198 check complete
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x701c8, value:0x9a61f72c
[QFUSE]qfprom_read end
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x701cc, value:0x7268d27
[QFUSE]qfprom_read end
[QFUSE]qfprom_verification_blow_data: 0x701c8 check complete
[QFUSE]qfprom_verification_blow_data: f5 fusing_verification
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x701d0, value:0x79ea7e3f
[QFUSE]qfprom_read end
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x701d4, value:0x794b7fbb
[QFUSE]qfprom_read end
[QFUSE]qfprom_verification_blow_data: 0x701d0 check complete
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x701d8, value:0x4821c249
[QFUSE]qfprom_read end
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x701dc, value:0x8e05ea7f
[QFUSE]qfprom_read end
[QFUSE]qfprom_verification_blow_data: 0x701d8 check complete
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x701e0, value:0xfecf72a0
[QFUSE]qfprom_read end
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x701e4, value:0x9614ce38
[QFUSE]qfprom_read end
[QFUSE]qfprom_verification_blow_data: 0x701e0 check complete
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x70378, value:0x303030
[QFUSE]qfprom_read end
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x7037c, value:0x69000000
[QFUSE]qfprom_read end
[QFUSE]qfprom_verification_blow_data: 0x70378 check complete
[QFUSE]qfprom_verification_blow_data: f7 fusing_verification
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x703b0, value:0x73
[QFUSE]qfprom_read end
[QFUSE]qfprom_verification_blow_data: 0x703b0 check complete
[QFUSE]qfprom_verification_blow_data end
[QFUSE]verification_blow_value = ff
[QFUSE]qfprom_verify_data: verification success
[QFUSE]qfprom_verify_data end
[QFUSE]qfusing_show end
[LAF] read property item = H91810j
[LAF] read property item = V10j
[LAF] read property item = 0
[LAF] read property item = user
[LAF] read property item = LG-H918
[LAF] read property item = 7.0
[LAF] read property item = US
[LAF] read property item = TMO
[LAF] read property item = msm8996
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x70198, value:0x0
[QFUSE]qfprom_read end
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x7019c, value:0xf
[QFUSE]qfprom_read end
[QFUSE]qfprom_is_version_enable : Anti-rollback fuse is blowed
[LAF] AR status? = E

[QFUSE]qfprom_read_version_show : Check rollback version
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x70198, value:0x0
[QFUSE]qfprom_read end
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x7019c, value:0xf
[QFUSE]qfprom_read end
[QFUSE]qfprom_is_version_enable : Anti-rollback fuse is blowed
[QFUSE]qfprom_read_version_show : Selected version name <appsb

[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x70168, value:0x0
[QFUSE]qfprom_read end
[QFUSE]qfprom_read start
[QFUSE]qfprom_read address:0x7016c, value:0x0
[QFUSE]qfprom_read end
[QFUSE]qfprom_version_check : Version - 0


This validates a couple of my theories on how / when the QFPROM is updated, but also opens up some ideas as to how we can get around it (them).

-- Brian
 

runningnak3d

Recognized Developer
Nov 10, 2010
2,649
7,227
Largo
And some more interesting....


<6>[ 1.165317 / 01-01 00:00:01.159][3] -------------------------------------------------
<6>[ 1.165323 / 01-01 00:00:01.159][3] below logs are got from bootloader
<6>[ 1.165329 / 01-01 00:00:01.159][3] -------------------------------------------------
<6>[ 1.165335 / 01-01 00:00:01.159][3]
<6>[ 1.165394 / 01-01 00:00:01.159][3] B - 460763 - DPE_MEMC_STATUS_0: DDR0 0x0000FFFF, DDR1 0x0000FFFF
<6>[ 1.165432 / 01-01 00:00:01.159][3] B - 460794 - ch 2, cs 1, mr8 0x08080808
<6>[ 1.165489 / 01-01 00:00:01.159][3] B - 460794 - DPE_MEMC_STATUS_0: DDR0 0x0000FFFF, DDR1 0x0000FFFF
<6>[ 1.165561 / 01-01 00:00:01.159][3] B - 461038 - ddr_info: SKH ver=21914 ch=0x3 cs=0x3 rev1=0x4 rev2=0x0 mr8=0x8 hwrev=12
<6>[ 1.165595 / 01-01 00:00:01.159][3] B - 461038 - ddr_trained[36c,0x3]
<6>[ 1.165634 / 01-01 00:00:01.159][3] B - 461038 - ddr_initialize_device, Delta
<6>[ 1.165683 / 01-01 00:00:01.159][3] B - 461068 - DDR ID, Rank 0, Rank 1, 0x6, 0x400, 0x400
<6>[ 1.165720 / 01-01 00:00:01.159][3] B - 461129 - [DDR] remap_size: 4096MB
<6>[ 1.165770 / 01-01 00:00:01.159][3] B - 461129 - [DDR] remap_info CS0: 0x80000000, CS1: 0x0
<6>[ 1.165803 / 01-01 00:00:01.159][3] B - 461251 - Basic DDR tests done
<6>[ 1.165839 / 01-01 00:00:01.159][3] B - 517219 - boot_pre_longkey_check
<6>[ 1.165874 / 01-01 00:00:01.159][3] B - 517219 - powerkey release state
<6>[ 1.165905 / 01-01 00:00:01.159][3] B - 525149 - Image Load, Start
<6>[ 1.165940 / 01-01 00:00:01.159][3] B - 525240 - bootLUN:1, currentLUN:1
<6>[ 1.165978 / 01-01 00:00:01.159][3] B - 525240 - xbl is matched with bootLUN
<6>[ 1.166028 / 01-01 00:00:01.159][3] D - 976 - LGE SBL Image Loaded, Delta - (51579 Bytes)
<6>[ 1.166059 / 01-01 00:00:01.159][3] B - 526094 - clock_init, Start
<6>[ 1.166089 / 01-01 00:00:01.159][3] B - 526430 - Image Load, Start
<6>[ 1.166145 / 01-01 00:00:01.159][3] D - 3843 - QSEE Dev Config Image Loaded, Delta - (46200 Bytes)
<6>[ 1.166176 / 01-01 00:00:01.159][3] B - 530669 - Image Load, Start
<6>[ 1.166223 / 01-01 00:00:01.159][3] D - 2562 - APDP Image Loaded, Delta - (7768 Bytes)
<6>[ 1.166255 / 01-01 00:00:01.159][3] B - 533262 - Image Load, Start
<6>[ 1.166305 / 01-01 00:00:01.159][3] D - 55266 - QSEE Image Loaded, Delta - (1640900 Bytes)
<6>[ 1.166335 / 01-01 00:00:01.159][3] B - 588497 - Image Load, Start
<6>[ 1.166373 / 01-01 00:00:01.159][3] B - 589260 - QFPROM flag != QFPROMblown
<6>[ 1.166419 / 01-01 00:00:01.159][3] D - 762 - SEC Image Loaded, Delta - (4116 Bytes)
<6>[ 1.166460 / 01-01 00:00:01.159][3] B - 589809 - sbl1_efs_handle_cookies, Start
<6>[ 1.166500 / 01-01 00:00:01.159][3] D - 91 - sbl1_efs_handle_cookies, Delta
<6>[ 1.166531 / 01-01 00:00:01.159][3] B - 589931 - Image Load, Start
<6>[ 1.166580 / 01-01 00:00:01.159][3] D - 12139 - QHEE Image Loaded, Delta - (254184 Bytes)
<6>[ 1.166611 / 01-01 00:00:01.159][3] B - 602100 - Image Load, Start
<6>[ 1.166660 / 01-01 00:00:01.159][3] D - 11193 - RPM Image Loaded, Delta - (223932 Bytes)
<6>[ 1.166691 / 01-01 00:00:01.159][3] B - 613294 - Image Load, Start
<6>[ 1.166735 / 01-01 00:00:01.159][3] D - 0 - STI Image Loaded, Delta - (0 Bytes)
<6>[ 1.166765 / 01-01 00:00:01.159][3] B - 614087 - cable type is 8
<6>[ 1.166818 / 01-01 00:00:01.159][3] B - 789096 - pm_app_smbchg: TA/USB attached, battery present
<6>[ 1.166864 / 01-01 00:00:01.159][3] B - 789157 - Charger source: SDP before APSD rerun
<6>[ 1.166914 / 01-01 00:00:01.159][3] B - 790011 - [ADC][mvol=1789][hw_rev_table[12]=[1700]
<6>[ 1.166958 / 01-01 00:00:01.159][3] B - 798002 - [Display] SW49407_QHD_DSC_CMD_PANEL
<6>[ 1.166992 / 01-01 00:00:01.159][3] B - 798032 - panel_type = CMD_PANEL
<6>[ 1.167025 / 01-01 00:00:01.159][3] B - 805352 - Panel power on done
<6>[ 1.167060 / 01-01 00:00:01.159][3] B - 805352 - soc_version:0x00030001
<6>[ 1.167092 / 01-01 00:00:01.159][3] B - 850431 - Panel pre init done
<6>[ 1.167154 / 01-01 00:00:01.159][3] [0] logbuf_relocate_sbl_log: log_start=0x85e11040, log_size=0x815, end_time=0
<6>[ 1.167173 / 01-01 00:00:01.159][3] [0] welcome to lk
<6>[ 1.167179 / 01-01 00:00:01.159][3]
<6>[ 1.167200 / 01-01 00:00:01.159][3] [10] platform_init()
<6>[ 1.167219 / 01-01 00:00:01.159][3] [10] target_init()
<6>[ 1.167239 / 01-01 00:00:01.159][3] [10] RPM GLink Init
<6>[ 1.167271 / 01-01 00:00:01.159][3] [10] Opening RPM Glink Port success
<6>[ 1.167302 / 01-01 00:00:01.159][3] [10] Opening SSR Glink Port success
<6>[ 1.167347 / 01-01 00:00:01.159][3] [10] Glink Connection between APPS and RPM established
<6>[ 1.167393 / 01-01 00:00:01.159][3] [10] Glink Connection between APPS and RPM established
<6>[ 1.167450 / 01-01 00:00:01.159][3] [20] bootmode_set_board_revision: board revision value is 12 from smem
<6>[ 1.167479 / 01-01 00:00:01.159][3] [20] HW Rev(12), vol_up gpio(2)
<6>[ 1.167501 / 01-01 00:00:01.159][3] [30] UFS init success
<6>[ 1.167538 / 01-01 00:00:01.159][3] [70] SW3800_Authentication [vendor code: 1]
<6>[ 1.167571 / 01-01 00:00:01.159][3] [120] set_dload_mode: download_mode:0


This verifies the order that parts of the firmware are loaded in. It also invalidates that I thought they weren't loaded when in download mode. I can now verify download mode will still load even if they fail verification.

This also validates that booting from SD card is no longer possible:

Code:
<6>[    1.165940 / 01-01 00:00:01.159][3] B -    525240 - bootLUN:1, currentLUN:1
<6>[    1.165978 / 01-01 00:00:01.159][3] B -    525240 - xbl is matched with bootLUN
<6>[    1.166028 / 01-01 00:00:01.159][3] D -       976 - LGE SBL Image Loaded, Delta - (51579 Bytes)
bootLUN is pulled from QFPROM, so they COULD have had SD card support, because ...... notice that SBL is a delta of XBL.

EDIT: my understanding of this was backwards. I now not only think it is possible to boot from SD card, but with a little more work, I am sure I can get it.

-- Brian
 
Last edited:

runningnak3d

Recognized Developer
Nov 10, 2010
2,649
7,227
Largo
Oh now this is promising:


<12>[ 1725.910810 / 01-08 00:52:31.299][0] [LAF] default access list.
<12>[ 1725.910904 / 01-08 00:52:31.299][0] [LAF] use write protection for /dev/block/sda
<12>[ 1725.910945 / 01-08 00:52:31.299][0] [LAF] Not protected partition!!! /dev/block/sda
<12>[ 1725.911067 / 01-08 00:52:31.299][0] [LAF] success to open the flash driver, dev = /dev/block/sda, fd = 39


Unfortunately I don't want to flash an entire block device, I want to flash a partition. But this is a start. Heck, I could flash the entire block device as long as it was valid. That would mean pulling down sda, loopback mount the image so that I would have the partitions. Change them locally, and then send sda back to the phone.

More to come! But I can tell you that this IS happening. ANY LG phone will be rootable between this research, and the research on unlocking bootloaders on phones that don't have fastboot.

-- Brian
 

runningnak3d

Recognized Developer
Nov 10, 2010
2,649
7,227
Largo
Well, I am still missing something that makes this writable:

/dev/block/sde1 is boot (IE: the kernel). It doesn't like me trying to write to that. UGH!!! Back to looking at packet sniffs. If LG UP can write to it, *I* can write to it.

<12>[ 590.222848 / 01-01 00:09:52.629][1] [LAF] Not protected partition!!! /dev/block/sde1
<5>[ 590.222992 / 01-01 00:09:52.629][1] audit: type=1400 audit(1451606992.629:5): avc: denied { read } for pid=483 comm="lafd" name="sde1" dev="tmpfs" ino=15965 scontext=u:r:vold:s0 tcontext=u:eek:bject_r:boot_block_device:s0 tclass=blk_file permissive=0
<12>[ 590.223035 / 01-01 00:09:52.629][1] [LAF] try open, fn = /dev/block/sde1, error = Permission denied, fd = -1, flag = 0
<12>[ 590.223098 / 01-01 00:09:52.629][1] [LAF] open failed, fn = /dev/block/sde1, error = Permission denied, fd = -1, flag = 0
<12>[ 590.223165 / 01-01 00:09:52.629][1] [LAF] laf_message.command = 0x4e45504f(OPEN)
<12>[ 590.223217 / 01-01 00:09:52.629][1] [LAF] laf_message.arg0 = 0x0
<12>[ 590.223264 / 01-01 00:09:52.629][1] [LAF] laf_message.arg1 = 0x0
<12>[ 590.223311 / 01-01 00:09:52.629][1] [LAF] laf_message.arg_opt0 = 0x0
<12>[ 590.223355 / 01-01 00:09:52.629][1] [LAF] laf_message.arg_opt1 = 0x0
<12>[ 590.223400 / 01-01 00:09:52.629][1] [LAF] laf_message.data_length = 0x10
<12>[ 590.223444 / 01-01 00:09:52.629][1] [LAF] laf_message.data_check = 0x5b2d
<12>[ 590.223487 / 01-01 00:09:52.629][1] [LAF] laf_message.magic = 0xb1baafb0

-- Brian
 

pbedard

Senior Member
Jul 30, 2010
4,386
1,122
boston
Rhanks for your effort i rooted same day dirty santa came out but now its gotten old and laggy asf due to rtcd and i get shut it off linux is too hard for me to set up
 

storm68

Senior Member
Sep 8, 2010
1,881
551
Orlando
Oh now this is promising:


<12>[ 1725.910810 / 01-08 00:52:31.299][0] [LAF] default access list.
<12>[ 1725.910904 / 01-08 00:52:31.299][0] [LAF] use write protection for /dev/block/sda
<12>[ 1725.910945 / 01-08 00:52:31.299][0] [LAF] Not protected partition!!! /dev/block/sda
<12>[ 1725.911067 / 01-08 00:52:31.299][0] [LAF] success to open the flash driver, dev = /dev/block/sda, fd = 39


Unfortunately I don't want to flash an entire block device, I want to flash a partition. But this is a start. Heck, I could flash the entire block device as long as it was valid. That would mean pulling down sda, loopback mount the image so that I would have the partitions. Change them locally, and then send sda back to the phone.

More to come! But I can tell you that this IS happening. ANY LG phone will be rootable between this research, and the research on unlocking bootloaders on phones that don't have fastboot.

-- Brian
That is just amazing. Your a genius... Thank you so much for your devotion and time.
 
  • Like
Reactions: androiddiego

runningnak3d

Recognized Developer
Nov 10, 2010
2,649
7,227
Largo
You welcome, but the genius work is still to come :)

Unfortunately it looks like I am going to have to pay for Hopper (the arm64 decompiler). The trial only gives you 30 minutes and then you have to reload -- and that is a PAIN.

[LAF] not found access list. 0000g

That right there is why I am going to have to reverse lafd. It appears that there is an access list that is stored, but it doesn't appear to be per partition. I sent a valid access list straight from an LG UP dump, and I can't get it to write. 0000 above was just me testing something.... :)

Anyway -- more to come.

-- Brian
 

runningnak3d

Recognized Developer
Nov 10, 2010
2,649
7,227
Largo
So - step1 - DONE! I can pull an image off a phone.

I know -- not really the way we want to go, but getting the ability to DUMP partitions is just as important as being able to write them. Also, I don't risk blowing up my phones by dumping data. I am going to have to do this a couple of times and do diffs of dumps that I make the "normal" way to make sure that they are identical all the time and there isn't some weird timing thing that I missed. Also, can't just issue an OPEN command, and then a READ command and have it go -- YEA! HERE have a partition. Even after all the setup is done for the READ to start, you can only read 4megs at a time. I could probably crank that up to 8megs, but anything over 8 megs locks up lafd. I am guessing it is some kind of buffer limit. Anyway, have to read, and then concatenate, wash / rinse / repeat. But there is another PITA. I know how big a partition is because I already have rooted phones so once I figured out that you can't read past the end of the block or ERRRR lafd locks up. I still have to find a way (and I KNOW it is there because when LG UP runs lafd dumps out all kinds of size info) to read the size. But I still have megs and megs of packet dumps to go through. Once I have the ability to get the size of partitions, then it will be time to start working on writing them. That actually won't be as hard now that I know how to read them.

Once we have all three, I am now 100% confident that every single LG phone currently on the market will be rootable. Some will require a little more research. For example, trial and error getting a boot loader unlocked. The good news is that as long as you have a KDZ you won't brick your phone, and when it is figured out for one model, it is for all of the same version. So, for example, I did for the H910 -- so all V20s can have their boot loaders unlocked without the engineering aboot.

Anywho -- that is enough playing tonight.

EDIT: I will open up a github and add ALL kinds of documentation to the wiki, but for now, just a little insight as to what is needed:

You have a handful of commands:
HELO
EXEC
READ
OPEN
KILO CENT
KILO METR
INFO GPRO
INFO SPRO
CLSE
SIGN
OPCM CHEK
MISC WRTE
CHCK CLER
WRTE

-- Brian
 
Last edited:

Top Liked Posts

  • There are no posts matching your filters.
  • 64
    EDIT: 2018-08-14

    Wow -- re-reading this, whoa, what a bunch of assumptions / misinformation.

    Note to self, update this post with the ACTUAL findings, and the ACTUAL way that the *current* (as of Nougat and Oreo) works. Also, add in the way that Google is going to F**K us all in the A** by adding AVB to the boot, and recovery, (and then LG can very easily add it to laf) in 9.0 (Pie). Pie in the face. A**holes.


    LAF Is the LG Advanced Flash. When you hold vol up and insert your USB cable to get into download mode, aboot loads a partition called LAF.

    It is just a boot image, but instead of the ramdisk (initrd) doing things like mounting system, so Android boots, it loads download mode.

    As part of my research on the Boot Chain of Trust (BCT), it occurred to me that if you have an unlocked boot loader, you can flash whatever you want to the recovery partition. The only LG V20s that have unlockable boot loaders WITHOUT using the engineering aboot are the US996 (unlock.bin from LG), and the H918 (fastboot oem unlock). This wouldn't really be needed by the US996 since it has all fastboot commands available, the H918 however, does not.

    In the thread about rooting the H918, I came up with the idea of patching LG UP to ignore ARB (Anti-RollBack). When a phone has an unlocked boot loader, aboot (applications boot) doesn't do RSA verification on the boot image. In addition, the boot image doesn't talk to the QFPROM to increment ARB. Heck, the boot image doesn't even have the code needed to write to QFPROM (ARB qfuse). So, the only thing stopping us from flashing an older kernel and system image is that LG UP checks the KDZ to see what ARB version it is at, and it checks QFPROM to see what ARB version the phone is at. If the KDZ is less -- it fails.

    So, that is one way. Patch LG UP to ignore ARB, and then flash boot and system from an older KDZ. Unfortunately, my reverse engineering skills aren't great. On the other hand, my ability to read packet dumps and figure out protocols is much better (worked on -- and still work on World of Warcraft emulation). So I got to thinking, LG UP talks to LAF, so time to load up some wireshark, and start sniffing the USB bus to figure out what exactly is being said.

    After working on this for a couple of days, I thought that there HAS to be someone else out there that thought of this same thing. Turns out I was correct: link.

    As you can see it is a little old, but it put me much farther ahead than I would have been. I think the project was dropped, because as stated above, you need an unlocked boot loader -- and I think T-Mobile is the only one that still does.

    BUT we have an engineering aboot. So, this tool is of use to ALL V20s, since we can just push the engineering aboot, and twrp just like back when dirtycow worked.

    Finally to the point of this post. I would like some help updating the protocol. It appears that dmesg works no matter what:


    Code:
    <snip>
     pseudo_chg_ui[0]
    <3>[ 3132.160144 / 01-01 01:06:45.539][1] LGE charging scenario : state 0 -> 0(0-0), temp=31, volt=3804, BTM=0, charger=1, cur_set=0/0, chg_cur = -232
    <6>[ 3132.160154 / 01-01 01:06:45.539][1] [LGE-CC] lge_monitor_batt_temp_work : otp_ibat_current=0
    <6>[ 3132.160177 / 01-01 01:06:45.539][1] [LGE-CC] lge_monitor_batt_temp_work : Reported Capacity : 17 / voltage : 3804
    <6>[ 3133.448127 / 01-01 01:06:46.819][3] FG: update_sram_data: soc:[17], soc_raw[1863], voltage:[3804909], ocv:[3749062], current:[-232542], batt_temp:[310], charge_raw [374287 / 3167000]
    <12>[ 3136.173937 / 01-01 01:06:49.549][3] [LAF] protocol version mismatch. rcv = 1000001, dev = 1000004 
    <12>[ 3136.174137 / 01-01 01:06:49.549][3] [LAF] read property item = ATT
    <12>[ 3136.289486 / 01-01 01:06:49.659][2] [LAF] execvp failed. error = 2
    <6>[ 3136.560128 / 01-01 01:06:49.939][3] pet_watchdog [enable : 1, jiffies : 4295250952, delay_time : 1000]
    <6>[ 3137.006156 / 01-01 01:06:50.379][2] SMBCHG: lgcc_charger_reginfo: [STATUS] USB_PRESENT[1], PARALLEL_STATUS[2], USB_TYPE[SDP]
    <6>[ 3137.006165 / 01-01 01:06:50.379][2] SMBCHG: lgcc_charger_reginfo: [STATUS] TOTAL_IUSB[500], PMI_IUSB[1700], SMB_IUSB[0]
    <6>[ 3137.006172 / 01-01 01:06:50.379][2] SMBCHG: lgcc_charger_reginfo: [STATUS] TOTAL_IBAT[3100/3100(vote)], PMI_IBAT[3000], SMB_IBAT[1000]
    <6>[ 3137.006179 / 01-01 01:06:50.379][2] SMBCHG: lgcc_charger_reginfo: [STATUS] CABLE_ID [OPEN], CABLE_INFO[SDP], USBIN_VOL[4973]
    <6>[ 3137.006185 / 01-01 01:06:50.379][2] SMBCHG: lgcc_charger_reginfo: [STATUS] BATT_SOC[17], BATT_VOL[3804], BATT_TEMP[310], BATT_CUR[-232542]
    <6>[ 3137.006193 / 01-01 01:06:50.379][2] SMBCHG: lgcc_charger_reginfo: [STATUS] CHG_EN[Enable], CHG_STATE[CHARGING/500MA/CC], SAFTY_STATE[Set/Not yet]
    <6>[ 3137.006199 / 01-01 01:06:50.379][2] SMBCHG: lgcc_charger_reginfo: [STATUS] XO_tHERM[36], PA_THERM[33], BOARD_THERM[32] VTS[333]
    <6>[ 3142.000053 / 01-01 01:06:55.379][2] [bm] monitoring
    <12>[ 3142.384450 / 01-01 01:06:55.759][3] [LAF] protocol version mismatch. rcv = 1000001, dev = 1000004 
    <12>[ 3142.384664 / 01-01 01:06:55.759][3] [LAF] read property item = ATT
    <12>[ 3142.498642 / 01-01 01:06:55.869][3] [LAF] dmesg!!


    Enough to let me know that at the very least, the protocol version has changed.

    So, once the missing pieces are back in place, we will be able to once again root any model, on any security patch.

    Why can't they plug this hole? They could actually. They could force all phones to require OTA updates -- no more download mode. Until they do, they can change the protocol all they want, but as long as LG UP can talk to the phone, then it can be figured out once again. As for the engineering aboot. That can of worms can't be closed -- they have no way of updating the RSA key in the CPU. Well they could have, if they didn't decide to go the full on / locked down / method. There are slots for 4 keys in QFPROM, but they made the mistake of locking the CPU so that no new keys can be written. The advantage to them was that people like myself can't write my own key. The disadvantage is that if something like the eng aboot leaks, they can't do a thing about it.

    So -- WHO'S WITH ME?!? :)

    -- Brian
    50
    You guys aren't going to believe this shiz. I just flashed TWRP onto my H918 by total accident.

    I was trying to solve the MISC WRTE / COPY (copy2 flashing), and I needed a test file descriptor. I knew that indirect flashing -- RSVD IDDD opens /data/idt.cfg for writing. I wanted ANYTHING except my onboard storage so I didn't brick my phone. When I went to make sure that idt.cfg was in write mode, I MEANT to type lsof (list open files), but what I typed was ls-f, and I got file not found. Then I typed dmesg to try and find out what just happened, and I didn't get anything. So then I typed ls-f again, and this time I got dmesg not found.

    So I figured I would try passing some things as the payload: RSVD IDDD /system/bin/sh
    ls-f did nothing. So I thought it was running a shell and exiting. Nope.

    Finally figured out that what it was looking for was an update file. So.... RSVD IDDD /storage/external_SD/SoftwareUpdate/update.zip

    and....

    Code:
    [LAF] Start flashing HW user partition 0
    [LAF] success to close handle to flash driver
    
    [LAF] flashing done.

    Turns out that download mode doesn't verify the integrity of update.zip when it is called via indirect flashing. As in it doesn't check to see that it was signed with the keys that are usually in /res :)

    Root is for real coming soon...

    Oh, the best part, this is available in ALL current versions of lafd on any and every LG model.

    Any LG model that can unlock their bootloader, or has an engineering aboot (G6 and down) or an engineering abl (V30 and up)

    -- Brian
    31
    So in today's news we have -- laf root shell for almost all V20s:

    First normal laf
    Code:
    ./lglaf.py 
    LGLAF.py by Peter Wu (https://lekensteyn.nl/lglaf)
    Type a shell command to execute or "exit" to leave.
    # whoami
    Hello, I am LAF. Nice to meet you.# 
    #

    As I stated before, normal laf has a very limited list of commands that execvp will allow. If you try and run a command that isn't on that whitelist, you get: "Hello, I am LAF. Nice to meet you."

    Now let's replace that laf:
    Code:
    ./partitions.py --restore patched-laf.img laf
     [ 100 % ] 2018-06-20 13:50:27,343 partitions: INFO: Done after writing 50331648 bytes from patched-laf.img

    Now notice, this is using --restore which is the normal KDZ flashing method. The SIGN payload gets sent, and then WRTE opcodes are used. This isn't using MISC WRTE / COPY, so ANY laf version can flash it onto any device.
    Once sent the hash is compared, and if it matches, it flushes the buffer to NAND.

    So what do we get now:
    Code:
    ./lglaf.py 
    LGLAF.py by Peter Wu (https://lekensteyn.nl/lglaf)
    Type a shell command to execute or "exit" to leave.
    # whoami
    root
    # uptime
     18:09:19 up 0 min,  0 users,  load average: 2.11, 0.50, 0.17

    So now we just slap TWRP and a few other files onto an SD card, and use dd to flash it onto recovery, and unlock the bootloader.

    Now, why is this important? Well right now it isn't. Even with this breakthrough the LS997 still can't be rooted on ARB 1 since there are no ARB 1 aboot images that can be unlocked (it is pulled from the stock LS997 aboot), and the engineering aboot is also ARB 0.

    However, if Oreo comes out and they increment ARB, and Oreo won't boot on older firmware, anyone without an H918 will have to choose between Nougat and root, or Oreo and no root. We need a third option ... and this is it :)

    I am posting this because there is nothing Qualcomm, LG or anyone else can do about it since it uses standard KDZ flashing (well -- I guess they could remove download mode completely -- but they won't) They can modify the protocol, but I will just reverse engineer the modifications. It is a cat and mouse game that they will always lose.
    I will be pushing the code and the image to my repo. Again, it really doesn't do anyone any good right now -- but it will be out there.

    What I am NOT releasing is the part that will have LG scratching their heads. How did I get a modified image to flash AND pass the hash check? If I can modify an image, why not just modify TWRP and flash that directly?

    Those questions will never be answered publicly.

    -- Brian
    30
    I am going to go through this with a fine tooth comb before I risk my device, but after decompiling it, and giving it a quick cursory glance, it doesn't look like ANY calls are made to the fusing functions on init.

    If anyone was curious (I was) as to whether you could use a firehose to just write anything you wanted -- nope. It checks the signature of the image being written, and if it doesn't pass -- no flash. Well, again, our engineering aboot is signed, or our phone wouldn't boot :)


    So it looks like the full root procedure will be:

    * Have a FULLY charged phone
    * Dump TZ (just to make sure that you have a copy on hand) - tool will be provided
    * Wipe TZ to get into EDL mode (yes - this is the scary 9008 - doesn't look like the phone even powers on mode) - tool will be provided
    * Use QFIL to flash TZ that you dumped, and engineering ABOOT
    * You will now have full fastboot so you can fastboot flash recovery twrp.img :)
    * Profit!

    This will work on any model V20 except the H918. You guys can thank T-Mobile for deciding to use their own cert.
    I will try to contact the person that provided me this firehose and see if they are willing to provide one for the H918.

    Lastly, I will be testing this later tonight once I chew through this decompiled code a bit more...

    -- Brian
    30
    So, I know I haven't posted much the past couple of weeks -- had a family emergency and I just went off the grid. Things are starting to kind of get back to normal, so I will be back around more.

    While I was away, I dropped my phone and got a crack in the screen, so I picked up another H918 off of eBay (freaking $120 mint condition with shipping -- that is insane).

    Anyway, it came with 10r which of course doesn't have the COPY opcode, so I needed to do some flashing to root it. I flashed 10p, but before I rooted it, I wanted to run some tests.

    It turns out I was WRONG about a major assumption (all laf is created equally across models -- as in H910 10p laf is the same as H918 10p laf).

    I am sticking by my "I am not releasing anything else until we get freaking Oreo", but I wanted to at least say this was a MAJOR breakthrough.

    Right now, with the exception of the LS997, all V20s can be rooted. I would really like to give the LS997 guys some help -- but if I do not want to delay Oreo anymore.

    With that said, this a REALLY cool, and I really want to post all the details about it -- going to have to cut off the beer so that I don't. :)

    Suffice it to say, LG are idiots. I am sure Samsung is too, but I have no desire to have a Samsung phone. As a matter of fact, I will be keeping a V20 until SOMEONE releases a flagship phone with:

    * removable battery
    * SD card
    * Headphone jack
    * IR blaster

    In other words, take a V20, drop in an SD845 with 8gigs RAM, and upgrade the camera (and the upgraded camera is optional).

    -- Brian