Android Hook技术
原文:http://blog.csdn.net/u011068702/article/details/53208825
附:Android Hook 全面入侵监听器
第一步、先爆项目demo照片,代码不多,不要怕
第二步、应该知道Java反射相关知识
第三步、应该知道Java静态代理知识
第四部、应该知道Java动态代理知识
第五步、应该知道Android里面的ActivityThread类和Instrumentation类
第六步、理解hook,并且分析源码
1、hook一般在哪里hook?
2、我们hook startActivity,分析startActivity到底是怎么实现的
我们每次Context.startActivity,由于Context的实现实际上是ContextImpl来实现的,;我们看ConetxtImpl类的startActivity方法:
- @Override
- public void startActivity(Intent intent, Bundle options) {
- warnIfCallingFromSystemProcess();
- if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
- throw new AndroidRuntimeException(
- "Calling startActivity() from outside of an Activity "
- + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
- + " Is this really what you want?");
- }
- mMainThread.getInstrumentation().execStartActivity(
- getOuterContext(), mMainThread.getApplicationThread(), null,
- (Activity)null, intent, -1, options);
- }
我们可以看到startActivity方法最后还是通过Instrumentation对象来执行execStartActivity来实现的,如果你认真看了《Android插件化开发之AMS与应用程序(客户端ActivityThread、Instrumentation、Activity)通信模型分析 》上面这篇博客,我们知道ActivityThread就是主线程,也就是我们常说的UI线程,可以去更新UI,一个进程只有一个主线程,我们可以在这里hook.
我们需要Hook掉我们的主线程对象,把主线程对象里面的mInstrumentation给替换成我们修改过的代理对象;要替换主线程对象里面的字段
- // 先获取到当前的ActivityThread对象
- Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");
- Method currentActivityThreadMethod = activityThreadClass.getDeclaredMethod("currentActivityThread");
- currentActivityThreadMethod.setAccessible(true);
- Object currentActivityThread = currentActivityThreadMethod.invoke(null);
2)拿到这个currentActivityThread之后,我们需要修改它的mInstrumentation这个字段为我们的代理对象,我们先实现这个代理对象,由于JDK动态代理只支持接口,而这个Instrumentation是一个类,我们可以手动写静态代理类,覆盖掉原始的方法,代码如下
- package com.example.hookstartactivity;
- import java.lang.reflect.Method;
- import android.app.Activity;
- import android.app.Instrumentation;
- import android.app.Instrumentation.ActivityResult;
- import android.content.Context;
- import android.content.Intent;
- import android.os.Bundle;
- import android.os.IBinder;
- import android.util.Log;
- public class InstrumentationProxy extends Instrumentation {
- public static final String TAG = "InstrumentationProxy";
- public static final String EXEC_START_ACTIVITY = "execStartActivity";
- // ActivityThread里面原始的Instrumentation对象,这里千万不能写成mInstrumentation,这样写
- //抛出异常,已亲测试,所以这个地方就要注意了
- public Instrumentation oldInstrumentation;
- //通过构造函数来传递对象
- public InstrumentationProxy(Instrumentation mInstrumentation) {
- oldInstrumentation = mInstrumentation;
- }
- //这个方法是由于原始方法里面的Instrumentation有execStartActivity方法来定的
- public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target,
- Intent intent, int requestCode, Bundle options) {
- Log.d(TAG, "\n打印调用startActivity相关参数: \n" + "who = [" + who + "], " +
- "\ncontextThread = [" + contextThread + "], \ntoken = [" + token + "], " +
- "\ntarget = [" + target + "], \nintent = [" + intent +
- "], \nrequestCode = [" + requestCode + "], \noptions = [" + options + "]");
- Log.i(TAG, "------------hook success------------->");
- Log.i(TAG, "这里可以做你在打开StartActivity方法之前的事情");
- Log.i(TAG, "------------hook success------------->");
- Log.i(TAG, "");
- //由于这个方法是隐藏的,所以需要反射来调用,先找到这方法
- try {
- Method execStartActivity = Instrumentation.class.getDeclaredMethod(
- EXEC_START_ACTIVITY,
- Context.class, IBinder.class, IBinder.class, Activity.class,
- Intent.class, int.class, Bundle.class);
- execStartActivity.setAccessible(true);
- return (ActivityResult) execStartActivity.invoke(oldInstrumentation, who,
- contextThread, token, target, intent, requestCode, options);
- } catch (Exception e) {
- //如果你在这个类的成员变量Instrumentation的实例写错mInstrument,代码讲会执行到这里来
- throw new RuntimeException("if Instrumentation paramerter is mInstrumentation, hook will fail");
- }
- }
- }
3)然后用代理对象替换,代码如下
- package com.example.hookstartactivity;
- import java.lang.reflect.Field;
- import java.lang.reflect.Method;
- import android.app.Application;
- import android.app.Instrumentation;
- import android.util.Log;
- public class MyApplication extends Application {
- public static final String TAG = "MyApplication";
- public static final String ACTIVIT_THREAD = "android.app.ActivityThread";
- public static final String CURRENT_ACTIVITY_THREAD = "currentActivityThread";
- public static final String INSTRUMENTATION = "mInstrumentation";
- @Override
- public void onCreate() {
- try {
- //这个方法一般是写在Application的oncreate函数里面,如果你写在activity里面的oncrate函数里面就已经晚了
- attachContext();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- public static void attachContext() throws Exception{
- //获取当前的ActivityThread对象
- Class<?> activityThreadClass = Class.forName(ACTIVIT_THREAD);
- Method currentActivityThreadMethod = activityThreadClass.getDeclaredMethod(CURRENT_ACTIVITY_THREAD);
- currentActivityThreadMethod.setAccessible(true);
- Object currentActivityThread = currentActivityThreadMethod.invoke(null);
- //拿到在ActivityThread类里面的原始mInstrumentation对象
- Field mInstrumentationField = activityThreadClass.getDeclaredField(INSTRUMENTATION);
- mInstrumentationField.setAccessible(true);
- Instrumentation mInstrumentation = (Instrumentation) mInstrumentationField.get(currentActivityThread);
- //构建我们的代理对象
- Instrumentation evilInstrumentation = new InstrumentationProxy(mInstrumentation);
- //通过反射,换掉字段,注意,这里是反射的代码,不是Instrumentation里面的方法
- mInstrumentationField.set(currentActivityThread, evilInstrumentation);
- //做个标记,方便后面查看
- Log.i(TAG, "has go in MyApplication attachContext method");
- }
- }
要注意这个替换要在Application里面的oncreate方法里面去执行,如果到Activity方法里面去执行的话就晚了,程序不会报错,但是hook不到。
然后我是在主页面写了一个按钮,点击来触发startActivity的。
MainActivity.java 文件如下
- package com.example.hookstartactivity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.support.v7.app.ActionBarActivity;
- import android.util.Log;
- import android.view.Menu;
- import android.view.MenuItem;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.TextView;
- public class MainActivity extends ActionBarActivity {
- public static final String TAG = "MainActivity";
- public TextView tv;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- tv = (TextView)findViewById(R.id.start);
- tv.setOnClickListener(new OnClickListener(){
- @Override
- public void onClick(View v) {
- try {
- Intent intent = new Intent(MainActivity.this, SecondActivity.class);
- Bundle bundle = new Bundle();
- Log.i(TAG, "-------------------------------->");
- Log.i(TAG, "startActivity before");
- Log.i(TAG, "-------------------------------->");
- startActivity(intent, bundle);
- Log.i(TAG, "-------------------------------->");
- Log.i(TAG, "startActivity after");
- Log.i(TAG, "-------------------------------->");
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- } );
- }
- }
跳转到的Second.java文件如下
- package com.example.hookstartactivity;
- import android.os.Bundle;
- import android.support.v7.app.ActionBarActivity;
- public class SecondActivity extends ActionBarActivity{
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_second);
- }
- }
第七步、运行代码
- pidcat.py 包名
第八步、总结
Android Hook技术的更多相关文章
- Android so注入(inject)和Hook技术学习(三)——Got表hook之导出表hook
前文介绍了导入表hook,现在来说下导出表的hook.导出表的hook的流程如下.1.获取动态库基值 void* get_module_base(pid_t pid, const char* modu ...
- Android Native Hook技术(二)
Hook技术应用 已经介绍了安卓 Native hook 原理,这里介绍 hook 技术的应用,及 Cyida Substrate 框架. 分析某APP,发现其POST请求数据经过加密,我们希望还原其 ...
- Android Native Hook技术(一)
原理分析 ADBI是一个著名的安卓平台hook框架,基于 动态库注入 与 inline hook 技术实现.该框架主要由2个模块构成:1)hijack负责将so注入到目标进程空间,2)libbase是 ...
- Hook技术
hook钩子: 使用技术手段在运行时动态的将额外代码依附现进程,从而实现替换现有处理逻辑或插入额外功能的目的. 它的技术实现要点有两个: 1)如何注入代码(如何将额外代码依附于现有代码中). 2)如何 ...
- Android官方技术文档翻译——新构建系统概述
本文译自Android官方技术文档<New Build System>,原文地址:http://tools.android.com/tech-docs/new-build-system. ...
- Android Hook框架adbi源码浅析(一)
adbi(The Android Dynamic Binary Instrumentation Toolkit)是一个Android平台通用hook框架,基于动态库注入与inline hook技术实现 ...
- 20145307陈俊达_安卓逆向分析_Xposed的hook技术研究
20145307陈俊达_安卓逆向分析_Xposed的hook技术研究 引言 其实这份我早就想写了,xposed这个东西我在安卓SDK 4.4.4的时候就在玩了,root后安装架构,起初是为了实现一些屌 ...
- Android Hook神器:XPosed入门与登陆劫持演示
前段时间写了一篇关于Cydia Substrate广告注入的文章,大家都直呼过瘾.但是,真正了解这一方面的同学应该知道,其实还有一个比Cydia Substrate更出名的工具:XPosed. 不是因 ...
- android hook 框架 ADBI 如何实现so函数挂钩
上一篇 android 5 HOOK 技术研究之 ADBI 项目 02 分析了hijack.c, 这个文件编译为一个可执行程序 hijack, 该程序实现了向目标进程注入一个动态库的功能.这一篇继续研 ...
随机推荐
- 关于i++引出的线程不安全性的分析以及解决措施
Q:i++是线程安全的吗? A:如果是局部变量,那么i++是线程安全. 如果是全局变量,那么i++不是线程安全的. 理由:如果是局部变量,那么i++是线程安全:局部变量其他线程访问不到,所以根本不存在 ...
- DNS原理及其解析过程 精彩剖析
本文章转自下面:http://369369.blog.51cto.com/319630/812889 DNS原理及其解析过程 精彩剖析 网络通讯大部分是基于TCP/IP的,而TCP/IP是基于IP地址 ...
- js对象和继承总结
创建对象方式: [工厂模式]:无法解决对象识别问题 [构造函数模式]:每个方法都要在每个实例上创建一遍 [原型模式]:原型上属性为引用类型的问题,见例子 [组合模式]:解决上述问题 [动态原型模式]: ...
- javascript操作系统检测
function detectOS() { var sUserAgent = navigator.userAgent;console.log(sUserAgent); var isWin = (nav ...
- 全国SHP地图数据赠送
百度搜索:GIS之家获取全国SHP图层数据的方式:收藏(ArcGIS地图全国电子地图shp格式版本GIS地图数据.GIS开发顺德政府GIS公共服务共享平台),并且截图验证,验证通过后,收下邮箱,我把下 ...
- android textview 自动换行 整齐排版
一.问题在哪里? textview显示长文字时会进行自动折行,如果遇到一些特殊情况,自动折行会杯具成这个样子: 上述特殊情况包括: 1)全角/半角符号混排(一般是数字.字母.汉字混排) 2)全角/半角 ...
- iOS App之间跳转
1.先来看看效果,这里做了三个功能 从MyApp跳转到YourApp 从MyApp跳转到YourApp的指定页面 从YourApp使用跳转url的方式跳回MyApp 2.实现app之间的跳转需要注意两 ...
- response和request的区别以及常见问题解决
request是请求,即客服端发来的请求 response是响应,是服务器做出的响应 --------------------------------------------------------- ...
- 5、项目间的沟通协调 - PMO项目管理办公室
沟通是人类所具备的优良而有一定技巧的一种方式.但是,沟通也是PMO项目管理办公室中所有项目组必须建立起来的能力,也是PMO项目管理办公室日常所需要进行的一项工作内容. 一.项目间的沟通: PMO项目管 ...
- kmeans算法并行化的mpi程序
用c语言写了kmeans算法的串行程序,再用mpi来写并行版的,貌似参照着串行版来写并行版,效果不是很赏心悦目~ 并行化思路: 使用主从模式.由一个节点充当主节点负责数据的划分与分配,其他节点完成本地 ...