首页
社区
课程
招聘
[讨论]关于LD_PRELOAD在Android API HOOK中的应用
发表于: 2014-3-18 09:49 35219

[讨论]关于LD_PRELOAD在Android API HOOK中的应用

2014-3-18 09:49
35219
受xposed启发,有了一些想法。

我以前都是通过注入的形式,拦截目标进程的API,从而达到一些目的。这个方法相对笨拙,每次都需要注入(启动时);关键问题是,除非做成INLINE HOOK,否则你就得Hook每个so中你想拦截的函数,也不方便。

看到xposed后,就萌发一个想法,能否用Preload,做API HOOK。

这个问题相对比较容易解决:传递一个系统环境变量LD_PRELOAD=xx给目标进程(Zygote)即可。然后所有的Android应用都被装上HOOK了。

目前我的做法是写一个自己的程序,命名为app_process,将系统原来的app_process修改为old_app_process。app_process中做2件事情:
1. 添加一个环境变量:setenv("LD_PROLOAD=xxxx");
2. 启动原来的app_process:execv("/system/bin/old_app_process", args, envs);

这样就把Preload的so加入到zygote中了,然后所有的Android应用都加载了Preload的so。

这个东西目前已经初步实现,这里提出来和大家一起讨论,希望同学们多多讨论。
收藏
免费 0
支持
分享
最新回复 (32)
雪    币: 181
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
沙发自留
2014-3-18 09:50
0
雪    币: 53
活跃值: (275)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
LD_PRELOAD=/.../xx.so:/.../yy.so
把你大体实现描述一下,否则不知道你想做什么,仅仅是做so hook?
2014-3-18 15:01
0
雪    币: 181
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
LD_PRELOAD生效后,应用首先加载该环境变量指向的so;同时搜索符号链接的时候也先从该so搜索(这个地方我描述的不一定专业,大致是这个意思)。

比如我在该库中实现了read函数,那么目标进程所有对read函数的调用都会走该该库的read上,这样就达到了hook目标进程Api的目的(不需要做成INLINE HOOK,技术难度较大)。

不晓得我说清楚没
2014-3-19 14:17
0
雪    币: 53
活跃值: (275)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
恩,这是可行的
2014-3-19 21:50
0
雪    币: 113
活跃值: (618)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
LD_PRELOAD 是不是只能hook系统api,自定义试了一下好像不行?
2014-3-20 12:49
0
雪    币: 181
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
只要是目标调用的函数都能拦截,但是一般都是拦截封装了系统调用的函数,比如connect、open等。
2014-3-20 17:01
0
雪    币: 181
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
其实我这个东西我的目的是去取代进程注入的,不知道有什么不足。

目前如果Android版本到4.4,使用安全linux内核的话,注入就很麻烦了;如果用该方式,就无需再进行注入了,可以达到一样的效果。
2014-3-20 17:04
0
雪    币: 113
活跃值: (618)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
我试了自己的程序里面的_luaL_loadbuffer,hook以后只__android_log_print了日志就通过RTLD_NEXT返回原函数,没有反应呢,export一下也看到LD_PRELOAD有值的呀
2014-3-21 11:03
0
雪    币: 181
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
啥叫没反应??
2014-4-2 11:09
0
雪    币: 71
活跃值: (242)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
11
貌似不能hook静态编译的
2014-4-2 11:51
0
雪    币: 181
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
这个不用貌似 肯定不行
2014-4-2 13:54
0
雪    币: 113
活跃值: (618)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
就是进不了自己的函数,我查google说4.1以上不支持?
2014-4-3 09:05
0
雪    币: 181
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
不是很清楚,我在android4.2和4.0上测试没有问题,你再找找问题吧;我个人认为这个跟android没啥关系,Preload是linux的东西。
2014-4-3 09:06
0
雪    币: 8
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
libdvm.so中的函数无法使用这个方法来hook吧
2014-4-27 11:25
0
雪    币: 8
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
/system/lib/libandroid_runtime.so
我想hook这个中的android_os_Process_myPid失败了
什么原因呢
libc中的fork我测试成功了

正常获得getJNIEnv的地址的时候,是这样获得的
void* handle = dlopen("/system/lib/libandroid_runtime.so", RTLD_NOW);  
  
getJNIEnv = dlsym(handle, "_ZN7android14AndroidRuntime9getJNIEnvEv");  
难道是编译的时候方法变了,所以不成功?
2014-4-27 12:42
0
雪    币: 181
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
你这个是jni函数吧,jni函数不是动态链接的,是直接使用函数指针。
2014-4-28 09:04
0
雪    币: 181
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
动态链接函数均可。
2014-4-28 09:06
0
雪    币: 8
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
想这个libandroid_runtime.so库中的
void AndroidRuntime::onVmCreated(JNIEnv* env)
{
    // If AndroidRuntime had anything to do here, we'd have done it in 'start'.
}
该如何通过dlsym来查找呢
dlsym (handle, "AndroidRuntime::onVmCreated");
这种方式找不到这个函数
2014-4-28 17:22
0
雪    币: 8
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
除了libc.so中的成功以外,其他都失败了
像libdvm.so中的JNI_CreateJavaVM,这个函数,我觉得完全没问题的,都失败了
为什么呢
2014-4-28 21:24
0
雪    币: 10
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
虚拟机器应该已经完成初始化了吧, 所以没法hook, 只能对标准库的函数起作用
2014-5-3 11:54
0
雪    币: 181
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
同学

JNI_*系列函数,你可以去看一下,都是Env->这样调用的,我看源码得知这类调用都是函数指针,走的根本不是动态链接。

还有关于C++的方法,首先要确定是否导出了你要调用的函数;若是函数被导出,函数名也绝对不是以'类::方法名'这种形式导出的。
2014-5-7 14:29
0
雪    币: 8
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
/*
749     * Initialize the VM.
750     *
751     * The JavaVM* is essentially per-process, and the JNIEnv* is per-thread.
752     * If this call succeeds, the VM is ready, and we can start issuing
753     * JNI calls.
754     */
755    if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
756        ALOGE("JNI_CreateJavaVM failed\n");
757        goto bail;
758    }
这个可不是指针调用吧
2014-5-7 14:43
0
雪    币: 181
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
我想想啊 这个函数应该是动态链接呀 libdvm里面的

我的目的是拦截execv这些函数,所以没考虑你说的这种情况。

建议你看看libdvm库的导出函数,看看名称是否正确。

这个东西我整出来也不完善,我们一起完善撒
2014-5-7 14:52
0
雪    币: 8
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
小弟最近在研究这块,我是要搞一个拦截不正常开启Camera和mic的。有一个不成熟的想法,通过注入,获取他们的open函数在plt/got表中位置,然后hook一个自己的函数
然后看了非虫大哥的文章,想从LD_PERLOAD入手,但是install.bat那块没看懂,不知道它在哪里执行,cmd上?找不着路径,手机上?不会。如果可以的话,教教小弟
上传的附件:
2014-5-7 20:03
0
游客
登录 | 注册 方可回帖
返回
//