Mac hook苹果系统进程监控劫持

Mac hook——DYLD_INSERT_LIBRARIES

  (2013-06-27 10:32:20)
标签: 

dyld_insert_librarie

 

it

 
分类: IOS学习

转自: http://danqingdani.blog.163.com/blog/static/186094195201311105254605/
网易微博:碳基体。

Mac可以通过设置DYLD_INSERT_LIBRARIES环境变量(linux上对应的环境变量是LD_PRELOAD ,效果实例可见 Android hook——LD_PRELOAD,重写动态链接库中的函数,实现hook功能。


以下是演示实例


一、替换动态链接库中的c函数

实例一:使用openhook.dylib中的f() 替换原始动态链接库mysharedlib.dylib中的f() 实例来源


(一)、源文件

1. mysharedlib.h

 

void f();
2. mysharedlib.c

 

 

#include 
#include "mysharedlib.h"

void f(){
printf("hello,dani \n");
}

3. main.c

 

#include 
#include "mysharedlib.h"

int main(){
f();
return 0;
}

 

4. openhook.c

 

 

#include 
#include 
#include 
#include "mysharedlib.h"

typedef void (*fType) ();
static void (*real_f)()=NULL;

void f(){
if (! real_f){
void * handle = dlopen("mysharedlib.dylib", RTLD_NOW);
real_f = (fType) dlsym(handle,"f");

if(! real_f) printf("NG");
}
printf("--------zz------");

real_f();
}
关键函数:
dlopen函数原型, void * dlopen( const char *  pathname , int  mode ),pathname是指定动态链接库地址,mode是打开模式
dlsym函数原型, void* dlsym(void* handle,const char* symbol), handle是由dlopen 打开动态链接库 后返回的指针 ,symbol是指定获取的符号 名,对c语言而言,符号名就是函数名,我们可以使用nm查看 mysharedlib.dylib
dani-2:testC leedani$ nm mysharedlib.dylib
0000000000000f20 T _f
U _puts
U dyld_stub_binder

(二)、编译
1. 生成mysharedlib.dylib, 该动态链接库的功能就是f(),打印“hello,dani”

 

gcc -dynamiclib -o mysharedlib.dylib mysharedlib.c
dynamiclib选项是指生成动态链接库

2. 编译 mysharedlib.dylib与main.c文件,生成最终的可执行文件

 

 

gcc mysharedlib.dylib main.-o main
3. 生成openhook.dylib,该动态链接库的功能就是替换mysharedlib.dylib中的 f()

 

 

gcc -flat_namespace -dynamiclib -o openhook.dylib openhook.c

flat_namespace选项指定了链接模式,有两种模式,flat-namespacetwo-levelnamespace,模式不一样生成的符号表也会不一样(具体区别)。

实例中mysharedlib.dylib没有采用该选项,而openhook.dylib采用了该选项,我们可以查看以下这两个文件的头结构,来对比一下

 

dani-2:testC leedani$ otool -hV mysharedlib.dylib 
mysharedlib.dylib:
Mach header
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
MH_MAGIC_64 X86_64 ALL 0x00 DYLIB 13 1200 NOUNDEFS DYLDLINK TWOLEVEL NO_REEXPORTED_DYLIBS
dani-2:testC leedani$ otool -hV openhook.dylib 
openhook.dylib:
Mach header
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
MH_MAGIC_64 X86_64 ALL 0x00 DYLIB 13 1272 DYLDLINK NO_REEXPORTED_DYLIBS

 

(三)、 运行

 

1. 正常的运行结果

 

dani-2:test leedani$ ./main 
hello,dani
2. Hook后的运行结果
通过设置环境变量DYLD_INSERT_LIBRARIES(linux上对应的环境变量是 LD_PRELOAD ,效果实例可见  Android hook——LD_PRELOAD

 

dani-2:test leedani$ export DYLD_FORCE_FLAT_NAMESPACE=1
dani-2:test leedani$ export DYLD_INSERT_LIBRARIES=openhook.dylib
dani-2:test leedani$ ./main 
--------zz------hello,dani

DYLD_INSERT_LIBRARIES与DYLD_FORCE_FLAT_NAMESPACE环境变量在apple官方手册中有说明,如下所示:

 
  
Mac hook——DYLD_INSERT_LIBRARIES - 碳基体 - 碳基体
 
实例二:替换系统动态链接库中的函数,如下所示替换/usr/lib/libSystem.dylib中的time函数
(一)、源码
time .c
#include 

//This function will override the one in /usr/lib/libSystem.dylib

time_t time(time_t *tloc){
//January 1st,2013
struct tm timeStruct;
timeStruct.tm_year= 2013-1900;
timeStruct.tm_mon = 0;
timeStruct.tm_mday = 1;
timeStruct.tm_hour = 0;
timeStruct.tm_min = 0;
timeStruct.tm_sec = 0;
timeStruct.tm_isdst = -1;

*tloc = mktime(&timeStruct);

return *tloc;
}

(二)、编译
gcc -flat_namespace -dynamiclib -current_version 1.0 time.-o libTime.dylib

(三)、运行
1. 正常的运行结果
dani-2:test leedani$ date
2013 2 1 星期五 144616 CST
2.替换系统函数后的运行结果
dani-2:test leedani$ export DYLD_FORCE_FLAT_NAMESPACE=1
dani-2:test leedani$ export DYLD_INSERT_LIBRARIES=libTime.dylib dani-2:test leedani$ date 2013 1 1 星期二 000000 CST

 

二、替换动态链接库中的c++ 类方法

 

</pre><div style="line-height: normal; font-family: Georgia, serif; font-size: 13px;"><a target=_blank target="_blank" href="http://koichitamura.blogspot.com/2008/11/hooking-library-calls-on-mac.html" style="text-decoration: none; color: rgb(62, 115, 160);">实例来源</a></div><div style="line-height: normal; font-family: Georgia, serif;"><span style="word-wrap: normal; word-break: normal; line-height: 23px; font-size: 13px;">(一)、</span><span style="font-size:14px;word-wrap: normal; word-break: normal; line-height: 28px;"><strong>源码</strong></span></div><div style="line-height: normal; font-family: Georgia, serif; font-size: 13px;">1. mysharedlib.h</div><div><pre style="white-space: normal; padding: 2px; border: 1px solid rgb(136, 136, 136);"><span style="font-size:14px;word-wrap: normal; word-break: normal; line-height: 23px;"><span style="word-wrap: normal; word-break: normal; line-height: 20px;"><span style="word-wrap: normal; word-break: normal; line-height: 23px; color: rgb(0, 0, 136);">class</span><span style="word-wrap: normal; word-break: normal; line-height: 23px; color: rgb(0, 0, 0);"> AAA</span><br style="line-height: 23px;" /><span style="word-wrap: normal; word-break: normal; line-height: 23px; color: rgb(102, 102, 0);">{</span><br style="line-height: 23px;" /><span style="word-wrap: normal; word-break: normal; line-height: 23px; color: rgb(0, 0, 136);">public</span><span style="word-wrap: normal; word-break: normal; line-height: 23px; color: rgb(102, 102, 0);">:</span><br style="line-height: 23px;" /><span style="word-wrap: normal; word-break: normal; line-height: 23px; color: rgb(0, 0, 136);">int</span><span style="word-wrap: normal; word-break: normal; line-height: 23px; color: rgb(0, 0, 0);"> m</span><span style="word-wrap: normal; word-break: normal; line-height: 23px; color: rgb(102, 102, 0);">;</span><br style="line-height: 23px;" /><br style="line-height: 23px;" /><span style="word-wrap: normal; word-break: normal; line-height: 23px; color: rgb(0, 0, 0);">AAA</span><span style="word-wrap: normal; word-break: normal; line-height: 23px; color: rgb(102, 102, 0);">()</span><br style="line-height: 23px;" /><span style="word-wrap: normal; word-break: normal; line-height: 23px; color: rgb(102, 102, 0);">{</span><br style="line-height: 23px;" /><span style="word-wrap: normal; word-break: normal; line-height: 23px; color: rgb(0, 0, 0);">m </span><span style="word-wrap: normal; word-break: normal; line-height: 23px; color: rgb(102, 102, 0);">=</span><span style="word-wrap: normal; word-break: normal; line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="word-wrap: normal; word-break: normal; line-height: 23px; color: rgb(0, 102, 102);">1234</span><span style="word-wrap: normal; word-break: normal; line-height: 23px; color: rgb(102, 102, 0);">;</span><br style="line-height: 23px;" /><span style="word-wrap: normal; word-break: normal; line-height: 23px; color: rgb(102, 102, 0);">}</span><br style="line-height: 23px;" /><br style="line-height: 23px;" /><span style="word-wrap: normal; word-break: normal; line-height: 23px; color: rgb(0, 0, 136);">void</span><span style="word-wrap: normal; word-break: normal; line-height: 23px; color: rgb(0, 0, 0);"> fff</span><span style="word-wrap: normal; word-break: normal; line-height: 23px; color: rgb(102, 102, 0);">(</span><span style="word-wrap: normal; word-break: normal; line-height: 23px; color: rgb(0, 0, 136);">int</span><span style="word-wrap: normal; word-break: normal; line-height: 23px; color: rgb(0, 0, 0);"> a</span><span style="word-wrap: normal; word-break: normal; line-height: 23px; color: rgb(102, 102, 0);">);</span><br style="line-height: 23px;" /><span style="word-wrap: normal; word-break: normal; line-height: 23px; color: rgb(102, 102, 0);">};</span></span></span>
2. mysharedlib.cpp
#include 
#include "mysharedlib.h"

void AAA::fff(int a)
{

printf("-- Original: %d --", a);

}
3. main.cpp
#include 
#include "mysharedlib.h"

int main()
{

AAA a;

printf("---------main1-------\n");

a.fff(50);

printf("\n---------main2-------\n");

return 0;
}
4. openhook.cpp
#include 
#include 
#include 
#include "mysharedlib.h"

typedef void (*AAAfffType)(AAA*,int);
static void (*real_AAAfff)(AAA*,int);

extern "C"
{

void _ZN3AAA3fffEi(AAA* a, int b)
{

printf("---------AAA::fff------\n");
printf("%d,%d \n",b,a->m);

void * handle = dlopen("mysharedlib.dylib", RTLD_NOW);

real_AAAfff = (AAAfffType)dlsym(handle, "_ZN3AAA3fffEi");

if(real_AAAfff) printf("OK");

real_AAAfff(a,b);
}
}
关键函数:
dlopen函数原型, void * dlopen( const char *  pathname , int  mode ),pathname是指定动态链接库地址,mode是打开模式
dlsym函数原型, void* dlsym(void* handle,const char* symbol), handle是由dlopen 打开动态链接库 后返回的指针 ,symbol是指定获取的符号 名,对c++语言而言,由于存在name mangling,符号名不再是函数名了,编译器不同生成的符号名也会有所区别, 我们可以使用nm查看 mysharedlib.dylib
dani-2:testCPP leedani$ nm mysharedlib.dylib 
0000000000000f0c T __ZN3AAA3fffEi
U _printf
U dyld_stub_binder
使用关键字extern "C"是为了防止符号名被mangle,使其可以像c一样被dlsym加载, 具体的如何在unix环境下使用dlopen 动态加载c++类函数可以看这篇文章《 c++ dlopen mini HOWTO

(二)、 编译
1. 生成mysharedlib.dylib, 该动态链接库的功能就是f(),打印“hello,dani”

 

gcc -dynamiclib -lstdc++ -o mysharedlib.dylib mysharedlib.cpp
2. 编译 mysharedlib.dylib与main.c文件,生成最终的可执行文件

 

 

gcc -lstdc++ mysharedlib.dylib main.cpp -o main
3. 生成openhook.dylib,该动态链接库的功能就是替换mysharedlib.dylib中的 f()

 

 

gcc -flat_namespace -dynamiclib -lstdc++ -o openhook.dylib openhook.cpp
(三)、 运行
1. 正常运行
dani-2:testCPP leedani$ ./main 
---------main1-------
-- Original: 50 --
---------main2-------
2. hook后的结果,通过设置环境变量DYLD_INSERT_LIBRARIES

 

 

dani-2:test leedani$ export DYLD_FORCE_FLAT_NAMESPACE=1
dani-2:test leedani$ export DYLD_INSERT_LIBRARIES=openhook.dylib
dani-2:testCPP leedani$ ./main ---------main1------- ---------AAA::fff------ 50,1234  OK  -- Original: 50 -- ---------main2-------

三、小结
这种通过设置环境变量DYLD_INSERT_LIBRARIES,动态加载函数、类方法来实现使用自己编写的动态连接库dylib来patch运行中的应用的手段,是外挂、MobileSubstrate插件的主要原理,推广到PC windows平台(dll hook),Android平台(linux平台)(so hook),iOS平台(mac平台)(dylib hook),可以说动态加载技术奠定了软件patch的基础,需要深入了解。

  参考:
http://koichitamura.blogspot.com/2008/11/hooking-library-calls-on-mac.html
http://hactheplanet.com/blog/80
https://developer.apple.com/library/mac/#documentation/Darwin/Reference/Manpages/man1/dyld.1.html
https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/dlopen.3.html
https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/dlsym.3.html
https://developer.apple.com/library/mac/#documentation/developertools/conceptual/MachOTopics/1-Articles/executing_files.html
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Hook进程创建函数是一种监控和拦截进程技术。当一个进程被创建时,操作系统会调用相应的进程创建函数来执行一系列的操作,例如分配内存、初始化资源等。通过hook进程创建函数,我们可以在进程创建的过程中插入自定义的代码,从而实现对进程监控和拦截。 通过hook进程创建函数,我们可以实现以下功能: 1. 监控进程创建:通过hook进程创建函数,我们可以记录下每个进程的创建情况,包括进程的名称、进程ID等信息。这对于进程管理、调试和安全审计等方面都非常有用。 2. 拦截进程创建:当我们希望阻止某个进程的创建时,可以通过hook进程创建函数实现进程的拦截。例如,某些恶意程序会通过创建新进程的方式进行传播,我们可以通过hook进程创建函数拦截这些进程的创建,从而保护系统的安全。 3. 修改进程创建参数:通过hook进程创建函数,我们可以修改进程的创建参数,例如修改程序的启动参数、运行环境等。这对于进程的定制化和优化非常有用。 4. 绕过进程创建限制:有些情况下,操作系统会对进程的创建做一些限制,例如限制某个程序创建的进程数量、限制进程的权限等。通过hook进程创建函数,我们可以绕过这些限制,实现一些我们需要的功能。 总之,hook进程创建函数是一种非常有用的技术,可以实现对进程监控和拦截。通过插入自定义代码来实现各种功能,从而对进程进行管理和控制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值