原创,首先国内各种rom版本不一,对官方教程中clock的hook很难做到,其次中文教程太少。。楼主也是刚接触Android hook,如有错误请多多指正
首先配置Xposed框架,这一步因机而异,网上有不同机型的各种rom,我这里用的是MI NOTE, MIUI 7 ,内核 Android 6.0,放一个别人做的挺好的教程
http://www.miui.com/thread-3694869-1-1.html
另外,本文参考资料如下:
https://github.com/rovo89/XposedBridge/wiki/Development-tutorial http://www.codefrom.com/paper/Xposed%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91%E5%9F%BA%E7%A1%80%E7%AF%87
全部文件下载链接在文末:
新建一个Xposed模块的步骤如下: 下载得到api-53.jar,api-53-source.jar ,版本低一点的话兼容性好 Android Studio新建空工程 Manifest配置如下: <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.dyna.hook1"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="15" />
<application
android:label="@string/app_name" >
<meta-data
android:name="xposedmodule"
android:value="true"/>
<meta-data
android:name="xposeddescription"
android:value="Easyexample" />
<meta-data
android:name="xposedminversion"
android:value="53"/>
</application>
</manifest> 两个文件放入app\libs目录,右键Add to library.(这还没完!注意!) 要把build.gradle下方新加上 repositories {
jcenter();
}
并把原有的dependencies块改成
dependencies {
provided 'de.robv.android.xposed:api:53'
provided 'de.robv.android.xposed:api:53:sources'
} 这样做的目的是编译出的apk不含有de\robv\...(如图) 再次编译提示出错时更改styles.xml为 <resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Light">
<!-- Customize your theme here. -->
</style>
</resources> 新建一个class如下: package com.dyna.hook1;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
public class MainActivity implements IXposedHookLoadPackage {
public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
XposedBridge.log("Loaded app: " + lpparam.packageName);
}
} 在app\src\main\assets目录(没有就新建这个目录)下新建文件xposed_init 入口assets/xposed_init配置,声明需要加载到 XposedInstaller 的入口类: com.dyna.hook1.MainActivity(完整类名:包名+类名)选择目标: 注意,你只能hook函数!替换或在之前或之后插入都是可以的,应当hook一些特殊而不常用的函数以避免性能和其他可能问题。 找到包xx.xx.xx中类xx.xx.xx.zz中的yy方法 public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable { if (!lpparam.packageName.equals("xx.xx.xx")) return; XposedBridge.log("we are in XX!");} 然后,代码这样: package com.dyna.hook1;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;//这里多了一个import
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
public class MainActivity implements IXposedHookLoadPackage {
public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
if (!lpparam.packageName.equals("xx.xx.xx"))
return;
findAndHookMethod("xx.xx.xx.zz", lpparam.classLoader, "yy", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
// this will be called before the clock was updated by the original method
}
@Override
protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
// this will be called after the clock was updated by the original method
}
});
}
} 注意此处的yy方法不带参数,如果有参数,需要在调用findAndHookMethod函数中列举它们的类型,该函数最后一个参数是一个XC_MethodHook的实例,其中有两个可重载的方法,beforeHookedMethod可以通过param.args操作传入值甚至跳过原有函数返回自定义的结果,afterHookedMethod可以修改返回值以及其他后期操作(完全替换可通过重载XC_MethodReplacement类的replaceHookedMethod方法实现)。 实例:如果调用了aa.yy(),那么param.thisObject的值应该是aa 动手吧! 首先,我们新建一个工程,包名就叫xx.xx.xx,新建一个类zz,继承于TextView(为贴近官方指导,这样可以对param.thisObject强制类型转换为TextView进行进一步操作)这个apk功能很简单,在屏幕上显示当前“硬币”数量,点击“Use Coin”后消耗硬币 首先是zz.java: package xx.xx.xx;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.TextView;
/**
* Created by Deva on 2016/4/17 0017.
*/
public class zz extends TextView{
public int coin;
public zz(Contextcontext) {
super(context);
coin = 10;
}
public zz(Contextcontext, AttributeSet attrs) {
super(context,attrs);
coin = 10;
}
final void yy(){
coin -= 1;
this.setText(String.valueOf(coin));
}
public void tt(){
coin += 1;
}
} 可以看到其中yy方法是我们按键所调用的,也是我们将要hook的对象 接着是MainActivity.java: package xx.xx.xx;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extendsAppCompatActivity {
Button usecoin;
zz cur_coin;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cur_coin =(zz) findViewById(R.id.coin);
usecoin =(Button) findViewById(R.id.usecoin);
usecoin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(Viewv) {
cur_coin.yy();
}
});
}
} 最后是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:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<TextView android:text="Coins:" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView2" />
<xx.xx.xx.zz
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="10"
android:id="@+id/coin"
android:layout_alignParentTop="true"
android:layout_toRightOf="@+id/textView2"
android:layout_toEndOf="@+id/textView2" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Use Coin"
android:id="@+id/usecoin"
android:layout_below="@+id/textView2"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout> 做完以上步骤,我们编译生成apk并运行,可以看到正常的效果。 接下来我们对apk进行hook。 按照一开始的部分一直操作,最后将MainActivity.class修改为: package com.dyna.hook1;
import android.graphics.Color;
import android.util.Log;
import android.widget.TextView;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
public class MainActivity implementsIXposedHookLoadPackage {
public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable{
if (lpparam.packageName.contains("xx.xx.xx") == false)
return;
XposedBridge.log("we are in " + lpparam.packageName);
findAndHookMethod("xx.xx.xx.zz", lpparam.classLoader,"yy", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
// this will be called before the clock wasupdated by the original method
}
@Override
protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
// this will be called after the clock wasupdated by the original method
TextView tv = (TextView) param.thisObject;
String text =tv.getText().toString();
tv.setText(text + " :)");
tv.setTextColor(Color.RED);
}
});
}
} 安装到手机上,进入xPosed Installer ->模块(Modules),会发现你写的hook1,勾选之后重启手机,再次运行XX,看看效果吧!
两个工程(Hook.rar) 下载地址:http://pan.baidu.com/s/1kV5yc0f 密码 x7z4
|