作者简介:周圣韬,百度高级Android开发工程师,博客地址:http://blog.csdn.net/yzzst

了解Hook

还没有接触过Hook技术读者一定会对Hook一词感觉到特别的陌生,Hook英文翻译过来就是“钩子”的意思,那我们在什么时候使用这个“钩子”呢?

我们知道,在Android操作系统中系统维护着自己的一套事件分发机制。应用程序,包括应用触发事件和后台逻辑处理,也是根据事件流程一步步的向下执行。而“钩子”的意思,就是在事件传送到终点前截获并监控事件的传输,像个钩子勾上事件一样。并且能够在勾上事件时,处理一些自己特定的事件。如下图所示:

Hook的这个本领,使它能够将自身的代码“融入”被勾住(Hook)的程序的进程中,成为目标进程的一个部分。我们也知道,在Android系统中使用了沙箱机制,普通用户程序的进程空间都是独立的,程序的运行彼此间都不受干扰。

这就使我们希望通过一个程序改变其他程序的某些行为的想法不能直接实现,但是Hook的出现给我们开拓了解决此类问题的道路。当然,根据Hook对象与Hook后处理的事件方式不同,Hook还分为不同的种类,如消息Hook、API Hook等。

Cydia Substrate框架

如果使用过苹果手机的用户应该对Cydia Substrate框架来说一点都不会陌生,因为Cydia Substrate框架为苹果用户提供了越狱相关的服务框架。

Cydia Substrate原名MobileSubstrate(类库中都是以MS开头),作者为大名鼎鼎的Jay Freeman(saurik)。

当然,Cydia Substrate也推出了Android版。Cydia Substrate是一个代码修改平台,它可以修改任何主进程的代码,不管是用Java还是C/C++(native代码)编写的。

安装Cydia Substrate框架Android本地服务

首先就是在Android设备中安装Cydia Substrate框架的本地服务应用substrate.apk,我们可以在其官网下载到。

当然,我们安装substrate后,需要“Link Substrate Files”(连接本地的Substrate服务文件),这一步是需要Root权限的,连接后还需要重启设备才能够生效。

下载使用Cydia Substrate库 

Cydia Substrate官方建议在Android SDK Manager中添加它们插件地址的方式进行更新下载。如:在用户自定义网址中添加http://asdk.cydiasubstrate.com/addon.xml

通过使用Android SDK Manager工具下载完Cydia Substrate框架后,其存储于目录${ANDROID_HOME}\sdk\extras\saurikit\cydia_substrate下。

但是,由于Android SDK Manager在国内使用起来存在很多的限制,下载的时候也不是非常稳定,所以还是建议大家直接去官网下载开发库。

下载完成后,将得到的所有文件(很多的jar包与so库),都拷贝都Android项目下的libs文件夹中,就可以直接使用了。其中的substrate.h头文件与lib文件夹下的so文件是提供在使用NDK进行原生Hook程序开发中的函数支持库。

TIPS:Cydia Substrate框架对于inline Hook的操作目前还是存在一些bug,使用的时候可能会出现崩溃的现象,部分使用了国内定制的ROM的设备在使用Cydia Substrate框架时会造成设备无法重新启动或无法Hook的现象。

Cydia Substrate怎么用?

Cydia Substrate怎么用?其实很简单,Cydia Substrate提供了三个静态的方法工具类,我们只需要学会使用它就好 。

  1. MS.hookClassLoad    拿到指定Class载入时的通知
  2. MS.hookMethod   使用一个Java方法去替换另一个Java方法
  3. 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);

开始实战(广告注入)

听到这个题目,我估计很多打包党也已经迫不及待了,稍安勿躁。靠广告是赚不了大钱的,笔者也是一个打包党。程序员还是以成长发展为主,一时的快钱带会让你在编程的路上越走越远。

回到正题,使用Cydia Substrate框架我们能够任意的Hook系统中的Java API,当然其中也用到了很多的反射机制,那么除了系统中给开发者提供的API以外,我们能否也Hook应用程序中的一些方法呢?答案是肯定的。下面我们就以一个实际的例子讲解一下如何Hook一个应用程序。

下面我们针对Android操作系统的浏览器应用,Hook其首页Activity的onCreate方法(其他方法不一定存在,但是onCreate方法一定会有),并在其中注入我们的广告。根据上面对Cydia Substrate的介绍,我们有了一个简单的思路。

首先,我们根据某广告平台的规定,在我们的AndroidManifest.xml文件中填入一些广告相关的ID。并且在AndroidManifest.xml文件中填写一些使用Cydia Substrate相关的配置与权限。当然,我们还会声明一个广告的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>

对于Cydia Substrate的主入口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,那么对于移动设备用户来说是极具欺骗性的。

写在最后

其实我不想发这篇文章,我做过广告打包党,深知这又为各个地下掘金的打包党提供了思路。但,Cydia Substrate不仅仅是为了对广告进行注入而生,希望大家多多挖掘思路,以共同学习提升为主。

Android上玩玩Hook:Cydia Substrate实战的更多相关文章

  1. Android上玩玩Hook?

    在中国互联网这片弱肉强食的丛林中.封闭抄袭是垄断巨头的通行证.创新是弱小创业者的墓志铭. 了解Hook 还没有接触过Hook技术读者一定会对Hook一词感觉到特别的陌生.Hook英文翻译过来就是&qu ...

  2. 使用Cydia Substrate 从Native Hook Android Native世界

    同系列文章: 使用Cydia Substrate 从Native Hook Android Java世界 使用Cydia Substrate Hook Android Java世界 一.建立工程 手机 ...

  3. 利用Cydia Substrate进行Android HOOK(二)

    在前面关于Substrate的介绍中我们已经讲了用Substrate hook java代码,现在我们讲下怎么用它hook native代码.hook native代码我们需要编写Substrate ...

  4. 使用Cydia Substrate 从Native Hook Android Java世界

    这里介绍了如何使用Cydia Substrate Hook安卓Java世界.这篇文章介绍如何从Native中Hook 安卓Java世界. 手机端配置见之前文章. 一.建立工程 建立一个Android工 ...

  5. 利用Cydia Substrate进行Android HOOK

    Cydia Substrate是一个代码修改平台.它可以修改任何主进程的代码,不管是用Java还是C/C++(native代码)编写的.而Xposed只支持HOOK app_process中的java ...

  6. Android逆向之旅---Native层的Hook神器Cydia Substrate使用详解

    一.前言 在之前已经介绍过了Android中一款hook神器Xposed,那个框架使用非常简单,方法也就那几个,其实最主要的是我们如何找到一个想要hook的应用的那个突破点.需要逆向分析app即可.不 ...

  7. Android HOOK工具Cydia Substrate使用详解

    目录(?)[+] Substrate几个重要API介绍 MShookClassLoad MShookMethod 使用方法 短信监控实例   Cydia Substrate是一个代码修改平台.它可以修 ...

  8. 使用Cydia Substrate Hook Android Java世界

    从来没接触过Android的HOOK,在看雪上找到了一篇HOOK 的文章,但是太复杂了,应该是本地环境问题,测试不成功. 后来搜到Cydia Substrate,看了几篇文章,进入官网查看了一下文档, ...

  9. Android 上传开源项目到 jcenter 实战踩坑之路

    本文微信公众号「AndroidTraveler」首发. 背景 其实 Android 上传开源项目到 jcenter 并不是一件新鲜事,网上也有很多文章. 包括我本人在将开源项目上传到 jcenter ...

随机推荐

  1. Ignatius and the Princess III - 拆分数-动态规划(dp)

    ---恢复内容开始--- 2017-08-10 20:00:45 writer:pprp 拆分数: 把正整数n拆分成k个正整数之和的方案数: 问题转换:将1转化为2 1.把n表示成m个正整数之和的方案 ...

  2. nodejs request-promise 请求返回中文乱码

    nodejs request-promise 请求返回中文乱码 解决方法: 具体步骤如下: 1. 引用iconv-lite 进行转码. 2. 请求时要写参数:encoding:null 3. 对bod ...

  3. 使用js合并table中的单元格

    用primefaces做的报表,领导要求合并相同内容的单元格,但是primefaces没有找到可以合并单元格的组件,想来想去,只有页面加载后用js合并了. http://blog.csdn.net/d ...

  4. 解决Eclipse Maven插件的最佳方案

    最近在尝试使用GAE,要求项目必须使用Maven,于是下载了Maven3.1.1配置了环境变量.但是在为Eclipse EE安装Maven插件的时候遇到了问题. 官网的建议是: 在Eclipse EE ...

  5. 浅谈NodeJs的模块机制

    J历史 我们都知道,js在刚被创建的时候,只是为了在网页上写一些小脚本而已,比如网页特效,表单验证等等,创立者也许没觉悟到以后的js会发展到如此规模.这是web1.0时代. 在web 2.0时代,各种 ...

  6. SQL使用CASE 语句

    CASE 语句可以在SELECT 子句和ORDER BY 子句中使用 CASE语句分为两种Case Simple Expression and Case Search Expression Case ...

  7. vs2012 在调试或运行的过程中不能加断点

    在使用VS2012 的过程中,突然发现在调试的过程中,不能加断点,显示断点未能绑定.在搜寻了很多解决方案后未能解决,3.23这一天,重装了VS也没有用. 便想着把网上所有的方法都试个遍也要解决这个问题 ...

  8. 项目使用文档管理:MediaWiki安装及使用入门

    MediaWiki是著名的开源wiki引擎,全球最大的wiki项目维基百科(百科词条协作系统)是使用MediaWiki的成功范例,MediaWiki的最大作用在于对知识的归档,可用于构建企业/个人知识 ...

  9. rabbitmq&&erlang 安装

    # yum install epel-release CentOS and Red Hat Enterprise Linux 6.x wget https://dl.fedoraproject.org ...

  10. IceScrum敏捷开发工具的安装文档-官方最新版

    Welcome to the iceScrum iceScrum install guide. If you don’t want to manage your own iceScrum instal ...