Android上玩玩Hook?
在中国互联网这片弱肉强食的丛林中。封闭抄袭是垄断巨头的通行证。创新是弱小创业者的墓志铭。
了解Hook
还没有接触过Hook技术读者一定会对Hook一词感觉到特别的陌生。Hook英文翻译过来就是“钩子”的意思,那我们在什么时候使用这个“钩子”呢?
我们知道,在Android操作系统中系统维护着自己的一套事件分发机制。
应用程序,包括应用触发事件和后台逻辑处理,也是依据事件流程一步步的向下运行。
而“钩子”的意思,就是在事件传送到终点前截获并监控事件的传输,像个钩子勾上事件一样。
而且可以在勾上事件时,处理一些自己特定的事件。
例如以下图所看到的:
Hook的这个本领。使它可以将自身的代码“融入”被勾住(Hook)的程序的进程中,成为目标进程的一个部分。
我们也知道,在Android系统中使用了沙箱机制,普通用户程序的进程空间都是独立的。程序的运行彼此间都不受干扰。
这就使我们希望通过一个程序改变其它程序的某些行为的想法不能直接实现。可是Hook的出现给我们开拓了解决此类问题的道路。当然。依据Hook对象与Hook后处理的事件方式不同。Hook还分为不同的种类,如消息Hook、API Hook等。
CydiaSubstrate框架
假设使用过苹果手机的用户应该对Cydiasubstrate框架来说一点都不会陌生,由于Cydiasubstrate框架为苹果用户提供了越狱相关的服务框架。
Cydiasubstrate原名MobileSubstrate(类库中都是以MS开头),作者为大名鼎鼎的Jay Freeman(saurik)。
当然 Cydiasubstrate 也推出了 Android版。Cydia Substrate是一个代码改动平台。它可以改动不论什么主进程的代码。无论是用Java还是C/C++(native代码)编写的。
官网地址:http://www.cydiasubstrate.com/。
安装Cydiastrate框架Android本地服务
首先就是在Android设备中安装Cydiasubstrate框架的本地服务应用substrate.apk。我们可以再其官网下载到。
官方下载地址为:http://www.cydiasubstrate.com/download/com.saurik.substrate.apk
当然。我们安装substrate后,须要“Link Substrate Files”(连接本地的Substrate服务文件),这一步是须要Root权限的,连接后还须要重新启动设备才可以生效。
下载使用Cydiasubstrate库
Cydiasubstrate官方建议在Android SDK Manager中加入它们插件地址的方式进行更新下载。
如:在用户自己定义网址中加入http://asdk.cydiasubstrate.com/addon.xml。
通过使用Android SDK Manager工具下载完Cydiasubstrate框架后,其存储于目录${ANDROID_HOME}\sdk\extras\saurikit\cydia_substrate下。
可是,由于Android SDK Manager在国内使用起来存在非常多的限制,下载的时候也不是非常稳定。所以还是建议大家直接去官网下载开发库。
官方下载地址为:http://asdk.cydiasubstrate.com/zips/cydia_substrate-r2.zip。
下载完毕后,将得到的全部文件(非常多的jar包与so库),都拷贝都Android项目下的libs目录中。就行直接使用了。
当中的substrate.h头文件与lib目录下的so文件是提供在使用NDK进行原生Hook程序开发中的函数支持库。
TIPS:CydiaSubstrate框架对于inline Hook的操作眼下还是存在一些bug,使用的时候可能会出现崩溃的现象,部分使用了国内定制的ROM的设备在使用CydiaSubstrate框架时会造成设备无法又一次启动或无法Hook的现象。
CydiaSubstrate怎么用?
CydiaSubstrate怎么用?事实上非常easy,CydiaSubstrate提供了三个静态的方法工具类,我们仅仅须要学会使用它就好 。
MS.hookClassLoad 拿到指定Class加载时的通知
MS.hookMethod 使用一个Java方法去替换还有一个Java方法
MS.moveUnderClassLoader 使用不同的ClassLoder重载对象
详细说明例如以下:
/**
* Hook一个指定的Class
*
* @param name Class的包名+类名,如android.content.res.Resources
* @param hook 成功Hook一个Class后的回调
*/
void hookClassLoad(String name, MS.ClassLoadHook hook);
/**
* Hook一个指定的方法,并替换方法中的代码
*
* @param _class Hook的calss
* @param member Hook class的方法參数
* @param hook 成功Hook方法后的回调
* @param old Hook前方法,相似C中的方法指针
*/
void hookMethod(Class _class, Member member, MS.MethodHook hook, MS.MethodPointer old);
/**
* Hook一个指定的方法。并替换方法中的代码
*
* @param _class Hook的calss
* @param member Hook class的方法參数
* @param alteration
*/
void hookMethod(Class _class, Member member, MS.MethodAlteration alteration);
/**
* 使用一个ClassLoader重载一个对象
*
* @param loader 使用的ClassLoader
* @param object 带重载的对象
* @return 重载后的对象
*/
<T> T moveUnderClassLoader(ClassLoader loader, T object);
開始实战(广告注入)
听到这个题目。我预计非常多打包党也已经迫不及待了。稍安勿躁。
靠广告是赚不了大钱的,笔者也是一个打包党。程序猿还是以成长发展为主。一时的快钱带会让你在编程的路上越走越远。
回到正题。使用Cydiasubstrate框架我们可以随意的Hook系统中的Java API。当然当中也用到了非常多的反射机制,那么除了系统中给开发人员提供的API以外,我们是否能也Hook应用程序中的一些方法呢?答案是肯定的。
以下我们就以一个实际的样例解说一下怎样Hook一个应用程序。
以下我们针对Android操作系统的浏览器应用。Hook其首页Activity的onCreate方法(其它方法不一定存在,可是onCreate方法一定会有)。并在当中注入我们的广告。依据上面对Cydiasubstrate的介绍,我们有了一个简单的思路。
首先,我们依据某广告平台的规定,在我们的AndroidManifest.xml文件里填入一些广告相关的ID。而且在AndroidManifest.xml文件里填写一些使用Cydiasubstrate相关的配置与权限。当然,我们还会声明一个广告的Activity。并设置此Activity为背景透明的Activity,为什么设置透明背景的Activity,例如以下图:
好了。以下我们就来实操一下。
其AndroidManifest.xml文件的部分内容例如以下所看到的:
<!-- 广告相关的权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.GET_TASKS" />
<!-- 加入substrate权限 -->
<uses-permission android:name="cydia.permission.SUBSTRATE" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<!-- 广告相关參数 -->
<meta-data
android:name="APP_ID"
android:value="c62bd976138fa4f2ec853bb408bb38af" />
<meta-data
android:name="APP_PID"
android:value="DEFAULT" />
<!-- 声明substrate的注入口味Main类 -->
<meta-data
android:name="com.saurik.substrate.main"
android:value="com.example.hookad.Main" />
<!-- 透明无动画的广告Activity -->
<activity
android:name="com.example.hookad.MainActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<!-- 广告的action -->
<action android:name="com.example.hook.AD" />
</intent-filter>
</activity>
</application>
对于Cydiasubstrate的主入口Main类,按照之前的步骤新建一个包括有initialize方法的Main类。
这个时候我们希望使用MS.hookClassLoad方式找到浏览器主页的Activity名称。
这里我们使用adb shell下使用dumpsys activity命令找到浏览器主页的Activity名称为com.android.browser.BrowserActivity。
使用MS.hookClassLoad方法获取了BrowserActivity之后再hook其onCreate方法。在当中启动一个含有广告的Activity。Main类的代码例如以下所看到的:
public class Main {
/**
* substrate 初始化后的入口
*/
static void initialize() {
//Hook 浏览器的主Activity,BrowserActivity
MS.hookClassLoad("com.android.browser.BrowserActivity", new MS.ClassLoadHook() {
public void classLoaded(Class<?> resources) {
Log.e("test", "com.android.browser.BrowserActivity");
// 获取BrowserActivity的onCreate方法
Method onCreate;
try {
onCreate = resources.getMethod("onCreate", Bundle.class);
} catch (NoSuchMethodException e) {
onCreate = null;
}
if (onCreate != null) {
final MS.MethodPointer old = new MS.MethodPointer();
// hook onCreate方法
MS.hookMethod(resources, onCreate, new MS.MethodHook() {
public Object invoked(Object object, Object...args) throws Throwable {
Log.e("test", "show ad");
// 运行Hook前的onCreate方法,保证浏览器正常启动
Object result = old.invoke(object, args);
// 没有Context
// 运行一个shell 启动我们的广告Activity
CMD.run("am start -a com.example.hook.AD");
return result;
}
}, old);
}
}
});
}
}
对于启动的广告MainActivity,在当中就是弹出一个插屏广告。
当然可也可是其它形式的广告或者浮层,内容比較简单这里不做演示了。对整个项目进行编译,运行。
这个时候我们又一次启动Android自带的浏览器的时候发现,浏览器会弹出一个广告弹框。
从上面的图片我们可以看出来了,之前我们设置插屏广告MainActivity为无标题透明(Theme.Translucent.NoTitleBar)就是为了使得弹出来的广告与浏览器融为一体。让用户感觉是浏览器弹出的广告。也是恶意广告程序为了防止自身被卸载掉的一些通用隐藏手段。
这里演示的注入广告是通过Hook指定的Activity中的onCreate方法来启动一个广告Activity。当然。这里我们演示的Activity仅仅是简单的弹出来了一个广告。
假设启动的Activity带有恶意性。如将Activity做得与原Activity一模一样的钓鱼Activity。那么对于移动设备用户来说是极具欺骗性的。
写在之后
事实上我不想发这篇文章,我做过广告打包党,深知这又为各个地下掘金的打包党提供了思路。
但。CydiaSubstrate不仅仅是为了对广告进行注入而生。希望大家多多挖掘思路。以共同学习提升为主。
最后,有兴趣探讨的加我一下微信,大家交交朋友。
/*
* @author zhoushengtao(周圣韬)
* @since 2015年8月6日 16:52:22
* @weixin stchou_zst
* @blog http://blog.csdn.net/yzzst
* @交流学习QQ群:341989536
* @私人QQ:445914891
/
Android上玩玩Hook?的更多相关文章
- Android上玩玩Hook:Cydia Substrate实战
作者简介:周圣韬,百度高级Android开发工程师,博客地址:http://blog.csdn.net/yzzst 了解Hook 还没有接触过Hook技术读者一定会对Hook一词感觉到特别的陌生,Ho ...
- android免root hook框架legend
一.前言 Android中hook框架已经非常多了,最优秀的当属Xposed和Substrate了,这两个框架我在之前的文章都详细介绍过了,不了解的同学,可以转战这里:http://www.wjdia ...
- AOP切面编程在android上的应用
代码地址如下:http://www.demodashi.com/demo/12563.html 前言 切面编程一直是一个热点的话题,这篇文章讲讲一个第三方aop库在android上的应用.第三方AOP ...
- 通杀所有系统的硬件漏洞?聊一聊Drammer,Android上的RowHammer攻击
通杀所有系统的硬件漏洞?聊一聊Drammer,Android上的RowHammer攻击 大家肯定知道前几天刚爆出来一个linux内核(Android也用的linux内核)的dirtycow漏洞.此洞可 ...
- 在Android上使用qemu-user运行可执行文件
在Android上使用qemu-user运行可执行文件 作者:寻禹@阿里聚安全 前言 QEMU简要介绍: QEMU可以解释执行可执行程序.既然QEMU可以解释执行可执行程序,那么QEMU就能够知道执行 ...
- 编译可在Android上运行的qemu user mode
前言 本文在Ubuntu 64位系统上对qemu项目进行交叉编译,并且只编译与qemu user mode有关的代码. 下文中的”NDK”若无特殊说明均指”Android NDK”. 下文中”$NDK ...
- 系列篇|编译可在Android上运行的依赖库(一):glib库
前言 这是系列文章,它们由<编译可在Android上运行的glib库>及其他4篇文章组成,这4篇文章在“编译依赖库”一节中列出.由于glib库依赖于其他第三方库,所以需要先将依赖的第三方库 ...
- EasyTouch绑定事件在电脑上点击有效Android上无效的解决方法
最近做一个RPG类的游戏发现使用EasyTouch虚拟摇杆插件在电脑上点击有效Android上无效,查找资料发现是Easy Joystick中的一个属性interaction type要设置成 Dir ...
- TensorFlow 在android上的Demo(1)
转载时请注明出处: 修雨轩陈 系统环境说明: ------------------------------------ 操作系统 : ubunt 14.03 _ x86_64 操作系统 内存: 8GB ...
随机推荐
- thinkphp 中模型究竟是什么用?
thinkphp 中模型究竟是什么用? 问题 似乎所有的操作都能在控制器中就能完成,模型除了几种验证之外,究竟是干什么用的,这个问题一直没理解透 解答 解答一 要明白这个问题,必须了解 MVC 历史. ...
- Python3基础笔记--装饰器
装饰器是十二分重要的高级函数. 参考博客:装饰器 所需前提知识: 1.作用域: LEGB 2.高阶函数 高阶函数是至少满足下列一个条件的函数: 1)接受一个或多个函数作为输入 2)输出一个函数 注意理 ...
- php八大设计模式之单例模式
单例模式的好处: 实例化后只得到一个对象,减少内存的开销. 实现单例模式: 提供一个私有的属性用来存储实例后的对象. 禁止外部实例化对象,提供公共的的方法,返回实例化后的对象. 避免继承此类,然后重写 ...
- [USACO14FEB]路障Roadblock
题目:洛谷P2176. 题目大意:有n个点m条无向边,一个人要从1走到n,他会走最短路.现在可以让一条边的长度翻倍,求翻倍后这个人要多走多少距离. 解题思路:首先可以知道,翻倍肯定是在最短路上的某条边 ...
- linux指令快速复制粘贴[龟速更新中]
由于有经常碰到要输入linux指令,但是却忘记了的情况.在家里我把常用的命令放到Xshell的快速命令集,但是在很多情况下不在家,可能用的他人电脑,以及在非Win环境下使用ssh时没有xshell使用 ...
- uptime---系统总共运行时间和系统的平均负载
uptime命令能够打印系统总共运行了多长时间和系统的平均负载.uptime命令可以显示的信息显示依次为:现在时间.系统已经运行了多长时间.目前有多少登陆用户.系统在过去的1分钟.5分钟和15分钟内的 ...
- Spring-boot非Mock测试MVC,调试启动tomcat容器
平常我们在使用spring-boot去debug一个web应用时,通常会使用MockMvc. 如下配置: @RunWith(value = SpringRunner.class) @SpringBoo ...
- Snail—UI学习之导航视图控制器UINavigationController(系统)
背景 有一个根视图控制器 然后跳转到第一个界面 第一个界面能够返回到根视图 也能够跳转到第二个视图 第二个视图能够直接返回到根视图 新建三个ViewController RootViewCon ...
- Codeforces Round #105 (Div. 2) 148C Terse princess(脑洞)
C. Terse princess time limit per test 1 second memory limit per test 256 megabytes input standard in ...
- Exchange2003迁移2010DAG的权限问题
exchange2010无法删除用户.在2010的控制台中新建一个通讯组.然后将它删除就会报告下面错误. MicrosoftExchange 错误:无法对对象"test"执行&qu ...