利用Cydia Substrate进行Android HOOK(二)
在前面关于Substrate的介绍中我们已经讲了用Substrate hook java代码,现在我们讲下怎么用它hook native代码。hook native代码我们需要编写Substrate extensions,它跟native库一样被视作标准的android包的一部分, 将作为一个共享库被编译 (使用复合扩展名.cy.so)。
一、相关API
| 名称 | 描述 |
Filter:Executable |
开发者试图hook的可执行文件的完整路径。一般为zygote, "/system/bin/app_process"。 |
Filter:Library |
开发者试图hook的lib库的名称,比如hook __android_log, 则指定 "liblog.so". |
如:
MSConfig(MSFilterExecutable, "/system/bin/app_process")
MSConfig(MSFilterLibrary, "liblog.so")
(2)void MSHookFunction(void *symbol, void *hook, void **old);
| 参数 | 描述 |
|---|---|
symbol |
被替换代码的地址,一般是一个函数 |
hook |
The address of an ABI-compatible replacement for the code at the address referenced by symbol. |
old |
指向函数指针的指针,用来调用原函数的实现。如果不需要对原函数进行处理则为NULL |
示例:
void *(*oldConnect)(int, const sockaddr *, socklen_t); void *newConnect(
int socket, const sockaddr *address, socklen_t length
) {
if (address->sa_family == AF_INET) {
sockaddr_in *address_in = address;
if (address_in->sin_port == htons()) {
sockaddr_in copy = *address_in;
address_in->sin_port = htons();
return oldConnect(socket, ©, length);
}
} return oldConnect(socket, address, length);
} MSHookFunction(&connect, &newConnect, &oldConnect);
(3)void *MSFindSymbol(MSImageRef image, const char *name);
| 参数 | 描述 |
|---|---|
image |
指定一个有效的image引用(通过调用MSGetImageByName返回的结果)。如果为NULL,则会搜索所有image |
name |
待查找的原始镜像符号的名称。这并非如dlopen所加载的高级符号,它可能需要以下划线为前缀或其他特定平台的编码。 |
return |
符号的地址(调整为ARM/Thumb类型),如果不能定位符号则返回NULL |
示例:
MSImageRef image;
image = MSGetImageByName("/usr/lib/libSystem.B.dylib"); void *(*palloc)(size_t);
palloc = (void *(*)(size_t)) MSFindSymbol(image, "_malloc"); void *data = (*palloc)();
free(data);
(4)MSImageRef MSGetImageByName(const char *file);
| 参数 | 描述 |
|---|---|
file |
根据so或者动态库的完整路径加载image |
return |
可以被其它API使用的image引用,如果image没有加载则为NULL |
示例:
MSImageRef image;
image = MSGetImageByName("/system/lib/libc.so");
if (image != NULL)
/* image is loaded */;
二、使用示例
下面以前一篇过签名验证的hook代码为例讲解native hook的代码编写过程:
1.创建android native工程HookVerify,so层hook并不需要界面(作为Cydia Substrate的扩展模块),所以在新建工程时无需建activity。接下来在工程目录下新建jni文件夹,并将libsubstrate.so,libsubstrate-dvm.so,substrate.h三个文件拷贝至jni文件夹下。
在jni目录下创建HookVerify.cy.cpp文件。

2.配置Manifest文件
需要添加权限:<uses-permission android:name="cydia.permission.SUBSTRATE"/>
由于我们只使用native code,将android:hasCode设为false。
3.Android.mk文件编写:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := substrate
LOCAL_SRC_FILES := libsubstrate.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := substrate-dvm
LOCAL_SRC_FILES := libsubstrate-dvm.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := HookVerify
#一定要有.cy作后缀
LOCAL_SRC_FILES := HookVerify.cy.cpp
LOCAL_LDLIBS := -llog
LOCAL_ARM_MODE := arm
LOCAL_LDLIBS += -L$(LOCAL_PATH) -lsubstrate-dvm -lsubstrate
include $(BUILD_SHARED_LIBRARY)
4.HookVerify.cy.cpp代码:
#include <jni.h>
#include "substrate.h"
#include <android/log.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <string.h>
#include <sys/stat.h>
#define TAG "HOOKDEMO"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
char* AppName = NULL;
//指定要hook的lib 库:
MSConfig(MSFilterLibrary, "/system/lib/libdvm.so");
//保留原来的地址:
void *(*oldUnzOpen64)(const char* filepath);
//替换的函数
void *newUnzOpen64(const char* filepath){
return oldUnzOpen64("/sdcard/myapk.apk");
}
//Hook dvmLoadNativeCode
bool (*_dvmLoadNativeCode)(char* pathName, void* classLoader, char** detail);
bool My_dvmLoadNativeCode(char* pathName, void* classLoader, char** detail){
bool b_Result = _dvmLoadNativeCode(pathName,classLoader,detail); //进行原来的调用,不影响程序运行
//LOGD("dvmLoadNativeCode AppName:%s", AppName);
if(strstr(pathName,"AppVerify") != NULL){
LOGD("dvmLoadNativeCode Find Hook");
MSImageRef image = MSGetImageByName(pathName);
if(image != NULL){
void* mFun = MSFindSymbol(image, "unzOpen64");
//开始Hook fork
if(mFun != NULL){
LOGD("dvmLoadNativeCode Hook");
//MSHookFunction(mFun,(void*)&My_fork,(void**)&_fork);
36 MSHookFunction(mFun, (void*)&newUnzOpen64, (void**)&oldUnzOpen64);
}
}
}
return b_Result;
}
//在初始化的时候进行hook,具体如下:
//Substrate entry point
MSInitialize{
__android_log_print(ANDROID_LOG_ERROR, TAG, "Substrate initialized.");
MSImageRef image;
image = MSGetImageByName("/system/lib/libdvm.so"); //载入lib
if (image != NULL)
{
//注意这个是个c++函数,可以通过objdump来获取
void * dvmload = MSFindSymbol(image, "_Z17dvmLoadNativeCodePKcP6ObjectPPc");
if(dvmload == NULL)
{
LOGD("error find dvmLoadNativeCode ");
}
else{
MSHookFunction(dvmload,(void*)&My_dvmLoadNativeCode,(void **)&_dvmLoadNativeCode);
}
}
else{
LOGD("ERROR FIND LIBDVM");
}
}
这样就完成了hook代码的编写。安装运行就行了。
利用Cydia Substrate进行Android HOOK(二)的更多相关文章
- 利用Cydia Substrate进行Android HOOK
Cydia Substrate是一个代码修改平台.它可以修改任何主进程的代码,不管是用Java还是C/C++(native代码)编写的.而Xposed只支持HOOK app_process中的java ...
- 使用Cydia Substrate 从Native Hook Android Native世界
同系列文章: 使用Cydia Substrate 从Native Hook Android Java世界 使用Cydia Substrate Hook Android Java世界 一.建立工程 手机 ...
- 使用Cydia Substrate 从Native Hook Android Java世界
这里介绍了如何使用Cydia Substrate Hook安卓Java世界.这篇文章介绍如何从Native中Hook 安卓Java世界. 手机端配置见之前文章. 一.建立工程 建立一个Android工 ...
- Android上玩玩Hook:Cydia Substrate实战
作者简介:周圣韬,百度高级Android开发工程师,博客地址:http://blog.csdn.net/yzzst 了解Hook 还没有接触过Hook技术读者一定会对Hook一词感觉到特别的陌生,Ho ...
- Cydia Substrate based DexDumper's weakness
得益于Cydia Substrate框架,HOOK Native函数变得简单,也给脱壳带来方便. 像ijiami免费版,360,classes.dex被加密到so文件并运行时释放到内存,因此针对相关函 ...
- Android逆向之旅---Native层的Hook神器Cydia Substrate使用详解
一.前言 在之前已经介绍过了Android中一款hook神器Xposed,那个框架使用非常简单,方法也就那几个,其实最主要的是我们如何找到一个想要hook的应用的那个突破点.需要逆向分析app即可.不 ...
- Android HOOK工具Cydia Substrate使用详解
目录(?)[+] Substrate几个重要API介绍 MShookClassLoad MShookMethod 使用方法 短信监控实例 Cydia Substrate是一个代码修改平台.它可以修 ...
- 使用Cydia Substrate Hook Android Java世界
从来没接触过Android的HOOK,在看雪上找到了一篇HOOK 的文章,但是太复杂了,应该是本地环境问题,测试不成功. 后来搜到Cydia Substrate,看了几篇文章,进入官网查看了一下文档, ...
- 利用FFmpeg玩转Android视频录制与压缩(二)<转>
转载出处:http://blog.csdn.net/mabeijianxi/article/details/72983362 预热 时光荏苒,光阴如梭,离上一次吹牛逼已经过去了两三个月,身边很多人的女 ...
随机推荐
- jQuery/javascript实现网页注册的表单验证
<html> <head> <meta charset="utf-8"> <title>注册表单验证</title> & ...
- jQuery的简单入门练习
<html> <head> <meta charset="utf-8"> <title>jQuery的练习</title> ...
- jsp、js分页功能的简单总结
一.概述 首先,我们要明确为何需要分页技术,主要原因有以下: 1.分页可以提高客户体验度,适当地选择合适的数据条数,让页面显得更有条理,使得用户体验感良好,避免过多数据的冗余. 2.提高性能的需要.分 ...
- javascript设计模式与开发实践阅读笔记(9)——命令模式
命令模式:有时候需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是什么,此时希望用一种松耦合的方式来设计软件,使得请求发送者和请求接收者能够消除彼此之间的耦合关系. 说法很复 ...
- iOS5可能会删除本地文件储存 - Caches 也不安全
转自:http://blog.163.com/ray_jun/blog/static/1670536422011101225132544/ 出处:http://superman474.blog.163 ...
- JPA 不在 persistence.xml 文件中配置每个Entity实体类的2种解决办法
在Spring 集成 Hibernate 的JPA方式中,需要在persistence配置文件中定义每一个实体类,这样非常地不方便,远哥目前找到了2种方法. 这2种方式都可以实现不用persist ...
- 今天踩过的坑——structs和spring
struts 如果实现了CookiesAware了,还需要引用org.apache.struts2.interceptor.CookieInterceptor过滤器,否则拿不到值同时还要能看到这样的错 ...
- cmd for 循环拷贝文件
这几天忙活部署测试环境, 中途需要拷贝 文件, 直接贴code吧: ::/定义原路径 set source=seventrat_test_backend,seventrat_test_frontend ...
- Asp.net WebApi + EF 单元测试架构 DbContext一站到底
其实关于webapi和Ef service的单元测试我以前已经写过相关文章,大家可以参考: Asp.net WebAPI 单元测试 单元测试 mock EF 中DbContext 和DbSet Inc ...
- ThinkBox DOC
插件源码下载 @github https://github.com/Aoiujz/ThinkBox.git 插件使用方法 引入文件 //使用ThinkBox弹出框必须引入以上三个文件. //jQuer ...