楼上说的不错,不过,有时候有些App只是ClassLoader被壳换了,这个时候,选对ClassLoader就可以了。比如这样:
引用:
public EncryptHook(ClassLoader cl) {
super();
XposedBridgelog("Now hooking");
try {
clzStubApp = (Class<>) XposedHelpersfindClass("comqihooutilStubApplication", cl);
XposedHelpersfindAndHookMethod(clzStubApp,
"getNewAppInstance",
Contextclass,
new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param)
throws Throwable {
Context ctx = (Context) paramargs[0];
11 概述
Xposed 是 GitHUB 上 rovo89 大大设计的一个针对 Android 平台的动态劫持项目,通过替换 /system/bin/app_process 程序控制 zygote 进程,使得 app_process 在启动过程中会加载 XposedBridgejar 这个 jar 包,从而完成对系统应用的劫持。
Xposed 框架的基本运行环境如下:
因为 Xposed 工作原理是在 /system/bin 目录下替换文件,在 install 的时候需要root 权限,但是运行时不需要 root 权限。
需要在 Android 40 以上版本的机器中
2 GitHub 上的 Xposed 资源梳理一下,可以这么分类:
XposedBridgejar : XposedBridgejar 是 Xposed 提供的 jar 文件,负责在 Native层与 FrameWork 层进行交互。 /system/bin/app_process 进程启动过程中会加载该jar 包,其它的 Modules 的开发与运行都是基于该 jar 包的。
Xposed : Xposed 的 C++ 部分,主要是用来替换 /system/bin/app_process ,并为 XposedBridge 提供 JNI 方法。
XposedInstaller : Xposed 的安装包,负责配置 Xposed 工作的环境并且提供对基于 Xposed 框架的 Modules 的管理。
XposedMods :使用 Xposed 开发的一些 Modules ,其中 AppSettings 是一个可以进行权限动态管理的应用
12 Mechanism :原理
121 Zygote
在 Android 系统中,应用程序进程都是由 Zygote 进程孵化出来的,而 Zygote 进程是由 Init 进程启动的。 Zygote 进程在启动时会创建一个 Dalvik 虚拟机实例,每当它孵化一个新的应用程序进程时,都会将这个 Dalvik 虚拟机实例复制到新的应用程序进程里面去,从而使得每一个应用程序进程都有一个独立的 Dalvik 虚拟机实例。
Zygote 进程在启动的过程中,除了会创建一个 Dalvik 虚拟机实例之外,还会将 Java运行时库加载到进程中来,以及注册一些 Android 核心类的 JNI 方法来前面创建的 Dalvik 虚拟机实例中去。注意,一个应用程序进程被 Zygote 进程孵化出来的时候,不仅会获得 Zygote 进程中的 Dalvik 虚拟机实例拷贝,还会与 Zygote 一起共享 Java 运行时库。这也就是可以将XposedBridge 这个 jar 包加载到每一个 Android 应用程序中的原因。 XposedBridge 有一个私有的 Native ( JNI )方法 hookMethodNative,这个方法也在 app_process 中使用。这个函数提供一个方法对象利用 Java 的 Reflection 机制来对内置方法覆写。具体的实现可以看下文的 Xposed 源代码分析。
122 Hook/Replace
Xposed 框架中真正起作用的是对方法的 hook 。在 Repackage 技术中,如果要对APK 做修改,则需要修改 Smali 代码中的指令。而另一种动态修改指令的技术需要在程序运行时基于匹配搜索来替换 smali 代码,但因为方法声明的多样性与复杂性,这种方法也比较复杂。
在 Android 系统启动的时候, zygote 进程加载 XposedBridge 将所有需要替换的 Method 通过 JNI 方法 hookMethodNative 指向 Native 方法 xposedCallHandler , xposedCallHandler 在转入 handleHookedMethod 这个 Java 方法执行用户规定的 Hook Func 。
XposedBridge 这个 jar 包含有一个私有的本地方法: hookMethodNative ,该方法在附加的 app_process 程序中也得到了实现。它将一个方法对象作为输入参数(你可以使用 Java 的反射机制来获取这个方法)并且改变 Dalvik 虚拟机中对于该方法的定义。它将该方法的类型改变为 native 并且将这个方法的实现链接到它的本地的通用类的方法。换言之,当调用那个被 hook 的方法时候,通用的类方法会被调用而不会对调用者有任何的影响。在 hookMethodNative 的实现中,会调用 XposedBridge中的handleHookedMethod这个方法来传递参数。 handleHookedMethod 这个方法类似于一个统一调度的 Dispatch 例程,其对应的底层的 C++ 函数是 xposedCallHandler 。而 handleHookedMethod 实现里面会根据一个全局结构 hookedMethodCallbacks 来选择相应的 hook函数,并调用他们的 before, after 函数。
当多模块同时 Hook 一个方法的时候, Xposed 会自动根据 Module 的优先级来排序,调用顺序如下:
Abefore -> Bbefore -> original method -> Bafter -> Aafter
2 源代码分析
21 Cpp 模块
其文件分类如下:
app_maincpp :类似 AOSP 中的 frameworks/base/cmds/app_process/app_maincpp,即/system/bin/app_process 这个 zygote 真实身份的应用程序的源代码。关于zygote 进程的分析可以参照 Android:AOSP&Core 中的 Zygote 进程详解。
xposedcpp :提供给 app_maincpp 的调用函数以及 XposedBridge 的 JNI 方法的实现。主要完成初始化工作以及 Framework 层的 Method 的 Hook *** 作。
xposedh , xposed_offsetsh :头文件
Xposed 框架中的 app_maincpp 相对于 AOSP 的 app_maincpp 中修改之处主要为区分了调用 runtimestart() 函数的逻辑。 Xposed 框架中的 app_maincpp 在此处会根据情况选择是加载 XposedBridge 类还是 ZygoteInit 或者 RuntimeInit 类。而实际的加载 XposedBridge 以及注册 JNI 方法的 *** 作发生在第四步: xposedOnVmCreated中。
1.包含 cutils/propertiesh ,主要用于获取、设置环境变量, xposedcpp 中需要将XposedBridge 设置到 ClassPath 中。
2.包含了 dlfcnh ,用于对动态链接库的 *** 作。
3.包含了 xposedh ,需要调用 xposedcpp 中的函数,譬如在虚拟机创建时注册 JNI 函数。
4.增加了 initTypePointers 函数,对于 Android SDK 大于等于 18 的会获取到 atrace_set_tracing_enabled 函数指针,在 Zygote 启动时调用。
5.AppRuntime 类中的 onVmCreated 函数中增加 xposedOnVmCreated 函数调用。
6.源代码中的 Log 全部重命名为 ALog, 所以 Logv 替换为 Alogv ,但是功能不变。
7.Main 函数开始处增加了大量的代码,但是对于 SDK 版本小于 16 的可以不用考虑。
211 Main 函数: zygote 入口
int main(int argc, char const argv[])
还是之前公司的那个需求,为满足客户需要,必须能够远程控制手下手机的相机和录音功能,之前能够使用设备管理器来禁用摄像头,但是毕竟需要手机使用者来手动点击确定激活的选项,这点就不是很美丽,虽然那个点击的 *** 作可以使用自动化服务来实现,但是有点大题小做并且效果还是不理想,所以我使用的禁用android底层相机和录音的api,通过修改android底层代码实现 功能失效,而通过反编译手机自带的相机录音的apk虽然也能够实现失效的效果,但是毕竟这只是一个apk,人家在下载个其他的照相或录音的app,你还是拿人家没有办法,所有相关的应用都会使用Camera、AudioRecord或是MediaRecorder类实现的照相 和 录制语音的功能,让我们查询相关底层代码,修改部分代码就能够一举多得的让所有调用这三个类的所有app都失效啦~
话不多说直接上代码~ 关于xposed模块配置方面我就不介绍了不会的同学可以看我的其他帖子或是去google一下,关于那三个类可以在AS上引出这三个包,然后ctri + 左键 点击进去查看源码,里面API介绍的很全面,对于是英文看不懂的同学可以再AS里面装一个自动翻译的插件,我可以推荐一个AS翻译的插件你们可以试试~无网络无法使用哦~网址如下所示点击就能进入(安装教程也讲解的很详细):
点击打开链接
private void hookCamera(XC_LoadPackageLoadPackageParam loadPackageParam) {
try {
XposedHelpersfindAndHookMethod("androidhardwareCamera", loadPackageParamclassLoader, "open", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
superafterHookedMethod(param);
if (ModelHelpergetGZipModel("Audioqwercom","disable")equals("disable")){
paramsetResult(null);
Loge("pptppt", "试试吧");
}
}
});
XposedHelpersfindAndHookMethod("androidhardwareCamera", loadPackageParamclassLoader, "open",
intclass, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
superafterHookedMethod(param);
if (ModelHelpergetGZipModel("Audioqwercom","disable")equals("disable")){
paramsetResult(null);
Loge("pptppt", "试试吧 啊哈哈");
}
}
});
} catch (Exception e) {
}
}
通过阅读Camera 的API 只要禁用掉open方法的返回值就能够实现无法开启摄像头 *** 作,接下来是禁用语音录音功能:
private void hookRecord(XC_LoadPackageLoadPackageParam loadPackageParam) {
try {
Class<> aClass = XposedHelpersfindClass("androidmediaMediaRecorder", loadPackageParamclassLoader);
XposedBridgehookAllMethods(aClass, "setOutputFile", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
superbeforeHookedMethod(param);
if (ModelHelpergetGZipModel("Audioqwercom","disable")equals("disable")){
paramargs[0] = null;
Loge("pptppt", "lalala1");
}
}
});
//
XposedHelpersfindAndHookMethod("androidmediaAudioRecord", loadPackageParamclassLoader, "getState", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
superafterHookedMethod(param);
if (ModelHelpergetGZipModel("Audioqwercom","disable")equals("disable")){
paramsetResult(0);
Loge("pptppt", "getState");
}
}
});
}catch (Exception e){
}
}
以上是实现禁用录音功能的代码,通过禁用AudioRecord 和 MediaRecorder 类来实现禁用效果。
不知道你们观察出来了没有,在修改参数或返回值的时候,我在外侧都会加一个if判断,读取一个压缩文件中的string字符串,不满足条件的时候在禁止,这样做是为了能够更灵活的实现禁用效果,当不需要禁用的时候就重新写入压缩文件中的内容就可以了~~ 如下是ModelHelper类的代码:
import androidutilLog;
import javaioBufferedReader;
import javaioBufferedWriter;
import javaioFile;
import javaioFileInputStream;
import javaioFileOutputStream;
import javaioInputStreamReader;
import javaioOutputStreamWriter;
import javaioReader;
import javautilzipGZIPInputStream;
import javautilzipGZIPOutputStream;
public final class ModelHelper {
public static final String DIR = "/sdcard/";
/
by kevin 07-03
解压文件 获得string数据
@param modelName 文件名
@param value 取不到或解压出错时 用来替代的默认数据
@return 返回数据 成功为modelName文件的内容 失败为value默认内容
/
public static String getGZipModel(String modelName, String value) {
try {
File file = new File(DIR + modelName);
if (!fileisFile() || !fileexists()) {
return value;
}
byte [] buffer = new byte[10240];
GZIPInputStream gis = new GZIPInputStream(new FileInputStream(file));
int cnt = gisread(buffer);
gisclose();
return new String(buffer, 0, cnt, "utf-8");
} catch (Exception e) {
eprintStackTrace();
return value;
}
}
/
by kevin 07-03
set cloudsv 设置数据内容
@param fileName 压缩文件名字
@param value 写入的内容
/
public static void setGZipModel(String fileName,String value){
try {
FileOutputStream fos = new FileOutputStream(DIR + fileName);
GZIPOutputStream gos = new GZIPOutputStream(fos);
goswrite(valuegetBytes());
gosflush();
gosfinish();
}catch (Exception e){
Loge("qswx", "写入文件内容出错或不存在");
}
}
/
by kevin 06-20
读文件的方法
@param modelName 文件名
@param value 没有这个文件或这不是文件的时候 返回的String类型信息
@return 返回的是文件中的数据信息 为String类型
/
public static String getModel(String modelName, String value) {
try {
File file = new File(DIR + modelName);
if (!fileisFile() || !fileexists()) {
return value;
}
Reader inputStreamReader = new InputStreamReader(new FileInputStream(file), "UTF-8");
String str3 = new BufferedReader(inputStreamReader)readLine();
inputStreamReaderclose();
return str3;
} catch (Exception e) {
eprintStackTrace();
return value;
}
}
/
by kevin 06-20
写入String字符串 写入到指定文件中
@param modelName 指定文件的文件名字
@param value 写入到文件的String字符串
BufferedWriter 写入到缓存区
flush()清空提交 不要忘记写
/
public static void setModel(String modelName, String value) {
BufferedWriter bufferedWriter = null;
try {
bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(DIR + modelName), false), "UTF-8"));
bufferedWriterwrite(value);
bufferedWriterflush();
bufferedWriterclose();
} catch (Exception e3) {
e3printStackTrace();
try {
if(bufferedWriter != null) {
bufferedWriterclose();
}
} catch (Exception e5) {
}
}
}
}
比普通的写入文件内容的方式,这种通过加
xp框架即Xposed框架(Xposed Framework),它是一套开源的、在Android高权限模式下运行的框架服务。
Xposed框架可以在不修改APK文件的情况下影响程序运行(修改系统)的框架服务,基于它可以制作出许多功能强大的模块,且在功能不冲突的情况下同时运作。
Android中一般存在两种hook:sdk hook和ndk hook。native hook的难点在于理解ELF文件与学习ELF文件,Java层Hook则需要了解虚拟机的特性与java上的反射使用。
另外还存在全局hook,即结合sdk hook和ndk hook,xposed就是一种典型的全局hook框架。
扩展资料:
Xposed框架的五个部分:
1、Xposed:
独立实现了一版Xposed版的zyogte,即生成用来替换/system/bin/app_process的可执行文件,该文件在系统启动时在initrc中被调用,启动Zygote进程。
2、XposedBridge:
Xposed框架的Java部分,编译输出为XposedBridgejar,为开发者提供接口。
3、android_art:
Xposed框架的C++部分,对XposedBridge的补充。
4、XposedTools:
框架编译工具,因为Xposed和XposedBridge编译依赖于Android源码,而且还有一些定制化的东西。
5、XposedInstaller:
Xposed插件管理和功能选择应用,界面如下图所示,其功能包括启动Xposed框架,下载和启用指定插件,或禁用插件等。
参考资料来源:百度百科-Xposed框架
安卓60由于SE策略更新,需要对内核的sepolicy打补丁才能应用对system分区进行的修改,再者三星应用了KNOX硬件安全体系,里面存在KNOX质保熔断机制,只要系统固件不是完全官方签名(包括曾经刷过第三方ROM之后又刷回完全官方固件“四件套”),knox保修就会失效(你可以在系统的Odin模式顶端看见“KNOX WARRANTY VOID 0x1”这个字样),届时你不能为这种设备申请三星的免费保修服务。
其实熔断KNOX质保也就跟解锁Bootloader一个性质,均以破坏系统安全体系为代价修改系统内核,这会导致系统缺乏必要的安全体系运行高安全性应用,例如三星智付(SAMSUNG PAY)或三星浏览器的无痕模式。
但是root权限的权利实在太大,像xposed那样直接在内存活跃命令行层面修改应用运行命令而不需要修改应用本体的高级权限,经常会被“自动抢红包”、“永久保存闪照”等损人利己的功能——甚至“自动激活设备管理器”以强制加密勒索用户这种损人不利己的病毒所滥用,这也是安卓60开始讨伐root权限的原因。
常规的root权限激活模式要同时修改boot分区、system分区(甚至data分区),但是system分区就是被sepolicy加锁了无法修改,所以会导致权限激活不完全进而开机失败(常见的就是死在开机后第一个见到的logo)。
现在的root权限管理器基本上对安卓60开始的sepolicy束手无策,但有的管理器(例如chainfire的SuperSU)就开发了免系统固件写入模式(例如SuperSU的System less模式)通过仅修改boot分区和data分区进行“root权限模拟”(“模拟”就是因为无法完全修改系统),有时候就会出现“root完还能运行OTA更新、OTA更新完成之后还要再装一遍SuperSU”等奇怪情形。可是xposed就是修改内存活跃命令行,就是要在system分区写入固件,本来xposed所依赖的“root权限”就无法写入system了,xposed安装失败也是果不其然的事情。(busybox工具箱同理)
尽管如此你也不要“千方百计”通过recovery刷入xposed,道理都在上文中说到,写不到system安装不完全就会开机失败。
(我上次就是因为直接以recovery刷xposed导致开机失败,连续五天四夜进行了“三星救砖计划”,结果以所有应用包括用户应用和系统设置完全初始化告终。)
(附录)
如果你的三星手机安卓版本就是安卓60或以上,只能通过“免固件修改模式(systemless)”激活root权限,Chainfire管网就有适配于三星的Odin线刷版本,下载并通过Odin刷入之后会替换recovery固件以指定SuperSU卡刷程序强制systemless安装模式,卡刷后还需要系统重新整理Bootloader(固定logo画面后不要以为它死机了,开机动画出现的时候早就改好了boot和system开始载入data了,至多应用时间20分钟,完成后会自动重启)才算激活成功,激活后的root权限只能对用户安装应用进行修改(幸运破解器还可以拯救一下)。
以后三星手机多用Odin刷机,少用recovery,Odin可是三星官方独家的高级线刷工具,只对三星手机保证完美刷机。
以上就是关于app被加固了,该怎么用xposed模块hook全部的内容,包括:app被加固了,该怎么用xposed模块hook、如何hook android sdk、安卓手机如何hook摄像头等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)