Android 卸载监控

0x00 前言

emmm,好像很久很久都没写点东西了,这一段时间看得倒是不少但是都没怎么记住,一是缺少上手二是理解不是很深入的样子,今天刚好看了一点简单的东西,就稍微记一下,还是先说一下,我的环境是一台7.1.2的机器和一个4.4.4的虚拟机,高版本现在还是不行,很尬。

0x01 Android卸载监控的思路

记得刚刚来数字的时候,土豆师傅就和我说过卸载监控怎么实现的,今天也随手看了点儿,没有很麻烦。实现卸载监控最关键的地方在于,卸载时app本身的进程会被杀死,所以正常情况下,写广播接收器之类的接收卸载广播这些思路,肯定是不行的,但是在linux中,如果fork出一个进程,那么当父进程被杀死之后,子进程并不会被杀死,而是变为init进程的子进程,而另一方面,当应用被卸载后,/data/data/packagename目录也会被删除,所以实现思路就很清晰了:先fork出一个子进程,然后再循环获取上面提到的目录是不是还存在,就实现了卸载监控。

0x02 实现

思路已经很清楚了,接下来就能着手实现一个简单的版本,直接从jni的Jni_OnLoad入手

代码在公司的电脑里面,这里写点伪码示意一下

1
2
3
4
5
6
7
8
9
pid_t pid=fork();
if(pid<0){

}else if(pid==0){
while(true){
读取对应data路径
根据对应文件是否存在来判断是否被卸载
}
}

嗯最简单的实现就是这样,但是这样一直读是不是显得头铁,那换一种头不那么铁的方法。

0x03 inotify机制

从网上找了一下大致说明

1
2
inotify是linux内核2.6.13以后支持的一种特性,功能是监视文件系统的变化,在监视到文件系统发生变化
以后,会向相应的应用程序发送变化事件。

可以利用这个机制来监听上文提到的文件是否存在,这样就不用持续的轮讯。

0x04 改进

使用linux的inotify机制

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
//子进程注册"/data/data/pym.test.uninstalledobserver"目录监听器
int fileDescriptor = inotify_init();
if (fileDescriptor < 0) {
LOGD("inotify_init failed");
exit(1);
}

int watchDescriptor;
watchDescriptor = inotify_add_watch(fileDescriptor,"/data/data/com.egguncle.uninstallmonitor", IN_DELETE);
LOGD("watchDescriptor=%d",watchDescriptor);
if (watchDescriptor < 0) {
LOGD("inotify_add_watch failed");
exit(1);
}
void *p_buf = malloc(sizeof(struct inotify_event));
if (p_buf == NULL) {
LOGD("malloc failed");
exit(1);
}
//开始监听
LOGD("start observer");
size_t readBytes = read(fileDescriptor, p_buf,sizeof(struct inotify_event));

free(p_buf);
inotify_rm_watch(fileDescriptor, IN_DELETE);

LOGD("uninstall");