我开始学习Java,并且在Android设备上安装了一个应用程序。该应用仅具有MainActivity(com.example.myapplication.MainActivity)。在MainActivity内部有一个public(doSomething1)和一个private(doSomething2)方法。假设我没有该应用程序的源文件。我要做的是使用Java Reflection从另一个应用程序(DEX)调用这些方法。这是执行运行时Dex注入的代码。
JNIEnv* (*getJNIEnv)();
/**
* Inject the DEX file and execute the method.
* @param dexPath: The dex file to inject
* @param dexOptDir: Cache path
* @param className: Class name to be executed after injection
* @param methodName: Method name to execute
* @param argc: number of arguments
* @param argv: arguments
* @return
*/
int invoke_dex_method(const char* dexPath, const char* dexOptDir, const char* className, const char* methodName, int argc, char *argv[]) {
LOGD("dexPath = %s, dexOptDir = %s, className = %s, methodName = %s\n", dexPath, dexOptDir, className, methodName);
// Acquisition of JNIEnv
void* handle = dlopen("/system/lib/libandroid_runtime.so", RTLD_NOW);
LOGD("dlopen = %x, %s\n", handle, strerror(errno));
getJNIEnv = dlsym(handle, "_ZN7android14AndroidRuntime9getJNIEnvEv");
LOGD("dlsym = %x, %s\n", getJNIEnv, strerror(errno));
JNIEnv* env = getJNIEnv();
LOGD("JNIEnv = %x\n", env);
// Call getSystemClassLoader of ClassLoader to get ClassLoader of current process
jclass classloaderClass = (*env)->FindClass(env,"java/lang/ClassLoader");
jmethodID getsysloaderMethod = (*env)->GetStaticMethodID(env,classloaderClass, "getSystemClassLoader", "()Ljava/lang/ClassLoader;");
jobject loader = (*env)->CallStaticObjectMethod(env, classloaderClass, getsysloaderMethod);
LOGD("loader = %x\n", loader);
// Read the dex file with DexClassLoader for processing with the current ClassLoader
jstring dexpath = (*env)->NewStringUTF(env, dexPath);
jstring dex_odex_path = (*env)->NewStringUTF(env,dexOptDir);
jclass dexLoaderClass = (*env)->FindClass(env,"dalvik/system/DexClassLoader");
jmethodID initDexLoaderMethod = (*env)->GetMethodID(env, dexLoaderClass, "<init>", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)V");
jobject dexLoader = (*env)->NewObject(env, dexLoaderClass, initDexLoaderMethod,dexpath,dex_odex_path,NULL,loader);
LOGD("dexLoader = %x\n", dexLoader);
// Load code to execute using DexClassLoader
jmethodID findclassMethod = (*env)->GetMethodID(env,dexLoaderClass,"findClass","(Ljava/lang/String;)Ljava/lang/Class;");
jstring javaClassName = (*env)->NewStringUTF(env,className);
jclass javaClientClass = (*env)->CallObjectMethod(env,dexLoader,findclassMethod,javaClassName);
if (!javaClientClass) {
LOGD("Failed to load target class %s\n", className);
printf("Failed to load target class %s\n", className);
return -1;
}
// Get the method to inject
jmethodID start_inject_method = (*env)->GetStaticMethodID(env, javaClientClass, methodName, "()V");
if (!start_inject_method) {
LOGD("Failed to load target method %s\n", methodName);
printf("Failed to load target method %s\n", methodName);
return -1;
}
// Execute method (this method must be a public static void method)
(*env)->CallStaticVoidMethod(env,javaClientClass,start_inject_method);
return 0;
}
上面的代码运行良好,没有任何问题,并调用了method(4th param)。这是Dex文件中Java类的代码。
public class HookTool {
public static final String TAG = "INJECT";
public static void dexInject() throws ClassNotFoundException, IllegalAccessException {
Log.d(TAG, "This is dex code. Start hooking process in Java world.");
try {
Class<?> activityClass = Class.forName("com.example.myapplication.MainActivity");
Method method2 = activityClass.getMethod("doSomething1");
Method method1 = activityClass.getDeclaredMethod("doSomething2");
} catch (ClassNotFoundException | NoSuchMethodException e) {
e.printStackTrace();
}
}
}
我没有从上面的代码中得到预期的结果。这是打印的logcat结果。
D/INJECT (15393): This is dex code. Start hooking process in Java world.
W/System.err(15393): java.lang.ClassNotFoundException: com.example.myapplication.MainActivity
W/System.err(15393): at java.lang.Class.classForName(Native Method)
W/System.err(15393): at java.lang.Class.forName(Class.java:309)
W/System.err(15393): at java.lang.Class.forName(Class.java:273)
W/System.err(15393): at net.cimadai.hookerApp.HookTool.dexInject(HookTool.java:43)
W/System.err(15393): at android.os.MessageQueue.nativePollOnce(Native Method)
W/System.err(15393): at android.os.MessageQueue.next(MessageQueue.java:143)
W/System.err(15393): at android.os.Looper.loop(Looper.java:122)
W/System.err(15393): at android.app.ActivityThread.main(ActivityThread.java:5254)
W/System.err(15393): at java.lang.reflect.Method.invoke(Native Method)
W/System.err(15393): at java.lang.reflect.Method.invoke(Method.java:372)
W/System.err(15393): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
W/System.err(15393): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
W/System.err(15393): Caused by: java.lang.ClassNotFoundException: Didn't find class "com.example.myapplication.MainActivity" on path: DexPathList[[zip file "/data/local/tmp/app-debug.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
W/System.err(15393): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
W/System.err(15393): at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
W/System.err(15393): at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
W/System.err(15393): ... 12 more
W/System.err(15393): Suppressed: java.lang.ClassNotFoundException: Didn't find class "com.example.myapplication.MainActivity" on path: DexPathList[[directory "."],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
W/System.err(15393): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
W/System.err(15393): at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
W/System.err(15393): at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
W/System.err(15393): ... 13 more
W/System.err(15393): Suppressed: java.lang.ClassNotFoundException: com.example.myapplication.MainActivityW/System.err(15393): at java.lang.Class.classForName(Native Method)
W/System.err(15393): at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
W/System.err(15393): at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
W/System.err(15393): at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
W/System.err(15393): ... 14 more
W/System.err(15393): Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available
所以问题
你能给我解释一下吗?
提前谢谢
答案 0 :(得分:0)
我找到了在右旋注射后获得最佳活动的方法。这是代码。
public static Activity getTopActivity() {
Activity topActivity = null;
try {
@SuppressLint("PrivateApi") Class activityThreadClass = Class.forName("android.app.ActivityThread");
@SuppressLint("DiscouragedPrivateApi") Method getATMethod = activityThreadClass.getDeclaredMethod("currentActivityThread");
Field activitiesField = activityThreadClass.getDeclaredField("mActivities");
Object activityThread = getATMethod.invoke(null);
activitiesField.setAccessible(true);
Object activityClientRecord;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
ArrayMap activities = (ArrayMap) activitiesField.get(activityThread);
activityClientRecord = activities.valueAt(0);
}else{
HashMap activities = (HashMap) activitiesField.get(activityThread);
activityClientRecord = activities.values();
}
@SuppressLint("PrivateApi") Class activityClientRecordClass = Class.forName("android.app.ActivityThread$ActivityClientRecord");
Field activityField = activityClientRecordClass.getDeclaredField("activity");
activityField.setAccessible(true);
topActivity = (Activity) activityField.get(activityClientRecord);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
return topActivity;
}
上面的代码将为您提供最活跃的活动的实例。