在前面关于Substrate的介绍中我们已经讲了用Substrate hook java代码,现在我们讲下怎么用它hook native代码。hook native代码我们需要编写Substrate extensions,它跟native库一样被视作标准的android包的一部分, 将作为一个共享库被编译 (使用复合扩展名.cy.so)。

一、相关API

(1)MSConfig
 
名称 描述
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, &copy, 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(二)的更多相关文章

  1. 利用Cydia Substrate进行Android HOOK

    Cydia Substrate是一个代码修改平台.它可以修改任何主进程的代码,不管是用Java还是C/C++(native代码)编写的.而Xposed只支持HOOK app_process中的java ...

  2. 使用Cydia Substrate 从Native Hook Android Native世界

    同系列文章: 使用Cydia Substrate 从Native Hook Android Java世界 使用Cydia Substrate Hook Android Java世界 一.建立工程 手机 ...

  3. 使用Cydia Substrate 从Native Hook Android Java世界

    这里介绍了如何使用Cydia Substrate Hook安卓Java世界.这篇文章介绍如何从Native中Hook 安卓Java世界. 手机端配置见之前文章. 一.建立工程 建立一个Android工 ...

  4. Android上玩玩Hook:Cydia Substrate实战

    作者简介:周圣韬,百度高级Android开发工程师,博客地址:http://blog.csdn.net/yzzst 了解Hook 还没有接触过Hook技术读者一定会对Hook一词感觉到特别的陌生,Ho ...

  5. Cydia Substrate based DexDumper's weakness

    得益于Cydia Substrate框架,HOOK Native函数变得简单,也给脱壳带来方便. 像ijiami免费版,360,classes.dex被加密到so文件并运行时释放到内存,因此针对相关函 ...

  6. Android逆向之旅---Native层的Hook神器Cydia Substrate使用详解

    一.前言 在之前已经介绍过了Android中一款hook神器Xposed,那个框架使用非常简单,方法也就那几个,其实最主要的是我们如何找到一个想要hook的应用的那个突破点.需要逆向分析app即可.不 ...

  7. Android HOOK工具Cydia Substrate使用详解

    目录(?)[+] Substrate几个重要API介绍 MShookClassLoad MShookMethod 使用方法 短信监控实例   Cydia Substrate是一个代码修改平台.它可以修 ...

  8. 使用Cydia Substrate Hook Android Java世界

    从来没接触过Android的HOOK,在看雪上找到了一篇HOOK 的文章,但是太复杂了,应该是本地环境问题,测试不成功. 后来搜到Cydia Substrate,看了几篇文章,进入官网查看了一下文档, ...

  9. 利用FFmpeg玩转Android视频录制与压缩(二)<转>

    转载出处:http://blog.csdn.net/mabeijianxi/article/details/72983362 预热 时光荏苒,光阴如梭,离上一次吹牛逼已经过去了两三个月,身边很多人的女 ...

随机推荐

  1. Atitit. 高级软件工程师and 普通的区别 高级编程的门槛总结

    Atitit.  高级软件工程师and 普通的区别 高级编程的门槛总结 1. 完备的知识体系 2 2. 编程理论/原理的掌握 2 1.1. 掌握常用的概念(ORM,IOC,AOP,event driv ...

  2. paip.刮刮卡砸金蛋抽奖概率算法跟核心流程.

    paip.刮刮卡砸金蛋抽奖概率算法跟核心流程. #---抽奖算法需要满足的需求如下: 1 #---抽奖核心流程 1 #---问题???更好的算法 2 #---实际使用的扩展抽奖算法(带奖品送完判断和每 ...

  3. paip.提高效率---集合的存取括号方式 uapi java python php js 的实现比较

    paip.提高效率---集合的存取括号方式 uapi java python php js 的实现比较 ##java ----------- 在JDK1.7中,摒弃了Java集合接口的实现类,如:Ar ...

  4. JAVA学习中Swing概述中的JFrame学习

    package com.swing; import java.awt.Color;import java.awt.Container;import java.awt.event.WindowAdapt ...

  5. gcc5.1.0升级指南

    请使用root权限用控制台安装gcc5.1.0(重要) 1.首先把旧的gcc相关的编译工具安装好(没有安装会导致后面的错误) yum upgrade gcc //升级gcc库 yum -y insta ...

  6. 内存中 OLTP - 常见的工作负荷模式和迁移注意事项(一)

    ----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<In-Memory OLTP – Comm ...

  7. use IFS in bash

    function dfd() { #http://www.cnblogs.com/hunterfu/archive/2010/02/23/1672129.html IFS=$'\n' for i in ...

  8. android: SQLite升级数据库

    如果你足够细心,一定会发现 MyDatabaseHelper 中还有一个空方法呢!没错,onUpgrade() 方法是用于对数据库进行升级的,它在整个数据库的管理工作当中起着非常重要的作用,可 千万不 ...

  9. C#中Math.Round()实现中国式四舍五入

    C#中Math.Round()实现中国式四舍五入 C#中的Math.Round()并不是使用的"四舍五入"法.其实在VB.VBScript.C#.J#.T-SQL中Round函数都 ...

  10. Autosizer应用程序窗口控制工具

    Autosizer是一个系统辅助软件,窗口控制工具,它能指定程序窗口的大小位置置顶等,可以将窗口最大化,最小化,比如在需要截图的时候可以讲窗口设定大小640*480,然后用FSCapture捕捉活动窗 ...