当我们使用Ptrace方式跟踪一个进程时,目标进程会记录自己被谁跟踪,可以查看/proc/pid/status看到这个信息,下图展示的是使用ida进行调试的情况。
Paste_Image.png Paste_Image.png而没有被调试的时候TracerPid为0:
Paste_Image.png因此一种常见的检测调试的办法就是去读取这个值,发现不是0则判定为被调试。
本文提供一个反检测的方法,通过修改和重新编译kernel的方式来让TracerPid在调试的时候仍然为0。
编译kernel参考编译nexus5的linux kernel源码。
下面说一下改动点:
kernel/msm/fs/proc/base.c
kernel/msm/fs/proc/array.c
base.c在 line285 处修改如下:
else {
if (strstr(symname, "trace")) {
return sprintf(buffer, "%s", "sys_epoll_wait");
}
return sprintf(buffer, "%s", symname);
}
array.c在 line134处修改如下:
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"S (sleeping)", /* 4 */
"S (sleeping)", /* 8 */
"Z (zombie)", /* 16 */
"X (dead)", /* 32 */
"x (dead)", /* 64 */
"K (wakekill)", /* 128 */
"W (waking)", /* 256 */
};
在 line187 处修改如下:
"Gid:\t%d\t%d\t%d\t%d\n",
get_task_state(p),
task_tgid_nr_ns(p, ns),
pid_nr_ns(pid, ns),
ppid, /*tpid*/0,
cred->uid, cred->euid, cred->suid, cred->fsuid,
cred->gid, cred->egid, cred->sgid, cred->fsgid);
修改后,重新编译kernel,替换zImage-dtb,重新编译AOSP,刷机即可。
效果:
Paste_Image.png至于代码为啥这么改,参考:http://www.evil0x.com/posts/26301.html
假如你不想重新编译kernel,可以参考逆向修改手机内核,绕过反调试
网友评论