AutojsPro 9.3.11 简单hook
AutojsPro 9.3.11 简单hook
/**
* 分别在主进程和脚本进程注入了gadget, hook时可针对当前进程进行判断
*/'use strict';let currentProcessName = "";
let scriptProcess = false;
Java.perform(main);function main() {try {initGlobalObj();const L = Java.use("com.qx.L")const map = L.printCurrentProcess(L.class)// 当前进程currentProcessName = map.get("processName")scriptProcess = isScriptProcess();//hookStartActivity("")log("frida-gadget hook currentProcessName:", currentProcessName);Java.use("org.autojs.autojs.ui.splash.SplashActivity").onCreate.implementation = function(b) {this.onCreate(b)}!scriptProcess && showAlert("hook成功", "这是hook弹窗")} catch (e) {log("hook脚本出错", e)showAlert("hook脚本出错", e.toString())}}//= util ===================================================================================================================================function toast(text, context) {if (context == undefined) {// 切换到主线程执行 UI 操作mainThreadToast(text)} else {Toast.makeText(context, Java.use("java.lang.String").$new(text), 1).show();}
}
function mainThreadToast(text) {try {log("gloabal toast")// 获取全局 Application Contextlog(Java.scheduleOnMainThread)runInMainThread(() => {Toast.makeText(context, Java.use("java.lang.String").$new(text), 1).show();})}catch(e) {log("hook-error", e)}
}
function getGlobalContext() {const ActivityThread = Java.use('android.app.ActivityThread');return ActivityThread.currentApplication().getApplicationContext();
}
// 自定义弹窗函数
function showAlert(title, text) {title = JavaString.$new(title == undefined?"提示": title);text = JavaString.$new(text == undefined?"null": text);const currentActivity = getCurrentActivity()// log("title=", title, "text=", text)if (currentActivity == null) {mainThreadToast(text);return;} else {Java.scheduleOnMainThread(() => {try {// 使用 Builder 创建弹窗const builder = AlertDialogBuilder.$new(currentActivity);builder.setTitle(title);builder.setMessage(text);builder.setPositiveButton(JavaString.$new("确定"), null);builder.create().show();} catch (e) {log("降级为 Toast 显示, 原因:", e)// 降级为 Toast 显示Toast.makeText(currentActivity, text, Toast.LENGTH_LONG.value).show();}});}}
function initGlobalObj() {globalThis.Toast = Java.use("android.widget.Toast");globalThis.context = getGlobalContext();globalThis.JavaString = Java.use("java.lang.String");globalThis.Log = Java.use("android.util.Log");globalThis.Activity = Java.use('android.app.Activity'); // 获取Activity类globalThis.ActivityThread = Java.use('android.app.ActivityThread');globalThis.Context = Java.use('android.content.Context'); // 获取Context类globalThis.ContextWrapper = Java.use('android.content.ContextWrapper'); // 获取ContextWrapper类globalThis.AlertDialogBuilder = Java.use('android.app.AlertDialog$Builder');globalThis.JavaMap = Java.use("java.util.Map")
}
// 1. 获取当前活动的 Activity
function getCurrentActivity() {const activityThreadInstance = ActivityThread.currentActivityThread();// 获取 mActivities 字段(存储所有 Activity)const activitiesField = activityThreadInstance.getClass().getDeclaredField('mActivities');activitiesField.setAccessible(true);const activities = Java.cast(activitiesField.get(activityThreadInstance), JavaMap);// 遍历所有 Activity,找到最顶层的有效 Activityconst iterator = activities.values().iterator();while (iterator.hasNext()) {const record = iterator.next();const recordClass = record.getClass();const pausedField = recordClass.getDeclaredField("paused");pausedField.setAccessible(true);if (!pausedField.getBoolean(record)) {const activityField = recordClass.getDeclaredField("activity");activityField.setAccessible(true);return Java.cast(activityField.get(record), Activity);}}return null;
}
function runInMainThread(cb) {Java.scheduleOnMainThread(cb);
}
function log() {let msg = "";for (let i = 0; i < arguments.length; i++) {const item = arguments[i]if (item == undefined) {msg += "undefined "} else if (item == null) {msg += "null"} else {try {msg += item.toString() + " "} catch (e) {msg += item + " "}}}const t = isScriptProcess() ? ":script": "";Log.e("frida-hook" + t, msg);
}
function isScriptProcess() {return (currentProcessName + "").endsWith(":script") != "";
}function hookStartActivity(targetClassName) {// 获取Fragment类(如果有使用Fragment启动Activity的情况)var Fragment = null;try {Fragment = Java.use('android.app.Fragment');} catch (e) {}// 获取androidx.fragment.app.Fragment类var SupportFragment = null;try {SupportFragment = Java.use('androidx.fragment.app.Fragment');} catch (e) {}// Hook Activity的startActivity方法hookStartActivity(Activity, 'Activity');hookStartActivity(Context, 'Context');hookStartActivity(ContextWrapper, 'ContextWrapper');if (Fragment) {hookStartActivity(Fragment, 'Fragment');}if (SupportFragment) {hookStartActivity(SupportFragment, 'SupportFragment');}function hookStartActivity(cls, type) {// Hook startActivity(Intent)var startActivity1 = cls.startActivity.overload('android.content.Intent');startActivity1.implementation = function (intent) {// 获取启动的Activity信息var targetComponent = intent.getComponent();if (targetComponent) {var targetClass = targetComponent.getClassName();var currentClass = this.getClass().getName();if (targetClassName != undefined && targetClass.indexOf(targetClassName) != -1) {log('[+] ' + type + ' ' + currentClass + ' started activity: ' + targetClass);// 打印调用栈log('Stack trace:');var stackTrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new());log(stackTrace);}}// 调用原方法return startActivity1.call(this, intent);};// Hook startActivity(Intent, Bundle)var startActivity2 = cls.startActivity.overload('android.content.Intent', 'android.os.Bundle');startActivity2.implementation = function (intent, options) {var targetComponent = intent.getComponent();if (targetComponent) {var targetClass = targetComponent.getClassName();var currentClass = this.getClass().getName();if (targetClassName != undefined && targetClass.indexOf(targetClassName) != -1) {log('[+] ' + type + ' ' + currentClass + ' started activity (with options): ' + targetClass);// 打印调用栈log('Stack trace:');var stackTrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new());log(stackTrace);}}return startActivity2.call(this, intent, options);};}
}
本示例仅供学习!