- 发布于
Xposed 安全与逆向分析:深入理解 Android 安全机制与防护技术
- 作者

- 姓名
- 全能波
- GitHub
- @weicracker
Xposed 安全与逆向分析:深入理解 Android 安全机制与防护技术
Xposed 框架在安全研究和逆向分析领域具有重要价值,同时也带来了安全挑战。本文将深入分析 Xposed 的安全应用、检测技术和防护机制。
Xposed 在安全研究中的应用
应用安全分析
// SecurityAnalysisHooks.java - 安全分析 Hook
package com.example.security.analysis;
import android.util.Log;
import java.security.MessageDigest;
import javax.crypto.Cipher;
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 SecurityAnalysisHooks {
private static final String TAG = "SecurityAnalysis";
// 分析加密算法使用
public static void analyzeCryptographicOperations(LoadPackageParam lpparam) {
// Hook 加密操作
hookCipherOperations(lpparam);
// Hook 哈希计算
hookHashOperations(lpparam);
// Hook 密钥生成
hookKeyGeneration(lpparam);
// Hook SSL/TLS 操作
hookSSLOperations(lpparam);
}
private static void hookCipherOperations(LoadPackageParam lpparam) {
try {
// Hook Cipher.init 方法
XposedHelpers.findAndHookMethod(
Cipher.class,
"init",
int.class,
java.security.Key.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
Cipher cipher = (Cipher) param.thisObject;
int opmode = (Integer) param.args[0];
java.security.Key key = (java.security.Key) param.args[1];
String operation = opmode == Cipher.ENCRYPT_MODE ? "ENCRYPT" : "DECRYPT";
String algorithm = cipher.getAlgorithm();
String keyAlgorithm = key.getAlgorithm();
XposedBridge.log(String.format(
"%s: Cipher操作 - %s, 算法: %s, 密钥算法: %s, 包名: %s",
TAG, operation, algorithm, keyAlgorithm, lpparam.packageName
));
// 记录密钥信息(注意:生产环境中不应记录敏感信息)
if (key.getEncoded() != null) {
XposedBridge.log(String.format(
"%s: 密钥长度: %d bits",
TAG, key.getEncoded().length * 8
));
}
}
}
);
// Hook Cipher.doFinal 方法
XposedHelpers.findAndHookMethod(
Cipher.class,
"doFinal",
byte[].class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
byte[] input = (byte[]) param.args[0];
XposedBridge.log(String.format(
"%s: Cipher.doFinal - 输入数据长度: %d bytes",
TAG, input != null ? input.length : 0
));
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
byte[] result = (byte[]) param.getResult();
XposedBridge.log(String.format(
"%s: Cipher.doFinal - 输出数据长度: %d bytes",
TAG, result != null ? result.length : 0
));
}
}
);
} catch (Throwable t) {
XposedBridge.log(TAG + ": Hook Cipher 操作失败 - " + t.getMessage());
}
}
private static void hookHashOperations(LoadPackageParam lpparam) {
try {
// Hook MessageDigest.digest 方法
XposedHelpers.findAndHookMethod(
MessageDigest.class,
"digest",
byte[].class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
MessageDigest md = (MessageDigest) param.thisObject;
byte[] input = (byte[]) param.args[0];
XposedBridge.log(String.format(
"%s: 哈希计算 - 算法: %s, 输入长度: %d bytes, 包名: %s",
TAG, md.getAlgorithm(),
input != null ? input.length : 0,
lpparam.packageName
));
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
byte[] hash = (byte[]) param.getResult();
if (hash != null) {
StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
hexString.append(String.format("%02x", b));
}
XposedBridge.log(String.format(
"%s: 哈希结果: %s",
TAG, hexString.toString()
));
}
}
}
);
} catch (Throwable t) {
XposedBridge.log(TAG + ": Hook 哈希操作失败 - " + t.getMessage());
}
}
private static void hookKeyGeneration(LoadPackageParam lpparam) {
try {
// Hook KeyGenerator.generateKey
XposedHelpers.findAndHookMethod(
"javax.crypto.KeyGenerator",
lpparam.classLoader,
"generateKey",
new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
javax.crypto.KeyGenerator keyGen = (javax.crypto.KeyGenerator) param.thisObject;
javax.crypto.SecretKey key = (javax.crypto.SecretKey) param.getResult();
XposedBridge.log(String.format(
"%s: 密钥生成 - 算法: %s, 包名: %s",
TAG, key.getAlgorithm(), lpparam.packageName
));
}
}
);
// Hook KeyPairGenerator.generateKeyPair
XposedHelpers.findAndHookMethod(
"java.security.KeyPairGenerator",
lpparam.classLoader,
"generateKeyPair",
new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
java.security.KeyPairGenerator keyPairGen = (java.security.KeyPairGenerator) param.thisObject;
XposedBridge.log(String.format(
"%s: 密钥对生成 - 算法: %s, 包名: %s",
TAG, keyPairGen.getAlgorithm(), lpparam.packageName
));
}
}
);
} catch (Throwable t) {
XposedBridge.log(TAG + ": Hook 密钥生成失败 - " + t.getMessage());
}
}
private static void hookSSLOperations(LoadPackageParam lpparam) {
try {
// Hook SSLContext.init
XposedHelpers.findAndHookMethod(
"javax.net.ssl.SSLContext",
lpparam.classLoader,
"init",
javax.net.ssl.KeyManager[].class,
javax.net.ssl.TrustManager[].class,
java.security.SecureRandom.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
javax.net.ssl.SSLContext sslContext = (javax.net.ssl.SSLContext) param.thisObject;
javax.net.ssl.TrustManager[] trustManagers = (javax.net.ssl.TrustManager[]) param.args[1];
XposedBridge.log(String.format(
"%s: SSL上下文初始化 - 协议: %s, TrustManager数量: %d, 包名: %s",
TAG, sslContext.getProtocol(),
trustManagers != null ? trustManagers.length : 0,
lpparam.packageName
));
// 检查是否使用自定义 TrustManager
if (trustManagers != null) {
for (javax.net.ssl.TrustManager tm : trustManagers) {
XposedBridge.log(String.format(
"%s: TrustManager类型: %s",
TAG, tm.getClass().getName()
));
}
}
}
}
);
} catch (Throwable t) {
XposedBridge.log(TAG + ": Hook SSL 操作失败 - " + t.getMessage());
}
}
}
网络通信分析
// NetworkAnalysisHooks.java - 网络通信分析
package com.example.security.network;
import java.net.URL;
import java.io.InputStream;
import java.io.OutputStream;
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 NetworkAnalysisHooks {
private static final String TAG = "NetworkAnalysis";
public static void analyzeNetworkCommunication(LoadPackageParam lpparam) {
// 分析 HTTP 请求
analyzeHttpRequests(lpparam);
// 分析 Socket 连接
analyzeSocketConnections(lpparam);
// 分析 WebView 请求
analyzeWebViewRequests(lpparam);
}
private static void analyzeHttpRequests(LoadPackageParam lpparam) {
try {
// Hook URL.openConnection
XposedHelpers.findAndHookMethod(
URL.class,
"openConnection",
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
URL url = (URL) param.thisObject;
XposedBridge.log(String.format(
"%s: HTTP连接 - URL: %s, 协议: %s, 主机: %s, 端口: %d, 包名: %s",
TAG, url.toString(), url.getProtocol(),
url.getHost(), url.getPort(), lpparam.packageName
));
// 检查是否为 HTTPS
if (!"https".equals(url.getProtocol())) {
XposedBridge.log(String.format(
"%s: 警告 - 使用非安全协议: %s",
TAG, url.getProtocol()
));
}
}
}
);
// Hook HttpURLConnection 方法
hookHttpURLConnection(lpparam);
} catch (Throwable t) {
XposedBridge.log(TAG + ": Hook HTTP 请求失败 - " + t.getMessage());
}
}
private static void hookHttpURLConnection(LoadPackageParam lpparam) {
try {
// Hook setRequestMethod
XposedHelpers.findAndHookMethod(
"java.net.HttpURLConnection",
lpparam.classLoader,
"setRequestMethod",
String.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
String method = (String) param.args[0];
java.net.HttpURLConnection conn = (java.net.HttpURLConnection) param.thisObject;
XposedBridge.log(String.format(
"%s: HTTP方法 - %s, URL: %s",
TAG, method, conn.getURL().toString()
));
}
}
);
// Hook setRequestProperty
XposedHelpers.findAndHookMethod(
"java.net.URLConnection",
lpparam.classLoader,
"setRequestProperty",
String.class,
String.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
String key = (String) param.args[0];
String value = (String) param.args[1];
XposedBridge.log(String.format(
"%s: HTTP头 - %s: %s",
TAG, key, value
));
// 检查敏感头信息
if ("Authorization".equalsIgnoreCase(key) ||
"Cookie".equalsIgnoreCase(key) ||
"X-API-Key".equalsIgnoreCase(key)) {
XposedBridge.log(String.format(
"%s: 敏感头信息 - %s: [已隐藏]",
TAG, key
));
}
}
}
);
// Hook getInputStream (响应读取)
XposedHelpers.findAndHookMethod(
"java.net.URLConnection",
lpparam.classLoader,
"getInputStream",
new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
java.net.URLConnection conn = (java.net.URLConnection) param.thisObject;
InputStream inputStream = (InputStream) param.getResult();
if (inputStream != null) {
XposedBridge.log(String.format(
"%s: 读取响应 - URL: %s",
TAG, conn.getURL().toString()
));
// 包装 InputStream 以监控数据读取
param.setResult(new MonitoredInputStream(inputStream, conn.getURL().toString()));
}
}
}
);
} catch (Throwable t) {
XposedBridge.log(TAG + ": Hook HttpURLConnection 失败 - " + t.getMessage());
}
}
private static void analyzeSocketConnections(LoadPackageParam lpparam) {
try {
// Hook Socket 构造函数
XposedHelpers.findAndHookConstructor(
"java.net.Socket",
lpparam.classLoader,
String.class,
int.class,
new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
String host = (String) param.args[0];
int port = (Integer) param.args[1];
XposedBridge.log(String.format(
"%s: Socket连接 - 主机: %s, 端口: %d, 包名: %s",
TAG, host, port, lpparam.packageName
));
}
}
);
// Hook Socket.getOutputStream
XposedHelpers.findAndHookMethod(
"java.net.Socket",
lpparam.classLoader,
"getOutputStream",
new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
java.net.Socket socket = (java.net.Socket) param.thisObject;
OutputStream outputStream = (OutputStream) param.getResult();
if (outputStream != null) {
XposedBridge.log(String.format(
"%s: Socket输出流 - %s:%d",
TAG, socket.getInetAddress().getHostAddress(), socket.getPort()
));
// 包装 OutputStream 以监控数据发送
param.setResult(new MonitoredOutputStream(outputStream,
socket.getInetAddress().getHostAddress() + ":" + socket.getPort()));
}
}
}
);
} catch (Throwable t) {
XposedBridge.log(TAG + ": Hook Socket 连接失败 - " + t.getMessage());
}
}
private static void analyzeWebViewRequests(LoadPackageParam lpparam) {
try {
// Hook WebView.loadUrl
XposedHelpers.findAndHookMethod(
"android.webkit.WebView",
lpparam.classLoader,
"loadUrl",
String.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
String url = (String) param.args[0];
XposedBridge.log(String.format(
"%s: WebView加载 - URL: %s, 包名: %s",
TAG, url, lpparam.packageName
));
}
}
);
// Hook WebViewClient.shouldOverrideUrlLoading
XposedHelpers.findAndHookMethod(
"android.webkit.WebViewClient",
lpparam.classLoader,
"shouldOverrideUrlLoading",
android.webkit.WebView.class,
String.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
String url = (String) param.args[1];
XposedBridge.log(String.format(
"%s: WebView URL拦截 - URL: %s",
TAG, url
));
}
}
);
} catch (Throwable t) {
XposedBridge.log(TAG + ": Hook WebView 请求失败 - " + t.getMessage());
}
}
// 监控 InputStream
private static class MonitoredInputStream extends InputStream {
private InputStream originalStream;
private String source;
private int totalBytesRead = 0;
public MonitoredInputStream(InputStream original, String source) {
this.originalStream = original;
this.source = source;
}
@Override
public int read() throws java.io.IOException {
int data = originalStream.read();
if (data != -1) {
totalBytesRead++;
}
return data;
}
@Override
public int read(byte[] buffer) throws java.io.IOException {
int bytesRead = originalStream.read(buffer);
if (bytesRead > 0) {
totalBytesRead += bytesRead;
XposedBridge.log(String.format(
"%s: 数据读取 - 来源: %s, 本次: %d bytes, 总计: %d bytes",
TAG, source, bytesRead, totalBytesRead
));
}
return bytesRead;
}
@Override
public void close() throws java.io.IOException {
XposedBridge.log(String.format(
"%s: 连接关闭 - 来源: %s, 总读取: %d bytes",
TAG, source, totalBytesRead
));
originalStream.close();
}
}
// 监控 OutputStream
private static class MonitoredOutputStream extends OutputStream {
private OutputStream originalStream;
private String destination;
private int totalBytesWritten = 0;
public MonitoredOutputStream(OutputStream original, String destination) {
this.originalStream = original;
this.destination = destination;
}
@Override
public void write(int data) throws java.io.IOException {
originalStream.write(data);
totalBytesWritten++;
}
@Override
public void write(byte[] buffer) throws java.io.IOException {
originalStream.write(buffer);
totalBytesWritten += buffer.length;
XposedBridge.log(String.format(
"%s: 数据发送 - 目标: %s, 本次: %d bytes, 总计: %d bytes",
TAG, destination, buffer.length, totalBytesWritten
));
}
@Override
public void close() throws java.io.IOException {
XposedBridge.log(String.format(
"%s: 连接关闭 - 目标: %s, 总发送: %d bytes",
TAG, destination, totalBytesWritten
));
originalStream.close();
}
}
}
Xposed 检测技术
框架检测方法
// XposedDetection.java - Xposed 检测
package com.example.security.detection;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import java.io.File;
import java.lang.reflect.Method;
public class XposedDetection {
// 检测方法1:检查 Xposed 相关文件
public static boolean detectXposedFiles() {
String[] xposedFiles = {
"/system/framework/XposedBridge.jar",
"/system/bin/app_process32_xposed",
"/system/bin/app_process64_xposed",
"/system/xposed.prop",
"/data/data/de.robv.android.xposed.installer/",
"/data/data/org.meowcat.edxposed.manager/",
"/data/data/top.canyie.dreamland.manager/"
};
for (String path : xposedFiles) {
if (new File(path).exists()) {
return true;
}
}
return false;
}
// 检测方法2:检查 Xposed 相关应用
public static boolean detectXposedApps(Context context) {
String[] xposedPackages = {
"de.robv.android.xposed.installer",
"org.meowcat.edxposed.manager",
"top.canyie.dreamland.manager",
"com.solohsu.android.edxp.manager"
};
PackageManager pm = context.getPackageManager();
for (String packageName : xposedPackages) {
try {
ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0);
if (appInfo != null) {
return true;
}
} catch (PackageManager.NameNotFoundException e) {
// 包不存在,继续检查下一个
}
}
return false;
}
// 检测方法3:检查堆栈跟踪
public static boolean detectXposedStack() {
try {
throw new Exception("Stack trace check");
} catch (Exception e) {
StackTraceElement[] stackTrace = e.getStackTrace();
for (StackTraceElement element : stackTrace) {
String className = element.getClassName();
if (className.contains("de.robv.android.xposed") ||
className.contains("EdXposed") ||
className.contains("LSPosed")) {
return true;
}
}
}
return false;
}
// 检测方法4:检查类加载器
public static boolean detectXposedClassLoader() {
try {
ClassLoader classLoader = XposedDetection.class.getClassLoader();
// 检查类加载器类型
String classLoaderName = classLoader.getClass().getName();
if (classLoaderName.contains("XposedBridge")) {
return true;
}
// 尝试加载 Xposed 类
try {
Class.forName("de.robv.android.xposed.XposedBridge");
return true;
} catch (ClassNotFoundException e) {
// Xposed 类不存在
}
} catch (Exception e) {
// 检测过程中出现异常
}
return false;
}
// 检测方法5:检查方法 Hook 状态
public static boolean detectMethodHook() {
try {
// 创建一个测试方法
Method testMethod = XposedDetection.class.getDeclaredMethod("testMethod");
// 检查方法是否被 Hook
// 这里可以通过检查方法的字节码或其他特征来判断
// 简单的检测方式:调用方法并检查行为
String result = testMethod.invoke(null).toString();
// 如果返回值不是预期的,可能被 Hook 了
if (!"expected_result".equals(result)) {
return true;
}
} catch (Exception e) {
// 检测过程中出现异常
}
return false;
}
// 测试方法
private static String testMethod() {
return "expected_result";
}
// 检测方法6:检查系统属性
public static boolean detectXposedProperties() {
try {
// 检查系统属性
String[] properties = {
"ro.xposed.version",
"ro.edxp.version",
"ro.lsposed.version"
};
for (String prop : properties) {
String value = System.getProperty(prop);
if (value != null && !value.isEmpty()) {
return true;
}
}
// 使用反射检查 SystemProperties
Class<?> systemProperties = Class.forName("android.os.SystemProperties");
Method get = systemProperties.getMethod("get", String.class);
for (String prop : properties) {
String value = (String) get.invoke(null, prop);
if (value != null && !value.isEmpty()) {
return true;
}
}
} catch (Exception e) {
// 检测过程中出现异常
}
return false;
}
// 综合检测方法
public static boolean isXposedPresent(Context context) {
return detectXposedFiles() ||
detectXposedApps(context) ||
detectXposedStack() ||
detectXposedClassLoader() ||
detectMethodHook() ||
detectXposedProperties();
}
// 高级检测:检查内存中的 Xposed 痕迹
public static boolean detectXposedMemory() {
try {
// 检查 /proc/self/maps 文件
java.io.BufferedReader reader = new java.io.BufferedReader(
new java.io.FileReader("/proc/self/maps")
);
String line;
while ((line = reader.readLine()) != null) {
if (line.contains("XposedBridge") ||
line.contains("libxposed") ||
line.contains("libart-xposed")) {
reader.close();
return true;
}
}
reader.close();
} catch (Exception e) {
// 读取失败
}
return false;
}
// 动态检测:运行时行为分析
public static boolean detectRuntimeBehavior() {
try {
// 检查方法执行时间异常
long startTime = System.nanoTime();
// 执行一个简单操作
String test = "test";
test.hashCode();
long endTime = System.nanoTime();
long duration = endTime - startTime;
// 如果执行时间异常长,可能被 Hook 了
if (duration > 1000000) { // 1ms
return true;
}
// 检查异常的方法调用
try {
// 调用一个不存在的方法,正常情况下应该抛出异常
Method nonExistentMethod = String.class.getMethod("nonExistentMethod");
// 如果没有抛出异常,可能被 Hook 了
return true;
} catch (NoSuchMethodException e) {
// 正常情况
}
} catch (Exception e) {
// 检测过程中出现异常
}
return false;
}
}
反检测技术
// AntiDetection.java - 反检测技术
package com.example.security.antidetection;
import java.io.File;
import java.lang.reflect.Method;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XC_MethodReplacement;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
public class AntiDetection {
// 隐藏 Xposed 文件存在
public static void hideXposedFiles(LoadPackageParam lpparam) {
try {
// Hook File.exists() 方法
XposedHelpers.findAndHookMethod(
File.class,
"exists",
new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
File file = (File) param.thisObject;
String path = file.getAbsolutePath();
// 隐藏 Xposed 相关文件
if (isXposedRelatedPath(path)) {
param.setResult(false);
}
}
}
);
// Hook File.listFiles() 方法
XposedHelpers.findAndHookMethod(
File.class,
"listFiles",
new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
File[] files = (File[]) param.getResult();
if (files != null) {
java.util.List<File> filteredFiles = new java.util.ArrayList<>();
for (File file : files) {
if (!isXposedRelatedPath(file.getAbsolutePath())) {
filteredFiles.add(file);
}
}
param.setResult(filteredFiles.toArray(new File[0]));
}
}
}
);
} catch (Throwable t) {
// Hook 失败
}
}
// 隐藏 Xposed 应用
public static void hideXposedApps(LoadPackageParam lpparam) {
try {
// Hook PackageManager.getApplicationInfo
XposedHelpers.findAndHookMethod(
"android.app.ApplicationPackageManager",
lpparam.classLoader,
"getApplicationInfo",
String.class,
int.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
String packageName = (String) param.args[0];
if (isXposedRelatedPackage(packageName)) {
// 抛出 NameNotFoundException
throw new android.content.pm.PackageManager.NameNotFoundException(
"Package " + packageName + " not found"
);
}
}
}
);
// Hook PackageManager.getInstalledApplications
XposedHelpers.findAndHookMethod(
"android.app.ApplicationPackageManager",
lpparam.classLoader,
"getInstalledApplications",
int.class,
new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
@SuppressWarnings("unchecked")
java.util.List<android.content.pm.ApplicationInfo> apps =
(java.util.List<android.content.pm.ApplicationInfo>) param.getResult();
if (apps != null) {
java.util.Iterator<android.content.pm.ApplicationInfo> iterator = apps.iterator();
while (iterator.hasNext()) {
android.content.pm.ApplicationInfo appInfo = iterator.next();
if (isXposedRelatedPackage(appInfo.packageName)) {
iterator.remove();
}
}
}
}
}
);
} catch (Throwable t) {
// Hook 失败
}
}
// 隐藏堆栈跟踪
public static void hideStackTrace(LoadPackageParam lpparam) {
try {
// Hook Throwable.getStackTrace
XposedHelpers.findAndHookMethod(
Throwable.class,
"getStackTrace",
new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
StackTraceElement[] stackTrace = (StackTraceElement[]) param.getResult();
if (stackTrace != null) {
java.util.List<StackTraceElement> filteredStack = new java.util.ArrayList<>();
for (StackTraceElement element : stackTrace) {
if (!isXposedRelatedStackElement(element)) {
filteredStack.add(element);
}
}
param.setResult(filteredStack.toArray(new StackTraceElement[0]));
}
}
}
);
} catch (Throwable t) {
// Hook 失败
}
}
// 隐藏类加载器
public static void hideClassLoader(LoadPackageParam lpparam) {
try {
// Hook Class.forName
XposedHelpers.findAndHookMethod(
Class.class,
"forName",
String.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
String className = (String) param.args[0];
if (isXposedRelatedClass(className)) {
throw new ClassNotFoundException("Class " + className + " not found");
}
}
}
);
// Hook ClassLoader.loadClass
XposedHelpers.findAndHookMethod(
ClassLoader.class,
"loadClass",
String.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
String className = (String) param.args[0];
if (isXposedRelatedClass(className)) {
throw new ClassNotFoundException("Class " + className + " not found");
}
}
}
);
} catch (Throwable t) {
// Hook 失败
}
}
// 隐藏系统属性
public static void hideSystemProperties(LoadPackageParam lpparam) {
try {
// Hook System.getProperty
XposedHelpers.findAndHookMethod(
System.class,
"getProperty",
String.class,
new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
String key = (String) param.args[0];
if (isXposedRelatedProperty(key)) {
param.setResult(null);
}
}
}
);
// Hook SystemProperties.get
XposedHelpers.findAndHookMethod(
"android.os.SystemProperties",
lpparam.classLoader,
"get",
String.class,
new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
String key = (String) param.args[0];
if (isXposedRelatedProperty(key)) {
param.setResult("");
}
}
}
);
} catch (Throwable t) {
// Hook 失败
}
}
// 辅助方法:检查是否为 Xposed 相关路径
private static boolean isXposedRelatedPath(String path) {
String[] xposedPaths = {
"XposedBridge",
"xposed",
"edxposed",
"lsposed",
"dreamland"
};
String lowerPath = path.toLowerCase();
for (String xposedPath : xposedPaths) {
if (lowerPath.contains(xposedPath.toLowerCase())) {
return true;
}
}
return false;
}
// 辅助方法:检查是否为 Xposed 相关包名
private static boolean isXposedRelatedPackage(String packageName) {
String[] xposedPackages = {
"de.robv.android.xposed",
"org.meowcat.edxposed",
"top.canyie.dreamland",
"com.solohsu.android.edxp"
};
for (String xposedPackage : xposedPackages) {
if (packageName.startsWith(xposedPackage)) {
return true;
}
}
return false;
}
// 辅助方法:检查是否为 Xposed 相关堆栈元素
private static boolean isXposedRelatedStackElement(StackTraceElement element) {
String className = element.getClassName();
return className.contains("de.robv.android.xposed") ||
className.contains("EdXposed") ||
className.contains("LSPosed") ||
className.contains("Dreamland");
}
// 辅助方法:检查是否为 Xposed 相关类
private static boolean isXposedRelatedClass(String className) {
return className.startsWith("de.robv.android.xposed") ||
className.contains("EdXposed") ||
className.contains("LSPosed") ||
className.contains("Dreamland");
}
// 辅助方法:检查是否为 Xposed 相关属性
private static boolean isXposedRelatedProperty(String property) {
return property.contains("xposed") ||
property.contains("edxp") ||
property.contains("lsposed") ||
property.contains("dreamland");
}
}
总结
Xposed 安全与逆向分析的关键要点:
🎯 安全研究应用
- 加密算法分析:监控加密操作和密钥使用
- 网络通信分析:拦截和分析网络请求
- 应用行为分析:深入了解应用内部逻辑
- 漏洞发现:通过 Hook 发现安全漏洞
✅ 检测技术
- 文件系统检测
- 应用包检测
- 堆栈跟踪分析
- 类加载器检查
- 运行时行为分析
🚀 防护策略
- 多层检测机制
- 动态检测技术
- 代码混淆和加固
- 反调试和反 Hook
⚠️ 道德和法律
- 仅用于合法的安全研究
- 遵守相关法律法规
- 负责任的漏洞披露
- 保护用户隐私和数据
掌握 Xposed 安全技术,提升 Android 安全防护能力!
安全研究需要在合法合规的框架内进行,技术的使用应当服务于提升整体安全水平的目标。