android hook 第三方app_Android三大hook框架
目前Android主流的hook框架有Xposed、Substrate和frida三种,下面依次介绍三种框架的原理和特点:
Xposed
Xposed是一个在andoid平台上比较成熟的hook框架,可以完美的在dalvik虚拟机上做到hook任意java方法
原理
Android系统中所有的app进程都是有zygote进程孵化而来的,Xposed会替换/system/bin/app_process文件,替换后的app_process在启动过程中会加载XposedBridge.jar这个jar包,从而完成对Zygote进程及其创建的Dalvik虚拟机的劫持
运行条件由于需要替换app_process,故需要root或在recovery下刷机
重启手机后插件才会生效
使用方法1.AndroidManifest.xml中添加Xposed
需在Application Node中添加三个Meta(xposedmodule,xposedminversion和xposeddescription)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package="com.example.xposedtest"
android:versionCode="1"
android:versionName="1.0" >
android:minSdkVersion="14"
android:targetSdkVersion="19" />
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
assets目录下新建一个xposed_init文件
重写XC_MethodHook的两个方法beforeHookedMethod和afterHookedMethod1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39package com.example.xposedtest;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
import android.graphics.Color;
import android.util.Log;
import de.robv.android.xposed.XposedBridge;
import android.widget.TextView;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
public class XposedTest implements IXposedHookLoadPackage{ //实现IXposedHookLoadPackage接口
public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable{
//判断Hook的包是否正确
if(!lpparam.packageName.equals("com.android.systemui"))
{
XposedBridge.log("not found package");
return;
}
//找到要Hook的类名和函数,创建自己的类
findAndHookMethod("com.android.systemui.statusbar.policy.Clock",lpparam.classLoader,"updateClock",new XC_MethodHook(){
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
// 这里的调用在正常函数调用之前执行,由于本例是Hook时间显示,需要在显示之后调用,所以省略
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable{
// 这里的调用在正常函数调用之后执行
XposedBridge.log("aaaaaaaaaaaaaa"+lpparam.packageName);
TextView tv=(TextView)param.thisObject;
String text=tv.getText().toString();
tv.setText(text+":)");
tv.setTextColor(Color.RED);
}
});
}
}
hook检测
1.通过PackageManager查看安装列表,判断是否有安装Xposed Installer相关的软件包1
2
3
4
5
6
7PackageManager packageManager = context.getPackageManager();
List applicationInfoList = packageManager.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo applicationInfo: applicationInfoList) {
if (applicationInfo.packageName.equals("de.robv.android.xposed.installer")) {
// Xposed find
}
}
通常情况下使用Xposed Installer框架都会屏蔽对其的检测,即Hook掉PackageManager的getInstalledApplications方法的返回值,以便过滤掉de.robv.android.xposed.installer来躲避这种检测。
2.根据调用栈判断
Xposed Installer框架对每个由Zygote孵化的App进程都会介入,因此在程序方法异常栈中就会出现Xposed相关的“身影”,我们可以通过制造异常Exception来读取异常堆栈,检查其中是否存在Xposed的调用方法。1
2
3
4
5
6
7try {
throw new Exception("blah");
} catch(Exception e) {
for (StackTraceElement stackTraceElement: e.getStackTrace()) {
// stackTraceElement.getClassName() stackTraceElement.getMethodName() 是否存 在Xposed
}
}
以下为使用xposed的调用栈:1
2
3
4
5
6
7
8
9
10
11
12
13E/GEnvironment: no such table: preference (code 1): while compiling: SELECT keyguard_show_livewallpaper FROM preference
...
at com.meituan.test.extpackage.ExtPackageManager.checkUpdate(ExtPackageManager.java:127)
at com.meituan.test.MiFGService$1.run(MiFGService.java:41)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5072)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
...
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132) //发现Xposed模块
at dalvik.system.NativeStart.main(Native Method)
3.读取/proc/self/maps判断
无论在Java层做何种检测,Xposed都可以通过Hook相关的API并返回指定的结果来绕过检测,只要有方法就可以被Hook。如果仅在Java层检测就显得很徒劳,为了有效提搞检测准确率,就须做到Java和Native层同时检测。
在Native层读取/proc/self/maps文件,判断App自身加载的库中是否存在XposedBridge.jar、相关的Dex、Jar和So库等文件1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21bool is_xposed()
{
bool rel = false;
FILE *fp = NULL;
char* filepath = "/proc/self/maps";
...
string xp_name = "XposedBridge.jar";
fp = fopen(filepath,"r"))
while (!feof(fp))
{
fgets(strLine,BUFFER_SIZE,fp);
origin_str = strLine;
str = trim(origin_str);
if (contain(str,xp_name))
{
rel = true; //检测到Xposed模块
break;
}
}
...
}
Frida
frida是一个跨平台的hook框架,可以hook Java和native层,且不需要每次都重启手机。官网:http://www.frida.re/
hook对抗遍历进程,判断frida-server是否运行1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public boolean checkRunningProcesses() {
boolean returnValue = false;
// Get currently running application processes
List list = manager.getRunningServices(300);
if(list != null){
String tempName;
for(int i=0;i
tempName = list.get(i).process;
if(tempName.contains("fridaserver")) {
returnValue = true;
}
}
}
return returnValue;
}
fridaserver 默认的 TCP 端口是 27047,可以检查这个端口是否开放1
2
3
4
5
6
7
8
9
10
11boolean is_frida_server_listening() {
struct sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port = htons(27047);
inet_aton("127.0.0.1", &(sa.sin_addr));
int sock = socket(AF_INET , SOCK_STREAM , 0);
if (connect(sock , (struct sockaddr*)&sa , sizeof sa) != -1) {
/* Frida server detected. Do something… */
}
}
每个开放的端口发送 D-Bus 的认证消息,哪个端口回复了哪个就是 fridaserver1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18for(i = 0 ; i <= 65535 ; i++) {
sock = socket(AF_INET , SOCK_STREAM , 0);
sa.sin_port = htons(i);
if (connect(sock , (struct sockaddr*)&sa , sizeof sa) != -1) {
__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "FRIDA DETECTION [1]: Open Port: %d", i);
memset(res, 0 , 7);
// send a D-Bus AUTH message. Expected answer is “REJECT"
send(sock, "x00", 1, NULL);
send(sock, "AUTHrn", 6, NULL);
usleep(100);
if (ret = recv(sock, res, 6, MSG_DONTWAIT) != -1) {
if (strcmp(res, "REJECT") == 0) {
/* Frida server detected. Do something… */
}
}
}
close(sock);
}
内存特征码检测
在内存中扫描 frida 的库特征 “gadgets”。例如字符串 “LIBFRIDA”在所有 frida-gadget 和 frida-agent 的版本中都有出现。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23static char keyword[] = "LIBFRIDA";
num_found = 0;
int scan_executable_segments(char * map) {
char buf[512];
unsigned long start, end;
sscanf(map, "%lx-%lx %s", &start, &end, buf);
if (buf[2] == 'x') {
return (find_mem_string(start, end, (char*)keyword, 8) == 1);
} else {
return 0;
}
}
void scan() {
if ((fd = my_openat(AT_FDCWD, "/proc/self/maps", O_RDONLY, 0)) >= 0) {
while ((read_one_line(fd, map, MAX_LINE)) > 0) {
if (scan_executable_segments(map) == 1) {
num_found++;
}
}
if (num_found > 1) {
/* Frida Detected */
}
}
Substrate
Substrate适用于对native层的hook
hook对抗读取/proc/self/maps
libsubstrate.so和libsubstrate-dvm.so两个文件为Substrate必载入的文件,当进程maps表中出现libsubstrate-dvm.so,可以尝试去load该so文件并调用MSJavaHookMethod方法,它会返回该方法的地址即判定为恶意模块(第三方程序)。1
2
3
4
5
6
7
8
9
10void* lookup_symbol(char* libraryname,char* symbolname)
{
void *imagehandle = dlopen(libraryname, RTLD_GLOBAL | RTLD_NOW);
if (imagehandle != NULL){
void * sym = dlsym(imagehandle, symbolname);
if (sym != NULL){
return sym; //发现Cydia Substrate相关模块
}
...
}
基于特征码的检测
参考资料:
android hook 第三方app_Android三大hook框架相关推荐
- android hook 第三方app_基于 VirtualApp 结合 whale hook框架实现hook第三方应用
要点 1. whale hook framework 使用示例: 2. 参考项目:VirtualHook: 3. 按照 VirtualHook 修改 VirtualApp: 4. 编写 hook pl ...
- 【Android 插件化】Hook 插件化框架总结 ( 插件包管理 | Hook Activity 启动流程 | Hook 插件包资源加载 ) ★★★
Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...
- 【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | Hook 点分析 )
Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...
- Android免Root环境下Hook框架Legend原理分析
0x1 应用场景 现如今,免Root环境下的逆向分析已经成为一种潮流! 在2015年之前的iOS软件逆向工程领域,要想对iOS平台上的软件进行逆向工程分析,越狱iOS设备与安装Cydia是必须的!几乎 ...
- android hook 第三方app_【MiSRC】技术分享-浅谈android hook技术
注:本文为"小米安全中心"原创,转载请联系"小米安全中心" 前言 xposed框架 xposed,主页:http://repo.xposed.info/modu ...
- Android插件化原理解析——Hook机制之动态代理
使用代理机制进行API Hook进而达到方法增强是框架的常用手段,比如J2EE框架Spring通过动态代理优雅地实现了AOP编程,极大地提升了Web开发效率:同样,插件框架也广泛使用了代理机制来增强系 ...
- android基于plt/got的hook原理
目录 概述 简单示例 ELF文件格式初探 装载.动态链接与重定位 PLT与GOT 如何定位基址? 如何修改呢? 解析基址和偏移 思考和小结 概述 我们日常开发中编写的C/C++代码经过NDK进行编译和 ...
- Android 插件化原理学习 —— Hook 机制之动态代理
前言 为了实现 App 的快速迭代更新,基于 H5 Hybrid 的解决方案有很多,由于 webview 本身的性能问题,也随之出现了很多基于 JS 引擎实现的原生渲染的方案,例如 React Nat ...
- Android插件化原理解析——Hook机制之Binder Hook
Android系统通过Binder机制给应用程序提供了一系列的系统服务,诸如ActivityManagerService,ClipboardManager, AudioManager等:这些广泛存在系 ...
- Android 插件化原理解析——Hook机制之AMSPMS
在前面的文章中我们介绍了DroidPlugin的Hook机制,也就是代理方式和Binder Hook:插件框架通过AOP实现了插件使用和开发的透明性.在讲述DroidPlugin如何实现四大组件的插件 ...
最新文章
- linux汇编div除法,汇编:div 除法指令
- virtualBox 创建新虚拟机
- 如何静态添加toolbar到datagrid
- squashfs重打包和ubi重打包
- 在Oracle Coherence中分发Spring Bean
- 高考失常错过清华,而今保送清华直博,还发了数篇 Nature
- Spring Boot——Redis安装配置与应用整合
- 【Java】Java对象序列化I/O体系总结
- 演练 聚美Y品商品分类导航 1002 html
- Python《搞事情==蜂-鸟-图-片(二)》
- 【ROS学习笔记】(八)服务数据的定义与使用
- Python – numpy.arange()
- 关于mssql的学习体会,仅供参考!
- java常见异常和代码演示
- ORACLE安装之环境搭建
- matlab神经网络流程图,BP神经网络算法步骤.doc
- 什么是前端总线,后端总线,内部总线、系统总线,外部总线,地址总线,数据总线,控制总线
- 论文阅读--Emotion Recognition in Conversation: Research Challenges, Datasets, and Recent Advances
- codevs2822 爱在心中(tarjan求缩点的度)
- Cesium中如何获取鼠标单击位置的经纬度
热门文章
- HackerRank python练习——Quartiles
- excel求四分位数(QUARTILE 函数)
- apollo之集群部署(二)
- 形式化方法 | Proof Engineering in Coq——Coq tatics 在命题逻辑证明中的应用
- PotPlayer不支持S/W HEVC(H.265)解码怎么办?一招解决所有的不支持解码
- Gradle实现多渠道打包(不同资源文件打不同的包)
- 5G NR 上行调度算法流程
- 常见的影视cms及安装环境说明
- 【C#.NET MVC】Deft框架简介与基本使用
- 南方电网数据安全建设分析——云集至