'JNI: SIGSEGV when calling native function from Java, after native registration of same function on library second opening
I have an Android app that is structured in the following way:
- CORE: Is the class of the accessibility service that dinamically loads a few dex files. It will be loaded when app starts;
- MODULE: Is the classe created by loading relative dex file
Actions
- When Core starts, in onServiceConnected, this service loads a native library libbridge.so.
- libbridge.so exposes two methods:
- openLib(module):
- this method opens the library libcloser.so first time and libcloser_2.so second time. These two libs are equals, only names are different.
- registers a function called doSum of libcloser.so / libsloser_2.so by using RegisterNatives JNI function, to the module received in input.
void* func = dlsym(handle, "Java_com_android_dynamic_FileGrabberModule_doSum"); static JNINativeMethod methods[] = { {"doSum", "()V", func} }; jclass clazz = env->GetObjectClass(module); int ret = (*env).RegisterNatives(clazz, methods, sizeof(methods)/sizeof(methods[0])); if (ret == 0) { LOGI("registerNatives() Successfull registration"); } else { LOGI("registerNatives() Registration Failed"); } (*env).DeleteLocalRef( clazz );
- closeLib(module): Unregisters the function doSum for the module received in input and closes the libcloser.so / libsloser_2.so lib
jclass clazz = env->GetObjectClass(module); int ret = (*env).UnregisterNatives(clazz); if (ret == 0) { LOGI("unregisterNatives() Successfull unregistration"); } else { LOGI("unregisterNatives() Unregistration Failed"); } (*env).DeleteLocalRef( clazz );
- openLib(module):
Core exposes two methods:
- onOpenLib(module): Calls libbridge.so method openLib(module)
- onCloseLib(module): Calls libbridge.so method closeLib(module)
From the Module, dinamically loaded from a dex, in doSumInLib function (called from constructor), Core openLib(module) is called, passing this:
Core.onOpenLib(this)
- libbridge.so openLib(module) is called;
- libcloser.so is opened, and an handle is returned;
- the function doSum is registered (with the same handle);
When Module call function doSum(), libcloser.so is called and executes code successfully.
With certain conditions, Core terminates the Module thread.
- Core onCloseLib(module) is called;
- libbridge.so closeLib(module) is called;
- function are unregistered (with the same handle);
- libcloser.so is closed (by the same handle);
After some time, Core reloads the Module from the dex file and tries to execute the same actions writed before (Back to 3). Now the lib that will be opened is libcloser_2.so.
At this time, when point 3 is executed again, when Module call libcloser_2.so doSum(), JNI crash and return this stack:
Build fingerprint: 'xiaomi/jasmine/jasmine_sprout:9/PKQ1.180904.001/V10.0.17.0.PDIMIXM:user/release-keys'
DEBUG : Revision: '0'
DEBUG : ABI: 'arm64'
DEBUG : pid: 17433, tid: 17517, name: Thread-3 >>> com.xxxxx.xxxx <<<
DEBUG : signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x72f74536b8
DEBUG : x0 000000730d82fc40 x1 00000072f92f58f4 x2 005b0000fc9280a0 x3 ac6603ef4e6e40fd
DEBUG : x4 0000000000000000 x5 0000000000000002 x6 00000072fc9280a0 x7 ac6603ef4e6e40fd
DEBUG : x8 ac6603ef4e6e40fd x9 ac6603ef4e6e40fd x10 0000000000430000 x11 00000072f92f5860
DEBUG : x12 00000072f92f58f4 x13 00000072f92f58e8 x14 0000000000000000 x15 00000072f92f43b8
DEBUG : x16 00000072f74536b8 x17 0000000000000000 x18 0000000000000010 x19 00000072fc928000
DEBUG : x20 0000000000000000 x21 00000072fc928000 x22 00000072f92f5bc0 x23 00000072f653e33b
DEBUG : x24 0000000000000004 x25 00000072f92f9588 x26 00000072fc9280a0 x27 0000000000000001
DEBUG : x28 00000072f92f58f0 x29 00000072f92f58f0
DEBUG : sp 00000072f92f58d0 lr 00000073162befe4 pc 00000072f74536b8
linker : CANNOT LINK EXECUTABLE "/system/bin/dpmd": "/system/lib64/libdpmframework.so" is 32-bit instead of 64-bit
[Wed Sep 01 11:08:57 GMT+02:00 2021] : [Downloader_88cfcebe-c617-4e72-b27f-5676229afb61] Received heartbeat ack
DEBUG :
DEBUG : backtrace:
DEBUG : #00 pc 00000000000eb6b8 <anonymous:00000072f7368000>
DEBUG : #01 pc 000000000055dfe0 /system/lib64/libart.so (offset 0x43f000) (art_quick_generic_jni_trampoline+144)
DEBUG : #02 pc 0000000000554f88 /system/lib64/libart.so (offset 0x43f000) (art_quick_invoke_stub+584)
DEBUG : #03 pc 00000000000cf6c8 /system/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+200)
DEBUG : #04 pc 000000000027f230 /system/lib64/libart.so (offset 0x20d000) (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+344)
DEBUG : #05 pc 0000000000279244 /system/lib64/libart.so (offset 0x20d000) (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+968)
DEBUG : #06 pc 000000000052473c /system/lib64/libart.so (offset 0x43f000) (MterpInvokeVirtual+588)
DEBUG : #07 pc 0000000000547694 /system/lib64/libart.so (offset 0x43f000) (ExecuteMterpImpl+14228)
DEBUG : #08 pc 0000000000010ec6 /dev/ashmem/dalvik-DEX data (deleted) (com.xxxx.xxxx.xxxx.doSumInLib+38)
( Other logs ...)
FYI
- 0x72f74536b8 is the memory address of the function gotten from libcloser.so with dlsym()
SO, JNI crash on doSum calling of libcloser_2.so and the address memory that generates exception is the handle of doSum of libcloser.so opened and closed before opening libcloser_2.so
Anyone can help me?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|