查看原文
其他

《来自高纬的对抗:魔改XPOSED过框架检测(下)》

r0ysue OPPO安全应急响应中心 2022-07-01





以上文章由作者【r0ysue】的连载有赏投稿,共有五篇,每周更新一篇;也欢迎广大朋友继续投稿,详情可点击OSRC重金征集文稿!!!了解~~
温馨提示:建议投稿的朋友尽量用markdown格式,特别是包含大量代码的文章



本篇中我们继续前文的话题,对Xposed源码进行修改,过XposedChecker框架检测,并基于修改后的API进行插件项目二次开发。

本文所涉及的环境、实验数据结果及代码资料等都在作者的Github:https://github.com/r0ysue/AndroidSecurityStudy上,欢迎大家取用和star。

魔改官方原版过检测

修改XposedInstaller源码

对于XposedInstaller来说,要改的只有两个地方,一个是整体的包名,还有一个就是.prop配置文件。

先来改下整体的包名,首先将目录折叠给取消掉,否则无法重构包名。

然后我们在包名路径中,将xposed改成xppsed,这样可以保证包名长度是一样,同时xposed特征消失不见,这就是总体的一个改名的策略。选择RefactorRename

改前是xposed,改后是xppsed

点击Refactor,会找到当前项目下所有包名中包含xposed的地方,点击Do Refactor才会真正的修改,进行重构,把所有地方的包名改成xppsed

可以随便打开某个代码文件看下,包名那里已经成为了

de.robv.android.xppsed.installer.util

接下来就是在整个项目的根文件夹下,进行整体的包名替换,因为还有很多编译配置、或者路径配置等等,需要进行包名的更换。

app文件夹右击,选择Replace in Path

把所有的de.robv.android.xposed.installer都改成de.robv.android.xppsed.installer。可以先搜一下,看看匹配的地方多不多。

其实搜出来匹配的地方只有在5个文件中的合计7处地方,并不多,直接Replace All替换掉即可。

到这里第一处就改好了。第二处也非常简单,就是把如下图处的xposed.prop改成xppsed.prop即可。

接下来就是编译了。编译时先BuildClean一下,然后再BuildMake Project,这样就直接编译通过了。可以连接到手机,刷到手机上去,App会被装在手机上,但是无法自动启动,得手动点开。

可以看到是没有问题的。

修改XposedBridge源码及生成新API

对于XposedBridge修改的地方也是两个,一个是包名,一个是生成出来的XposedBridge.jar文件。

首先是改包名,方法与上文一模一样,也是首先将xposed进行重构,改成xppsed

改完之后随便打开几个文件看看,头顶的包名应该已经变成xppsed了。

然后也是一样的在项目根目录下,执行Replace in Path,将所有的de.robv.android.xposed.installer都改成de.robv.android.xppsed.installer。当然也可以先搜一下,其实匹配的也不是很多,大多数都在一个txt文件里。

最后就是编译,记得先Make Clean一下,然后编译,将编译出来的文件复制一份,命名为XppsedBridge.jar即可。

编译API还是跟之前一样的流程,在操作上无需更改,会编译出来新的api.jar,后面会用来替换原来的api.jar

有时候会怀疑,编译出来的文件是新生成的么?会不会是老文件?其实只要看下文件的生成(或修改)时间就可以,如果是当下的时间,那肯定是新生成的。

修改Xposed框架源码去特征

在前文中,对于Xposed框架的编译是最轻松的,而且其实Xposed框架的代码文件并不是很多,但是改的地方倒还是不少。

首先改下libxposed_common.h中的源码:

改之前

#define CLASS_XPOSED_BRIDGE "de/robv/android/xposed/XposedBridge"#define CLASS_ZYGOTE_SERVICE "de/robv/android/xposed/services/ZygoteService"#define CLASS_FILE_RESULT "de/robv/android/xposed/services/FileResult"

改之后

#define CLASS_XPOSED_BRIDGE "de/robv/android/xppsed/XposedBridge"#define CLASS_ZYGOTE_SERVICE "de/robv/android/xppsed/services/ZygoteService"#define CLASS_FILE_RESULT "de/robv/android/xppsed/services/FileResult"

然后修改Xposed.h文件:

改之前

#define XPOSED_PROP_FILE "/system/xposed.prop"#define XPOSED_LIB_ART XPOSED_LIB_DIR "libxposed_art.so"#define XPOSED_JAR "/system/framework/XposedBridge.jar#define XPOSED_CLASS_DOTS_ZYGOTE "de.robv.android.xposed.XposedBridge"#define XPOSED_CLASS_DOTS_TOOLS "de.robv.android.xposed.XposedBridge$ToolEntryPoint"

改之后

#define XPOSED_PROP_FILE "/system/xppsed.prop"#define XPOSED_LIB_ART XPOSED_LIB_DIR "libxppsed_art.so"#define XPOSED_JAR "/system/framework/XppsedBridge.jar#define XPOSED_CLASS_DOTS_ZYGOTE "de.robv.android.xppsed.XposedBridge"#define XPOSED_CLASS_DOTS_TOOLS "de.robv.android.xppsed.XposedBridge$ToolEntryPoint"

然后在xposed_service.cpp之后,只有一处修改:

改之前

IMPLEMENT_META_INTERFACE(XposedService, "de.robv.android.xposed.IXposedService");

改之后

IMPLEMENT_META_INTERFACE(XposedService, "de.robv.android.xppsed.IXposedService");

接下来是xposed_shared.h

改之前

#define XPOSED_DIR "/data/user_de/0/de.robv.android.xposed.installer/"#define XPOSED_DIR "/data/data/de.robv.android.xposed.installer/"

改之后

#define XPOSED_DIR "/data/user_de/0/de.robv.android.xppsed.installer/"#define XPOSED_DIR "/data/data/de.robv.android.xppsed.installer/"

接下来是ART.mk

改之前

libxposed_art.cppLOCAL_MODULE := libxposed_art

改之后

libxppsed_art.cppLOCAL_MODULE := libxppsed_art

这个截图有些截不全了,分散得比较开,总之就这两个地方,没有别处。

最后将文件夹下的libxposed_art.cpp文件,重命名为libxppsed_art.cpp

到这里Xposed框架源码修改完成。

修改XposedTools编译工具源码

修改XposedTools主要的原则是,只要编译过程不报错就行,因为XposedTools中的代码并不会进入最终的编译包,它只是负责准备环境和将Xposed各个模块进行编译而已。

前面我们改生成文件的地方主要有三个,xppsed.propXppsedBridge.jarlibxppsed_art

build.plzipstatic/_all/META-INF/com/google/android/flash-script.sh这两个文件中的上述字符串,改成修改后的字符串即可,可以充分发挥查找替换的功能。

记得不要有遗漏,可以在修改完之后,到根目录下运行下述grep命令试试看,找不到相应的字符串即为全部替换完成。

# grep -ril "xposed.prop" *

在最终编译之前,记得把编译出来的XppsedBridge.jar放到$AOSP/out/java/目录中去噢,替换旧的XposedBridge.jar(删掉)。

然后运行编译的命令,开始编译即可。

# ./build.pl -t arm64:25

编译的过程是非常快的,毕竟已经编译过一次了,

按照本篇的流程来,应该会一步成功,如果有报错,那就看下报错的地方在哪里,根据提示把漏看的、漏改的地方改掉即可。

魔改后的API插件开发

刷机过Xposed Checker框架检

按照前文将新的zip刷入到手机中,可以发现已经成功了,主界面显示绿色,系统日志也显示已经按照将XppsedBridge.jar加载到CLASSPATH中了,Xposed框架基本正常运行。

然后可以上Xposed Checker框架检测来看下,可以发现Xposed框架检测的部分全部通过了,毕竟Xposed的特征已经变成Xppsed了。

最后的root检测其实只要给su文件换个名字就可以过,当然这是题外话了。

市面上现有模块不再生效

如果给现在的手机装上Gravity这款Xposed模块的话,会出现“系统框架未响应GravityBox,正在退出”的提示,模块无法正常工作,设置界面都进不去。

原因是在于GravityBox会在后台寻找de.robv.android.xposed.IXposedHookZygoteInit这个类,而这个类很明显包名被改掉了,报ClassNotFoundError

所以说如果想要继续使用魔改后的Xposed框架,得自己基于编译出来的源码API,重新开发。

基于新API的插件开发

前文中介绍了使用编译出来的api.jar进行开发的方法,这里主要也就是将新编译出来的api.jar替换原来的api.jar,然后会发现马上xposed包名相关的代码就变红了。

只要在import的地方,将包名处的xposed改成xppsed即可。

接下来就是正常的编译和安装,重启之后模块即可生效,可以看到时钟后面加了ID,颜色也变了,同时也是bypass所有框架检测项目的。

基于新编译的api.jar二次开发成功。

魔改后的项目源码和编译结果

最后稍微总结下,魔改XPOSED后的源码,修改后的工程源码见附件文件夹,合计五个工程,android_art没有改源码,用原来的就可以。

编译成果是三个XposedApp2.zipxposed-v89-sdk25-arm64.zipXposedInstaller_3.1.5-debug.apk.zip,也在附件文件夹中,不想编译源码的话可以直接使用。

整个项目的开发流程如下:

全部弄好有134G,最高标准压缩后也有94G,我也打包上传到我的百度云盘上了,大家可以下载来玩。

小总结

最后来总结一下,在前文中介绍了官方原版XPOSED的编译流程,刷入手机、安装插件、开发插件都能正常使用;然后在其基础之上,本篇中进行源码的一些魔改,修改之后再编译刷入手机,最后讲根据新源码编译出来的API进行自己的插件开发流程,实现了从源码的高维bypass低维框架检测的目的。


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存