万物皆可Hook!从新捡起Hook神器-Xposed框架

引言

  这个Hook不是邓紫棋要给你唱的Hook哦!而是在程序界流传的强大秘技-Hook函数,Hook原意是指钩子,它表示的就是在某个函数的上下文作自定义的处理来实现咱们想要的黑科技。   在不少技术领域都存在的这种Hook技术,好比下面这些:java

  • PythonWeb框架中,如DjangoFlask都存在这种Hook技术,能够在请求的上下文应用的上下文作自定义操做。android

  • Scrapy框架中,能够自定义MiddlerWare,在请求解析的时候作自定操做。编程

  • K8S编排框架中,咱们也能够在执行某些函数的上下文中插入Hook函数,这也是和Web框架同理   而今天咱们讲解的是关于AndroidHook技术,而有一款神器可以帮助咱们快速地开发Hook模块,也就是Xposed框架。其实网上的关于Xposed模块编写的教程可谓是一抓一大把。但因为时间的推移,不少工具和方法都发生了变化(如Eclipse退出安卓编程舞台,AndroidStudio 不断升级致使其一些设置也随之变化等)也正所以,网上的教程每每有一些时限性,好比现现在 provide 这个关键字已经被舍弃了却仍有人在用,还有些说要把jar包放到lib文件夹而非libs文件夹……种种错误或者落伍的教程对新手产生了很大的误导。以前也搞过一阵子Xposed框架,而今天在从新部署环境的时候参考某些教程的时候也遇到了不少的坑,因此想从新结合最新的配套工具写个小教程,主要讲解的如下两个方面:segmentfault

  • Xposed框架介绍以及原理api

  • Xposed框架实战bash

Xposed框架介绍以及原理

  XposedGithubrovo89大佬设计的一个针对Android平台的动态劫持项目,经过替换/system/bin/app_process程序控制Zygote进程,使得app_process在启动过程当中会加载XposedBridge.jar这个jar包,从而完成对Zygote进程及其建立的Dalvik虚拟机的劫持。   由于Xposed工做原理是在/system/bin目录下替换文件,在install的时候须要root权限,可是运行时不须要root权限。   看到这里不少人会很懵,什么是Zygote?简单来讲在Android系统中,应用程序进程都是由Zygote进程孵化出来的,而Zygote进程是由Init进程启动的。Zygote进程在启动时会建立一个Dalvik虚拟机实例,每当它孵化一个新的应用程序进程时,都会将这个Dalvik虚拟机实例复制到新的应用程序进程里面去,而一个应用程序进程被Zygote进程孵化出来的时候,不只会得到Zygote进程中的Dalvik虚拟机实例拷贝,还会与Zygote一块儿共享Java运行时库。这也就是能够将XposedBridge这个jar包加载到每个Android应用程序中的缘由。XposedBridge有一个私有的Native(JNI)方法hookMethodNative,这个方法也在app_process中使用。这个函数提供一个方法对象利用JavaReflection机制来对内置方法覆写。。。。等等这些都会借鉴各路大神的思路和分析,总而言之,就是从底层替换方法,可让咱们在不修改APK源码的状况下,经过本身编写的模块来影响程序运行的框架服务,实现相似于自动抢红包、微信消息自动回复等功能。   其实,从本质上来说,Xposed模块也是一个Android程序。但与普通程序不一样的是,想要让写出的Android程序成为一个``Xposed 模块,要额外多完成如下四个硬性任务:微信

一、让手机上的xposed框架知道咱们安装的这个程序是个xposed模块。

二、模块里要包含有xposed的API的jar包,以实现下一步的hook操做。

三、这个模块里面要有对目标程序进行hook操做的方法。

四、要让手机上的xposed框架知道,咱们编写的xposed模块中,哪个方法是实现hook操做的。
复制代码

  这就引出我即将要介绍的四大件(与前四步一一对照):网络

一、AndroidManifest.xml

二、XposedBridgeApi-xx.jar 与 build.gradle

三、实现hook操做的具体代码

四、xposed_Init
复制代码

  牢记以上四大件,按照顺序一个一个实现,就能完成咱们的第一个Xposed模块编写。以上的原理咱们大体就介绍这么多,下面咱们实战开始吧!架构

Xposed框架实战

1. 迈开第一步,新建项目并编辑AndroidManifest.xml

  咱们使用的 IDEAndroid Studio,首先打开 AndroidStudio(以版本 3.4.2为例,还在用老版本的请升级),创建一个工程,提示咱们选择“ Activity”,那就选一个 Empty Activity吧。(这个是模块的界面,随意选择便可)。

二、快速运行模板的Xposed模块

  咱们能够把项目查看方式设置为Project模式,以方便查看。而后在 “项目名称/app/src/main/”目录下找到AndroidManifest.xml,打开这个文件,并在指定位置插入如下三段代码:app

<meta-data
          android:name="xposedmodule"
            android:value="true" />
        <meta-data
            android:name="xposeddescription"
            android:value="微信hook" />
        <meta-data
            android:name="xposedminversion"
            android:value="53" />
复制代码

  效果如图:

  插入代码以后,咱们能够点击 Run运行 App
  不过,此时会出现如图提示,也就是缺乏 Device设备来运行这个 App
  下一步咱们要把手机链接 Android Studio,链接的办法不少,包括经过 USB链接(物理链接)Wifi链接(也就是网络链接),咱们为了节省方法,就采用物理链接,Ps: 有关于远程链接能够参考 这篇文章,链接好咱们的实体机以后咱们点击这里
  咱们等待 Android Studio链接手机,链接好咱们就能够看到在 Logcat选项里面看到咱们的手机运行的日志报告。
  有如图所示的日志打印以后咱们就会发现咱们就能够运行了,点击 Run以后会提示咱们的手机安装咱们刚才刚写的 Apk,不过个人手机提示 安装时验证超时,不能直接安装,苦恼,之后选手机也要选个正常的。关于 Android Studio安装 Apk失败的缘由能够参考 这篇文章,既然咱们不能直接安装 Apk,咱们就使用 adb直接来安装
  安装好应用以后咱们在 Xposed框架中勾选咱们刚才的模块,而后咱们重启一下 Xposed框架,就能够啦
  这一步只是说明 Xposed框架已经认出了咱们写的程序。但先别高兴太早——虽然框架已经以为他是一个 Xposed模块了,但咱们本身内心清楚,这个模块还啥都不会干呢。下一步,咱们让这个模块长点本事。

三、搞定XposedBridgeApi-xx.jar 与 build.gradle

  咱们知道,Xposed模块主要功能是用来Hook其余程序的各类函数。可是,如何让前一步中的那个“一贫如洗”的模块长本事呢?那就要引入 XposedBridgeApi.jar 这个包,你能够理解为一把兵器,模块有了这把宝刀才能施展出Hook本领。不少之前的老教程都须要手动下载诸如XposedBridgeApi-54.jarXposedBridgeApi-82.jarjar包,而后手工导入到libs目录里,才能走下一步道路,而这些jar没有官方的渠道来安装,一般只是一个传一个的,都不知道变成了什么版本。其实在最新的AndroidStudio 3.1之后,咱们彻底不用这么麻烦,只须要多写一行代码,就让AndroidStuido自动给咱们配置XposedBridgeApi.jar!下面操做开始:   在 “项目名称/app/src/main/”目录下找到build.gradle,在图示位置加上:

repositories {

    jcenter()

}
compileOnly 'de.robv.android.xposed:api:82'

compileOnly 'de.robv.android.xposed:api:82:sources'
复制代码

  这句代码是告诉AndroidStuido使用jcenter做为代码仓库,从这个仓库里远程寻找 de.robv.android.xposed:api:82这个API。这个网上不多有Xposed教程介绍它的!(咱们不用本身找XposedBridgeApi.jar了。注意!此处要用compileOnly这个修饰符!网上有些写的是provide,可是如今已经停用了!坑人啊!)   写完以后, build.gradle会提示文件已经修改,是否同步。点击 “sync now”,同步便可:

  等待依赖构建完成
  【Ps:若是网络不通,或者同步不顺畅,就不要进行第三步的 repositories { jcenter()}这个步骤了,改作这个步骤:手动下载 XposedBridgeApi-82.jar,拖放到 “项目名称/app/libs/”里面(不是网上说的单独创建 lib文件夹,那是好久之前的故事了!),而后右键 “Add As Library”自行添加这个 jar包。而 compileOnly ‘de.robv.android.xposed:api:82′compileOnly ‘de.robv.android.xposed:api:82:sources’这两句仍然照常添加。】   好了,咱们如今已经搞好了全部的准备工做。下一步,就要开始“施展刀法”(编写 hook代码)了。

四、实现hook操做的具体代码

  在“施展刀法”(编写hook代码)以前,咱们先要立一个靶子。在界面上画一个按钮,并在MainAcitiviy里写代码以下:

package com.example.wx;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.View;

import android.widget.Button;

import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private Button button;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        button = (Button) findViewById(R.id.button);

        button.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {

                Toast.makeText(MainActivity.this, toastMessage(), Toast.LENGTH_SHORT).show();

            }

        });

    }

    public String toastMessage() {

        return "我未被劫持";

    }

}
复制代码

  而在页面布置的文件中,也就是activity_main.xml中增长以下红框的代码

  这个靶子很简单: MainActivity界面有个按钮,点击按钮后会弹出一个 toast提示,该提示的内容由 toastMessage()方法提供,而 toastMessage()的返回值为 “我未被劫持”。   如今,咱们已经作好了咱们的 App了,下面咱们正式开始“施展刀法”(编写 hook代码) 来 hook咱们的 MainActivity并修改这个类的 toastMessage()方法,让它的返回值为 “你已被劫持”

五、在MainActivity的同级路径下新建一个类“HookTest.java”

package com.example.wx;

import de.robv.android.xposed.IXposedHookLoadPackage;

import de.robv.android.xposed.XC_MethodHook;

import de.robv.android.xposed.XposedBridge;

import de.robv.android.xposed.XposedHelpers;

import de.robv.android.xposed.callbacks.XC_LoadPackage;

public class HookTest implements IXposedHookLoadPackage {

    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {

        if (loadPackageParam.packageName.equals("com.example.root.xposd_hook_new")) {

            XposedBridge.log(" has Hooked!");

            Class clazz = loadPackageParam.classLoader.loadClass(

                    "com.example.root.xposd_hook_new.MainActivity");

            XposedHelpers.findAndHookMethod(clazz, "toastMessage", new XC_MethodHook() {

                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {

                    super.beforeHookedMethod(param);

                    //XposedBridge.log(" has Hooked!");

                }

                protected void afterHookedMethod(MethodHookParam param) throws Throwable {

                    param.setResult("你已被劫持");

                }

            });

        }

    }

}
复制代码

  由代码可知,咱们是经过 IXposedHookLoadPackage接口中的 handleLoadPackage方法来实现 Hook并篡改程序的输出结果的。代码中 “com.example.wx”是目标程序的包名, ”com.example.wx.MainActivity”是想要Hook的类, “toastMessage”是想要 Hook的方法。咱们在 afterHookedMethod方法(用来定义Hook了目标方法以后的操做)中,修改了 toastMessage()方法的返回值为“你已被劫持”。在完成代码编写以前,说一下为何要 Hook toastMessage这个方法,咱们先用 Jadx查看一下咱们 Apk的源代码
  这个源码是没有通过混淆的,因此咱们能够看到这个源码和咱们以前写的同样,咱们根据项目结构能够判断出咱们须要 Hook的函数。   OK,以上用来 hook的代码编写完毕,让咱们进行下一步操做。

六、最后一步,添加入口点

  右键点击 “main ”文件夹 , 选择new –> Folder –>Assets Folder,新建assets文件夹:

  而后右键点击 assets文件夹, new–> file,文件名为xposed_init(文件类型选text),并在其中写上入口类的完整路径(就是本身编写的那一个Hook类),这样,Xposed框架就可以从这个xposed_init读取信息来找到模块的入口,而后进行Hook操做了:

  好了,曙光就在前面!最后选择禁用Instant Run: 单击 File -> Settings -> Build, Execution, Deployment -> Instant Run,把勾所有去掉。   咱们从新以前的安装Xposed模块的方法,运行模块,点击,奇迹出现~

  大功告成!!!

结语

  从上面的实战中咱们能够发现Hook的基本原理以及步骤,从新看看咱们以前说的四大步,Hook的关键其实咱们须要知道针对哪一个模块的哪一个方法进行Hook

一、让手机上的xposed框架知道咱们安装的这个程序是个xposed模块。

二、模块里要包含有xposed的API的jar包,以实现下一步的hook操做。

三、这个模块里面要有对目标程序进行hook操做的方法。

四、要让手机上的xposed框架知道,咱们编写的xposed模块中,哪个方法是实现hook操做的。
复制代码

  像咱们这个例子很简单,没有特地的进行代码混淆以及程序入口改写等等,咱们寻找仍是很简单的,通常市面上的App都是有不少反Xposed的行为,咱们其实要学习的还有不少,这个小教程就当作个小入门吧。   下一篇文章和最近工做上的需求有关系,针对的是2019.10.28以后搜狗微信关闭了在某些公众号内搜索的功能,因此咱们想要获取最新的公众号文章就不能采起搜狗微信这个渠道了,网上有不少教程都在谈论其余的方法,相比较来讲,仍是Hook这个渠道是最实际的,咱们将会在以后的文章里详细谈论,你们能够期待一下~

注意:  项目已经完成,想要得到源码能够关注下面的微信号,回复“hook入门”便可得到项目地址以及现成的Apk

号主介绍

  • 前两年在二线大厂工做,目前在创业公司搬砖

  • 接触方向是爬虫云原生架构方面

  • 丰富的反爬攻克经验以及云原生二次开发经验

  • 其余诸如数据分析黑客增加也有所涉猎

  • 作过百余人的商业分享以及屡次开办培训课程

  • 目前也是CSDN博客专家华为云享专家

震惊 | 只需3分钟!极速部署我的Docker云平台

深刻理解Python的TLS机制和Threading.local()

我为何不建议你使用Python3.7.3?

下一代容器架构已出,Docker何去何处?看看这里的6问6答!!

公众号内回复“私藏资料”便可领取爬虫高级逆向教学视频以及多平台的中文数据集

相关文章
相关标签/搜索