PAGalaxyLab / YAHFA

Yet Another Hook Framework for ART
GNU General Public License v3.0
1.56k stars 350 forks source link

HookingTest.hookStaticMethod test fails with crash in libart.so on Android 12 beta 4, arm64 #151

Open beaver-android opened 2 years ago

beaver-android commented 2 years ago

Logfile: YAHFA_Android12_Beta4_Crash.txt

08-26 16:54:57.607 24473 24491 I TestRunner: run started: 1 tests
08-26 16:54:57.610 24473 24491 I TestRunner: started: hookStaticMethod(lab.galaxy.yahfa.HookingTest)
08-26 16:54:57.613 24473 24473 I MonitoringInstr: Activities that are still in CREATED to STOPPED: 0
08-26 16:54:57.614 24473 24491 I HookingTest: ABI=arm64-v8a
08-26 16:54:57.617 24473 24491 I YAHFA-Native: init to SDK 31
08-26 16:54:57.617 24473 24491 W laxy.yahfa.tes: Accessing hidden field Ljava/lang/reflect/Executable;->artMethod:J (unsupported, JNI, allowed)
08-26 16:54:57.617 24473 24491 I DLFUNC  : dlfunc_init done
08-26 16:54:57.618 24473 24491 I YAHFA-Native: runtime bss is at 0x6dd1217a98, runtime instance is at 0xb400006f0360e090
08-26 16:54:57.618 24473 24491 I YAHFA-Native: classLinker is at 0xb400006f0360e090, value 0x7042b528
08-26 16:54:57.618 24473 24491 I YAHFA-Native: MakeInitializedClassesVisiblyInitialized is at 0x6dd0a5314c
08-26 16:54:57.618 24473 24491 I YAHFA-Native: thread is at 0x6f43643d80
08-26 16:54:57.618 24473 24491 F libc    : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x10000009f in tid 24491 (roidJUnitRunner), pid 24473 (laxy.yahfa.test)
08-26 16:54:57.654 24495 24495 I crash_dump64: obtaining output fd from tombstoned, type: kDebuggerdTombstoneProto
08-26 16:54:57.654   867   867 I tombstoned: received crash request for pid 24491
08-26 16:54:57.655 24495 24495 I crash_dump64: performing dump of process 24473 (target tid = 24491)
08-26 16:54:57.661 24495 24495 E DEBUG   : failed to read /proc/uptime: Permission denied
08-26 16:54:57.735 24495 24495 W unwind  : Failed to initialize DEX file support: dlopen failed: library "libdexfile.so" not found
08-26 16:54:57.851 24495 24495 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
08-26 16:54:57.851 24495 24495 F DEBUG   : Build fingerprint: 'google/sunfish/sunfish:12/SPB4.210715.014/7654839:user/release-keys'
08-26 16:54:57.851 24495 24495 F DEBUG   : Revision: 'MP1.0'
08-26 16:54:57.851 24495 24495 F DEBUG   : ABI: 'arm64'
08-26 16:54:57.851 24495 24495 F DEBUG   : Timestamp: 2021-08-26 16:54:57.661192623+0300
08-26 16:54:57.851 24495 24495 F DEBUG   : Process uptime: 0s
08-26 16:54:57.851 24495 24495 F DEBUG   : Cmdline: lab.galaxy.yahfa.test
08-26 16:54:57.851 24495 24495 F DEBUG   : pid: 24473, tid: 24491, name: roidJUnitRunner  >>> lab.galaxy.yahfa.test <<<
08-26 16:54:57.851 24495 24495 F DEBUG   : uid: 10238
08-26 16:54:57.851 24495 24495 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x10000009f
08-26 16:54:57.851 24495 24495 F DEBUG   :     x0  0000006de3619d90  x1  000000706d2657cc  x2  0000000000000000  x3  0000000000000010
08-26 16:54:57.851 24495 24495 F DEBUG   :     x4  0000000000000000  x5  8080808000008000  x6  0000000000000010  x7  7f7f7f7fffff7f7f
08-26 16:54:57.851 24495 24495 F DEBUG   :     x8  0000000000000000  x9  0000000000000000  x10 0000000027ca27dc  x11 00000000e3619da0
08-26 16:54:57.851 24495 24495 F DEBUG   :     x12 0000ffff00000eff  x13 000000005234ce68  x14 0000006d577c25a8  x15 0000000000553a7e
08-26 16:54:57.851 24495 24495 F DEBUG   :     x16 00000070718af7f8  x17 000000706d1cac78  x18 0000006d5735c000  x19 0000006f43643d80
08-26 16:54:57.851 24495 24495 F DEBUG   :     x20 0000000000000000  x21 000000007042b6a0  x22 00000000ffffffff  x23 0000006d577c2970
08-26 16:54:57.851 24495 24495 F DEBUG   :     x24 0000006d577ca000  x25 0000000000000002  x26 000000000000001f  x27 0000006d577ca000
08-26 16:54:57.851 24495 24495 F DEBUG   :     x28 0000006d577c2a50  x29 0000006d577c29b0
08-26 16:54:57.851 24495 24495 F DEBUG   :     lr  0000006dd0a531c8  sp  0000006d577c2960  pc  0000006dd0a531d0  pst 0000000060000000
08-26 16:54:57.851 24495 24495 F DEBUG   : backtrace:
08-26 16:54:57.851 24495 24495 F DEBUG   :       #00 pc 00000000004531d0  /apex/com.android.art/lib64/libart.so (art::ClassLinker::MakeInitializedClassesVisiblyInitialized(art::Thread*, bool)+132) (BuildId: 50c25b4aa1972771dac15f87d726a606)
08-26 16:54:57.851 24495 24495 F DEBUG   :       #01 pc 000000000000224c  /data/app/~~4vcmDcLAGusumi7CdxiDyQ==/lab.galaxy.yahfa.test-euO-V4SjVKay6uTRIt-aiw==/lib/arm64/libyahfa.so (Java_lab_galaxy_yahfa_HookMain_00024Utils_visiblyInit+236) (BuildId: 88746668f271647609589380a2d625a9ae10e09d)
08-26 16:54:57.851 24495 24495 F DEBUG   :       #02 pc 0000000000330044  /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+148) (BuildId: 50c25b4aa1972771dac15f87d726a606)
08-26 16:54:57.851 24495 24495 F DEBUG   :       #03 pc 00000000003269e8  /apex/com.android.art/lib64/libart.so (art_quick_invoke_static_stub+568) (BuildId: 50c25b4aa1972771dac15f87d726a606)
08-26 16:54:57.851 24495 24495 F DEBUG   :       #04 pc 0000000000323ba4  /apex/com.android.art/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+320) (BuildId: 50c25b4aa1972771dac15f87d726a606)
08-26 16:54:57.851 24495 24495 F DEBUG   :       #05 pc 000000000032335c  /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+2312) (BuildId: 50c25b4aa1972771dac15f87d726a606)
08-26 16:54:57.851 24495 24495 F DEBUG   :       #06 pc 000000000078a4f4  /apex/com.android.art/lib64/libart.so (MterpInvokeStatic+304) (BuildId: 50c25b4aa1972771dac15f87d726a606)
08-26 16:54:57.852 24495 24495 F DEBUG   :       #07 pc 000000000033cf94  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_static+20) (BuildId: 50c25b4aa1972771dac15f87d726a606)
08-26 16:54:57.852 24495 24495 F DEBUG   :       #08 pc 0000000000001420  [anon:dalvik-classes2.dex extracted in memory from /data/app/~~4vcmDcLAGusumi7CdxiDyQ==/lab.galaxy.yahfa.test-euO-V4SjVKay6uTRIt-aiw==/base.apk!classes2.dex]
08-26 16:54:57.852 24495 24495 F DEBUG   :       #09 pc 0000000000349634  /apex/com.android.art/lib64/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.15880507524294088337)+628) (BuildId: 50c25b4aa1972771dac15f87d726a606)
08-26 16:54:57.852 24495 24495 F DEBUG   :       #10 pc 0000000000352ea4  /apex/com.android.art/lib64/libart.so (art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*)+124) (BuildId: 50c25b4aa1972771dac15f87d726a606)
08-26 16:54:57.852 24495 24495 F DEBUG   :       #11 pc 00000000003234bc  /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+2664) (BuildId: 50c25b4aa1972771dac15f87d726a606)
08-26 16:54:57.852 24495 24495 F DEBUG   :       #12 pc 000000000078a4f4  /apex/com.android.art/lib64/libart.so (MterpInvokeStatic+304) (BuildId: 50c25b4aa1972771dac15f87d726a606)
08-26 16:54:57.852 24495 24495 F DEBUG   :       #13 pc 000000000033cf94  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_static+20) (BuildId: 50c25b4aa1972771dac15f87d726a606)
...
beaver-android commented 2 years ago

Looks like the other two tests fail in the same way:

rk700 commented 2 years ago

OFFSET_classlinker_in_Runtime is not initialized on Android 12: https://github.com/PAGalaxyLab/YAHFA/blob/fe3971295f149068664a28be6589f9d28bcedc86/library/src/main/jni/utils.c#L17

So maybe we could set the offset value for Android 12 and try again?

beaver-android commented 2 years ago

OFFSET_classlinker_in_Runtime is not initialized on Android 12:

https://github.com/PAGalaxyLab/YAHFA/blob/fe3971295f149068664a28be6589f9d28bcedc86/library/src/main/jni/utils.c#L17

So maybe we could set the offset value for Android 12 and try again?

Yes, thanks for the hint! Adding +24 bytes to the OFFSET_classlinker_in_Runtime for R (472) = 496, fixes the hookInstanceMethod and hookCtorMethod tests.

    if(SDKVersion > __ANDROID_API_R__) {
#if defined(__x86_64__) || defined(__aarch64__)
        OFFSET_classlinker_in_Runtime = 472 + 24;
#endif
    }

However, the hookStaticMethod test is still failing, this time with a different backtrace.

Do you know why the call to ClassLink.MakeInitializedClassesVisiblyInitialized() is needed?

Log file: beta_4_yahfa_hookStaticMethod_fail_crash.txt

...
08-27 12:13:17.171 21802 21819 I HookAnnotation: Hooked public static int lab.galaxy.yahfa.HookingTest$StaticHook.target(int): hook=public static int lab.galaxy.yahfa.HookingTest$StaticHook.hook(int), backup=public static int lab.galaxy.yahfa.HookingTest$StaticHook.backup(int)
--------- beginning of crash
08-27 12:13:17.174 21802 21819 F libc    : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 in tid 21819 (roidJUnitRunner), pid 21802 (laxy.yahfa.test)
08-27 12:13:17.235 21823 21823 I crash_dump64: obtaining output fd from tombstoned, type: kDebuggerdTombstoneProto
08-27 12:13:17.239   839   839 I tombstoned: received crash request for pid 21819
08-27 12:13:17.241 21823 21823 I crash_dump64: performing dump of process 21802 (target tid = 21819)
08-27 12:13:17.260 21823 21823 E DEBUG   : failed to read /proc/uptime: Permission denied
08-27 12:13:17.463  1579  3670 D ConnectivityService: NetReassign [no changes]
8-27 12:13:17.493 21823 21823 W unwind  : Failed to initialize DEX file support: dlopen failed: library "libdexfile.so" not found
08-27 12:13:17.731 21823 21823 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
08-27 12:13:17.731 21823 21823 F DEBUG   : Build fingerprint: 'google/sunfish/sunfish:12/SPB4.210715.014/7654839:user/release-keys'
08-27 12:13:17.731 21823 21823 F DEBUG   : Revision: 'MP1.0'
08-27 12:13:17.731 21823 21823 F DEBUG   : ABI: 'arm64'
08-27 12:13:17.731 21823 21823 F DEBUG   : Timestamp: 2021-08-27 12:13:17.259496227+0300
08-27 12:13:17.731 21823 21823 F DEBUG   : Process uptime: 0s
08-27 12:13:17.731 21823 21823 F DEBUG   : Cmdline: lab.galaxy.yahfa.test
08-27 12:13:17.731 21823 21823 F DEBUG   : pid: 21802, tid: 21819, name: roidJUnitRunner  >>> lab.galaxy.yahfa.test <<<
08-27 12:13:17.731 21823 21823 F DEBUG   : uid: 10223
08-27 12:13:17.731 21823 21823 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
08-27 12:13:17.731 21823 21823 F DEBUG   : Cause: null pointer dereference
08-27 12:13:17.731 21823 21823 F DEBUG   :     x0  00000071282c50a0  x1  000000719c82b994  x2  0000000000000000  x3  0000000000000000
08-27 12:13:17.731 21823 21823 F DEBUG   :     x4  0000000000000000  x5  0000000000000000  x6  00000000ebad6076  x7  00000000ebad6077
08-27 12:13:17.731 21823 21823 F DEBUG   :     x8  0000000000000000  x9  0000000000000000  x10 00000071282c4fa0  x11 0000000000001a60
08-27 12:13:17.731 21823 21823 F DEBUG   :     x12 00000071282c4f69  x13 00000071282c5168  x14 0000000000000000  x15 00000071282c517c
08-27 12:13:17.731 21823 21823 F DEBUG   :     x16 000000719d011a18  x17 000000743c742ce0  x18 0000007127b2a000  x19 00000071282c5140
08-27 12:13:17.731 21823 21823 F DEBUG   :     x20 0000000000000000  x21 b4000072cd642c70  x22 000000730d673a10  x23 b4000072cd642f28
08-27 12:13:17.731 21823 21823 F DEBUG   :     x24 00000071282c5174  x25 00000071282c5158  x26 0000000000000000  x27 b40000727d6452f0
08-27 12:13:17.731 21823 21823 F DEBUG   :     x28 0000000000000000  x29 00000071282c4fe0
08-27 12:13:17.731 21823 21823 F DEBUG   :     lr  000000719c9329dc  sp  00000071282c4e40  pc  000000719c82baa8  pst 0000000020000000
08-27 12:13:17.731 21823 21823 F DEBUG   : backtrace:
08-27 12:13:17.731 21823 21823 F DEBUG   :       #00 pc 000000000022baa8  /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp<true, false>(art::interpreter::SwitchImplContext*)+276) (BuildId: 50c25b4aa1972771dac15f87d726a606)
08-27 12:13:17.731 21823 21823 F DEBUG   :       #01 pc 00000000003329d8  /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: 50c25b4aa1972771dac15f87d726a606)
08-27 12:13:17.731 21823 21823 F DEBUG   :       #02 pc 0000000000349558  /apex/com.android.art/lib64/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.15880507524294088337)+408) (BuildId: 50c25b4aa1972771dac15f87d726a606)
08-27 12:13:17.731 21823 21823 F DEBUG   :       #03 pc 0000000000348950  /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+1184) (BuildId: 50c25b4aa1972771dac15f87d726a606)
08-27 12:13:17.731 21823 21823 F DEBUG   :       #04 pc 0000000000330178  /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: 50c25b4aa1972771dac15f87d726a606)
08-27 12:13:17.731 21823 21823 F DEBUG   :       #05 pc 00000000003269e8  /apex/com.android.art/lib64/libart.so (art_quick_invoke_static_stub+568) (BuildId: 50c25b4aa1972771dac15f87d726a606)
08-27 12:13:17.731 21823 21823 F DEBUG   :       #06 pc 0000000000323ba4  /apex/com.android.art/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+320) (BuildId: 50c25b4aa1972771dac15f87d726a606)
08-27 12:13:17.731 21823 21823 F DEBUG   :       #07 pc 000000000032335c  /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+2312) (BuildId: 50c25b4aa1972771dac15f87d726a606)
08-27 12:13:17.731 21823 21823 F DEBUG   :       #08 pc 000000000078a4f4  /apex/com.android.art/lib64/libart.so (MterpInvokeStatic+304) (BuildId: 50c25b4aa1972771dac15f87d726a606)
08-27 12:13:17.731 21823 21823 F DEBUG   :       #09 pc 000000000033cf94  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_static+20) (BuildId: 50c25b4aa1972771dac15f87d726a606)
08-27 12:13:17.731 21823 21823 F DEBUG   :       #10 pc 00000000000005dc  [anon:dalvik-classes5.dex extracted in memory from /data/app/~~1_fQPIPLwVdDAALV6AW_uQ==/lab.galaxy.yahfa.test-BI0tpIWW_BvkpuvJXINCkQ==/base.apk!classes5.dex]
...
rk700 commented 2 years ago

Visibly initialization was added for Class initialization after Android R. Detailed discussion for the YAHFA commits can be found here. In short, when running visibly initialization, static method addresses are resolved and the previous method hooks would be overwritten. So we have to call MakeInitializedClassesVisiblyInitialized explicitly before applying hooks.

I guess the crash for hookStaticMethod may also be related to that.

ghost commented 2 years ago

hook _ZN3art11ClassLinker22FixupStaticTrampolinesEPNS_6ThreadENS_6ObjPtrINS_6mirror5ClassEEE

beaver-android commented 2 years ago

I see. However calling MakeInitializedClassesVisiblyInitialized before each hook doesn't fix the static method hooking, even after I fixed the pointer to ClassLinker object.

Looks like if the hooked method is static and we set art::kAccNative access flag on it => then it causes libart crash. If I remove the access_flags |= kAccNative; in HookMain.c, replaceMethod => then there is no crash, but the hookStaticMethod test still fails

09-06 12:06:42.599 10223 16664 16689 I TestRunner: java.lang.UnsupportedOperationException: Stub!
09-06 12:06:42.599 10223 16664 16689 I TestRunner:  at lab.galaxy.yahfa.HookingTest$StaticHook.backup(HookingTest.java:187)
09-06 12:06:42.599 10223 16664 16689 I TestRunner:  at lab.galaxy.yahfa.HookingTest$StaticHook.hook(HookingTest.java:181)
09-06 12:06:42.599 10223 16664 16689 I TestRunner:  at lab.galaxy.yahfa.HookingTest.hookStaticMethod(HookingTest.java:92)

The backup stub is called, instead of the original method.

ghost commented 2 years ago

I see. However calling MakeInitializedClassesVisiblyInitialized before each hook doesn't fix the static method hooking, even after I fixed the pointer to ClassLinker object.

Looks like if the hooked method is static and we set art::kAccNative access flag on it => then it causes libart crash. If I remove the access_flags |= kAccNative; in HookMain.c, replaceMethod => then there is no crash, but the hookStaticMethod test still fails

09-06 12:06:42.599 10223 16664 16689 I TestRunner: java.lang.UnsupportedOperationException: Stub!
09-06 12:06:42.599 10223 16664 16689 I TestRunner:    at lab.galaxy.yahfa.HookingTest$StaticHook.backup(HookingTest.java:187)
09-06 12:06:42.599 10223 16664 16689 I TestRunner:    at lab.galaxy.yahfa.HookingTest$StaticHook.hook(HookingTest.java:181)
09-06 12:06:42.599 10223 16664 16689 I TestRunner:    at lab.galaxy.yahfa.HookingTest.hookStaticMethod(HookingTest.java:92)

The backup stub is called, instead of the original method.

This is an another issue same as Android 11's. To fix this issue, you must fix "Debug mode enabled cause crash" on Android 11. For Android 11+, you must hook FixupStaticTrampolines for enable pending hook.

yujincheng08 commented 2 years ago

I see. However calling MakeInitializedClassesVisiblyInitialized before each hook doesn't fix the static method hooking, even after I fixed the pointer to ClassLinker object.

Looks like if the hooked method is static and we set art::kAccNative access flag on it => then it causes libart crash. If I remove the access_flags |= kAccNative; in HookMain.c, replaceMethod => then there is no crash, but the hookStaticMethod test still fails

09-06 12:06:42.599 10223 16664 16689 I TestRunner: java.lang.UnsupportedOperationException: Stub!
09-06 12:06:42.599 10223 16664 16689 I TestRunner:    at lab.galaxy.yahfa.HookingTest$StaticHook.backup(HookingTest.java:187)
09-06 12:06:42.599 10223 16664 16689 I TestRunner:    at lab.galaxy.yahfa.HookingTest$StaticHook.hook(HookingTest.java:181)
09-06 12:06:42.599 10223 16664 16689 I TestRunner:    at lab.galaxy.yahfa.HookingTest.hookStaticMethod(HookingTest.java:92)

The backup stub is called, instead of the original method.

how about invoking backup by reflection

vegedreamgagnoa commented 2 years ago

I see. However calling MakeInitializedClassesVisiblyInitialized before each hook doesn't fix the static method hooking, even after I fixed the pointer to ClassLinker object. Looks like if the hooked method is static and we set art::kAccNative access flag on it => then it causes libart crash. If I remove the access_flags |= kAccNative; in HookMain.c, replaceMethod => then there is no crash, but the hookStaticMethod test still fails

09-06 12:06:42.599 10223 16664 16689 I TestRunner: java.lang.UnsupportedOperationException: Stub!
09-06 12:06:42.599 10223 16664 16689 I TestRunner:  at lab.galaxy.yahfa.HookingTest$StaticHook.backup(HookingTest.java:187)
09-06 12:06:42.599 10223 16664 16689 I TestRunner:  at lab.galaxy.yahfa.HookingTest$StaticHook.hook(HookingTest.java:181)
09-06 12:06:42.599 10223 16664 16689 I TestRunner:  at lab.galaxy.yahfa.HookingTest.hookStaticMethod(HookingTest.java:92)

The backup stub is called, instead of the original method.

how about invoking backup by reflection

This works, but it feels uncomfortable to use reflection everytime.

yetnelson commented 2 years ago

I have two devices with android 12. One build id is SP1A 210812.016.C1 which works well. Another one is SP2A 220305.012 has same issue with above.