Xposed用法示例
API
选择需要Hook的APP包名及类名
import android.util.Log;
import java.util.Map;
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.LoadPackageParam;
public class TestCode implements IXposedHookLoadPackage {
public void handleLoadPackage(final LoadPackageParam loadPackageParam) throws Throwable {
Log.d("tag", "Hooking......");
if (loadPackageParam.packageName.equals("包名")) {
final Class clazz = XposedHelpers.findClass("类名路径", loadPackageParam.classLoader);
}
}
}
Hook修改变量
import android.util.Log;
import java.util.Map;
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.LoadPackageParam;
public class TestCode implements IXposedHookLoadPackage {
public void handleLoadPackage(final LoadPackageParam loadPackageParam) throws Throwable {
Log.d("tag", "Hooking......");
if (loadPackageParam.packageName.equals("包名")) {
final Class clazz = XposedHelpers.findClass("类名路径", loadPackageParam.classLoader);
XposedHelpers.setStaticIntField(clazz, "字段名", 数字);
XposedHelpers.setStaticObjectField(clazz, "字段名", "字符串");
}
}
}
Hook修改普通方法并获取参数与返回值
import android.util.Log;
import java.util.Map;
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.LoadPackageParam;
public class TestCode implements IXposedHookLoadPackage {
public void handleLoadPackage(final LoadPackageParam loadPackageParam) throws Throwable {
Log.d("tag", "Hooking......");
if (loadPackageParam.packageName.equals("包名")) {
final Class clazz = XposedHelpers.findClass("类名路径", loadPackageParam.classLoader);
XposedHelpers.findAndHookMethod(clazz,
"publicFunc <- 需要hook的函数名",
String.class,
new XC_MethodHook() {
/* access modifiers changed from: protected */
public void beforeHookedMethod(MethodHookParam param) throws Throwable {
Log.d("获取publicFunc函数参数", "" + param.args[0]);
Log.d("publicFunc被hook前执行", "publicFunc is hooked before");
}
/* access modifiers changed from: protected */
public void afterHookedMethod(MethodHookParam param) throws Throwable {
Log.d("获取publicFunc函数返回值", "" + param.getResult());
Log.d("publicFunc被hook后执行", "publicFunc is hooked after");
}
});
}
}
}
Hook无参构造函数
import android.util.Log;
import java.util.Map;
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.LoadPackageParam;
public class TestCode implements IXposedHookLoadPackage {
public void handleLoadPackage(final LoadPackageParam loadPackageParam) throws Throwable {
Log.d("tag", "Hooking......");
if (loadPackageParam.packageName.equals("包名")) {
final Class clazz = XposedHelpers.findClass("类名路径", loadPackageParam.classLoader);
XposedHelpers.findAndHookConstructor(clazz, new XC_MethodHook() {
/* access modifiers changed from: protected */
public void beforeHookedMethod(MethodHookParam param) throws Throwable {
Log.d("tag", "这是无参构造函数前");
}
/* access modifiers changed from: protected */
public void afterHookedMethod(MethodHookParam param) throws Throwable {
Log.d("tag", "这是无参构造函数后");
}
});
}
}
}
Hook有参构造函数
import android.util.Log;
import java.util.Map;
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.LoadPackageParam;
public class TestCode implements IXposedHookLoadPackage {
public void handleLoadPackage(final LoadPackageParam loadPackageParam) throws Throwable {
Log.d("tag", "Hooking......");
if (loadPackageParam.packageName.equals("包名")) {
final Class clazz = XposedHelpers.findClass("类名路径", loadPackageParam.classLoader);
XposedHelpers.findAndHookConstructor(clazz, String.class, new XC_MethodHook() {
/* access modifiers changed from: protected */
public void beforeHookedMethod(MethodHookParam param) throws Throwable {
param.args[0] = "第一个参数";
}
/* access modifiers changed from: protected */
public void afterHookedMethod(MethodHookParam param) throws Throwable {
Log.d("tag", "这是有参构造函数后");
}
});
}
}
}
Hook复杂参数
import android.util.Log;
import java.util.Map;
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.LoadPackageParam;
public class TestCode implements IXposedHookLoadPackage {
public void handleLoadPackage(final LoadPackageParam loadPackageParam) throws Throwable {
Log.d("tag", "Hooking......");
if (loadPackageParam.packageName.equals("包名")) {
final Class clazz = XposedHelpers.findClass("类名路径", loadPackageParam.classLoader);
XposedHelpers.findAndHookMethod(
clazz,
"functionName", //函数名
"java.lang.String", //字符串
"[[Ljava.lang.String;", //二维字符串数组
Map.class,
Class.forName("java.util.ArrayList"),
new XC_MethodHook() {
/* access modifiers changed from: protected */
public void beforeHookedMethod(MethodHookParam param) throws Throwable {
Log.d("tag", "functionName is hooked before");
}
/* access modifiers changed from: protected */
public void afterHookedMethod(MethodHookParam param) throws Throwable {
Log.d("tag", "functionName is hooked after");
}
});
}
}
}
Hook自定义类参数
import android.util.Log;
import java.util.Map;
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.LoadPackageParam;
public class TestCode implements IXposedHookLoadPackage {
public void handleLoadPackage(final LoadPackageParam loadPackageParam) throws Throwable {
Log.d("tag", "Hooking......");
if (loadPackageParam.packageName.equals("包名")) {
final Class clazz = XposedHelpers.findClass("要hook函数的类名路径", loadPackageParam.classLoader);
Class cls = Class.forName("自定义类名路径",
true,
loadPackageParam.classLoader);
XposedHelpers.findAndHookMethod(
clazz,
"functionName", //要hook的函数名
"类名路径", //自定义的类名 或者 cls
String.class, //字符串参数
new XC_MethodHook() {
/* access modifiers changed from: protected */
public void beforeHookedMethod(MethodHookParam param) throws Throwable {
Log.d("tag", "这是自定义类参数的Hook Class.forName");
}
});
}
}
}
Hook替换函数与函数置空
import android.util.Log;
import java.util.Map;
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.LoadPackageParam;
public class TestCode implements IXposedHookLoadPackage {
public void handleLoadPackage(final LoadPackageParam loadPackageParam) throws Throwable {
Log.d("tag", "Hooking......");
if (loadPackageParam.packageName.equals("包名")) {
final Class clazz = XposedHelpers.findClass("要hook函数的类名路径", loadPackageParam.classLoader);
XposedHelpers.findAndHookMethod(clazz, "要替换的函数名",
new XC_MethodReplacement() {
/* access modifiers changed from: protected */
public Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
Log.d("tag", "这是替换之后的输出");
return null;
}
});
}
}
}
Hook内部类
import android.util.Log;
import java.util.Map;
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.LoadPackageParam;
public class TestCode implements IXposedHookLoadPackage {
public void handleLoadPackage(final LoadPackageParam loadPackageParam) throws Throwable {
Log.d("tag", "Hooking......");
if (loadPackageParam.packageName.equals("包名")) {
final Class clazz = XposedHelpers.findClass("要hook函数的类名路径", loadPackageParam.classLoader);
XposedHelpers.findAndHookMethod(XposedHelpers.findClass(
"要hook函数的类名路径$内部类名",
loadPackageParam.classLoader),
"内部类的函数名",
String.class, new XC_MethodHook() {
/* access modifiers changed from: protected */
public void beforeHookedMethod(MethodHookParam param)
});
}
}
}
Hook匿名类
import android.util.Log;
import java.util.Map;
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.LoadPackageParam;
public class TestCode implements IXposedHookLoadPackage {
public void handleLoadPackage(final LoadPackageParam loadPackageParam) throws Throwable {
Log.d("tag", "Hooking......");
if (loadPackageParam.packageName.equals("包名")) {
final Class clazz = XposedHelpers.findClass("要hook函数的类名路径", loadPackageParam.classLoader);
XposedHelpers.findAndHookMethod(XposedHelpers.findClass(
"要hook函数的类名路径$1", //匿名类用数字(查阅smali)表示, 例: new Demo()无变量赋值操作
loadPackageParam.classLoader),
"内部类的函数名",
String.class, new XC_MethodHook() {
/* access modifiers changed from: protected */
public void beforeHookedMethod(MethodHookParam param) throws Throwable {
});
}
}
}
Xposed主动调用
import android.util.Log;
import java.util.Map;
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.LoadPackageParam;
public class TestCode implements IXposedHookLoadPackage {
public void handleLoadPackage(final LoadPackageParam loadPackageParam) throws Throwable {
Log.d("tag", "Hooking......");
if (loadPackageParam.packageName.equals("包名")) {
final Class clazz = XposedHelpers.findClass("要hook函数的类名路径", loadPackageParam.classLoader);
XposedHelpers.findAndHookMethod(XposedHelpers.findClass(
"要hook函数的类名路径$1", //匿名类用数字(查阅smali)表示, 例: new Demo()无变量赋值操作
loadPackageParam.classLoader),
"内部类的函数名",
String.class, new XC_MethodHook() {
/* access modifiers changed from: protected */
public void beforeHookedMethod(MethodHookParam param) throws Throwable {
Log.d("tag", "主动调用前");
XposedHelpers.callMethod(clazz.newInstance(), "想要调用的方法名");
Log.d("tag", "主动调用后");
int aa = XposedHelpers.getIntField(param.thisObject, "内部类字段名");
Log.d("tag", "" + aa);
}
});
}
}
}
Java反射
import android.util.Log;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
public class TestCode implements IXposedHookLoadPackage {
public void handleLoadPackage(final LoadPackageParam loadPackageParam) throws Throwable {
Log.d("tag", "Hooking......");
if (loadPackageParam.packageName.equals("包名")) {
final Class clazz = XposedHelpers.findClass("要hook函数的类名路径", loadPackageParam.classLoader);
XposedHelpers.findAndHookMethod(XposedHelpers.findClass(
"要hook函数的类名路径",
loadPackageParam.classLoader),
"要hook的函数名",
String.class, new XC_MethodHook() {
/* access modifiers changed from: protected */
public void beforeHookedMethod(MethodHookParam param) throws Throwable {
Field field = clazz.getDeclaredField("fieldName");
Object obj = clazz.newInstance();
field.setAccessible(true);
String str = (String) field.get(obj);
Log.d("这是反射前获取的字段", str);
field.set(obj, "newInfo");
String str2 = (String) field.get(obj);
Log.d("这是反射后设置的字段", str2);
Method method = clazz.getDeclaredMethod("methodNmae");
method.setAccessible(true);
method.invoke(obj);
}
});
Log.d("tag", clazz.getName());
//获取所有的方法名
for (Method method : clazz.getDeclaredMethods()) {
Log.d("tag", method.toString());
}
//获取所有的字段名
Field[] fd = clazz.getDeclaredFields();
for (Field field : fd) {
Log.d("tag", field.toString());
}
Log.d("tag", "====================================");
//获取所有内部类名再迭代获取类的方法名与字段名
Class[] cls = clazz.getDeclaredClasses();
for (int i = 0; i < fd.length; i++) {
Log.d("tag", cls[i].getName());
for (Method method2 : cls[i].getDeclaredMethods()) {
Log.d("tag", method2.toString());
}
for (Field field2 : cls[i].getDeclaredFields()) {
Log.d("tag", field2.toString());
}
}
}
}
}
Hook所有类的所有方法
import android.util.Log;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
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.LoadPackageParam;
public class TestCode implements IXposedHookLoadPackage {
public void handleLoadPackage(final LoadPackageParam loadPackageParam) throws Throwable {
Log.d("tag", "Hooking......");
if (loadPackageParam.packageName.equals("包名")) {
XposedHelpers.findAndHookMethod(ClassLoader.class,
"loadClass",
String.class, new XC_MethodHook() {
/* access modifiers changed from: protected */
public void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
Class clazz = (Class) param.getResult();
String clazzName = clazz.getName();
Log.d("tag", "LoadClass: " + clazzName);
if (clazzName.contains("com.xxx")) {
Method[] mds = clazz.getDeclaredMethods();
for (int i = 0; i < mds.length; i++) {
final Method md = mds[i];
int mod = mds[i].getModifiers();
if (!Modifier.isAbstract(mod) && !Modifier.isNative(mod) && !Modifier.isInterface(mod)) {
XposedBridge.hookMethod(mds[i], new XC_MethodHook() {
public void beforeHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
if (md.getName().contains("complexParameterFunc")) {
for (Object obj : param.args) {
Log.d("tag", obj.getClass().getName());
}
}
}
});
}
}
}
}
});
}
}
}
multiDex的Hook方法
import android.app.Application;
import android.content.Context;
import android.util.Log;
import java.util.ArrayList;
import java.util.Map;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
public class TestCode implements IXposedHookLoadPackage {
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
Log.d("tag", "hooking Start...");
if (lpparam.packageName.equals("包名")) {
XposedHelpers.findAndHookMethod(Application.class, "attach", Context.class, new XC_MethodHook() {
/* access modifiers changed from: protected */
public void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
try {
XposedHelpers.findAndHookMethod(((Context) param.args[0]).getClassLoader().loadClass("类名路径"), "方法名", String.class, String[][].class, Map.class, ArrayList.class, new XC_MethodHook() {
/* access modifiers changed from: protected */
public void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
String arg0 = (String) param.args[0];
String arg1 = (String) param.args[1];
Log.d("tag", arg0);
Log.d("tag", "测试分dexHook");
}
});
} catch (Exception e) {
Log.e("tag", "类没找到", e);
}
}
});
}
}
}
Java加密算法示例
单向散列函数(消息摘要算法)
Utils
public class Utils {
public static String byteToHexString(byte[] by) {
StringBuffer SB = new StringBuffer();
for (byte k : by) {
int j = k;
if (k < 0) {
j = k + 256;
}
if (j < 16) {
SB.append("0");
}
SB.append(Integer.toHexString(j));
}
return SB.toString();
}
public static byte[] hexStringToByte(byte[] b) {
if (b.length % 2 != 0) {
throw new IllegalArgumentException("长度不是偶数");
}
byte[] b2 = new byte[(b.length / 2)];
for (int n = 0; n < b.length; n += 2) {
b2[n / 2] = (byte) Integer.parseInt(new String(b, n, 2), 16);
}
return b2;
}
}
MD5
import java.security.MessageDigest;
public class MD5 {
public static String md5_1(String args) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5", "BC");
md.update(args.getBytes());
return Utils.byteToHexString(md.digest());
}
public static String md5_2(String args) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5", "BC");
md.update(args.getBytes(), 2, 5);
return Utils.byteToHexString(md.digest("xiaojianbang".getBytes()));
}
}
SHA
import java.security.MessageDigest;
public class SHA {
public static String sha_1(String args) throws Exception {
MessageDigest md = MessageDigest.getInstance("SHA-1", "BC");
md.update(args.getBytes());
return Utils.byteToHexString(md.digest());
}
public static String sha_2(String args) throws Exception {
MessageDigest md = MessageDigest.getInstance("SHA-1", "BC");
md.update(args.getBytes(), 2, 5);
return Utils.byteToHexString(md.digest("xiaojianbang".getBytes()));
}
}
Mac
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class MAC {
public static String mac_1(String args) throws Exception {
SecretKey key = new SecretKeySpec("FridaHook".getBytes(), "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(key);
mac.update(args.getBytes());
return Utils.byteToHexString(mac.doFinal());
}
public static String mac_2(String args) throws Exception {
SecretKey key = new SecretKeySpec("FridaHook".getBytes(), "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(key);
mac.update(args.getBytes(), 2, 5);
return Utils.byteToHexString(mac.doFinal("xiaojianbang".getBytes()));
}
}
对称加密算法在Java中的调用
DES
import android.util.Base64;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
public class DES {
public static String des_1(String args) throws Exception {
SecretKey secretKey = SecretKeyFactory.getInstance("DES").generateSecret(new DESKeySpec("12345678".getBytes()));
AlgorithmParameterSpec iv = new IvParameterSpec("87654321".getBytes());
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
cipher.init(1, secretKey, iv);
cipher.update(args.getBytes());
return Base64.encodeToString(cipher.doFinal(), 0);
}
public static String des_2(String args) throws Exception {
SecretKey secretKey = SecretKeyFactory.getInstance("DES").generateSecret(new DESKeySpec("12345678".getBytes()));
AlgorithmParameterSpec iv = new IvParameterSpec("87654321".getBytes());
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
cipher.init(1, secretKey, iv);
return Base64.encodeToString(cipher.doFinal(args.getBytes()), 0);
}
}
DESede
import android.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
public class DESede {
public static String desede(String args) throws Exception {
SecretKey secretKey = SecretKeyFactory.getInstance("DESede").generateSecret(new DESedeKeySpec("123456781234567812345678".getBytes()));
Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
cipher.init(1, secretKey);
cipher.update(args.getBytes());
return Base64.encodeToString(cipher.doFinal("xiaojianbang".getBytes()), 0);
}
}
AES
import android.util.Base64;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class AES {
public static String aes(String args) throws Exception {
SecretKeySpec key = new SecretKeySpec("1234567890abcdef1234567890abcdef".getBytes(), "AES");
AlgorithmParameterSpec iv = new IvParameterSpec("1234567890abcdef".getBytes());
Cipher aes = Cipher.getInstance("AES/CBC/PKCS5Padding");
aes.init(1, key, iv);
return Base64.encodeToString(aes.doFinal(args.getBytes("UTF-8")), 0);
}
}
数字签名算法在Java中的调用
RSA
import android.util.Base64;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
public class RSA {
public static String priKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJWFpHc6vuy5SXAdSXYvLfq5WZuhnf4eGi+iAOMuBET0JtpSiRLZ6oZpUV9vEBTEVOE0O5er98EP5J1SCmmZxmsjDgcww/gC0TaoklAf8rE9aZtcfsu/70KKw209g6W9Yn8YdGp/3HdMEqON4nYKO5XGU8ENfrf4RyKXYlH2SVVrAgMBAAECgYAJ0TeGOI42nsfKm7GqF9juAGN4y3jDKZjQjdN/FxNir6Epboffe/1hC+My3+jvZCCqlLJg+AKRY4jAJ5XVbypO3tHRd9uLFgCjzREJ09J6SWyNj3KFKCkJ4vpaO0jbUAAtFGlLElc6ZtHNKabeJ0ECOgcIvVsfHpP47j1GTRU8oQJBAMXsksEmrIvCJ0l5mdDX73nRJzbxDK6m7jndE4fBe0h3Wl06iBCfuaS2x+PTjmiRWvfFu2B1/9E9Tt0jc4FQS3ECQQDBZUKZjnv6rKtwqBj1EqjIXVF2SAsttW/6vTpg6mhHYITlrqQqrt1NJ5+6PRVQr1FLDxPArNVSdoz6MFIIAiibAkA+3K+Tt0PQM78koAGRijPePea1lYPQqOY67JN6Z6JPVtEVkTSMCx78SK1eF+BAKAJ7dYrYzUGN5Gn65HqYFLeRAkBcBOFWjSxCjwwX03PkkBdNFtHe9NKU0iLQ7F6tpHsvkyZI3vrv8DoOLw9aHxxYQsLscuUUJWhvD0du97TgaJ6HAkEAoRXjsQO2UmgQcddE2e6Uxp5riOuWIEEzoW6YssCW9BznCnwXy/xamrTKhoW2cIHwn6cFx+MFmyaK5T0xAtF5pw==";
public static String pubKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9xhBZOWWF5Icw384mJksmaJ53RBLPUbEq5hXWW4Xgf82r6Zj24e3MWOnBTcblDodXYtSsaRJilosdTQVWGetJewebKmyqh1l1lUagS1/dbII9GsGat5zMboMHLWUO9NoBS9VDxqYL2VLppNEj/Xe39gBRHIiSnmtggiHuYsEv8wIDAQAB";
public static PublicKey getPublicKey(String key) throws Exception {
return KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(Base64.decode(key, 0)));
}
public static PrivateKey getPrivateKey(String key) throws Exception {
return KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(Base64.decode(key, 0)));
}
public static String sign(String data) throws Exception {
PrivateKey priK = getPrivateKey(priKey);
Signature sig = Signature.getInstance("SHA256withRSA");
sig.initSign(priK);
sig.update(data.getBytes());
return Base64.encodeToString(sig.sign(), 0);
}
public static boolean verify(byte[] data, byte[] sign) throws Exception {
PublicKey pubK = getPublicKey(pubKey);
Signature sig = Signature.getInstance("SHA256withRSA");
sig.initVerify(pubK);
sig.update(data);
return sig.verify(sign);
}
public static byte[] encrypt(byte[] plaintext) throws Exception {
PublicKey publicKey = getPublicKey(pubKey);
Cipher cipher = Cipher.getInstance("RSA/None/NoPadding", "BC");
cipher.init(1, publicKey);
return cipher.doFinal(plaintext);
}
public static byte[] decrypt(byte[] encrypted) throws Exception {
PrivateKey privateKey = getPrivateKey(priKey);
Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding", "BC");
cipher.init(2, privateKey);
return cipher.doFinal(encrypted);
}
public static String rsa(String args) throws Exception {
return Base64.encodeToString(encrypt("xiaojianbang".getBytes()), 0);
}
}
快速定位关键代码
Log.e("tag", "Stack:", new Throwable("stack dump"));
Xposed过 H5 APP 远程调试限制
package com.xiaojianbang.xposed;
import android.util.Log;
import android.webkit.WebView;
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 {
public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam loadPackageParam) throws ClassNotFoundException {
Log.d("xiaojianbang", "Hooking by xiaojianbang ......");
XposedBridge.hookAllConstructors(WebView.class, new XC_MethodHook() {
public void beforeHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
XposedHelpers.callStaticMethod(WebView.class, "setWebContentsDebuggingEnabled", new Object[]{true});
Log.d("xiaojianbang", "Hooking WebView Constructor from: " + loadPackageParam.packageName);
}
});
XposedBridge.hookAllMethods(WebView.class, "setWebContentsDebuggingEnabled", new XC_MethodHook() {
public void beforeHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
param.args[0] = true;
Log.d("xiaojianbang", "Hooking WebView Debugging from: " + loadPackageParam.packageName);
}
});
XposedHelpers.findAndHookMethod("io.dcloud.common.adapter.ui.WebViewImpl", loadPackageParam.classLoader, "setWebViewData", new Object[]{new XC_MethodReplacement() {
/* access modifiers changed from: protected */
public Object replaceHookedMethod(XC_MethodHook.MethodHookParam methodHookParam) throws Throwable {
Log.d("xiaojianbang", "setWebViewData is replace");
return null;
}
}});
}
}
Xposed过全局代理检测
package com.xiaojianbang.xposed;
import android.util.Log;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
public class Hook implements IXposedHookLoadPackage {
public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam loadPackageParam) {
Log.d("xiaojianbang", "Hooking by xiaojianbang ......");
XposedHelpers.findAndHookMethod(System.class, "getProperty", new Object[]{String.class, new XC_MethodHook() {
/* access modifiers changed from: protected */
public void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
Log.d("xiaojianbang", "Hooking getProperty from: " + loadPackageParam.packageName);
String str = (String) param.args[0];
if (str.equals("https.proxyHost") || str.equals("http.proxyHost") || str.equals("http.proxyPort") || str.equals("https.proxyPort")) {
param.setResult((Object) null);
}
}
}});
}
}
数字证书
openssl x509 -inform PEM -subject_hash_old -in 1111.cer |head -1
/system/etc/security/cacerts/269953fb.0
/data/misc/keystore/user_0
AOSP包含的所有根证书都位于 libcore/luni/src/main/files/cacerts
certlm.msc
Hook过证书检测
看JustTrustMePlus的源码,GitHub上搜一下
JustTrustMe失效的处理
就是系统库或第三方库做了混淆(即要hook的函数名发生了改变),将JustTrustMePlus源码做个适配与替换就ok
强制代理
import android.util.Log;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
public class Hello implements IXposedHookLoadPackage {
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
Log.d("xiaojianbang", "hooking Start...");
if (lpparam.packageName.equals("com.xiaojianbang.https")) {
XposedHelpers.findAndHookMethod(URL.class, "openConnection", new Object[]{Proxy.class, new XC_MethodHook() {
public void beforeHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
param.args[0] = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("192.168.1.7", 16666));
Log.d("xiaojianbang", "Hooking openConnection");
}
}});
}
}
}
Hook加固APP
import android.content.Context;
import android.util.Log;
import android.util.Base64;
import javax.crypto.Mac;
import javax.crypto.Cipher;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.math.BigInteger;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.PublicKey;
import java.util.List;
import com.alipay.app.XC_MethodHook;
import com.alipay.app.AlipayBridge;
import com.alipay.app.AlipayHelpers;
import com.alipay.app.IAlipayLoadPackage;
import com.alipay.app.XC_MethodReplacement;
import com.alipay.app.callbacks.XC_LoadPackage.LoadPackageParam;
public class Main implements IAlipayLoadPackage {
public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
Log.d("xiaojianbang", "hooking...");
if(!(lpparam.packageName.equals("com.oyohotels.consumer"))) return;
// AlipayHelpers.findAndHookMethod(System.class, "getProperty", String.class, new XC_MethodHook() {
//
// public void behindTencentMethod(MethodHookParam param) throws Throwable {
// StringBuilder sb = new StringBuilder();
// sb.append("Hooking getProperty from: ");
// sb.append(lpparam.packageName);
// Log.d("xiaojianbang", sb.toString());
// String str = (String) param.args[0];
// if (str.equals("https.proxyHost") || str.equals("http.proxyHost") || str.equals("http.proxyPort") || str.equals("https.proxyPort")) {
// param.setResult(null);
// }
// }
// });
AlipayHelpers.findAndHookMethod("com.stub.StubApp", lpparam.classLoader,
"attachBaseContext", Context.class, new XC_MethodHook() {
@Override
protected void behindTencentMethod(MethodHookParam param) throws Throwable {
super.behindTencentMethod(param);
//获取到Context对象,通过这个对象来获取classloader
Context context = (Context) param.args[0];
//获取classloader,之后hook加固后的就使用这个classloader
ClassLoader classLoader = context.getClassLoader();
//下面就是classloader修改成壳的classloader就可以成功的hook了
//https://github.com/square/okhttp/blob/parent-3.0.1/okhttp/src/main/java/okhttp3/CertificatePinner.java#L144
Log.d("xiaojianbang", "Hooking okhttp3.CertificatePinner.check(String,List) (3.x)");
try {
classLoader.loadClass("okhttp3.CertificatePinner");
Log.d("xiaojianbang", "找到CertificatePinner类");
AlipayHelpers.findAndHookMethod("okhttp3.CertificatePinner", classLoader, "check", String.class, List.class, new XC_MethodReplacement() {
@Override
protected Object displaceTencentMethod(MethodHookParam methodHookParam) throws Throwable {
return null;
}
});
} catch (ClassNotFoundException e) {
Log.d("xiaojianbang", "OKHTTP 3.x not found -- not hooking");
// pass
}
//https://github.com/square/okhttp/blob/parent-3.0.1/okhttp/src/main/java/okhttp3/internal/tls/OkHostnameVerifier.java
try {
classLoader.loadClass("okhttp3.internal.tls.OkHostnameVerifier");
AlipayHelpers.findAndHookMethod("okhttp3.internal.tls.OkHostnameVerifier", classLoader, "verify", String.class, javax.net.ssl.SSLSession.class, new XC_MethodReplacement() {
@Override
protected Object displaceTencentMethod(MethodHookParam methodHookParam) throws Throwable {
return true;
}
});
} catch (ClassNotFoundException e) {
Log.d("xiaojianbang", "OKHTTP 3.x not found in -- not hooking OkHostnameVerifier.verify(String, SSLSession)");
// pass
}
//https://github.com/square/okhttp/blob/parent-3.0.1/okhttp/src/main/java/okhttp3/internal/tls/OkHostnameVerifier.java
try {
classLoader.loadClass("okhttp3.internal.tls.OkHostnameVerifier");
AlipayHelpers.findAndHookMethod("okhttp3.internal.tls.OkHostnameVerifier", classLoader, "verify", String.class, java.security.cert.X509Certificate.class, new XC_MethodReplacement() {
@Override
protected Object displaceTencentMethod(MethodHookParam methodHookParam) throws Throwable {
return true;
}
});
} catch (ClassNotFoundException e) {
Log.d("xiaojianbang", "OKHTTP 3.x not found in -- not hooking OkHostnameVerifier.verify(String, X509)(");
// pass
}
}
});
// AlipayHelpers.findAndHookMethod("android.app.Application", lpparam.classLoader, "attach", Context.class, new XC_MethodHook() {
// @Override
// protected void behindTencentMethod(MethodHookParam param) throws Throwable {
// // Hook OkHttp or third party libraries.
// Context context = (Context) param.args[0];
// ClassLoader classLoader = context.getClassLoader();
//
//
//
//
//
// }
// }
// );
}
}