android对java函数的hook,替换系统变量

java的hook与so完全不同了,目前有xposed和substrate两种框架来帮助hook住java函数,我介绍下前者的使用,后者我使用过一次把机器搞成砖头了,囧,暂时不去碰他。(源码:http://pan.baidu.com/s/1o7wTIuI)

关于实现原理以后我研究好了再补充上去。

xposed文档:
xposed api jar包:
xposed 框架apk:

xposed框架采用了模块安装的方式来进行功能扩展,因此其提供了一个apk来管理功能模块,开发者可以自己写一个模块来实现对应功能,该apk内部还可以下载社区别人提交的模块。

环境:root过的手机
步骤:
1、安装xposed的框架apk,点击“框架”->“安装/更新”,然后重启( 这里最好选择稳定版本,见链接的“Release type”,如果某个xposed版本在你手机上有问题,就试试其他版本了,我用的是2.6.1版本)
    这一步xposed会替换系统的一些程序,如system/bin/app_process,了解android的都知道这个程序是启动安卓程序的入口。
2、重启以后,如果界面上没有提示你“xposed框架未被激活...”之类的红色文字,就说明成功注入了xposed框架, 如果有红色错误提示,一般来说到“设置”->勾选“禁用资源钩子”就可以解决了;成功注入以后,可以选择到“下载模块”去下载模块,然后到“模块”下去勾选上模块,再次重启即可。
3、编写自己的模块:
    3.1、eclipse创建一个工程,去掉Acyivity类,我们不需要界面;新建一个lib目录,把xposed api jar包加进去,然后右键“build path”->“add to build path”( 注意:不要把jar包放在libs目录下,否则会被exlipse编译到class文件里面去,这会导致后面运行出现IllegalAccessError错误
    3.2、创建模块入口类:
package com.example.xposedHook;

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;
import de.robv.android.xposed.XposedHelpers;

/**
 * Created by  luowp@warthog.cn on 2015/12/21.
 */
public class Hook implements IXposedHookLoadPackage {
    public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
        XposedBridge.log("Loaded app: " + lpparam.packageName);
        XposedHelpers.findAndHookMethod("android.telephony.TelephonyManager", lpparam.classLoader, "getDeviceId", new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                // this will be called before the clock was updated by the original method
             XposedBridge.log("getDeviceId before\n");
            }
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                // this will be called after the clock was updated by the original method
             XposedBridge.log("getDeviceId after\n");
             param.getResult();
             param.setResult("luowp");
            }
     });

            //hook static variable with reflect
            Field model = Build.class.getDeclaredField("MODEL");
            model.setAccessible(true);
            model.set(Build.class, "sbsbsb");

    }
}

很简单,我这里hook的是TelephonyManager类的getDeviceId方法,两个重载的方法,before和after分别回调于call原始实现之前和之后,所以我们可以在before方法里面修改参数(param.args)或者在after方法里面修改返回值(param.setResult);
    3.3、告知xposed框架我们的入口类,在assets目录下建一个文件xposed_init,里面用一行com.example.xposedHook.Hook来告知xposed;

然后,安装该木块到手机上,再到xposed的apk上,我们就可以在"模块"下看到我们的模块了,勾选上然后重启(囧:这里就是不断重启手机,比hook so蛋疼多了)。

好了,最后我们写一个测试app来测试下getDeviceId函数是否被成功hook了:

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
InetSocketAddress net = new InetSocketAddress(9000);
int port = net.getPort();

TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String ua = tm.getDeviceId();

hook静态常量

由于xposed是在每个虚拟机启动的时候来执行,因此我们可以借助它+反射机制来完成对系统常量的替换,如上面的代码替换掉了Build.MODEL的值


xposedHook.zip

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值