簡介:Xposed框架是1款可以在不修改APK的情況下影響程序運行的框架服務,通過替換/system/bin/app_process程序控制zygote進程,使得app_process在啟動進程中會加載XposedBridge.jar這個jar包,從而完成對Zygote進程及其創建的虛擬機的劫持。
Github地址:https://github.com/rovo89/Xposed
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:id="@+id/tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
package com.cockroach.hook_object;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv1 = (TextView) findViewById(R.id.tv1);
TextView tv2 = (TextView) findViewById(R.id.tv2);
TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
tv1.setText("imei:" + tm.getDeviceId());
tv2.setText("imsi:" + tm.getSubscriberId());
}
}
這就是我們的等會要hook的apk程序,下面編寫xposed插件
在 application 標簽中增加模塊說明信息
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!-- 使 xposed 模塊有效 -->
<meta-data android:name="xposedmodule" android:value="true"></meta-data>
<!-- xposed 模塊名稱,我們可以隨意起1個和模塊功能類似的便可 -->
<meta-data android:name="xposeddescription" android:value="qq迅雷提速神器"></meta-data>
<!-- xposed 模塊最低版本 -->
<meta-data android:name="xposedminversion" android:value="54"></meta-data>
</application>
將 xposed 庫文件 XposedBridgeApi-XX.jar, 放入 app/lib 文件夾下
需要注意的是: 修改 Scope 為 Provided
package com.cockroach.xposedhookdemo;
import android.telephony.TelephonyManager;
import de.robv.android.xposed.IXposedHookLoadPackage;
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;
/**
* Created by 18459 on 2016/6/27.
*/
public class Main implements IXposedHookLoadPackage{
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
if(!loadPackageParam.packageName.equals("com.cockroach.hook_object"))
return;
XposedBridge.log("Loaded app: " + loadPackageParam.packageName);
// 找到對應的方法,進行替換
// 參數 1:類名
// 參數 2: 方法名
// 參數 3:實現監聽,重寫方法
// replaceHookedMethod 替換方法
// beforeHookedMethod 方法前履行
// afterHookedMethod 方法后履行
XposedHelpers.findAndHookMethod(TelephonyManager.class, "getSubscriberId", new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
return "Hook 成功了 哈哈!!!";
}
});
}
}
需要在 main 文件夾下建立 assets 文件夾中新建1個 xposed_init 的文件,并在其中聲明主入口類
到這里這個hook無參函數的簡單demo插件就完成了,
布局文件中添加
<EditText
android:id="@+id/et1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="請輸入你的賬號"/>
<EditText
android:id="@+id/et2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="請輸入你的密碼"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="my_onClick"
android:text="登陸"
android:textSize="26dp"/>
MainActivity中添加
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void my_onClick(View view) {
EditText editText = (EditText) findViewById(R.id.et1);
EditText editText1 = (EditText) findViewById(R.id.et2);
String string = editText.getText().toString();
String string1 = editText1.getText().toString();
if(CheckRegister(string,string1)){
Toast.makeText(MainActivity.this,"登陸成功",Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(MainActivity.this,"登陸失敗",Toast.LENGTH_SHORT).show();
}
}
private boolean CheckRegister(String string, String string1) {
return string.equals(string1);
}
}
效果,兩個輸入框輸入相同時 提示登陸成功,不同時 提示登陸失敗
到這里測試app完成
這里配置和前面無參插件編寫1樣,只需修改MainActivity
package com.cockroach.xposedhookdemo;
import android.util.Log;
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;
/**
* Created by 18459 on 2016/6/27.
*/
public class Main implements IXposedHookLoadPackage{
//被HOOK的程序的包名和類名
String packName = "com.cockroach.myapplication";
String className = "com.cockroach.myapplication.MainActivity";
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
if(!loadPackageParam.packageName.equals(packName))
return;
XposedBridge.log("Loaded app: " + loadPackageParam.packageName);
// replaceHookedMethod 替換方法
// beforeHookedMethod 方法前履行
// afterHookedMethod 方法后履行
// 處理是的情況
// 找到對應類的方法,進行hook,hook的方式有兩種
XposedHelpers.findAndHookMethod(className, // 類名
loadPackageParam.classLoader, // 類加載器
"CheckRegister", // 方法名
String.class, // 參數1
String.class, // 參數2
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.d("xposedplugin", (String) param.args[0]);
Log.d("xposedplugin", (String) param.args[1]);
//將兩個參數改成相等
param.args[0] = "123";
param.args[1] = "123";
//這樣設置函數的返回值
param.setResult(true);
}
@Override
//這個hook方法以后有啥用還不知道
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Log.d("xposedplugin", (String) param.args[0]);
Log.d("xposedplugin", (String) param.args[1]);
}
});
}
}
到這里hook有參函數的插件完成了
上面我們寫了共寫了兩個測試app和兩個插件app,我們用第1對app,來做測試
開機后我們運行測試app,看到已hook成功了
hook以后運行測試app
如果你是新手,沒看明白可以問我,或許可以幫到你。
上一篇 紅黑樹算法
下一篇 java加解密之RSA使用