OnePlus 7 Pro: Update System Firmware on Custom ROM

Follow up to the OnePlus 7 Pro: LineageOS+MicroG post, where I mentioned I would have to update the Bluetooth & Modem firmware on my device. This fortunately went as smoothly as the LineageOS+MicroG install, so I’m very happy about that.

The first step was downloading the latest OxygenOS ZIP through this post: XDA Developers: [ROM][STOCK][FASTBOOT][OP7P] Stock Fastboot ROMs for OnePlus 7 Pro/ 7 Pro 5G by mauronofrio. The specific ZIP i pulled down from Android File Host was “”. From there, it was just a simple matter of extracting that,, & flashing the bluetooth.img & modem.img files:

➜  Downloads cd 10.0-GM21AA-OnePlus7ProOxygen_21.O.20_OTA_020_all_1909172051_db7a3f61-FASTBOOT/images
➜  images file bluetooth.img
bluetooth.img: DOS/MBR boot sector, code offset 0x3c+2, OEM-ID "MSDOS5.0", Bytes/sector 4096, sectors/cluster 4, root entries 512, Media descriptor 0xf8, sectors/FAT 3, sectors/track 63, heads 255, sectors 16384 (volumes > 32 MB), serial number 0xbc614e, unlabeled, FAT (16 bit)
➜  images file modem.img
modem.img: DOS/MBR boot sector, code offset 0x3c+2, OEM-ID "MSDOS5.0", Bytes/sector 4096, sectors/cluster 4, root entries 512, Media descriptor 0xf8, sectors/FAT 10, sectors/track 63, heads 255, sectors 76800 (volumes > 32 MB), serial number 0xbc614e, unlabeled, FAT (16 bit)

➜  images adb devices
* daemon not running; starting now at tcp:5037
* daemon started successfully
List of devices attached
➜  images adb devices
List of devices attached
1234abcd        device
➜  images adb reboot bootloader
➜  images fastboot devices
1234abcd        fastboot
➜  images fastboot flash bluetooth_a bluetooth.img
Sending 'bluetooth_a' (828 KB)                     OKAY [  0.030s]
Writing 'bluetooth_a'                              OKAY [  0.005s]
Finished. Total time: 0.049s
➜  images fastboot flash bluetooth_b bluetooth.img
Sending 'bluetooth_b' (828 KB)                     OKAY [  0.032s]
Writing 'bluetooth_b'                              OKAY [  0.005s]
Finished. Total time: 0.050s
➜  images fastboot flash modem_a modem.img
Sending 'modem_a' (161700 KB)                      OKAY [  4.308s]
Writing 'modem_a'                                  OKAY [  0.633s]
Finished. Total time: 4.954s
➜  images fastboot flash modem_b modem.img
Sending 'modem_b' (161700 KB)                      OKAY [  3.769s]
Writing 'modem_b'                                  OKAY [  0.696s]
Finished. Total time: 4.480s
➜  images fastboot reboot
Rebooting                                          OKAY [  0.002s]
Finished. Total time: 0.002s
➜  images

OnePlus 7 Pro: LineageOS+MicroG

After a full weekend of originally getting CrDroid on my new OnePlus 7 Pro a few months back, I decided to switch to LineageOS+MicroG because I was never able to get location working on CrDroid. This was mostly due to the changes in Android 10, but when I was still unable to get it working with the new UnifiedNLP package, I just decided it was easier to switch & settled for reinstalling MicroG, which I had avoided on CrDroid because I wanted to avoid as many Google services as possible.

Since I had so many issues getting CrDroid setup in the first place (mainly due to me lack of experience with A\B partitions & not knowing I needed to flash OxygenOS first, then the ROM on top of it), I wanted to keep track of the exact steps I took to get LineageOS+MicroG so I could follow it the next time I decide I want to try a new ROM. Posting it here just makes it easier to come back to & maybe it will help out someone else.

First step was just backup & prep: Making sure I had backups of my messages, F-Droid repositories, 2FA tokens, as well as my list of installed apps.

One thing I was surprised at for the installation was that I wasn’t expected to flash an OxygenOS ROM first… Below are the two “guides” i followed:

This one specifically included when to flash Magisk:
XDA Developers: [ROM]-[10-04-2020]-[microG] Unofficial LineageOS 17 w/ microG support by gigatex

Flashing Recovery: I thought this was one place where I had issues, but that may have only been on the Essential Phone, where I couldn’t boot recovery. that did work on the OP7Pro:

➜ OP7Pro adb reboot fastboot
➜ OP7Pro fastboot devices
0810d6ea fastboot
➜ OP7Pro fastboot boot twrp-3.4.0-0-guacamole.img
Sending 'boot.img' (31704 KB) OKAY [ 0.742s]
Booting OKAY [ 0.106s]
Finished. Total time: 0.886s
➜ OP7Pro

Once I was booted into TWRP I formatted DATA & pushed the LineageOS+MicroG & TWRP installer ZIPs, then rebooted to recovery again (without flashing anything). I ended up having to push the two ZIPs again because they were not present on the “SD Card” after the reboot. After pushing the files again I flashed & rebooted the system to complete setup.

An issue I did run into with Magisk appeared to be due to the A\B slots again. The fix seemed to be flashing when getting into TWRP, then manually changing the A\B slot, rebooting to recovery, & flashing again. Just a simple “Reboot > Recovery” didn’t change the slots.

I did just attempt a system update yesterday, & it was successful, following the same process I took during CrDroid: Use the internal updater, but DO NOT REBOOT through the updater. You have to go into Magisk Manager > Magisk Install > Install > Install to Inactive Slot (After OTA). You can then reboot & will still be rooted with Magisk.

I will have another update shortly about updating firmware, since I just noticed this morning that Bluetooth will not stay enabled. While on CrDroid the fix seemed to be flashing Bluetooth & Modem firmware from an official OxygenOS update.

Remapping Hardware Buttons: Mi MIX 3

Now that I was able to get my Mi MIX 3 setup with TWRP & a custom ROM (unofficial LineageOS 16 build), I started looking into remapping the AI button to something actually useful. I found a few posts to point me in the right direction, as well as a Magisk module that is supposed to handle this:

I tried out a bunch of the codes to see what would work, & for now just remapped the key to SEARCH, until I can find something better \ more useful.

There is a Magisk module for this, but I had issues making the selection during the install process: Magisk-Modules-Repo/XiaomiAI-remap. When I tried using the volume keys to change the intended function, it was actually changing my volume, not anything on the screen. Pressing the AI button during that process seemed to make changes to the choices, but still couldn’t get it working as intended. Instead, I just used the script for that module to make the change myself.

File: /system/usr/keylayout/gpio-keys.kl

cat gpio-keys.kl
# Copyright (c) 2013, The Linux Foundation. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#     * Neither the name of The Linux Foundation nor the names of its
#       contributors may be used to endorse or promote products derived
#       from this software without specific prior written permission.

key 115   VOLUME_UP
key 114   VOLUME_DOWN
key 102   HOME
key 528   FOCUS
key 766   CAMERA
key 689   CAMERA

I changed key 689 to SEARCH on my device. If I can get the key to open a specific app, then I will likely end up changing the key to perform that function. Sending the keyevent for CAMERA doesn’t appear to do anything on my phone, but that may just be due to running the custom ROM. To test, the command to input key events is: adb shell input keyevent << number or function >>

Custom ROM on Mi MIX 3

I recently picked up a Xiaomi Mi MIX 3 & was able to unlock the bootloader after the 72 hour waiting period. That wasn’t a problem, however getting TWRP up & running was where I had a problem.

For some reason, whenever I would flash TWRP, but device was stuck in a fastboot loop — could not reboot out of it, boot the TWRP image, or any other method of exiting fastboot. I finally got TWRP working properly after flashing perseus_global_images_9.5.17_20190517.0000.00_9.0 _global_134d3070e5.tgz. I tried flashing one of the China ROM’s, & that was of no help.

Since this was turning out to be nothing close to simple like other devices, I was then running into an issue flashing NanoDroid after my ROM. That one seemed to be related to the /system partition not being found. It looks like my partition was instead mounted as /system_root, but the NanoDroid install script was looking for /system. Managed to fix that as well:

Results of mount:

/dev/block/sde48 on /system_root type ext4 (rw,seclabel,relatime,block_validity,delalloc,barrier,user_xattr)

Remount /system_root as /system:

perseus:/ # mount -o bind /system_root/system /system

Taking a look at\CommonInstaller: Lines 248-252:

if [ -f /system/init.rc ]; then
mkdir /system_root 2>/dev/null
mount –move /system /system_root
mount -o bind /system_root/system /system

Once NanoDroid was working, I then needed to double check how to restore my backed up Signal messages: Signal: Backup & Restore Messages.

Protecting Linux Login with 2FA

This is definitely not the first time I’ve tried getting this working, but glad I was finally able to. Looks like if I had read a bit more, I never would have run into issues…

By the second or third time I ran into problems, I at least figured out why: with my home directory being encrypted, the “secret” 2FA files could not be accessed & verified.

Now for the fun part… It looks like Google had the instructions for encrypted home directories in the README the whole time.

Encrypted home directories
If your system encrypts home directories until after your users entered their password, you either have to re-arrange the entries in the PAM configuration file to decrypt the home directory prior to asking for the OTP code, or you have to store the secret file in a non-standard location:

auth required secret=/var/unencrypted-home/${USER}/.google_authenticator

would be a possible choice. Make sure to set appropriate permissions. You also have to tell your users to manually move their .google_authenticator file to this location.

In addition to “${USER}”, the secret= option also recognizes both “~” and ${HOME} as short-hands for the user’s home directory.

When using the secret= option, you might want to also set the user= option. The latter forces the PAM module to switch to a dedicated hard-coded user id prior to doing any file operations. When using the user= option, you must not include “~” or “${HOME}” in the filename.

The user= option can also be useful if you want to authenticate users who do not have traditional UNIX accounts on your system.

So, after getting through that tedious “reading” thing, I followed their suggestion, & created the “unencrypted-home” directory, moved the ~/.google_authenticator file there, edited /etc/pam.d/common-auth & included the path to the file at the encrypted location. After that… Working as expected!

user@Hostname:~$ cat /etc/pam.d/common-auth | tail -n 1
auth required secret=/var/unencrypted-home/${USER}/.google_authenticator

Password “Complexity” Requirement

I actually forget what web site this one, but found this little gem while trying to setup a new account:

I guess my password doesn’t meet their requirements?
Then I decide to use this instead.

No, I didn’t actually make my password “password123” but I would have thought a site warning my against it wouldn’t allow “password”+< something >. The fact that it wouldn’t accept my random password probably should have been my first hint that it was not going to go well.

FINALLY Got my OpenVPN Server Setup on My DD-WRT Router

This took way longer than I would have liked, but at least it seems to be working right now.

After moving recently, I needed to purchase a new router, leaving my rooted Google WiFi AP’s behind. I decided to replace it with a D-LINK AC2600 EXO MU-MIMO Wi-Fi Router. After some more router related fun, I was able to get DD-WRT custom firmware running on the device. With that finally in place, my next project was to get the OpenVPN Server feature enabled. I had all the certificates & keys I needed, it was just a matter of getting the right config in the DD-WRT Admin GUI. Below is what I finally had in the “Additional Config” field that, that ended up working:

push “route”
push “dhcp-option DNS”
verb 5
dev tun0
proto udp4
keepalive 10 120
dh /tmp/openvpn/dh.pem
ca /tmp/openvpn/ca.crt
cert /tmp/openvpn/cert.pem
key /tmp/openvpn/key.pem
script-security 2
# Only use crl-verify if you are using the revoke list – otherwise leave it commented out
# crl-verify /tmp/openvpn/ca.crl
# management parameter allows DD-WRT’s OpenVPN Status web page to access the server’s management port
# port must be 5001 for scripts embedded in firmware to work
# management localhost 5001

Where is my local subnet, & is a subnet I’m assigning to VPN clients.

I haven’t started configuring clients yet, but don’t believe that will be anywhere near as difficult as getting the server running. For reference, below is a history of the commands I ran to get the certificates, keys, etc setup for the server:

v3ritas@Hostname:~/.openvpn/20190101$ history
2956 make-cadir 20190101
2957 cd 20190101/
2958 ls
2959 nano vars
2960 source vars
2961 cp openssl-1.0.0.cnf openssl.cnf
2962 source vars
2963 ./clean-all
2964 ./build-ca
2965 ./build-key-server OpenVPN-Server
2966 ./clean-all
2967 nano vars
2968 ./build-ca
2969 source vars
2970 ./build-ca
2971 ./build-key-server OpenVPN-Server
2972 ./build-dh
2973 ls keys
2974 openvpn –genkey –secret pfs.key
2975 ls keys
2976 cat keys/ca.crt
2977 cat OpenVPN-Server.crt
2978 cat keys/OpenVPN-Server.crt
2979 cat keys/OpenVPN-Server.key
2980 cat keys/dh4096.pem
2981 cat pfs.key
2982 md5 ~/Downloads/factory-to-ddwrt.bin
2983 md5 ~/Downloads/dlink-dir882-a1-webflash.bin
2984 ./build-key Client01
2985 ls keys
2986 cat keys/ca.crt
2987 cat keys/OpenVPN-Server.crt
2988 cat keys/OpenVPN-Server.key
2989 cat keys/dh4096.pem
2990 cat pfs.key

Just of dump of my command history.

New Nintendo Switch Payload: ArgonNX

Guillem96 has a new payload available on GitHub: argon-nx.

As he states in the description there, it’s meant to be used to choose which payload you’d actually like to launch; just use the ArgonNX payload, & then choose from any BIN you have located in the \argon\payloads\ directory. What’s nice about this is that you can choose the logos to go along with each BIN. Still have some work to do, but this is what my selection screen looks like right now:

Photo of the ArgonNX payload running.
Photo of the ArgonNX payload running.
ArgonNX logos.
Some quick logos I put together to be used with ArgonNX. Crappy screenshot because apparently WordPress \ Gutenberg views BMP files as a security risk… See screenshot below.
BMP files are a security risk?