/
/
这个函数的 Visit 会被回调,传入所有的对象。
class
LookupClassesVisitor : public ClassLoaderVisitor {
public:
LookupClassesVisitor(JNIEnv
*
env, JavaVMExt
*
pExt) {
int
offsetOfVmExt
=
findOffset(env,
0
,
10000
, (void
*
) pExt);
/
/
LOGV(
"g_env offsetOfVmExt = %d"
,offsetOfVmExt);
uint8_t
*
u_env
=
reinterpret_cast<uint8_t
*
>(env);
jniEnvExt
=
reinterpret_cast<JNIEnvExt
*
>(u_env
+
offsetOfVmExt
-
sizeof(void
*
));
}
void Visit(ObjPtr<
Object
> class_loader)
REQUIRES_SHARED(Locks::classlinker_classes_lock_, Locks::mutator_lock_) OVERRIDE {
AndroidRunAPI
*
androidRunApi
=
AndroidRunAPI::getInstance();
jobject classLoader_obj
=
androidRunApi
-
>AddGlobalRef( jniEnvExt
-
>vm_,jniEnvExt
-
>self_, class_loader);
vec_obj.push_back(classLoader_obj);
}
std::vector<jobject> getVecObj(){
return
vec_obj;
}
private:
JNIEnvExt
*
jniEnvExt;
std::vector<jobject> vec_obj;
};
void getAndroidSystemFunction(){
AndroidRunAPI
*
androidRunApi
=
AndroidRunAPI::getInstance();
androidRunApi
-
>VisitClassLoaders
=
(void (
*
) (void
*
, void
*
))resolve_elf_internal_symbol(
"libart.so"
,
"_ZNK3art11ClassLinker17VisitClassLoadersEPNS_18ClassLoaderVisitorE"
);
androidRunApi
-
>AddGlobalRef
=
(jobject (
*
)(void
*
, void
*
,ObjPtr<
Object
> ))resolve_elf_internal_symbol(
"libart.so"
,
"_ZN3art9JavaVMExt12AddGlobalRefEPNS_6ThreadENS_6ObjPtrINS_6mirror6ObjectEEE"
);
}
/
/
有很多对比的代码,是在动态找runtime,抄袭别人的
jobjectArray getClassLoaders(JNIEnv
*
env, jint targetSdkVersion) {
JavaVM
*
javaVM;
env
-
>GetJavaVM(&javaVM);
JavaVMExt
*
javaVMExt
=
(JavaVMExt
*
) javaVM;
void
*
runtime
=
javaVMExt
-
>runtime;
LOGV(
"runtime ptr: %p, vmExtPtr: %p"
, runtime, javaVMExt);
LOGV(
"std::unique_ptr<PartialRuntime13> size: %d"
, sizeof (std::unique_ptr<PartialRuntime13>));
LOGV(
"get_heap_to_jvm_offset size: %d"
, get_heap_to_jvm_offset());
const
int
MAX
=
5000
;
int
offsetOfVmExt
=
findOffset(runtime,
0
,
MAX
, (void
*
) javaVMExt);
LOGV(
"offsetOfVmExt: %d"
, offsetOfVmExt);
int
head_offset
=
offsetOfVmExt
-
get_heap_to_jvm_offset()
+
sizeof (void
*
);
LOGV(
"head_offset: %d"
, head_offset);
void
*
heap
=
(char
*
)runtime
+
head_offset;
AndroidRunAPI
*
androidRunApi
=
AndroidRunAPI::getInstance();
LOGV(
"1"
);
androidRunApi
-
>partialRuntime
=
static_cast<PartialRuntime
*
>(heap);
getAndroidSystemFunction();
LOGV(
"1"
);
LookupClassesVisitor visitor(env, javaVMExt);
LOGV(
"1 %p"
,androidRunApi
-
>VisitClassLoaders);
androidRunApi
-
>VisitClassLoaders(androidRunApi
-
>partialRuntime
-
>class_linker_,&visitor);
LOGV(
"1"
);
std::vector<jobject> vectorObject
=
visitor.getVecObj();
jclass ClassLoader_cls
=
env
-
>FindClass(
"java/lang/ClassLoader"
);
LOGV(
"2"
);
for
(auto it
=
vectorObject.begin(); it !
=
vectorObject.end();
/
*
no increment here
*
/
) {
jboolean re
=
env
-
>IsInstanceOf(
*
it,ClassLoader_cls);
if
(!re){
it
=
vectorObject.erase(it);
}
else
{
+
+
it;
}
}
jobjectArray objectArray
=
env
-
>NewObjectArray(vectorObject.size(), ClassLoader_cls, NULL);
for
(
int
i
=
0
;i<vectorObject.size();i
+
+
){
env
-
>SetObjectArrayElement(objectArray, i, vectorObject[i]);
}
return
objectArray;
}