I have a android app which inline hooked the read function in libc.so.
Before hook,the read function looks like:
.text:000000000006B1A0 MOV X8, #0x3F ; '?'
.text:000000000006B1A4 SVC 0
.text:000000000006B1A8 CMN X0, #1,LSL#12
.text:000000000006B1AC CINV X0, X0, HI
.text:000000000006B1B0 B.HI __set_errno_internal
.text:000000000006B1B4 RET
After the read hooked,the assembly code is like this:
0x7f800d2714: ldr x17, #0x7f800d271c
0x7f800d2718: br x17
0x7f800d271c: some data
0x7f800d2720: some data
The inline hook work fine in most times. But sometimes it will caused a SIGILL crash in some special devices,crash informations looks like:
03-02 20:04:19.041 668-668/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
03-02 20:04:19.041 668-668/? A/DEBUG: Build fingerprint: 'Xiaomi/rolex/rolex:6.0.1/MMB29M/V10.2.2.0.MCCCNXM:user/release-keys'
03-02 20:04:19.041 668-668/? A/DEBUG: Revision: '0'
03-02 20:04:19.041 668-668/? A/DEBUG: ABI: 'arm64'
03-02 20:04:19.042 668-668/? A/DEBUG: pid: 31673, tid: 31686, name: FileObserver >>> com.nd.pptshell <<<
03-02 20:04:19.042 668-668/? A/DEBUG: signal 4 (SIGILL), code 1 (ILL_ILLOPC), fault addr 0x7f800d271c
03-02 20:04:19.060 668-668/? A/DEBUG: x0 0000000000000090 x1 0000007f7bb11e18 x2 0000000000000200 x3 0000000000570000
03-02 20:04:19.060 668-668/? A/DEBUG: x4 0000000000430000 x5 0000000000000000 x6 0000007f7cd93000 x7 0000007f7cd959c8
03-02 20:04:19.060 668-668/? A/DEBUG: x8 000000000000003f x9 000000559d4e6068 x10 0000000000000002 x11 0000007f7c87c8d0
03-02 20:04:19.060 668-668/? A/DEBUG: x12 0000000000000003 x13 0000000000000000 x14 0000007f7c87c9c0 x15 0000000000000000
03-02 20:04:19.060 668-668/? A/DEBUG: x16 0000007f803ddf40 x17 0000007f800d2714 x18 000000559d4e5ec0 x19 000000559d4defe0
03-02 20:04:19.061 668-668/? A/DEBUG: x20 0000007f803601cc x21 000000559d4e5ec0 x22 000000007012e6f0 x23 0000007f7bb12208
03-02 20:04:19.061 668-668/? A/DEBUG: x24 0000007f7bb122b8 x25 0000007f7bb11e18 x26 0000007f803ef000 x27 0000007f7bb12034
03-02 20:04:19.061 668-668/? A/DEBUG: x28 000000000000000e x29 0000007f7bb11da0 x30 0000007f8036022c
03-02 20:04:19.061 668-668/? A/DEBUG: sp 0000007f7bb11da0 pc 0000007f800d271c pstate 0000000020000000
03-02 20:04:19.063 668-668/? A/DEBUG: backtrace:
03-02 20:04:19.063 668-668/? A/DEBUG: #00 pc 000000000000071c /system/lib64/libc.so (offset 0x6a000)
03-02 20:04:19.063 668-668/? A/DEBUG: #01 pc 0000000000128228 /system/lib64/libandroid_runtime.so
03-02 20:04:19.063 668-668/? A/DEBUG: #02 pc 00000000727a4724 /data/dalvik-cache/arm64/system@framework@boot.oat (offset 0x2566000)
03-02 20:04:19.576 1383-31787/? W/ActivityManager: Force finishing activity com.nd.pptshell/.newui.HomeTabContainerActivity
03-02 20:04:19.576 668-668/? A/DEBUG: Tombstone written to: /data/tombstones/tombstone_02
03-02 20:04:19.576 668-668/? E/DEBUG: AM write failed: Broken pipe
I'm sure that the hooked read function has been execute many times before this crash, because I print some debug information and can see it in logcat.
From the crash information we can get that the pc jump from the libandroid_runtime.so by GOT table which used the x17 as the temporary register whose value is 0x7f800d2714 correspond to the read function start address.
The libandroid_runtime.so's relative code looks like:
text:000000000012821C loc_12821C ; fd
.text:000000000012821C MOV W0, W28
.text:0000000000128220 MOV X1, X25 ; buf
.text:0000000000128224 MOV X2, #0x200 ; nbytes
.text:0000000000128228 BL .read
.text:000000000012822C CMP W0, #0xF
.text:0000000000128230 MOV W22, W0
.text:0000000000128234 B.GT loc_128298
and the read entry:
.plt:0000000000086DC0 ; ssize_t read(int fd, void *buf, size_t nbytes)
.plt:0000000000086DC0 .read
.plt:0000000000086DC0 ADRP X16, #read_ptr@PAGE
.plt:0000000000086DC4 LDR X17, [X16,#read_ptr@PAGEOFF]
.plt:0000000000086DC8 ADD X16, X16, #read_ptr@PAGEOFF
.plt:0000000000086DCC BR X17
So if the instruction in 0x7f800d2714 was executed,the X17 register must be modified to other values.
Is it possible the CPU out-of-order execution fetch the data from 0x7f800d271c before the ldr x17, #0x7f800d271c?