您的位置:首页 > 移动开发 > Android开发

Cydia Substrate Android SO Hook

2016-06-03 21:06 288 查看
Cydia Substrate出了android版本的hook框架,不仅能hook java层函数,还能hook so中的函数,其核心原理是函数的inline hook,与xposed有着十分大的差别(xposed主要通过hookMethodNative将java层函数替换成native层函数而完成hook)。

合理使用Cydia Substrate可以有效绕过反调试,签名校验还可以制作脱壳机等,大大加快分析APK的效率。这篇文章主要介绍使用Cydia Substrate Android框架进行so层的hook。


1.安装apk并下载SDK

在官网(http://www.cydiasubstrate.com/)中下载substrate的android版apk并安装(需要root权限)。

在官网中下载SDK(http://www.cydiasubstrate.com/id/73e45fe5-4525-4de7-ac14-6016652cc1b8/):。so层hook只需要用到SDK中的libsubstrate.so,libsubstrate-dvm.so,substrate.h。


2.新建Android工程

so层hook并不需要界面(作为Cydia Substrate的扩展模块),所以在新建工程时无需建activity。接下来在工程目录下新建jni文件夹,并将libsubstrate.so,libsubstrate-dvm.so,substrate.h三个文件拷贝至jni文件夹下。

在AndroidManifest.xml中添加权限:

1<uses-permission android:name="cydia.permission.SUBSTRATE"/>

3.编写hook模块

本次演示实例hook了libc.so中的fopen函数,完整代码如下:

1

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

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

#include <stdio.h>

#include <android/log.h>

#include <unistd.h>

#include "substrate.h"

 

#define TAG "CydiaHook"

#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG ,__VA_ARGS__)
// 定义LOGI类型

 

 

#define GETLR(store_lr)  \

  __asm__
__volatile__(  \

    "mov
%0, lr\n\t"  \

    :  "=r"(store_lr)  \

  )

 

 

//指明要hook的lib

MSConfig(MSFilterLibrary,
"/system/lib/libc.so")

 

int
(*
oldfopen)(const
char*
path,
const
char*
mode);

 

int
newfopen(const
char*
path,
const
char*
mode)
{

 

LOGI("call
my fopen!!:%d",getpid());

unsigned
lr;

GETLR(lr);

 

if
(strstr(path,
"status")
!=
NULL)
{

LOGI("[*]
Traced-fopen Call function: 0x%x\n",
lr);

if
(strstr(path,
"task")
!=
NULL)
{

LOGI("[*]
Traced-anti-task/status");

}
else

LOGI("[*]
Traced-anti-status");

}
else
if
(strstr(path,
"wchan")
!=
NULL)
{

LOGI("[*]
Traced-fopen Call function: 0x%x\n",
lr);

LOGI("[*]
Traced-anti-wchan");

}

return
oldfopen(path,
mode);

}

 

 

 

/*

* Substrate entry point

*/

//初始化时进行hook

MSInitialize

{

//
Let the user know that the extension has been

//
extension has been registered

LOGI(
"Substrate initialized.");

MSImageRef
image;

 

image
=
MSGetImageByName("/system/lib/libc.so");

 

if
(image
!=
NULL)

{

void
*
hookfopen=MSFindSymbol(image,"fopen");

if(hookfopen==NULL)

{

LOGI("error
find fopen ");

}

else
{

MSHookFunction(hookfopen,(void*)&newfopen,(void
**)&oldfopen);

}

}

else
{

LOGI("ERROR
FIND LIBC");

}

 

}

注意:在初始配置MSConfig中第一个参数是MSFilterLibrary,表示要hook lib,如果要hook可执行文件的话,这个参数为MSFilterExecutable。

本实例实现的效果为:在调用fopen时打印调用这pid,如果发现打开特殊文件(/proc/pid/status等)则打印出调用这地址,arm汇编中lr寄存器保存了函数返回地址,所以在进入函数时打印该值就表示调用者的虚拟地址。


4.编写makefile

在jni文件夹下新建Android.mk文件,内容如下:

1

2

3

4

5

6

7

8

9

10

11

12

LOCAL_PATH
:=
$(call
my-dir)

 

include
$(CLEAR_VARS)

LOCAL_MODULE:=
substrate-dvm

LOCAL_SRC_FILES
:=
libsubstrate-dvm.so

include
$(PREBUILT_SHARED_LIBRARY)

 

include
$(CLEAR_VARS)

LOCAL_MODULE    :=
hooktest.cy
#生成的模块名

LOCAL_SRC_FILES
:=
hooktest.cy.cpp
#源文件名

LOCAL_LDLIBS:=
-L$(LOCAL_PATH)
-lsubstrate
-lsubstrate-dvm  -llog
#加入substrate模块

include
$(BUILD_SHARED_LIBRARY)

接下来通过ndk-build编译生成hooktest.cy模块,再运行安装apk,在substrate中点击Link Substrate Files,最后软重启即可看到hook的效果:





5.后记

本次演示实例只是简单hook了fopen函数,反调试时经常会读取关键文件,hook了fopen就可以很方便的知道它的调用点,当然还可以进行重定向等直接绕过;几个月前ThomasKing牛在看雪上发表的《基于HOOK的Anti-debug调用点trace和Anti-anti》,就是通过cydia
substrate完成的,当然还有很早之前空道牛发表的《过百分之八十的签名校验模块》也是基于substrate,所以说如果能用好substrate,可以大大简化apk破解的难度,当然这对于移动安全而言也是一个很大的挑战。

http://burningcodes.net/cydia-substrate-android-so-hook/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: