利用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 预热 时光荏苒,光阴如梭,离上一次吹牛逼已经过去了两三个月,身边很多人的女 ...
随机推荐
- Leetcode 88 Merge Sorted Array STL
合并有序数组 时间复杂度O(m+n) 该算法来自各种算法与数据结构书,写得已经烂得不能再烂了,这个应该是最短的代码了吧,不知如何归类 class Solution { public: void mer ...
- python基于LeanCloud的短信验证
python基于LeanCloud的短信验证 1. 获取LeanCloud的Id.Key 2. 安装Flask框架和Requests库 pip install flask pip install re ...
- 用自己的算法实现startsWith和endsWith功能
package hanqi; import java.util.Random; import java.util.Scanner; public class zuoye { public static ...
- [推荐]PaaS技术知识贴
[推荐]PaaS技术知识贴 云计算PaaS技术与应用 http://wenku.baidu.com/view/08f77eefaeaad1f346933f20?fr=prin大型WEB网站架构深入分析 ...
- Apache Solr查询语法(转)
查询参数 常用: q - 查询字符串,必须的. fl - 指定返回那些字段内容,用逗号或空格分隔多个. start - 返回第一条记录在完整找到结果中的偏移位置,0开始,一般分页用. rows - 指 ...
- WebClient的异步处理
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Te ...
- //暴力打开某个APP iOS 私有API LSApplicationWorkspace
//暴力打开某个APP = .= 如果可以打开.直接打开不解释 +(BOOL)isOpenApp:(NSString*)appIdentifierName { Class LSApplicationW ...
- libevent 安装异常
有homebrew的可以使用 1 brew install memcached 这个命令来安装没有homebrew的可以直接手动安装1.去官网http://memcached.org/下载最新的包,然 ...
- JAVA自动化测试数据设计
数据管理是很重要的,数据管理与方法一样,依然是有层次的,我们在测试的过程中,可能会有多个环境,每个环境的URL啊,登录名啊,数据库连接地址啊等等不一样,我们可以把这些环境每个都配置一个数据文件,里面写 ...
- android:style.xml
<?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2006 The Andr ...