我在博客上发表一些我的Android学习心得,希望对大家能有帮助。
这一篇我们讲述一下Hook技术
Hook
动态注入技术由来已久,通过Hook,我们可以改变变量或者方法的执行。在Android上进行Hook,需要跨进程操作,所以需要Root权限。对于Android平台的Hook,有两大类,一类是:Java层的Hook,另一个类是:Native层Hook
常见的工具
1、Cydia Substrate
2、Xposed
3、ADBI/DDI
Cydiasubstrate工具使用
首先给出官方网站,其中介绍了方法的使用,我主要通过例子来给大家演示一下该工具的使用
http://www.cydiasubstrate.com/
java层Hook实例
首先,官网中给出了一个例子,该例子是修改手机中getColor函数来改变字体的颜色
1、导入substarta-api.jar到libs中
2、首先构建Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<meta-data android:name="com.saurik.substrate.main"
android:value=".Main"/>
</application>
<uses-permission android:name="cydia.permission.SUBSTRATE"/>
</manifest>
3、主函数
import com.saurik.substrate.MS;
public class Main {
static void initialize() {
// ... code to run when extension is loaded
}
}
4、在initializa中调用hookClassLoad函数
MS.hookClassLoad("android.content.res.Resources", new MS.ClassLoadHook() {
public void classLoaded(Class<?> resources) {
// ... code to modify the class when loaded
}
});
5、在classLoaded中调用getMethod获取方法,并调用hookMethod来修改
例子
public static void initialize() {
// 通过hookClassLoad找到相应类
MS.hookClassLoad("android.content.res.Resources", new MS.ClassLoadHook() {
public void classLoaded(Class<?> resources) {
// ... code to modify the class when loaded
Method getColor;
try {
//获取相应getColor方法
getColor = resources.getMethod("getColor", Integer.TYPE);
} catch (NoSuchMethodException e) {
getColor = null;
}
if (getColor != null) {
//指向原来的方法
final MS.MethodPointer old = new MS.MethodPointer();
MS.hookMethod(resources, getColor, new MS.MethodHook() {
public Object invoked(Object resources, Object... args)
throws Throwable
{
// 进行修改
int color = (Integer) old.invoke(resources, args);
return color & ~0x0000ff00 | 0x00ff0000;
}
}, old);
}
}
});
}
我们运行substrate,并安装该应用
点击Link Substrate Files
点击Restart System后系统颜色变了,说明hook成功
继续依葫芦画瓢,我们hook短信sendTextMessage方法,将其内容打印出来
static void initialize() {
MS.hookClassLoad("android.telephony.SmsManager", new MS.ClassLoadHook() {
@Override
public void classLoaded(Class<?> SmsManager) {
// code to modify the class when loaded
Method sendTextMessage;
try {
sendTextMessage = SmsManager.getMethod(
"sendTextMessage", new Class[] {
String.class, String.class,
String.class, PendingIntent.class,
PendingIntent.class });
} catch (NoSuchMethodException e) {
sendTextMessage = null;
}
if(sendTextMessage != null) {
final MS.MethodPointer old = new MS.MethodPointer();
MS.hookMethod(SmsManager, sendTextMessage,
new MS.MethodAlteration() {
public Object invoked(Object _this,Object... _args) throws Throwable {
Log.d("Hook", "SEND_SMS");
Log.d("Hook", "destination:" + _args[0]);
Log.d("Hook", "source:" + _args[1]);
Log.d("Hook", "text:" + _args[2]);
return old.invoke(_this, _args);
}
},old);
}
}
});
}
运行smsManager.sendTextMessage(“123456789”, “987654321”, “Hello”, null, null);
在log信息中已经打印出来短信的内容