In my infinite hunt for a product to tinker with, I decided to give the Inseego FX2000 a run for its money. Less than $100 on eBay in fact! I was a little weary of working with this device because Novatel/Inseego is known for locking down their devices more heavily than their competitors.
This guide takes into account that you have knowledge of ADB/Fastboot tools, hex editing, and some Qualcomm tool knowledge. This is by no means a step-by-step tutorial.
Gaining ADB Access
Inseego devices hide their various ports behind an HID port, where you can send values to enable them. In newer devices, the value is encrypted, and can not be done unless you know the crypt. In my testing, the FX2000 worked fine, but my M2000 did not (I think my M2000 is haunted, it just refuses to connect to T-Mobile).
Connect a Windows computer to the USB-C port on the rear of the FX2000. Download the mifilink
utility from here. In a terminal, execute mifilink.exe diag
. There should now be a plethora of ports at our disposal, including ADB and DIAG.
Modifying TTL
Now that you have ADB access, we can access the shell and mangle the TTL and HL on our device. When booted, the runlevel of the device is 3, meaning we can place a file in /etc/rc3.d/
and it'll be executed on startup.
Contents of /etc/init.d/set-ttl.sh
#!/bin/sh
sleep 15
iptables -t mangle -I POSTROUTING -o rmnet+ ! -p icmp -j TTL --ttl-set 64
ip6tables -t mangle -I POSTROUTING -o rmnet+ ! -p icmpv6 -m hl ! --hl-eq 255 -j HL --hl-set 64
What these two commands do is modify the outgoing TTL/HL of any packet on an rmnet wildcard interface to 64, so it appears as on-device traffic. It excludes ICMP because pings and traceroutes won't function correctly. For IPv6, it also ignores packets with a HL of 255 as that is used for neighbor-discovery, and without the exclusion, downstream devices of the router won't receive an IPv6 address.
Once we create that file, we want to mark it as executable and link it to the rc3.d folder.
# chmod +x /etc/init.d/set-ttl.sh
# ln -s /etc/init.d/set-ttl.sh /etc/rc3.d/S98ttl
# chmod +x /etc/rc3.d/S98ttl
If you give the device a reboot and run iptables -vL -t mangle
and ip6tables -vL -t mangle
, our rules should be there!
SSH Access
Let's enable SSH access so we don't have to continually connect our laptop and use the ADB shell to execute commands.
First, execute passwd
in the ADB shell and set a new root password. Then create /etc/init.d/dropbear.sh
.
Contents of /etc/init.d/dropbear.sh
:
#!/bin/sh
sleep 15
/etc/init.d/dropbear start
Then execute the following commands:
# chmod +x /etc/init.d/dropbear.sh
# ln -s /etc/init.d/dropbear.sh /etc/rc3.d/S98dropbear
# chmod +x /etc/rc3.d/S98dropbear
Now SSH will be enabled on boot! By default, your SSH clients probably won't like the ciphers dropbear uses, but you can ignore this on UNIX with the following command:
ssh -oKexAlgorithms=+diffie-hellman-group1-sha1 -oHostKeyAlgorithms=+ssh-rsa [email protected]
Repairing IMEI
This is not for the weary. It involves backing up and wiping a sensitive EFS partition, modifying the backup in a hex editor, and restoring it onto the device. As far as I am aware, you cannot repair the IMEI on this device without wiping the EFS partition. That is because the NV item 550 (where the IMEI is held) is read-only, and can only be written to once.
With QPST tools on your computer, launch QFIL and select the port of your router, then in the menu bar, head to Tools > QCN Backup Restore. Select Backup QCN to begin the backup.
I also took the liberty to make an xQCN backup here, using the Software Download tool in QPST, since this contains more data than a regular QCN. If we restore this after we restore the QCN we're about to modify, it will not repair the IMEI to the original since it is now read-only. Allegedly there are also some nv items that are used during a factory reset, which these processes may not backup, which could lead to bootlooping after a factory reset.
With the completed QCN backup, open it in your preferred hex editor, and search for hex 089A
. (That is, if your IMEI begins with 9
. If it is something else, search for 08xA
, where x is that first digit.) For me, the offset of the IMEI value is 29560.
If your original IMEI is 358314360147956
, then the hex value should be 08 3A 85 13 43 06 41 97 65
. The first octet will always be 08
, and the second will always be the first digit, followed by A
. For every octet after that, it is the digits reversed. Save the file once done under a new filename.
There is a possibility of bricking your device after this. Know the risks. I might even recommend making a nanddump backup of the efs2 partition (/dev/mtd2
).
On your laptop connected via USB to the router, execute the following commands in your shell:
adb reboot bootloader
fastboot erase efs2
fastboot reboot
The device should reboot, but it will not come up as normal. It is now in a persistent runlevel 2.
This is not required, but if you execute telinit 3
in an ADB shell, the device will come back up as normal, and you can verify that there is no IMEI in the device's settings.
With the device back up, launch QFIL and navigate to the same menu as before under Tools > QCN Backup Restore, and choose the modified hex file and restore it. Once the restore is completed, reboot the device. When the device comes back up, we need to tell the device to return to a persistent runlevel 3. In an ADB shell, execute:
# dsm_cli set_persistent_rl
When prompted Is runlevel persistent 0/1:
, type 1
and hit enter, then when prompted Enter runlevel 2/3/4:
, type 3
and hit enter. Reboot the device again. It should now come back up as normal, and you can check the device's settings to make sure your repaired IMEI is present.
Random device knowledge
General
Manufacturer: Inseego
Model: FX2000-3
Software Components
Modem Firmware Version: SDX55MOR-4.05.1.1 1 [2022-12-15 07:35:29]
Wi-Fi Firmware Version: 1.0.1.2.193.0
OS Version: 4.14
Cute Version: 3A
ati
Manufacturer: Inseego Corp.
Model: FX2000
Revision: 4.05.1.1 SVN 18 [2022-12-15 07:35:29] (Release Build - nvtl)
SVN: 18
IMEI: xx
+GCAP: +CLTE3, +MS, +ES, +DS
OK
# cat /proc/mtd
dev: size erasesize name
mtd0: 00280000 00040000 "sbl"
mtd1: 00280000 00040000 "mibib"
mtd2: 01500000 00040000 "efs2"
mtd3: 001c0000 00040000 "tz"
mtd4: 00100000 00040000 "tz_devcfg"
mtd5: 00180000 00040000 "ddr"
mtd6: 00100000 00040000 "apdp"
mtd7: 00100000 00040000 "xbl_config"
mtd8: 00100000 00040000 "multi_image"
mtd9: 00100000 00040000 "aop"
mtd10: 00100000 00040000 "qhee"
mtd11: 00100000 00040000 "abl"
mtd12: 00280000 00040000 "uefi"
mtd13: 00180000 00040000 "toolsfv"
mtd14: 00180000 00040000 "loader_sti"
mtd15: 00d00000 00040000 "boot"
mtd16: 00100000 00040000 "scrub"
mtd17: 06b40000 00040000 "modem"
mtd18: 001c0000 00040000 "misc"
mtd19: 00180000 00040000 "devinfo"
mtd20: 01900000 00040000 "recovery"
mtd21: 001c0000 00040000 "fota"
mtd22: 02940000 00040000 "recoveryfs"
mtd23: 000c0000 00040000 "ipa_fw"
mtd24: 00100000 00040000 "usb_qti"
mtd25: 00100000 00040000 "sec"
mtd26: 00100000 00040000 "fotacookie"
mtd27: 11200000 00040000 "system"
# cat /proc/cpuinfo
processor : 0
model name : ARMv7 Processor rev 5 (v7l)
BogoMIPS : 38.40
Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xc07
CPU revision : 5
Hardware : Qualcomm Technologies, Inc SDXPRAIRIE
Revision : 0000
Serial : 0000000000000000
# cat /proc/mounts
ubi0:rootfs / ubifs rw,relatime,bulk_read,ubi=0,vol=0 0 0
devtmpfs /dev devtmpfs rw,relatime,size=373084k,nr_inodes=93271,mode=755 0 0
proc /proc proc rw,relatime 0 0
none /tmp ramfs rw,relatime 0 0
none /sys sysfs rw,relatime 0 0
none /run ramfs rw,relatime 0 0
none /var/log ramfs rw,relatime 0 0
none /run ramfs rw,relatime 0 0
none /var/lock ramfs rw,relatime 0 0
none /sys/kernel/debug debugfs rw,relatime 0 0
ramfs /opt/nvtl/tmp ramfs rw,relatime 0 0
devpts /dev/pts devpts rw,relatime,gid=5,mode=620,ptmxmode=000 0 0
/dev/ubi1_0 /firmware ubifs ro,relatime,bulk_read,ubi=1,vol=0 0 0
none /sys/kernel/config configfs rw,relatime 0 0
adb /dev/usb-ffs/adb functionfs rw,relatime 0 0
# cat /proc/version
Linux version 4.14.206-perf (builder@nvtlsdselbld06) (clang version 6.0.9 for Android NDK, GNU ld (GNU Binutils) 2.31.1.20181224) #1 PREEMPT Thu Apr 6 02:19:08 PDT 2023
# uname -a
Linux mifi 4.14.206-perf #1 PREEMPT Thu Apr 6 02:19:08 PDT 2023 armv7l GNU/Linux
Also, I may be crazy, but using the MBN profile ROW_Commercial instead of Commercial-TMO and a custom DNS server appears to solve my video throttling issue on T-Mobile.