新手不要再被误导!这是一篇最新的Xposed模块编写教程_xposedbridgeapi-82.jar-程序员宅基地

技术标签: Android逆向及Hook  

0x00 前言

作者写于2018.11.21,我在转载时日期为2021.01.01,博客内容已经测试了,完全正确且可以运行,新手建议从此看起再看官方文档。

在互联网上,关于Xposed模块编写的教程可谓是一抓一大把。但由于时间的推移,很多工具和方法都发生了变化(如Eclipse退出安卓编程舞台,AndroidStudio 不断升级导致其一些设置也随之变化等)也正因此,网上的教程往往有一些时限性,比如现如今 provide 这个关键字已经被舍弃了却仍有人在用,还有些说要把jar包放到lib文件夹而非libs文件夹……种种错误或者落伍的教程对新手产生了很大的误导。 笔者近日收到过朋友初学Xposed模块编写时的求助,看了一些他找的参考教程,觉得多多少少都存在点问题,因此萌生了写一篇关于在最新AndriodStudio 开发环境下实现Xposed模块开发入门的文章。

0x01 Xposed 模块编写简介

Xposed 框架的原理就不多说了,它部署在ROOT后的安卓手机上,通过替换/system/bin/app_process程序控制zygote进程,使得app_process在启动过程中会加载XposedBridge.jar这个jar包,从而完成对Zygote进程及其创建的Dalvik虚拟机的劫持。可以让我们在不修改APK源码的情况下,通过自己编写的模块来影响程序运行的框架服务,实现类似于自动抢红包、微信消息自动回复等功能。

其实,从本质上来讲,Xposed 模块也是一个 Android 程序。但与普通程序不同的是,想要让写出的Android程序成为一个Xposed 模块,要额外多完成以下四个硬性任务:

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

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

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

4、要让手机上的xposed框架知道,我们编写的xposed模块中,哪一个方法是实现hook操作的。

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

1、AndroidManifest.xml

2、XposedBridgeApi-xx.jar 与 build.gradle

3、实现hook操作的具体代码

4、xposed_Init

牢记以上四大件,按照顺序一个一个实现,就能完成我们的第一个Xposed模块编写。下面我们就开始吧!

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

1、首先打开AndroidStudio(以版本3.1为例,还在用老版本的请升级),建立一个工程,提示我们选择“Activity”,那就选一个Empty Activity吧。(这个是模块的界面,随意选择即可)。

新建项目并编辑AndroidManifest.xml

2、我们可以把项目查看方式设置为Project模式,以方便查看。然后在 “项目名称/app/src/main/”目录下找到AndroidManifest.xml,双击之,并在指定位置插入以下三段代码:

 

<meta-data

android:name="xposedmodule"

android:value="true" />

<meta-data

    android:name="xposeddescription"

    android:value="这是一个Xposed例程" />

<meta-data

    android:name="xposedminversion"

    android:value="53" />

插入位置及代码说明如图所示:

插入位置及代码说明

插入之后,如果你把手机连上AndroidStudio ,点击“编译”或者“运行”的话,手机就会启动刚刚编写的这个程序。而在手机里的Xposed框架中也会显示出这个模块:

手机里的Xposed框架

说明Xposed框架已经认出了我们写的程序。但先别高兴太早——虽然框架已经觉得他是一个Xposed模块了,但我们自己心里清楚,这个模块还啥都不会干呢。下一步,我们让这个模块长点本事。

0x03 走出第二步,搞定XposedBridgeApi-xx.jar 与 build.gradle

我们知道,Xposed模块主要功能是用来Hook其他程序的各种函数。但是,如何让前一步中的那个“一穷二白”的模块长本事呢?那就要引入 XposedBridgeApi.jar 这个包,你可以理解为一把兵器,模块有了这把宝刀才能施展出Hook本领。以前,都需要手动下载诸如XposedBridgeApi-54.jar 、 XposedBridgeApi-82.jar 等jar包,然后手工导入到libs目录里,才能走下一步道路。其实在AndroidStudio 3.1里面,我们完全不用这么麻烦,只需要多写一行代码,就让AndroidStuido自动给我们配置XposedBridgeApi.jar !下面操作开始(序号接着上一节):

3、在 “项目名称/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代码)了。

0x04 迈开第三步,实现hook操作的具体代码

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

 

package com.example.root.xposd_hook_new;

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 "我未被劫持";

    }

}

实现hook操作的具体代码

实现hook操作的具体代码

这个靶子很简单:MainActivity界面有个按钮,点击按钮后会弹出一个toast提示,该提示的内容由 toastMessage() 方法提供,而toastMessage()的返回值为“我未被劫持”:

我未被劫持

下面我们正式开始“施展刀法”(编写hook代码) 来hook我们的MainActivity并修改这个类的toastMessage()方法,让它的返回值为“你已被劫持”:

5、在MainActivity的同级路径下新建一个类“HookTest.java”,代码如下:

 

package com.example.root.xposd_hook_new;

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("你已被劫持");

                }

            });

        }

    }

}

新建一个类“HookTest.java”

由代码可知,我们是通过IXposedHookLoadPackage接口中的handleLoadPackage方法来实现Hook并篡改程序的输出结果的。代码中“com.example.root.xposd_hook_new ”是目标程序的包名,"com.example.root.xposd_hook_new.MainActivity" 是想要Hook的类, "toastMessage"是想要Hook的方法。我们在afterHookedMethod方法(用来定义Hook了目标方法之后的操作)中,修改了toastMessage()方法的返回值为“你已被劫持”。

OK,以上用来hook的代码编写完毕,让我们进行下一步操作。

0x05 最后一步,添加入口点

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

新建assets 文件夹

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

进行Hook操作

进行Hook操作

好了,曙光就在前面!最后选择禁用 Instant Run: 单击 File -> Settings -> Build, Execution, Deployment -> Instant Run,把勾全部去掉。

禁用 Instant Run

然后点击小三角“运行”!在Xposed框架里找到自己写的模块,打上勾,重启——点开自己的程序看看,是不是toast的提示已经变了?

toast的提示

本次教程就到这里,谢谢!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/THMAIL/article/details/112061448

智能推荐

oracle 12c 集群安装后的检查_12c查看crs状态-程序员宅基地

文章浏览阅读1.6k次。安装配置gi、安装数据库软件、dbca建库见下:http://blog.csdn.net/kadwf123/article/details/784299611、检查集群节点及状态:[root@rac2 ~]# olsnodes -srac1 Activerac2 Activerac3 Activerac4 Active[root@rac2 ~]_12c查看crs状态

解决jupyter notebook无法找到虚拟环境的问题_jupyter没有pytorch环境-程序员宅基地

文章浏览阅读1.3w次,点赞45次,收藏99次。我个人用的是anaconda3的一个python集成环境,自带jupyter notebook,但在我打开jupyter notebook界面后,却找不到对应的虚拟环境,原来是jupyter notebook只是通用于下载anaconda时自带的环境,其他环境要想使用必须手动下载一些库:1.首先进入到自己创建的虚拟环境(pytorch是虚拟环境的名字)activate pytorch2.在该环境下下载这个库conda install ipykernelconda install nb__jupyter没有pytorch环境

国内安装scoop的保姆教程_scoop-cn-程序员宅基地

文章浏览阅读5.2k次,点赞19次,收藏28次。选择scoop纯属意外,也是无奈,因为电脑用户被锁了管理员权限,所有exe安装程序都无法安装,只可以用绿色软件,最后被我发现scoop,省去了到处下载XXX绿色版的烦恼,当然scoop里需要管理员权限的软件也跟我无缘了(譬如everything)。推荐添加dorado这个bucket镜像,里面很多中文软件,但是部分国外的软件下载地址在github,可能无法下载。以上两个是官方bucket的国内镜像,所有软件建议优先从这里下载。上面可以看到很多bucket以及软件数。如果官网登陆不了可以试一下以下方式。_scoop-cn

Element ui colorpicker在Vue中的使用_vue el-color-picker-程序员宅基地

文章浏览阅读4.5k次,点赞2次,收藏3次。首先要有一个color-picker组件 <el-color-picker v-model="headcolor"></el-color-picker>在data里面data() { return {headcolor: ’ #278add ’ //这里可以选择一个默认的颜色} }然后在你想要改变颜色的地方用v-bind绑定就好了,例如:这里的:sty..._vue el-color-picker

迅为iTOP-4412精英版之烧写内核移植后的镜像_exynos 4412 刷机-程序员宅基地

文章浏览阅读640次。基于芯片日益增长的问题,所以内核开发者们引入了新的方法,就是在内核中只保留函数,而数据则不包含,由用户(应用程序员)自己把数据按照规定的格式编写,并放在约定的地方,为了不占用过多的内存,还要求数据以根精简的方式编写。boot启动时,传参给内核,告诉内核设备树文件和kernel的位置,内核启动时根据地址去找到设备树文件,再利用专用的编译器去反编译dtb文件,将dtb还原成数据结构,以供驱动的函数去调用。firmware是三星的一个固件的设备信息,因为找不到固件,所以内核启动不成功。_exynos 4412 刷机

Linux系统配置jdk_linux配置jdk-程序员宅基地

文章浏览阅读2w次,点赞24次,收藏42次。Linux系统配置jdkLinux学习教程,Linux入门教程(超详细)_linux配置jdk

随便推点

matlab(4):特殊符号的输入_matlab微米怎么输入-程序员宅基地

文章浏览阅读3.3k次,点赞5次,收藏19次。xlabel('\delta');ylabel('AUC');具体符号的对照表参照下图:_matlab微米怎么输入

C语言程序设计-文件(打开与关闭、顺序、二进制读写)-程序员宅基地

文章浏览阅读119次。顺序读写指的是按照文件中数据的顺序进行读取或写入。对于文本文件,可以使用fgets、fputs、fscanf、fprintf等函数进行顺序读写。在C语言中,对文件的操作通常涉及文件的打开、读写以及关闭。文件的打开使用fopen函数,而关闭则使用fclose函数。在C语言中,可以使用fread和fwrite函数进行二进制读写。‍ Biaoge 于2024-03-09 23:51发布 阅读量:7 ️文章类型:【 C语言程序设计 】在C语言中,用于打开文件的函数是____,用于关闭文件的函数是____。

Touchdesigner自学笔记之三_touchdesigner怎么让一个模型跟着鼠标移动-程序员宅基地

文章浏览阅读3.4k次,点赞2次,收藏13次。跟随鼠标移动的粒子以grid(SOP)为partical(SOP)的资源模板,调整后连接【Geo组合+point spirit(MAT)】,在连接【feedback组合】适当调整。影响粒子动态的节点【metaball(SOP)+force(SOP)】添加mouse in(CHOP)鼠标位置到metaball的坐标,实现鼠标影响。..._touchdesigner怎么让一个模型跟着鼠标移动

【附源码】基于java的校园停车场管理系统的设计与实现61m0e9计算机毕设SSM_基于java技术的停车场管理系统实现与设计-程序员宅基地

文章浏览阅读178次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot + mybatis + Maven +mysql5.7或8.0+html+css+js等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。_基于java技术的停车场管理系统实现与设计

Android系统播放器MediaPlayer源码分析_android多媒体播放源码分析 时序图-程序员宅基地

文章浏览阅读3.5k次。前言对于MediaPlayer播放器的源码分析内容相对来说比较多,会从Java-&amp;amp;gt;Jni-&amp;amp;gt;C/C++慢慢分析,后面会慢慢更新。另外,博客只作为自己学习记录的一种方式,对于其他的不过多的评论。MediaPlayerDemopublic class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal..._android多媒体播放源码分析 时序图

java 数据结构与算法 ——快速排序法-程序员宅基地

文章浏览阅读2.4k次,点赞41次,收藏13次。java 数据结构与算法 ——快速排序法_快速排序法