Android逆向6-XPosed

来自吾爱破解-正己

https://www.52pojie.cn/thread-1701353-1-1.html

Xposed简介

Xposed是一款可以在不修改APK的情况下影响程序运行的框架,基于它可以制作出许多功能强大的模块,且在功能不冲突的情况下同时运作。在这个框架下,我们可以编写并加载自己编写的插件APP,实现对目标apk的注入拦截等。

原理:

用自己实现的app_process替换掉了系统原本提供app_process,加载一个额外的jar包,入口从原来的: com.android.internal.osZygoteInit.main()被替换成了: de.robv.android.xposed.XposedBridge.main(),

创建的Zygote进程就变成Hook的Zygote进程了,从而完成对zygote进程及其创建的Dalvik/ART虚拟机的劫持(zytoge注入)

image-20250306233338684

Xposed的发展及免root框架

名称 地址 支持版本 是否免root
xposed https://github.com/rovo89/Xposed 2.3-8.1
EDXposed https://github.com/ElderDrivers/EdXposed 8.0-10
LSPosed https://github.com/LSPosed/LSPosed 8.1-13
VirtualXposed https://github.com/android-hacker/VirtualXposed 5.0-10.0
太极 https://www.coolapk.com/apk/me.weishu.exp 5.0-13
两仪 https://www.coolapk.com/apk/io.twoyi 8.1-13
天鉴 https://github.com/Katana-Official/SPatch-Update 6-10

Xposed可以做什么?

  1. 修改app布局:上帝模式
  2. 劫持数据,修改参数值、返回值、主动调用等。例:微信防撤回、步数修改、一键新机应用变量

image-20250306233650978

  1. 自动化操作,例:微信抢红包

2022 最好的Xposed模块: GravityBox, Pixelify, XPrivacyLua

基于Xposed的抖音爬虫,抖音风控后自动一键新机,模拟一个全新的运行环境

基于xposed的frida持久化方案

A Xposed Module for Android Penetration Test, with NanoHttpd.

GravityBox

Xposed-Modules-Repo

一个旨在使QQ变得更好用的开源Xposed模块

杜比大喇叭

知乎去广告Xposed模块

哔哩漫游

曲境

自动化创建Xposed模块及钩子,让Xposed模块编写时只需关注钩子实现

Xposed环境配置

环境搭建

image-20250307233928153

1
2
3
4
5
6
7
8
9
10
11
12
<!-- 是否是xposed模块,xposed根据这个来判断是否是模块 -->
<meta-data
android:name="xposedmodule"
android:value="true" />
<!-- 模块描述,显示在xposed模块列表那里第二行 -->
<meta-data
android:name="xposeddescription"
android:value="这是一个Xposed模块" />
<!-- 最低xposed版本号(lib文件名可知) -->
<meta-data
android:name="xposedminversion"
android:value="89" />

修改build.gradle,将此处修改为compileOnly 默认的是implementation

image-20250307234112706

1
2
implementation 使用该方式依赖的库将会参与编译和打包
compileOnly 只在编译时有效,不会参与打包

对app->新建–>Folder–>Assets Folder,创建xposed_init(不要后缀名):只有一行代码,就是说明入口类

image-20250307234452460

新建Hook类,实现IXposedHookLoadPackage接口,然后在handleLoadPackage函数内编写Hook逻辑

1
2
3
4
5
6
7
8
9
import de.robv.android.xposed.IXposedHookLoadPackage; 
import de.robv.android.xposed.callbacks.XC_LoadPackage;

public class Hook implements IXposedHookLoadPackage {
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {

}
}

继承了IXposedHookLoadPackag便拥有了hook的能力

Xpoosed常用API

An efficient Hook API and Xposed Module solution built in Kotlin

image-20250331195701335

1
2
3
4
5
6
7
8
9
10
XposedHelpers.findAndHookMethod("com.zj.wuaipojie.Demo", classLoader, "a", java.lang.String.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
}
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.example.xposeddemo;

import android.util.Log;

import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XC_MethodReplacement;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;

public class Hook implements IXposedHookLoadPackage {
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
if(!loadPackageParam.packageName.equals("com.zj.wuaipojie")){
return;
}
Log.d("zj2595","abc");
// XposedHelpers.findAndHookMethod("com.zj.wuaipojie.Demo", loadPackageParam.classLoader, "a", String.class, new XC_MethodHook() {
// @Override
// protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
// super.beforeHookedMethod(param);
// Log.d("abc", param.args[0].toString());
// XposedBridge.log(param.args[0].toString());
// Log.d("abc","abc");
// String a = "pt";
// param.args[0] = a;
// Log.d("abc", param.args[0].toString());
// }
// @Override
// protected void afterHookedMethod(MethodHookParam param) throws Throwable {
// super.afterHookedMethod(param);
// Log.d("abc", param.getResult().toString());
// param.setResult("123456");
// }
// });
Class a = loadPackageParam.classLoader.loadClass("com.zj.wuaipojie.Demo");
XposedBridge.hookAllMethods(a, "complexParameterFunc", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.d("zj2595", param.args[0].toString());
}

@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
}
});

}
}

Hook普通方法

修改返回值

1
2
3
4
5
6
7
XposedHelpers.findAndHookMethod("com.zj.wuaipojie.Demo", loadPackageParam.classLoader, "a", String.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
param.setResult(999);
}
});

修改参数

1
2
3
4
5
6
7
XposedHelpers.findAndHookMethod("com.zj.wuaipojie.Demo", loadPackageParam.classLoader, "a", String.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
String a = "pt";
param.args[0] = a; }
});

Hook复杂&自定义参数

1
2
3
4
5
6
7
Class a = loadPackageParam.classLoader.loadClass("类名");
XposedBridge.hookAllMethods(a, "方法名", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
}
});

Hook替换函数

1
2
3
4
5
6
7
Class a = classLoader.loadClass("类名")
XposedBridge.hookAllMethods(a,"方法名",new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
return "";
}
});

Hook加固通杀

1
2
3
4
5
6
7
8
XposedHelpers.findAndHookMethod(Application.class, "attach", Context.class, new XC_MethodHook() {  
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
Context context = (Context) param.args[0];
ClassLoader classLoader = context.getClassLoader();
//hook逻辑在这里面写
}
});

Hook变量

静态变量

1
2
final Class clazz = XposedHelpers.findClass("com.zj.wuaipojie.Demo", loadPackageParam.classLoader);
XposedHelpers.setStaticIntField(clazz, "staticInt", 999);

实例变量

1
2
3
4
5
6
7
8
9
10
final Class clazz = XposedHelpers.findClass("com.zj.wuaipojie.Demo", loadPackageParam.classLoader);
XposedBridge.hookAllConstructors(clazz, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
//param.thisObject获取当前所属的对象
Object ob = param.thisObject;
XposedHelpers.setIntField(ob,"publicInt",9999);
}
});

Hook构造函数

无参构造函数

1
2
3
4
5
6
7
8
9
10
XposedHelpers.findAndHookConstructor("com.zj.wuaipojie.Demo", classLoader, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
}
});

有参构造函数

1
2
3
4
5
6
7
8
9
10
XposedHelpers.findAndHookConstructor("com.zj.wuaipojie.Demo", classLoader, String.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
}
});

Hook multiDex方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
XposedHelpers.findAndHookMethod(Application.class, "attach", Context.class, new XC_MethodHook() {  
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
ClassLoader cl= ((Context)param.args[0]).getClassLoader();
Class<?> hookclass=null;
try {
hookclass=cl.loadClass("类名");
}catch (Exception e){
Log.e("zj2595","未找到类",e);
return;
}
XposedHelpers.findAndHookMethod(hookclass, "方法名", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
}
});
}
});

主动调用

静态方法:

1
2
Class clazz = XposedHelpers.findClass("类名",lpparam.classLoader);
XposedHelpers.callStaticMethod(clazz,"方法名",参数(非必须));

实例方法:

1
2
Class clazz = XposedHelpers.findClass("类名",lpparam.classLoader);
XposedHelpers.callMethod(clazz.newInstance(),"方法名",参数(非必须));

Hook内部类

1
2
3
4
5
6
7
XposedHelpers.findAndHookMethod("com.zj.wuaipojie.Demo$InnerClass", lpparam.classLoader, "innerFunc",String.class,  new XC_MethodHook() {  
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
}
});

反射大法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Class clazz = XposedHelpers.findClass("com.zj.wuaipojie.Demo", lpparam.classLoader);
XposedHelpers.findAndHookMethod("com.zj.wuaipojie.Demo$InnerClass", lpparam.classLoader, "innerFunc",String.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
//第一步找到类
//找到方法,如果是私有方法就要setAccessible设置访问权限
//invoke主动调用或者set修改值(变量)
Class democlass = Class.forName("com.zj.wuaipojie.Demo",false,lpparam.classLoader);
Method demomethod = democlass.getDeclaredMethod("refl");
demomethod.setAccessible(true);
demomethod.invoke(clazz.newInstance());
}
});

遍历所有类下的所有方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
XposedHelpers.findAndHookMethod(ClassLoader.class, "loadClass", String.class, new XC_MethodHook() {  
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Class clazz = (Class) param.getResult();
String clazzName = clazz.getName();
//排除非包名的类
if(clazzName.contains("com.zj.wuaipojie")){
Method[] mds = clazz.getDeclaredMethods();
for(int i =0;i<mds.length;i++){
final Method md = mds[i];
int mod = mds[i].getModifiers();
//去除抽象、native、接口方法
if(!Modifier.isAbstract(mod)
&& !Modifier.isNative(mod)
&&!Modifier.isAbstract(mod)){
XposedBridge.hookMethod(mds[i], new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.d("zj2595",md.toString());
}
});
}

}
}

}
});

点击事件监听

1
2
3
4
5
6
7
8
9
10
11
Class clazz = XposedHelpers.findClass("android.view.View", lpparam.classLoader);
XposedBridge.hookAllMethods(clazz, "performClick", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Object listenerInfoObject = XposedHelpers.getObjectField(param.thisObject, "mListenerInfo");
Object mOnClickListenerObject = XposedHelpers.getObjectField(listenerInfoObject, "mOnClickListener");
String callbackType = mOnClickListenerObject.getClass().getName();
Log.d("zj2595",callbackType);
}
});

改写布局

1
2
3
4
5
6
7
8
9
10
XposedHelpers.findAndHookMethod("com.zj.wuaipojie.ui.ChallengeSixth", lpparam.classLoader,  
"onCreate", Bundle.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
View img = (View)XposedHelpers.callMethod(param.thisObject,
"findViewById", 0x7f0800de);
img.setVisibility(View.GONE);
}
});

LSPatch

image-20250402095733241

https://www.bilibili.com/video/BV1Sb411X7D6/?spm_id_from=333.1007.top_right_bar_window_history.content.click&vd_source=d76ad0aadca055336653cd966075f064

大部分功能算法助手都有

Xposed快速Hook

SimpleHook

jshook

Xpsoed源码

XPOSED魔改一:获取特征
Lsposed 技术原理探讨 && 基本安装使用
[原创]源码编译(2)——Xopsed源码编译详解