xposed 的基本使用

xposed 的基本使用本文转载自 xposed 的基本使用 一 原理 Android 运行的核心是 zygote 进程 所有 app 的进程都是通过 zygote fork 出来的 通过替换 system bin 下面的 app process 等文件 相当于替换了 zygote 进程 实现了控制手机上的所有 APP 基本原理是修改了

大家好,我是讯享网,很高兴认识大家。

本文转载自:xposed 的基本使用

一、原理

Android 运行的核心是 zygote 进程,所有 app 的进程都是通过 zygote fork 出来的。通过替换 system/bin/ 下面的 app_process 等文件,相当于替换了 zygote 进程,实现了控制手机上的所有 APP。基本原理是修改了 ART/Davilk 虚拟机,将需要 hook 的函数注册为 Native 层函数,当执行到该函数时,虚拟机会先执行 Native 层函数,然后执行 Java 层函数,这样完成 hook。

更详细的可以参考:https://blog.csdn.net/wxyyxc1992/article/details/

二、Xposed 安装

环境:网易 mumu、Android Studio3.3.1

github 地址:https://github.com/rovo89/XposedInstaller

Xposedinstaller 的 apk:https://repo.xposed.info/module/de.robv.android.xposed.installer

在网易 mumu 中安装好 xposedinstaller apk 后,关闭应用兼容性 (不关闭的话安装 xposed 框架会出错),进去之后点击小云彩即可安装完成。


讯享网

三、Xposed 代码编写

新建项目,选择 empty activity,创建成功后,在 AndroidManifest.xml 中添加如下代码

<meta-data android:name="xposedmodule" android:value="true" /> <!--告诉xposed框架这是一个xposed模块--> <meta-data android:name="xposeddescription" android:value="这是一个Xposed例程" /> <!--模块描述--> <meta-data android:name="xposedminversion" <!--模块支持的最低版本--> android:value="30" /> 

讯享网

在 gradle 中配置 XposedbridgeApi,build.gradle 中配置

讯享网repositories { jcenter() } dependencies { ... compileOnly 'de.robv.android.xposed:api:82' compileOnly 'de.robv.android.xposed:api:82:sources' ... } 

这是在网络通畅的情况下进行的, 网络不通畅的话,可以手动下载 XposedBridgeApi-82.jar,拖动到 /app/libs 中,删除上述 gradle 中配置的 jcenter,右键 "Add As Library" 添加这个 jar 包。

在界面上画个按钮,并在 MainAcitiviy 中编写如下代码 (单纯写 hook 的话前面新建项目的时候可以 add no activity)

package com.example.myapplication; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.Button; import android.widget.Toast; import android.view.View; public class MainActivity2 extends AppCompatActivity { private Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Toast.makeText(MainActivity2.this, toastMessage(), Toast.LENGTH_SHORT).show(); } }); } public String toastMessage() { return "我未被劫持"; } } 

编写 Hook 代码,在 MainActivity 同级目录下新建 HookTest.java,并且继承接口 IXposedHookLoadPackage 和重写 handleLoadPackage 方法

讯享网package com.example.myapplication; import java.lang.reflect.Array; import java.security.PublicKey; import java.util.Arrays; import java.util.Map; import de.robv.android.xposed.IXposedHookLoadPackage; import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.callbacks.XC_LoadPackage; public class HookTest implements IXposedHookLoadPackage { private static final String HOOK_APP_NAME = "APP名字"; public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable { //性能优化,避免操作无关app if (!lpparam.packageName.equals(HOOK_APP_NAME)) return; if (lpparam.packageName.equals("HOOK_APP_NAME")) { XposedBridge.log(" 劫持成功!!!"); XposedBridge.log("XposedMainInit handleLoadPackage 执行"); XposedBridge.log("Loaded app: " + lpparam.packageName); XposedHelpers.findAndHookMethod("APP名字.MainActivity",//hook的类 lpparam.classLoader, "toastMessage", // 被Hook的函数 //Map.class, 被Hook函数的第一个参数 (此处没有,只是举个例子) //String.class, 被Hook函数的第二个参数String new XC_MethodHook() { protected void beforeHookedMethod(MethodHookParam param) throws Throwable { super.beforeHookedMethod(param); // 参数获取 XposedBridge.log("入口函数执行"); //参数1 XposedBridge.log("beforeHookedMethod map:" + param.args[0]); //参数2 XposedBridge.log("beforeHookedMethod hash_key:" + param.args[1]); //函数返回值 XposedBridge.log("beforeHookedMethod result:" + param.getResult()); } protected void afterHookedMethod(MethodHookParam param) throws Throwable { XposedBridge.log("afterHookedMethod result:" + param.getResult()); param.setResult("你已被劫持"); } }); } } } 

在 src/mian 目录下添加一个 assets 目录,目录下添加一个 xposed_init 文件,里面的代码是你的 Hook 类的包名 + 类名。

com.example.myapplication.HookTest

最后选择禁用 Instant Run: 单击 File -> Settings -> Build, Execution, Deployment -> Instant Run,把勾全部去掉。

这个时候钩子已经执行了,具体想钩什么,就看自己的需求了。

注:实际操作中,需要对 APP 先进行反编译 (反编译了才能知道要钩那个函数),反编译工具有很多,这里就不细说了。

四、面对加了壳的 APP

直接用反编译工具打开 apk,查看加的是哪种壳,寻找对应的函数,类似 attachBaseContext 这样的方法。

参考链接:https://www.cnblogs.com/xiaobaiyey/p/6442417.html

public class EncryptHook implements IXposedHookLoadPackage { public void handleLoadPackage(LoadPackageParam loadPackageParam) throws Throwable { if (!loadPackageParam.packageName.equals("app包名")) { return; } XposedBridge.log("Start hook " + loadPackageParam.packageName); XposedHelpers.findAndHookMethod("com.stub.StubApp", loadPackageParam.classLoader, //com.stub.StubApp 加壳的类 "attachBaseContext", Context.class, new XC_MethodHook() { // attachBaseContext 加壳的方法 @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { super.afterHookedMethod(param); Context context = (Context) param.args[0]; ClassLoader classLoader = context.getClassLoader(); XposedBridge.log("Enter stubApp"); XposedHelpers.findAndHookMethod("com.huijiemanager.utils.t", classLoader, "a", byte[].class, PublicKey.class, new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { XposedBridge.log("rsa before params: " + new String( (byte[]) param.args[0]) + "," + param.args[1]); } @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { XposedBridge.log("rsa after params: " + new String( (byte[]) param.args[0]) + "," + param.args[1]); } }); } }); } } 

注:反编译的代码不一定准确,逆向的时候最好对每个关键函数都挂上钩子,查看参数是否正确。

附上 xposedAPI 文档:https://api.xposed.info/reference/packages.html

小讯
上一篇 2025-02-20 11:34
下一篇 2025-03-13 22:30

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/23543.html