Does the CPU out-of-order execution will cause a SIGILL crash if there are some data after instruction?

Viewed 67

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?

0 Answers
Related