对抗静态分析——番外:文件操作检测
2016-12-26 00:00
387 查看
1.文章难易度【★★★】
2.文章作者:penguin_wwy
3.本文参与
i春秋社区原创文章奖励计划,未经许可禁止转载
4.阅读基础:linux
【预备~~~起】
老子科二考挂了,哈哈哈哈哈哈哈哈哈哈
【一二三四~~~】
这篇番外主要讲的是一个Linux的特性——Inotify。这个东西的主要作用是检测文件行为,比如读取、写入、创建等等。主要有以下几个API:
这两个API都是用于初始化inotify,根据Linux一切皆文件的设计观点,返回的也自然是文件描述符。第一个inotify_init(void)等同于inotify_init1(0)。除此之外还可以设置下列标志位
第一个IN_CLOEXEC表示对新文件描述符设置执行后关闭,第二个IN_NONBLOCK表示对新文件描述符设置O_NONBLOCK。当初始化执行失败时返回-1,并设置相应的errno。
初始化完毕后设置监视,也就是添加你需要监视的文件(目录)以及你想关心的操作事件(读取、写入)。注意的是对于目录的监视不包含监视目录的子目录,监视过程不是递归的。函数的第一个参数是前一步初始化返回的文件描述符,第二个是文件或目录,最后一个是确定监视事件的监视掩码(watch mask),有以下几种
最后还有一个
表示所有合法事件
inotify_add_watch执行成功会返回一个新的监视描述符,失败返回-1
结构体inotify_event描述了inotify事件
wd表示监视描述符,mask为监视事件掩码,name保存和路径相关的文件名,len为name中的有效长度(name中可以通过填充无效字符来保持对齐)
除了上述内容之外,当完成添加监视后,可以通过select或者poll来监视它,通过read读取获得结果。
【二二三四~~~】
我们来实际操作一下。前面提到过在APK中通过native层代码对APK加固或者执行核心程序,在对应APK的lib文件夹下会有我们的so文件。我们可以检测lib目录,检测有没有其他程序想进入该文件夹,拷贝读取等操作走我们的so文件。创建一个APK,就叫Inotify,Java层代码就不写了
native开始函数
runInotify是我们的主要函数
初始化,然后对/data/data/com.example.inotify/lib添加监视,事件设置为所有
event_check函数调用select的进行监视操作
read_event读取inotify事件
下面执行看看效果,首先开一个cmd窗口查看log
然后我们再开一个cmd窗口到lib目录下执行操作
先输入ls
log窗口有反应了
再试试rm 删除当前的so文件
name字符串输出了libnative-lib.so
实验成功。
【三二三四~~~】
前面实验的对lib目录监控只是一方面,事实上我们可以对更对的比如解密完落地的dex,so监控或者各类资源文件监控达到对抗阻止破解的目的。Inotify同时也是双刃剑,破解方也可以记录APK目录下各类文件的操作顺序,达到某些目的。
【小结~~~】
对抗静态分析这个系列写着写着就超纲了,不过我个人觉得动态静态都是相辅相成的一环套一环,穿插在一起更有利于理解。这个系列我个人觉得差不多了,最多再有个一两篇的内容。之后写什么我也不太确定,有什么想看的关于移动安全的,或者关于逆向,源码分析方面的可以写评论,我量(kan)力(xin)而(qing)行。就酱
更多安全技术、精品好文、白帽黑客大佬尽在:http://bbs.ichunqiu.com/portal.php
2.文章作者:penguin_wwy
3.本文参与
i春秋社区原创文章奖励计划,未经许可禁止转载
4.阅读基础:linux
【预备~~~起】
老子科二考挂了,哈哈哈哈哈哈哈哈哈哈
【一二三四~~~】
这篇番外主要讲的是一个Linux的特性——Inotify。这个东西的主要作用是检测文件行为,比如读取、写入、创建等等。主要有以下几个API:
int inotify_init(void);
int inotify_init1(int);
这两个API都是用于初始化inotify,根据Linux一切皆文件的设计观点,返回的也自然是文件描述符。第一个inotify_init(void)等同于inotify_init1(0)。除此之外还可以设置下列标志位
#define IN_CLOEXEC O_CLOEXEC /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ #define IN_NONBLOCK O_NONBLOCK
第一个IN_CLOEXEC表示对新文件描述符设置执行后关闭,第二个IN_NONBLOCK表示对新文件描述符设置O_NONBLOCK。当初始化执行失败时返回-1,并设置相应的errno。
int inotify_add_watch(int, const char*, uint32_t);
初始化完毕后设置监视,也就是添加你需要监视的文件(目录)以及你想关心的操作事件(读取、写入)。注意的是对于目录的监视不包含监视目录的子目录,监视过程不是递归的。函数的第一个参数是前一步初始化返回的文件描述符,第二个是文件或目录,最后一个是确定监视事件的监视掩码(watch mask),有以下几种
#define IN_ACCESS 0x00000001 //从文件中读 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ #define IN_MODIFY 0x00000002 //写入文件中 #define IN_ATTRIB 0x00000004 //文件的元数据(所有者、权限、扩展属性) #define IN_CLOSE_WRITE 0x00000008 //写入模式打开 #define IN_CLOSE_NOWRITE 0x00000010 //未曾以写入模式打开 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ #define IN_OPEN 0x00000020 //文件已打开 #define IN_MOVED_FROM 0x00000040 //文件从监视目录中删除 #define IN_MOVED_TO 0x00000080 //文件已添加到监视目录中 #define IN_CREATE 0x00000100 //文件已在监视目录创建 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ #define IN_DELETE 0x00000200 //文件已从监视目录删除 #define IN_DELETE_SELF 0x00000400 //监视对象本身被删除 #define IN_MOVE_SELF 0x00000800 //监视对象本身被删除 #define IN_UNMOUNT 0x00002000 //文件系统被unmount
#define IN_Q_OVERFLOW 0x00004000 //在内核中,事件的数据超过了max_events #define IN_IGNORED 0x00008000 //文件已被删除 #define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE) #define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO) /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ #define IN_ONLYDIR 0x01000000 //Only watch the path if it is a directory #define IN_DONT_FOLLOW 0x02000000 //Do not follow a sym link #define IN_EXCL_UNLINK 0x04000000 #define IN_MASK_ADD 0x20000000 //Add to the mask of an already existing watch /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ #define IN_ISDIR 0x40000000 //Event occurred against dir #define IN_ONESHOT 0x80000000 //Only send event once
最后还有一个
#define IN_ALL_EVENTS (IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE | IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM | IN_MOVED_TO | IN_DELETE | IN_CREATE | IN_DELETE_SELF | IN_MOVE_SELF)
表示所有合法事件
inotify_add_watch执行成功会返回一个新的监视描述符,失败返回-1
结构体inotify_event描述了inotify事件
struct inotify_event { __s32 wd; __u32 mask; __u32 cookie; /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ __u32 len; char name[0]; };
wd表示监视描述符,mask为监视事件掩码,name保存和路径相关的文件名,len为name中的有效长度(name中可以通过填充无效字符来保持对齐)
除了上述内容之外,当完成添加监视后,可以通过select或者poll来监视它,通过read读取获得结果。
【二二三四~~~】
我们来实际操作一下。前面提到过在APK中通过native层代码对APK加固或者执行核心程序,在对应APK的lib文件夹下会有我们的so文件。我们可以检测lib目录,检测有没有其他程序想进入该文件夹,拷贝读取等操作走我们的so文件。创建一个APK,就叫Inotify,Java层代码就不写了
native开始函数
JNIEXPORT void JNICALL Java_com_example_inotify_MainActivity_runInotify(JNIEnv *env, jobject instance) { // TODO ALOGD("Task ============== Start"); runInotify(); }
runInotify是我们的主要函数
void runInotify() { keep_running = 1; if (signal(SIGINT, signal_handle) == SIG_IGN) { signal(SIGINT, SIG_IGN); } int fd; fd = inotify_init();//初始化 if (fd == -1) { //错误处理 ALOGE("inotify_init error"); switch (errno){ case EMFILE: ALOGD("errno: EMFILE");break; case ENFILE: ALOGD("errno: ENFILE");break; case ENOMEM: ALOGD("errno: ENOMEM");break; default: ALOGD("unkonw errno"); } return; }
int wd; wd = inotify_add_watch(fd, "/data/data/com.example.inotify/lib", IN_ALL_EVENTS); //添加监视 if (wd == -1) { //错误处理 ALOGE("inotify_add_watch"); switch (errno) { case EACCES: ALOGD("errno: EACCES");break; case EBADF: ALOGD("errno: EBADF");break; case EFAULT: ALOGD("errno: EFAULT");break; case EINVAL: ALOGD("errno: EINVAL");break; case ENOMEM: ALOGD("errno: ENOMEM");break; case ENOSPC: ALOGD("errno: ENOSPC");break; default: ALOGD("unkonw errno"); } return; } while (keep_running) { if (event_check(fd) > 0) { read_event(fd); } } return; }
初始化,然后对/data/data/com.example.inotify/lib添加监视,事件设置为所有
event_check函数调用select的进行监视操作
int event_check(int fd) { fd_set rfds; FD_ZERO(&rfds); FD_SET(fd, &rfds); return select(FD_SETSIZE, &rfds, NULL, NULL, NULL); }
read_event读取inotify事件
int read_event(int fd) { char buffer[16384] = {0}; size_t index = 0; struct inotify_event *ptr_event; ssize_t r = read(fd, buffer, 16384); if (r <= 0) { ALOGE("read_event"); return r; } while (index < r) { ptr_event = (struct inotify_event *)&buffer[index]; ALOGD("wd = %d mask = %d cookie = %d len = %d dir = %s\n", ptr_event->wd, ptr_event->mask, ptr_event->cookie, ptr_event->len, (ptr_event->mask & IN_ISDIR) ? "yes" : "no"); if (ptr_event->len) ALOGD("name = %s", ptr_event->name); index += sizeof(struct inotify_event) + ptr_event->len; } return 0; }
下面执行看看效果,首先开一个cmd窗口查看log
然后我们再开一个cmd窗口到lib目录下执行操作
先输入ls
log窗口有反应了
再试试rm 删除当前的so文件
name字符串输出了libnative-lib.so
实验成功。
【三二三四~~~】
前面实验的对lib目录监控只是一方面,事实上我们可以对更对的比如解密完落地的dex,so监控或者各类资源文件监控达到对抗阻止破解的目的。Inotify同时也是双刃剑,破解方也可以记录APK目录下各类文件的操作顺序,达到某些目的。
【小结~~~】
对抗静态分析这个系列写着写着就超纲了,不过我个人觉得动态静态都是相辅相成的一环套一环,穿插在一起更有利于理解。这个系列我个人觉得差不多了,最多再有个一两篇的内容。之后写什么我也不太确定,有什么想看的关于移动安全的,或者关于逆向,源码分析方面的可以写评论,我量(kan)力(xin)而(qing)行。就酱
更多安全技术、精品好文、白帽黑客大佬尽在:http://bbs.ichunqiu.com/portal.php
相关文章推荐
- 阿里巴巴发布《2015移动安全漏洞年报》
- 阿里巴巴发布《2015数据风控年报》,互联网业务黑色产业链分析
- 破坏网络可信身份认证,黑灰产业链正在兴起
- 【移动开发】浅谈安卓开发代码混淆技术
- AndroidLinker与SO加壳技术之上篇
- AndroidLinker与SO加壳技术之下篇
- 转载:爱内测 1分钟找APP漏洞,开发者就可以开心「捉虫」
- (分享)码农们不得不重视的问题
- WAP PUSH解析(3)——Android中实现
- 检测root access的三种方式
- Android IOS 安全书籍
- 阿里移动安全 Writeup
- 安天移动安全应对“DressCode”威胁,发布企业移动威胁检查工具
- 户曝iPhone 5S指纹识别灵敏度大幅下降
- 2015阿里&看雪移动安全挑战赛-第一题
- 2015阿里&看雪移动安全挑战赛-第二题
- IT安全支出上升,聚焦移动软件
- 移动安全之Android安全检测工具大全
- Android-Activity劫持
- 全站 HTTPS 来了