# 某查 Token Xposed+Sekiro 升级方案
Xposed Frida 对比
当涉及到安卓逆向工程中的Xposed和Frida时,它们都有各自的优点和缺点。下面是对它们进行详细比较:
|
Xposed |
Frida |
实现原理 |
通过修改应用程序的DEX文件来实现对应用程序的修改和扩展 |
通过在应用程序中注入JavaScript代码来实现对应用程序的修改和扩展 |
安装配置 |
需要安装Xposed框架和相应的模块 |
需要在设备上安装Frida服务器和Frida客户端 |
功能定制 |
通过选择和启用/禁用不同的Xposed模块来实现功能定制 |
可以使用JavaScript代码实现对应用程序的定制 |
兼容性 |
需要与特定版本的安卓系统兼容 |
支持多种安卓版本和架构 |
开发门槛 |
需要了解Xposed框架和模块开发的基本知识 |
需要了解JavaScript和Frida的API |
功能强大性 |
提供丰富的Xposed模块和功能扩展 |
具有更灵活的动态插桩和功能定制能力 |
性能影响 |
可能对应用程序的性能产生一定影响 |
对应用程序的性能影响较小 |
Xposed的优势在于它提供了丰富的Xposed模块,可以直接选择和启用/禁用这些模块来实现功能定制。它的兼容性取决于与特定版本的安卓系统的兼容性,但在兼容的情况下,它可以对应用程序进行较为深入的修改。
Frida的优势在于它具有更灵活的动态插桩和功能定制能力。通过注入JavaScript代码,开发者可以对应用程序的函数进行替换、监视和调用,实现更细粒度的修改。Frida支持多种安卓版本和架构,因此在兼容性方面更加灵活。
Xposed 开发
创建项目
打开 AndroidStudio,简单的 Xposed 插件不需要任何Activity。
选择 Project 模式
熟悉目录
目录如下
下面是对上述文件夹目录的详细介绍:
app
目录是 Android 项目的主要目录,包含应用的主要代码和资源文件。
build.gradle
是应用的构建脚本,用于配置构建过程和依赖项。
libs
目录用于存放应用所需的第三方库文件(例如 JAR 文件)。
proguard-rules.pro
是 ProGuard 的规则文件,用于代码混淆和优化。
src
目录包含应用的源代码和资源文件。
androidTest
目录用于存放应用的 Android 测试代码。
java
目录是存放 Android 测试代码的 Java 源代码目录。
main
目录是主要的源代码目录,包含应用的主要逻辑和资源。
AndroidManifest.xml
是 Android 应用的清单文件,包含应用的配置信息和组件声明。
java
目录是存放应用的 Java 源代码的目录。
com.example.app
是你在创建项目时指定的包名,你的 Java 代码文件应该放在这个目录或其子目录中。
res
目录是存放应用的资源文件的目录。
test
目录用于存放应用的单元测试代码。
java
目录是存放应用的单元测试代码的 Java 源代码目录。
build.gradle
是项目的根级构建脚本,用于配置整个项目的构建过程和依赖项。
gradle
目录是存放 Gradle 构建工具的目录。
wrapper
目录包含 Gradle Wrapper 相关的文件,用于自动下载和运行指定版本的 Gradle。
gradle-wrapper.jar
是 Gradle Wrapper 的 JAR 文件。
gradle-wrapper.properties
是 Gradle Wrapper 的配置文件。
gradle.properties
是项目的 Gradle 配置文件,用于定义项目级的属性和变量。
gradlew
和 gradlew.bat
是可执行的 Gradle Wrapper 脚本,用于在命令行中运行 Gradle 命令。
local.properties
是本地配置文件,用于指定 Android SDK 的路径。
settings.gradle
是项目的设置文件,用于配置项目的模块和构建选项。
初始配置
引入 Jar包
将下载好的 Jar 包直接拉入 app/libs
然后右键选这个再点 Ok ,这样才能在代码中引入Jar 包
build.gradle
打开 app 目录下的 build.gradle
会发现dependencies
多了两行,为了只编译不打包,节省空间,删掉这行
1 2
| implementation files('libs/XposedBridgeApi-82.jar') implementation files('libs/sekiro-open-demo-0.0.1.jar')
|
然后引入
1 2 3
| implementation 'com.virjar:sekiro-api:1.0.1' compileOnly 'de.robv.android.xposed:api:82' implementation('cn.iinti.sekiro3.business:sekiro-business-api:1.1')
|
最终是
1 2 3 4 5 6 7 8
| dependencies { implementation 'com.virjar:sekiro-api:1.0.1' compileOnly 'de.robv.android.xposed:api:82' implementation('cn.iinti.sekiro3.business:sekiro-business-api:1.1') implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'com.google.android.material:material:1.8.0' testImplementation 'junit:junit:4.13.2' }
|
在 android 下增加packagingOptions
最终是
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
| android { namespace 'com.example.tychook' compileSdk 33
packagingOptions {
exclude'META-INF/INDEX.LIST' exclude'META-INF/io.netty.versions.properties'
}
defaultConfig { applicationId "com.example.tychook" minSdk 24 targetSdk 33 versionCode 1 versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" }
buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } }
|
settings.gradle
打开根目录下的settings.gradle文件,我们需要引入Xposed和 Sekiro的库
在dependencyResolutionManagement下的repositories添加
1 2 3 4 5 6
| repositories { google() mavenCentral() maven { url 'https://api.xposed.info/' } maven { url "https://nexus.iinti.cn/repository/maven-public/" } }
|
AndroidManifest.xml
在 app/src/main/AndroidManifest.xml 添加 xposed文件描述,并指出这是一个 xposed 插件,直接复制即可
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
| <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
<application android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" tools:targetApi="31" > <meta-data android:name="xposedmodule" android:value="true"/> <meta-data android:name="xposeddescription" android:value="我是Xposed模块简介" /> <meta-data android:name="xposedminversion" android:value="82"/> </application>
</manifest>
|
- xposedmodule 表明是一个xposed模块
- xposeddescription 描述
- xposedminversion API version(一般等于构建它的Xposed的version)
核心代码
Class 文件
右键,新建一个 ClassHookStart
Sekiro 代码
Sekiro 长链接代码参考 官网 demo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class XposedMain implements IXposedHookLoadPackage {
@Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) { if (loadPackageParam.processName.equals("cn.iinti.sekiroApp")) { new SekiroClient("test_xposed", UUID.randomUUID().toString()) .setupSekiroRequestInitializer((sekiroRequest, handlerRegistry) -> handlerRegistry.registerSekiroHandler(new ActionHandler() { @Override public String action() { return "testAction"; }
@Override public void handleRequest(SekiroRequest sekiroRequest, SekiroResponse sekiroResponse) { sekiroResponse.success("ok"); } }) ).start(); } } }
|
不一样的是,我们需要用SekiroClient另一个重写版本,直接看源码即可,直接看截图
最终Hook代码
写入我们的 Hook 代码
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
| package com.example.testxp; import android.util.Log; import java.util.UUID; import cn.iinti.sekiro3.business.api.SekiroClient; import cn.iinti.sekiro3.business.api.interfaze.ActionHandler; import cn.iinti.sekiro3.business.api.interfaze.SekiroRequest; import cn.iinti.sekiro3.business.api.interfaze.SekiroResponse; import de.robv.android.xposed.IXposedHookLoadPackage; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.callbacks.XC_LoadPackage; public class HookStart implements IXposedHookLoadPackage { @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable { if (!loadPackageParam.packageName.equals("com.tianyancha.skyeye")) return; new SekiroClient("xposed", UUID.randomUUID().toString(),"自己的服务器地址",5621) .setupSekiroRequestInitializer((sekiroRequest, handlerRegistry) -> handlerRegistry.registerSekiroHandler(new ActionHandler() { @Override public String action() { return "tycHeaderAuth"; } @Override public void handleRequest(SekiroRequest sekiroRequest, SekiroResponse sekiroResponse) { Class<?> targetClass = XposedHelpers.findClass("com.tianyancha.base.utils.g3", loadPackageParam.classLoader); String res = (String) XposedHelpers.callStaticMethod(targetClass, "a0"); sekiroResponse.success(res); } }) ).start(); Log.e("zyb","注入连接成功!");
} }
|
xposed_init
告诉XposedBridge hook入口在哪里,在app/src/main目录下创建assets文件夹,在assets文件夹内创建文件xposed_init, 该文件每行包含一个class的全限定名,在这里文件内容为:
1
| com.example.testxp.HookStart
|
构建
如图,右上角构建完成后,如果显示 finished,就直接去文件夹找 app-debug.apk,此时一个 xposed 插件就已经开发完成了。
结尾
将 插件安装到手机后看到 Logcat 输出链接成功,即可!
此时我们调用一下 Sekiro 接口
大功告成了~