android上的简单hook
2016-02-06 20:21
579 查看
cydia substrate目前也支持android了,cydia substrate是一个代码修改平台。它可以修改任何主进程的代码,官方网址:http://www.cydiasubstrate.com/
1. root你的手机
2. 下载官方的apk,并且安装进手机,点击运行,点击按钮,允许操作。
3. 更新sdk
http://asdk.cydiasubstrate.com/addon.xml
添加完成之后,在extra下回多了一个选项,点击勾选下载
下载完成之后,会在sdk/extra目录下生成我们需要的文件:
MS.hookClassLoad
- MS.hookMethod
添加meta标签,name为cydia.permission.SUBSTRATE,value为自己接下来创建的类名.Main
这里由于不需要acitivity,所以讲manifest中额activity相关配置全部删除。如下:
运行,安装当前组件,重启手机,效果如下:
可以发现整个手机系统都已经改变为红色的字体了。
这里只有用户名为zhangsan以及密码为123,时候,才返回true,即表示登录成功,否则返回false。
同样在Main类的initialize方法里,增加一个hookClassLoad方法,来hook当前登录的activity
这里的checklogin是刚才登录逻辑的判断,这里,在hook之后横返回true,也就是无论如何都会登录成功,效果如下:
首先,需要知道如何通过代码获取IMEI值
代码:
这里更改的android.telephony.TelephonyManager类下的getDeviceId方法。
此时我们通过:
获得的就是aaaaaaaaaa了
在adb shell下可以通过如下代码启动activity
完整代码:
此时效果如下:
ok,可以看到,到目前为止,已经完成了我们想要的效果了。但是还是有很多限制最大的就是手机必须要有root权限,在5.0之后的版本已经不能使用。
源码下载
准备活动
在正式学习之前,需要做如下准备:1. root你的手机
2. 下载官方的apk,并且安装进手机,点击运行,点击按钮,允许操作。
3. 更新sdk
更新sdk
打开sdkmanagerhttp://asdk.cydiasubstrate.com/addon.xml
添加完成之后,在extra下回多了一个选项,点击勾选下载
下载完成之后,会在sdk/extra目录下生成我们需要的文件:
API介绍
在正式开始之前,我们先来学习下cydia中重要的api。MS.hookClassLoad
//该方法实现在指定的类被加载的时候发出通知 void hookClassLoad(String name, MS.ClassLoadHook hook);
参数 | 描述 |
---|---|
name | 包名+类名,使用java的.符号 |
hook | MS.ClassLoadHook的一个实例,当这个类被加载的时候,它的 classLoaded 方法会被执行。 |
//该API允许开发者提供一个回调函数替换原来的方法,这个回调函数是一个实现了MS.MethodHook接口的对象,是一个典型的匿名内部类。它包含一个invoked函数 void hookMethod(Class _class, Member member, MS.MethodHook hook, MS.MethodPointer old);
参数 | 描述 |
---|---|
_class | 加载的目标类,为classLoaded传下来的类参数 |
member | 通过反射得到的需要hook的方法(或构造函数)。不能够hook字段 |
hook | MS.MethodHook的一个实例,其包含的invoked方法会被调用,用以代替member中的代码 |
创建android工程
添加jar文件
将SDK中的substrate-api.jar更改AndroidManifest.xml
添加cydia.permission.SUBSTRATE权限添加meta标签,name为cydia.permission.SUBSTRATE,value为自己接下来创建的类名.Main
这里由于不需要acitivity,所以讲manifest中额activity相关配置全部删除。如下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.rectnativetest"> <application> <meta-data android:name="com.saurik.substrate.main" android:value=".Main"/> </application> <uses-permission android:name="cydia.permission.SUBSTRATE"/> </manifest>
创建Main.java
接下来就是创建Main.java,并且需要包含一个static void initialize()方法。// 当插件被加载的时候,该方法中的代码就会运行 static void initialize() {}
获取目标类的实例
这里我们按照官网上给出的栗子,hook类android.content.res.ResourcesMS.hookClassLoad("android.content.res.Resources", new MS.ClassLoadHook() { public void classLoaded(Class<?> resources) { } });
通过MS.MethodHook更改源代码
这里更改android.content.res.Resources类的getColor方法的返回值,将其返回红色。Method getColor; try { 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); }
运行,安装当前组件,重启手机,效果如下:
可以发现整个手机系统都已经改变为红色的字体了。
Hook登录方法
这里,我自己写了一个简单应用,只有登录功能,逻辑如下:if (name.equals("zhangsan") && pass.equals("123")) { return true; } else { return false; }
这里只有用户名为zhangsan以及密码为123,时候,才返回true,即表示登录成功,否则返回false。
同样在Main类的initialize方法里,增加一个hookClassLoad方法,来hook当前登录的activity
MS.hookClassLoad("reacthello.myapplication.MainActivity", new MS.ClassLoadHook() { public void classLoaded(Class<?> resources) { Method checkLogin; try { checkLogin = resources.getMethod("checkLogin", new Class[]{String.class,String.class}); } catch (NoSuchMethodException e) { checkLogin = null; } if (checkLogin != null) { final MS.MethodPointer old = new MS.MethodPointer(); MS.hookMethod(resources, checkLogin, new MS.MethodHook() { public Object invoked(Object resources, Object... args) throws Throwable { return true; } }, old); } } });
这里的checklogin是刚才登录逻辑的判断,这里,在hook之后横返回true,也就是无论如何都会登录成功,效果如下:
更改系统Imei的值
现在大家应该都已经知道了可以通过hookClassLoad和hookMethod来更改指定方法运行的代码,以及返回值。现在我们来更改一下手机系统的IMEI值。首先,需要知道如何通过代码获取IMEI值
android.telephony.TelephonyManager.getDeviceId();
代码:
MS.hookClassLoad("android.telephony.TelephonyManager", new MS.ClassLoadHook() { public void classLoaded(Class<?> resources) { Method getDeviceId; try { getDeviceId = resources.getMethod("getDeviceId",null); } catch (NoSuchMethodException e) { getDeviceId = null; } if (getDeviceId != null) { final MS.MethodPointer old = new MS.MethodPointer(); MS.hookMethod(resources, getDeviceId, new MS.MethodHook() { public Object invoked(Object resources, Object... args) throws Throwable { String imei = (String)old.invoke(resources, args); imei = "aaaaaaaaaaaaaaa"; return imei; } }, old); } } });
这里更改的android.telephony.TelephonyManager类下的getDeviceId方法。
此时我们通过:
String imei = telephonyManager.getDeviceId(); Toast.makeText(MainActivity.this,"imei is :"+imei,Toast.LENGTH_SHORT).show();
获得的就是aaaaaaaaaa了
实现应用拦截
最后一次尝试一下当我打开一个应用的时候,自动打开一个毫不相干的应用,比如当我每次打开今日头条的时候,系统会跳转到网易新闻,首先我们需要知道“今日头条”和”网易新闻”的主界面的activity,使用如下命令可以获得当前界面的activity:dumpsys activity | grep mFocusedActivity
在adb shell下可以通过如下代码启动activity
Runtime.getRuntime().exec("am start -n com.netease.newsreader.activity/com.netease.nr.biz.ad.AdActivity");
完整代码:
MS.hookClassLoad("com.ss.android.article.news.activity.MainActivity", new MS.ClassLoadHook() { public void classLoaded(Class<?> resources) { Log.d("hookstart","com.ss.android.article.news.activity.MainActivity loaded"); Method onCreate; try { onCreate = resources.getMethod("onCreate",Bundle.class); } catch (NoSuchMethodException e) { onCreate = null; } if (onCreate != null) { final MS.MethodPointer old = new MS.MethodPointer(); MS.hookMethod(resources, onCreate, new MS.MethodHook() { public Object invoked(Object resources, Object... args) throws Throwable { Log.d("hang.liu","the ooooooo"); Object object = old.invoke(resources, args); try { Log.d("hookstart","onCreate hooked."); Runtime.getRuntime().exec("am start -n com.netease.newsreader.activity/com.netease.nr.biz.ad.AdActivity"); } catch (Exception e) { Log.d("hookstart","start activity exception happend..."); } return object; } }, old); } } });
此时效果如下:
ok,可以看到,到目前为止,已经完成了我们想要的效果了。但是还是有很多限制最大的就是手机必须要有root权限,在5.0之后的版本已经不能使用。
源码下载
相关文章推荐
- Android Learning:多线程与异步消息处理机制
- android日常开发60条经验
- 王学岗高级控件滚动视图(一)
- android数据存储的四种方案(一)
- ubuntu14.04中搭建qt for android环境
- Android中Nine-Patch(.9)图片介绍与制作
- Android使用序列化接口Parcelable、Serializable
- Android 内核常见目录的作用
- Android 内核常见目录的作用
- Android 内核常见目录的作用
- Android 内核常见目录的作用
- Android 实战之: 去除安卓应用启动前闪烁的黑屏或白屏效果
- 安卓开发——获取Android数字签名证书的SHA1值
- android项目 之 记事本(12) ----- 图片的等比例缩放及给图片加入边框
- Android 推断当前Activity是不是最后一个Activity 以及 应用或Activity是否存在
- android经常使用的电话操作
- Android 性能优化 三 布局优化ViewStub标签的使用
- Android ListView 的优化使用
- Android Material Design II-自定义动画
- Android学习笔记(十五)——碎片的生命周期(附源代码)