rovo89 / XposedBridge

The Java part of the Xposed framework.
3.91k stars 1.1k forks source link

JNI Error: local reference table overflow #188

Closed daimoniuma closed 7 years ago

daimoniuma commented 7 years ago

I tried to getDeclaredMethods from class and hook them all.

Class<?> classToHook = XposedHelpers.findClass(className, lpparam.classLoader);
        Method[] methods = classToHook.getDeclaredMethods();

It works well with simple classes which nothing extends, but when I tried to hook classes which extends AppCompatActivity or Fragment...

JNI ERROR (app bug): local reference table overflow (max=512)
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113] local reference table dump:
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]   Last 10 entries (of 512):
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]       511: 0x12c9b500 dalvik.system.PathClassLoader
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]       510: 0x12c9b500 dalvik.system.PathClassLoader
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]       509: 0x12d38580 java.lang.Object[] (1 elements)
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]       508: 0x12e26440 java.lang.String "com.daimonium.mu... (32 chars)
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]       507: 0x12c9b500 dalvik.system.PathClassLoader
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]       506: 0x12c9b500 dalvik.system.PathClassLoader
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]       505: 0x12d381f0 java.lang.Object[] (1 elements)
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]       504: 0x12e263a0 java.lang.String "com.daimonium.mu... (32 chars)
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]       503: 0x12c9b500 dalvik.system.PathClassLoader
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]       502: 0x12c9b500 dalvik.system.PathClassLoader
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]   Summary:
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]        84 of java.lang.Object[] (1 elements) (84 unique instances)
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]       251 of dalvik.system.PathClassLoader (1 unique instances)
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]         1 of java.lang.Object[] (1 elements)
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]         1 of dalvik.system.PathClassLoader
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]        36 of java.lang.Object[] (1 elements) (36 unique instances)
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]         2 of java.lang.Class (2 unique instances)
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]         4 of java.lang.Object[] (1 elements) (4 unique instances)
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]        81 of java.lang.String (81 unique instances)
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]         1 of java.lang.String[] (3 elements)
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]        34 of java.lang.String (34 unique instances)
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]         3 of java.lang.Class (3 unique instances)
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]         4 of java.lang.String (4 unique instances)
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]         1 of java.lang.Class
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113]         9 of java.lang.String (9 unique instances)
09-25 05:03:35.186 F/art     (12112): art/runtime/indirect_reference_table.cc:113] 
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287] Runtime aborting...
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287] Aborting thread:
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287] "main" prio=5 tid=1 Runnable
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   | group="" sCount=0 dsCount=0 obj=0x76339a30 self=0xb4827800
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   | sysTid=12112 nice=0 cgrp=apps sched=0/0 handle=0xb6f65ec8
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   | state=R schedstat=( 860152861 284727402 854 ) utm=70 stm=16 core=3 HZ=100
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   | stack=0xbe2f6000-0xbe2f8000 stackSize=8MB
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   | held mutexes= "abort lock" "mutator lock"(shared held)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   native: #00 pc 000045b4  /system/lib/libbacktrace_libc++.so (UnwindCurrent::Unwind(unsigned int, ucontext*)+23)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   native: #01 pc 00002e1d  /system/lib/libbacktrace_libc++.so (Backtrace::Unwind(unsigned int, ucontext*)+8)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   native: #02 pc 0023d811  /system/lib/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, char const*, art::mirror::ArtMethod*)+68)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   native: #03 pc 002238c7  /system/lib/libart.so (art::Thread::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const+150)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   native: #04 pc 00213c9f  /system/lib/libart.so (art::AbortState::DumpThread(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, art::Thread*)+22)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   native: #05 pc 00213edd  /system/lib/libart.so (art::AbortState::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)+324)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   native: #06 pc 002140d1  /system/lib/libart.so (art::Runtime::Abort()+72)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   native: #07 pc 000a8577  /system/lib/libart.so (art::LogMessage::~LogMessage()+1066)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   native: #08 pc 0015296f  /system/lib/libart.so (art::IndirectReferenceTable::Add(unsigned int, art::mirror::Object*)+346)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   native: #09 pc 0027a1e9  /system/lib/libart.so (art::BuildQuickArgumentVisitor::Visit()+48)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   native: #10 pc 0027e6e7  /system/lib/libart.so (artQuickProxyInvokeHandler+938)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   native: #11 pc 000a473d  /system/lib/libart.so (art_quick_proxy_invoke_handler+12)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   native: #12 pc 000895fc  [anon:libc_malloc] (???)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   at java.lang.ClassLoader.loadClass [XposedHooked](<Xposed>:469)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   at libcore.reflect.InternalNames.getClass(InternalNames.java:53)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   at java.lang.Class.getDexCacheType(Class.java:479)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   at java.lang.reflect.ArtMethod.getDexCacheType(ArtMethod.java:229)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   at java.lang.reflect.ArtMethod.getParameterTypes(ArtMethod.java:169)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   at java.lang.reflect.Method.getParameterTypes(Method.java:174)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   at java.lang.Class.getDeclaredMethods(Class.java:772)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   at com.some.app.xposed.ExtendedSystem.onClassLoaded(ExtendedSystem.java:175)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   - locked <0x0d40e3ba> (a com.some.app.xposed.ExtendedSystem)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   at com.some.app.xposed.ExtendedSystem.access$1000008(ExtendedSystem.java:-1)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   at com.some.app.xposed.ExtendedSystem$100000003.afterHookedMethod(ExtendedSystem.java:167)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   at de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:348)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   at java.lang.ClassLoader.loadClass [XposedHooked](<Xposed>:469)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   at libcore.reflect.InternalNames.getClass(InternalNames.java:53)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   at java.lang.Class.getDexCacheType(Class.java:479)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   at java.lang.reflect.ArtMethod.getDexCacheType(ArtMethod.java:229)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   at java.lang.reflect.ArtMethod.getParameterTypes(ArtMethod.java:169)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   at java.lang.reflect.Method.getParameterTypes(Method.java:174)
09-25 05:03:37.325 F/art     (12112): art/runtime/runtime.cc:287]   at java.lang.Class.getDeclaredMethods(Class.java:772)
09-25 05:03:37.326 F/art     (12112): art/runtime/runtime.cc:287]   at com.some.app.xposed.ExtendedSystem.onClassLoaded(ExtendedSystem.java:175)
09-25 05:03:37.326 F/art     (12112): art/runtime/runtime.cc:287]   - locked <0x0d40e3ba> (a com.some.app.xposed.ExtendedSystem)
09-25 05:03:37.326 F/art     (12112): art/runtime/runtime.cc:287]   at com.some.app.xposed.ExtendedSystem.access$1000008(ExtendedSystem.java:-1)
09-25 05:03:37.326 F/art     (12112): art/runtime/runtime.cc:287]   at com.some.app.xposed.ExtendedSystem$100000003.afterHookedMethod(ExtendedSystem.java:167)
rovo89 commented 7 years ago

Looks like you have hooked critical methods like ClassLoader.loadClass(). Try if it also crashes without this hook.

daimoniuma commented 7 years ago

Absolutely correct.

"java.lang.ClassLoader", lpparam.classLoader, "loadClass", String.class, new XC_MethodHook()

It was done to catch things from PathClassLoader and so on. Not all classes are hooked, it waits for defined class.

No errors if I dismiss this catcher. How can I bring it back? Where is mistake?

rovo89 commented 7 years ago

There's probably some error in your hook. The stack looks like you call getDeclaredMethods() from your hook, which in turn calls loadClass() again, so you probably have some infinite recursion. If you execute your logic before the class load, try to move it to afterwards. But if you always look up all methods of a class, and then look up all classes of their parameter types, and repeat that often enough, something like this will happen as you load and process lots of classes while your stack grows. There are ways to convert code from recursive to iterative, that might help. But seriously, I really recommend not to hook such critical methods.

daimoniuma commented 7 years ago

You was right. Here is infinity loop.

findAndHookMethod("java.lang.ClassLoader", lpparam.classLoader, "loadClass", String.class, boolean.class, new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    String loadedClass = (String) param.args[0];

                    if(targetClasses.contains(loadedClass)){
                        XposedBridge.log(loadedClass);
                        onClassLoaded(lpparam, (Class<?>) param.getResult(), catcher);
                    }
                }
            });

private void onClassLoaded(final LoadPackageParam lpparam, Class<?> classToHook, XC_MethodHook catcher){
        Method[] methods = classToHook.getDeclaredMethods();

For some reason return Class<?> is null. getDeclaredMethods tries to load class into loop. Why?

daimoniuma commented 7 years ago

Solved. 😸

String loadedClass = (String) param.args[0];

                    if(inspectClasses.contains(loadedClass)){
                        Class<?> classToHook = (Class<?>) param.getResult();

                        if(classToHook == null)
                            return;

                        inspectClasses.remove(loadedClass);

                        onClassLoaded(lpparam, classToHook, catcher);