Android Hook Java
2015-07-23 16:00
441 查看
Android Hook Java
由于项目需要,实现了一个脱离XPosed框架的Android Hook Java方法。其原理是注入某系统进程,使该进程加载某动态链接库,执行该库里的某函数,通过该函数执行某jar包里的java函数,然后执行hook该进程中的java函数操作。其中Hook Java部分提取了XPosed框架中的hook原理。1、进程注入
target_pid = find_pid_of("system_server"); if(inject_remote_process(target_pid, "/system/lib/libtest.so", "java_hook_test", "I'm parameter!", strlen("I'm parameter!")) == 0) LOGV("inject success");
2、在C层执行Java方法
JavaVM* jvm = AndroidRuntime::getJavaVM(); JNIEnv* env; jvm->AttachCurrentThread(&env, NULL); jstring apk_path = env->NewStringUTF(INJECT_JAR_PATH); jstring dex_out_path = env->NewStringUTF("/data/dalvik-cache"); jclass dexloader_claxx = env->FindClass("dalvik/system/DexClassLoader"); snprintf(sig_buffer, 512, "(%s%s%s%s)V", JSTRING, JSTRING, JSTRING, JCLASS_LOADER); jmethodID dexloader_init_method = env->GetMethodID(dexloader_claxx, "<init>", sig_buffer); snprintf(sig_buffer, 512, "(%s)%s", JSTRING, JCLASS); jmethodID loadClass_method = env->GetMethodID(dexloader_claxx, "loadClass", sig_buffer); jclass class_loader_claxx = env->FindClass("java/lang/ClassLoader"); snprintf(sig_buffer, 512, "()%s", JCLASS_LOADER); jmethodID getSystemClassLoader_method = env->GetStaticMethodID(class_loader_claxx, "getSystemClassLoader", sig_buffer); jobject class_loader = env->CallStaticObjectMethod(class_loader_claxx, getSystemClassLoader_method); check_value(class_loader); jobject dex_loader_obj = env->NewObject(dexloader_claxx, dexloader_init_method, apk_path, dex_out_path, NULL, class_loader); jstring class_name = env->NewStringUTF(CLASS_JAVA); jclass class_jia = static_cast<jclass>(env->CallObjectMethod(dex_loader_obj, loadClass_method, class_name)); check_value(class_jia); jmethodID invoke_method = env->GetStaticMethodID(class_jia, "hook", "(I)V"); check_value(invoke_method); env->CallStaticObjectMethod(class_jia, invoke_method, 0); LOGI("end hook java"); jvm->DetachCurrentThread();
3、添加你想执行hook操作的java函数,interceptKeyBeforeQueueing方法主要做一下对特殊按键的处理。
Bridge.hookAllMethods(Helpers.findClass("com.android.internal.policy.impl.PhoneWindowManager"), "interceptKeyBeforeQueueing");
4、类似于XPosed框架,添加你想替换的java函数cb_interceptKeyBeforeQueueing,可根据需求添加执行真正函数前与执行完后的操作。
static XC_MethodHook cb_interceptKeyBeforeQueueing = new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { Log.v("test", "[KeyPress]" + param.args[0] + " | " + param.args[1] + " | " + param.args[2]); } };handleHookedMethod是真正替换的函数。
private static Object handleHookedMethod(Member method, int originalMethodId, Object additionalInfoObj, Object thisObject, Object[] args) throws Throwable { //Log.v("test", "enter handleHookedMethod"); AdditionalHookInfo additionalInfo = (AdditionalHookInfo) additionalInfoObj; MethodHookParam param = new MethodHookParam(); param.method = method; param.thisObject = thisObject; param.args = args; // call "before method" callbacks try { if (method.getName().equals("interceptKeyBeforeQueueing")) Hook.cb_interceptKeyBeforeQueueing.beforeHookedMethod(param); } catch (Throwable t) { Log.v("test", t.getMessage()); // reset result (ignoring what the unexpectedly exiting callback did) param.setResult(null); param.returnEarly = false; } // call original method if not requested otherwise if (!param.returnEarly) { try { param.setResult(invokeOriginalMethodNative(method, originalMethodId, additionalInfo.parameterTypes, additionalInfo.returnType, param.thisObject, param.args)); } catch (InvocationTargetException e) { param.setThrowable(e.getCause()); } } // call "after method" callbacks Object lastResult = param.getResult(); Throwable lastThrowable = param.getThrowable(); try { //<span style="white-space:pre"> </span>if (method.getName().equals("init")) //<span style="white-space:pre"> </span>Hook.cb_init.afterHookedMethod(param); } catch (Throwable t) { Log.v("test", t.getMessage()); // reset to last result (ignoring what the unexpectedly exiting callback did) if (lastThrowable == null) param.setResult(lastResult); else param.setThrowable(lastThrowable); } // return if (param.hasThrowable()) throw param.getThrowable(); else return param.getResult();}
整个工程已上传至github:https://github.com/phoebe1990/javaHook
运行结果如下:
hook类PhoneWindowManager中interceptKeyBeforeQueueing函数成功,使每次手机按键时都打印一条log信息。
相关文章推荐
- android APK应用安装过程以及默认安装路径
- Android 百分比布局支持库介绍
- Android 进阶
- Android基础_活动_生命周期
- android studio使用遇到问题
- Android adb 发送广播、启动Activity、Service等
- Android照片墙完整版,的完美结合LruCache和DiskLruCache
- Android 反编译
- Android学习笔记之AndroidManifest.xml文件解析 service
- android TextView 显示字数的限制问题
- Android控件:RadioButton(单选按钮)
- Android 权限介绍
- Android Environment.getExternalStorageState使用
- Android 创建Listener监听器形式选择:匿名内部类?外部类?
- Android 手机听筒Earpiece和扬声器speaker切换
- Android单元测试
- Android-横屏应用在竖屏情况下解锁引起销毁
- android 比较靠谱的图片压缩
- android 围绕中心旋转动画
- 麦子学院android开发教程:android手势翻页效果