# 【開始前的準備】
1. 掌握基本的android開發知識,搭建好android開發環境(環境怎么搭啥的也有一堆蛋疼問題,這里就不說了,改天我仔細探索整理一下)
2. 有xposed框架作為環境(真機或者模擬器,我下面直接真機調試)
3. Xposed框架API(網上各種坑爹教程附各種不知啥時候會掛掉,資源老,老子可能要賬號才能下載的坑爹鏈接,也不給個官網地址,所以)
4. ?由于它是不斷更新的,請大家直接到官網頁面進行下載:[https://jcenter.bintray.com/de/robv/android/xposed/api/](https://jcenter.bintray.com/de/robv/android/xposed/api/)
下載如下兩個文件:
[api-82-sources.jar](https://bintray.com/rovo89/de.robv.android.xposed/download_file?file_path=de%2Frobv%2Fandroid%2Fxposed%2Fapi%2F82%2Fapi-82-sources.jar)? ?
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???[api-82.jar](https://bintray.com/rovo89/de.robv.android.xposed/download_file?file_path=de%2Frobv%2Fandroid%2Fxposed%2Fapi%2F82%2Fapi-82.jar)
# 【環境的搭建】
## 就是將Xposed框架API引用到項目中,這樣就能進行Xposed模塊的開發了
1. 使用android studio構建一個項目
(小提示,注意設置為project查看,這樣項目結構看得更加清楚)

下方修改處皆在上圖中用箭頭指出(build.gradle是app文件夾中的,注意不要搞錯)
**1.將下載下來的兩個文件復制到文件夾libs中**
**2.在build.gradle中將添加圖中兩句**

~~~
provided 'de.robv.android.xposed:api:82'
provided 'de.robv.android.xposed:api:82:sources'
~~~
**3.在AndroidManifest.xml將自己標識為一個Xposed模塊,語句添加在如下位置**

```xml
<meta-data
android:name="xposedmodule"
android:value="true" />
<meta-data
android:name="xposeddescription"
android:value="我是一個Xposed例程" />
<meta-data
android:name="xposedminversion"
android:value="53" />
```
作用:
xposedmodule:value為true,表示自己是一個xposed模塊
xposeddescription:value中的文字就是對模塊的描述,這些能夠在手機上的Xposed框架中看到,舉個栗子

情遷搶包是項目名,后面一堆文字描述就是在xposeddescription的value中標注的(這個搶紅包賊穩)
**xposedminversion:xposed最低版本,這些應該都是向下兼容的吧?所以直接填最低版本好了**
**4.下面就可以開車啦**
## 【第一個Xposed模塊的編寫】
直接輸出日志什么的太low了,找其他軟件hook我怕被舉報(放屁,其實是我特么也還不會),所以就自己寫個類來hook練練手吧!
我們先寫一個MainActivity類輸出一個Toast提示,然后再寫一個HookToast類作為Xposed模塊來hook它,實現修改
**0.在界面中添加一個可愛的小button**

**1.代碼邏輯如下:**
```java
public class MainActivity extends AppCompatActivity {
private Button button;
public 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(MainActivity.this, toastMessage(), Toast.LENGTH_SHORT).show();
}
});
}
public String toastMessage() {
return "我未被劫持";
}
}
```
比較容易理解,這個類的功能是,點擊按鈕,彈出一個toast提示,內容由toastMessage()方法提供,而toastMessage()的返回值為“我未被劫持”
下面我們正式開始寫我們的xposed模塊,來hook我們的MainActivity,修改toastMessage()方法的返回值為“你已被劫持”
**2.我們新建一個HookToast類**
```java
public class HookToast implements IXposedHookLoadPackage {
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
if (loadPackageParam.packageName.equals("com.example.mingking.xposedtest")) {
Class clazz = loadPackageParam.classLoader.loadClass("com.example.mingking.xposedtest.MainActivity");
XposedHelpers.findAndHookMethod(clazz, "toastMessage", new XC_MethodHook() {
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
}
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
param.setResult("你已被劫持");
}
});
}
}
}
```
到此,所有代碼已經寫完,之前在AndroidManifest.xml中標識了我們的項目是一個Xposed模塊,可是我們可能會有許多Activity,
它怎么才能知道模塊的入口在哪呢?
所以,下面要告訴Xposed框架,我們的應用中,Xposed模塊的入口到底在哪。
**3.標注Xposed模塊入口**
右鍵點擊 main , 選擇new --> Folder -->Assets Folder,然后確認即可。

在assets中new一個file,文件名為xposed_init(文件類型選text),并在其中寫上入口類的完整路徑(下面是我的類路徑,你們填自己的,就是activity中packege后面的包名)


這樣,xposed框架就能夠讀取xposed\_init中的信息來找到模塊的入口
**4.Run**
請確保禁用Instant Run(File -> Settings -> Build, Execution, Deployment -> Instant Run),否則您的類不會直接包含在APK中,導致HOOK失敗!!!

以上是來自官方的警告,一定要注意,之前我死活hook不了,日志也輸出不了,就是因為這個!!!
**如果你不這樣做,你會驚喜地發現發現xposed日志反復給你拋出類似這樣一個錯誤:**
**xposed didn't find class on dexpathlist:……(省略一長串)**
**而這個錯誤是你百度到死(google也沒用)也不一定查的到解決方案的(這個故事提醒我們要仔細閱讀官方文檔)**
**Run成功后……**
可以發現,xposed模塊里出現了我們的模塊
XposedTest是應用名
后面的文字注釋正是我們之前在AndroidManifest.xml中的xposeddescription里所標注的信息
# 在新版本的Androi Studio 3.5.1上踩的坑
```
~~~
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "com.gyk.xposedmodule"
minSdkVersion 16
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compileOnly files('libs/api-82.jar')
// compileOnly 'de.robv.android.xposed:api:82:sources'
// 有這句我們就hook不了,我日他媽
// implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}
~~~
```