先交代一下自己的背景和探索情况吧。
首先按照Jack_jia的Dex加壳方法自己实现了一下,但是发现如果被加壳的程序比较大的话,启动的时候会非常慢。
然后我就把加载dex文件的方法改为了内存加载,并按照帖子http://bbs.pediy.com/showthread.php?p=1412357#post1412357中的方法,在native层实现了自己版本的解析dex的方法,并将解析后的DexOrJar类型对象的指针添加到gDvm.userDexFiles这个HashTable里面了。希望能够提高启动速度。
我是在解壳的时候把被加壳的dex直接解析并加载到系统gDvm中了,并没有去新建DexClassLoader(因为新建的话会做optimize,会耗费很多时间)。
但是按照上面的方法运行被加壳的程序时会提醒找不到被加壳程序的入口类。我另外又做了个小实验,新建了一个Android工程,它启动的时候会去加载sdcard上一个dex文件,并运行里面的一个方法,加载sdcard上dex文件我使用的就是上面介绍的自己实现的解析dex文件并加入到系统gDvm的方法,然后直接用getClassLoader().loadClass()就可以加载sdcard上dex中的类并执行里面的方法了。
问题1:我不明白为什么同样的方法,小实验中完全没问题,在解壳的时候就找不到类?我用ida调试了好多次,奈何由于自己太菜,并没有看出问题在哪。
为了解决问题,我自己看了一下Android的源码,加载一个类时流程大概是Dalvik_dalvik_system_DexFile_defineClass()===>dvmDefineClass()===>findClassNoInit()===>dvmLookUpClass(),在这个函数里会去gDvm.loadedClasses这个HashTable去查找类,但没有找到然后null,然后返回findClassNoInit()函数中loadClassFromDex()找到目标类对应的ClassObject指针,然后dvmAddClassToHash将其加入到gDvm.loadedClasses中去。
上面的过程都是与ClassLoader相关的,然后我又使用java反射机制,将底层解析Dex文件得到的DexOrJar指针作为mCookie构造了DexFile对象,并加入到BaseDexClassLoader->pathList->dexElements这个数组中了,心想已经把整个dex解析后的东西都添加到系统中了,这次应该没问题了吧。但还是有崩溃,且崩溃栈有两种:
一种是:
I/DEBUG(172): backtrace:
I/DEBUG(172): #00 pc 0005d354 /system/lib/libdvm.so (dvmOptResolveMethod(ClassObject*, unsigned int, MethodType, VerifyError*)+259)
I/DEBUG(172): #01 pc 0005732d /system/lib/libdvm.so
I/DEBUG(172): #02 pc 00059961 /system/lib/libdvm.so (dvmVerifyCodeFlow(VerifierData*)+8376)
I/DEBUG(172): #03 pc 0005c759 /system/lib/libdvm.so
I/DEBUG(172): #04 pc 0005c817 /system/lib/libdvm.so (dvmVerifyClass(ClassObject*)+34)
I/DEBUG(172): #05 pc 0006ae49 /system/lib/libdvm.so (dvmInitClass+116)
I/DEBUG(172): #06 pc 0006664b /system/lib/libdvm.so
I/DEBUG(172): #07 pc 00027060 /system/lib/libdvm.so
I/DEBUG(172): #08 pc 0002b5ec /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
I/DEBUG(172): #09 pc 000601df /system/lib/libdvm.so (dvmInvokeMethod(Object*, Method const*, ArrayObject*, ArrayObject*, ClassObject*, bool)+350)
I/DEBUG(172): #10 pc 00067ddf /system/lib/libdvm.so
I/DEBUG(172): #11 pc 00027060 /system/lib/libdvm.so
I/DEBUG(172): #12 pc 0002b5ec /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
I/DEBUG(172): #13 pc 000601df /system/lib/libdvm.so (dvmInvokeMethod(Object*, Method const*, ArrayObject*, ArrayObject*, ClassObject*, bool)+350)
I/DEBUG(172): #14 pc 00067ddf /system/lib/libdvm.so
I/DEBUG(172): #15 pc 00027060 /system/lib/libdvm.so
I/DEBUG(172): #16 pc 0002b5ec /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
I/DEBUG(172): #17 pc 0005ff21 /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+292)
I/DEBUG(172): #18 pc 00049b67 /system/lib/libdvm.so
I/DEBUG(172): #19 pc 0004b697 /system/lib/libandroid_runtime.so
I/DEBUG(172): #20 pc 0004c327 /system/lib/libandroid_runtime.so (android::AndroidRuntime::start(char const*, char const*)+378)
I/DEBUG(172): #21 pc 0000105b /system/bin/app_process
I/DEBUG(172): #22 pc 0000db4f /system/lib/libc.so (__libc_init+50)
I/DEBUG(172): #23 pc 00000d7c /system/bin/app_process
另外一种:
I/DEBUG(172): backtrace:
I/DEBUG(172): #00 pc 000699f6 /system/lib/libdvm.so (dvmLinkClass(ClassObject*)+477)
I/DEBUG(172): #01 pc 0006aa89 /system/lib/libdvm.so
I/DEBUG(172): #02 pc 00064c69 /system/lib/libdvm.so
I/DEBUG(172): #03 pc 00027060 /system/lib/libdvm.so
I/DEBUG(172): #04 pc 0002b5ec /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
I/DEBUG(172): #05 pc 000601df /system/lib/libdvm.so (dvmInvokeMethod(Object*, Method const*, ArrayObject*, ArrayObject*, ClassObject*, bool)+350)
I/DEBUG(172): #06 pc 00067ddf /system/lib/libdvm.so
I/DEBUG(172): #07 pc 00027060 /system/lib/libdvm.so
I/DEBUG(172): #08 pc 0002b5ec /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
I/DEBUG(172): #09 pc 000601df /system/lib/libdvm.so (dvmInvokeMethod(Object*, Method const*, ArrayObject*, ArrayObject*, ClassObject*, bool)+350)
I/DEBUG(172): #10 pc 00067ddf /system/lib/libdvm.so
I/DEBUG(172): #11 pc 00027060 /system/lib/libdvm.so
I/DEBUG(172): #12 pc 0002b5ec /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
I/DEBUG(172): #13 pc 0005ff21 /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+292)
I/DEBUG(172): #14 pc 00049b67 /system/lib/libdvm.so
I/DEBUG(172): #15 pc 0004b697 /system/lib/libandroid_runtime.so
I/DEBUG(172): #16 pc 0004c327 /system/lib/libandroid_runtime.so (android::AndroidRuntime::start(char const*, char const*)+378)
I/DEBUG(172): #17 pc 0000105b /system/bin/app_process
I/DEBUG(172): #18 pc 0000db4f /system/lib/libc.so (__libc_init+50)
I/DEBUG(172): #19 pc 00000d7c /system/bin/app_process
问题2:不知道我的解壳过程中不新建DexClassLoader,或者将解析后的dex加入到dexElements中,这些方法中有没有什么问题才会导致上面的崩溃。
本人是新手小菜,对系统解析和加载dex以及app启动的过程了解的不是特别透彻,还望高手耐心指教,感谢!