注意
この記事の内容は2016年10月27日時点の物です。
内容が古くなっている場合があります。
Ⅰ はじめに
Xposed Frameworkを利用します。 ネイティブ(C/C++)で書かれたコードはhookできません。
また、初歩的な事は以下の記事を参照して下さい。 https://kagasu.hatenablog.com/entry/2020/04/23/034804
Ⅱゴール
今回は以下のmyAdd
をhookして、足し算の結果を書き換える事をゴールとします。
private int myAdd(int val1, int val2) { return val1 + val2; }
Ⅲ hookする
1. 戻り値を999に書き換える
final Class<?> _class = XposedHelpers.findClass("net.kagasu.calculator.MainActivity", lpparam.classLoader); XposedBridge.hookAllMethods(_class, "myAdd", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { //super.afterHookedMethod(param); // 戻り値を999に書き換える param.setResult(999); } });
2. 引数をとり、戻り値を書き換える
final Class<?> _class = XposedHelpers.findClass("net.kagasu.calculator.MainActivity", lpparam.classLoader); XposedBridge.hookAllMethods(_class, "myAdd", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { //super.afterHookedMethod(param); int val1 = (int)param.args[0]; int val2 = (int)param.args[1]; // 掛け算にする param.setResult(val1 * val2); } });
ソースコード
1. Androidアプリ
MainActivity.java
public class MainActivity extends AppCompatActivity { private Button button1; private EditText et1, et2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et1 = (EditText) findViewById(R.id.editText1); et2 = (EditText) findViewById(R.id.editText2); button1 = (Button) findViewById(R.id.button1); button1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int val1 = Integer.valueOf(et1.getText().toString()); int val2 = Integer.valueOf(et2.getText().toString()); int result = myAdd(val1, val2); new AlertDialog.Builder(MainActivity.this) .setTitle("result") .setMessage(String.valueOf(result)) .setPositiveButton("OK", null) .show(); } }); } private int myAdd(int val1, int val2) { return val1 + val2; } }
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="net.kagasu.calculator.MainActivity"> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:inputType="numberDecimal" android:layout_weight="1" android:id="@+id/editText1" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="+" /> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:inputType="numberDecimal" android:layout_weight="1" android:id="@+id/editText2" /> </LinearLayout> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Calculate" android:id="@+id/button1"/> </LinearLayout> </RelativeLayout>
2. Xposedモジュール
XposedHookAdd.java
package net.kagasu.xposedhookadd; 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 XposedHookAdd implements IXposedHookLoadPackage { public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable { if(!lpparam.packageName.equals("net.kagasu.calculator")) { return; } final Class<?> _class = XposedHelpers.findClass("net.kagasu.calculator.MainActivity", lpparam.classLoader); XposedBridge.hookAllMethods(_class, "myAdd", new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { //super.beforeHookedMethod(param); XposedBridge.log("[" + lpparam.packageName + "] beforeHookedMethod"); } @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { //super.afterHookedMethod(param); XposedBridge.log("[" + lpparam.packageName + "] afterHookedMethod"); int val1 = (int)param.args[0]; int val2 = (int)param.args[1]; XposedBridge.log("引数1: " + val1); XposedBridge.log("引数2: " + val2); XposedBridge.log("書き換える前の値: " + param.getResult()); // 掛け算にする param.setResult(val1 * val2); // 999にする //param.setResult(999); XposedBridge.log("書き換えた後の値: " + param.getResult()); } }); } }