在华为手机鸿蒙系统4.2.0上面发现有JNI报错信息:

1
2
3
4
5
6
2024-08-14 18:Fatal signal 5 (SIGTRAP), code 1 (TRAP_BRKPT), fault addr 0x7bdd911c30 in tid 3011 (Thread-11), pid 2175 (t.myapplication)
2024-08-14 18:Cmdline: com.myapplication
2024-08-14 18:pid: 2175, tid: 3011, name: Thread-11 >>> com.myapplication <<<
2024-08-14 18: #00 pc 0000000000020c30 /data/app/~~fknWHZgCIhPELEYcOIDVFg==/com.myapplication-kIlrv3njQZh8GuDC_8Qs4w==/lib/arm64/libnativelib.so!libnativelib.so (foo11111(void*, void*)+44) (BuildId: 2dfe839fe371a6783616544bbb05e6a1e8d212e1)
2024-08-14 18: #01 pc 0000000000020a7c /data/app/~~fknWHZgCIhPELEYcOIDVFg==/com.myapplication-kIlrv3njQZh8GuDC_8Qs4w==/lib/arm64/libnativelib.so!libnativelib.so (Java_com_nativelib_NativeLib_getPackageCodePathFromJNI+100) (BuildId: 2dfe839fe371a6783616544bbb05e6a1e8d212e1)
2024-08-14 18: #04 pc 000000000000cf28 /data/app/~~fknWHZgCIhPELEYcOIDVFg==/com.myapplication-kIlrv3njQZh8GuDC_8Qs4w==/base.apk (com.myapplication.MainActivity$3.run+60)

使用ida查看报错的地方:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
.text:0000000000020C04 ; __int64 __fastcall foo11111(void *, void *)
.text:0000000000020C04 WEAK _Z8foo11111PvS_
.text:0000000000020C04 _Z8foo11111PvS_ ; CODE XREF: foo11111(void *,void *)+C↓j
.text:0000000000020C04 ; DATA XREF: LOAD:0000000000003600↑o ...
.text:0000000000020C04
.text:0000000000020C04 var_10 = -0x10
.text:0000000000020C04 var_8 = -8
.text:0000000000020C04 var_s0 = 0
.text:0000000000020C04
.text:0000000000020C04 ; __unwind {
.text:0000000000020C04 SUB SP, SP, #0x20
.text:0000000000020C08 STP X29, X30, [SP,#0x10+var_s0]
.text:0000000000020C0C ADD X29, SP, #0x10
.text:0000000000020C10 STR X0, [SP,#0x10+var_8]
.text:0000000000020C14 STR X1, [SP,#0x10+var_10]
.text:0000000000020C18 MOV W0, #3 ; prio
.text:0000000000020C1C ADRL X1, aNativelib ; "nativelib"
.text:0000000000020C24 ADRL X2, aCallFromHook11 ; "call from hook111"
.text:0000000000020C2C BL .__android_log_print
.text:0000000000020C30 BRK #1
.text:0000000000020C30 ; } // starts at 20C04

确实有个BRK #1指令!

而C++的代码如下:

1
2
3
4
5
6
inline void * foo11111(void *,void *)
{
__android_log_print(ANDROID_LOG_DEBUG, TAG,"call from hook111");
//return nullptr;
}

发现对于inline 的函数,如果声明返回值类型, 不是void无返回值,但是没有return 语句时, 编译器就会增加这个指令.

修复的方法也简单,返回nullptr,或者声明为void类型即可.

参考:

https://patchwork.kernel.org/project/linux-arm-kernel/patch/1434036566-9848-10-git-send-email-Dave.Martin@arm.com/