首页
社区
课程
招聘
[原创]Nexus 5X过反调试修改Android内核实践笔记
发表于: 2021-4-4 17:46 16118

[原创]Nexus 5X过反调试修改Android内核实践笔记

2021-4-4 17:46
16118

最近开始学习用修改内核的方式过反调试,过程也十分艰难,最后总算是成功了。由于此次学习成果颇丰,所以记录下来供日后自己参考。

首先,我的手机的Nexus 5X所以系统名称叫bullhead。参考kernels我的内核大版本如下。

由于网络连接问题,可以把上面所有 git clone命令中https://android.googlesource.com/网址换成清华镜像站的https://aosp.tuna.tsinghua.edu.cn/ 网址。
所以最后我执行以下命令就把大版本内核源码clone下来了

注意clone下来以后,master分支是不会有任何文件的。这是正常的,我需要checkout到我们的小版本才能显示源码。

打开手机设置-关于手机,查看内核版本可得知我的小版本短名称是b3a9f915f1fa

进入手机adb命令行

我们也可以得知我们的手机内核版本是b3a9f915f1fa,以上两个方法都适用。

这时候msm目录下就有文件了

改为

修改后task_state_array数组全貌

找到引用变量tpid的地方,直接强制使用0即可。-> 因为tpid就是TracerPid的意思。
修改后task_state函数全貌

函数原样

修改if逻辑后

总结:修改内核涉及到fs/proc/array.c和fs/proc/base.c两个文件共计3处地方的修改,这里痛批网上其他教程核心地方不说清楚。一看就是在抄文章,肯定没实践过。

在msm目录直接执行以下命令,配置临时环境变量就好了。如果你想配置到/etc/profile也可以

注意1、ANDROID_AARCH64可以用你Android源码编译套件里面的,
注意2、export PATH=$PATH:$ANDROID_AARCH64这条命令一定是在export ANDROID_AARCH64以后执行,如果执行顺序错误就会报如下异常

在msm目录下执行make就可以了,不出意外的话将在几分钟后编译完成。

编译完成以后会在msm/arch/arm64/boot目录下生成内核文件

我们要的是Image.gz-dtb这个文件,它才是替换boot.img中kernel的。

下载后进入bootimg-tools目录,执行make 命令编译该项目,在 makebootimg目录下生成了相应的二进制执行文件,将该二进制文件所在路径添加到 PATH路径中

我们回到安卓系统编译目标目录

在这个目录下我们创建一个testboot目录作为重打包的工作目录,万一失败了我们刷回原来的系统就是。

解包成功后,unmkbootimg 会生成你待会儿重打包的命令。这个用户体验设计很贴心,点赞!!!
解压之后我们得到 kernel 和 ramdisk.cpio.gz 两个文件

我们把刚才编译好的内核文件Image.gz-dtb拷贝过来

更改重打包命令中--kernel kernel为--kernel Image.gz-dtb,所以产生如下命令

执行重打包命令,这时候目录下多了一个newboot.img文件

我们把newboot.img移动到/data/android-8.0.0_r3/out/target/product目录下,覆盖原boot.img文件(万一后面刷机失败了,我们可以用boot.img恢复下)

刷机成功!!!

我们准备一个会基于TracerPid反调试的app AliCrackme.apk,点击下载AliCrackme.apk
该app只要进行了ptrace就会崩溃,这个本人前期已经验证。

总结:编译内核其实不难,主要是步骤很多很繁琐!重点是修改内核文件之前不知道修改哪些代码,这里我都详细阐述了。逆向工程师是真正的全栈工程师,不接受反驳!

git clone https://aosp.tuna.tsinghua.edu.cn/kernel/msm.git
git clone https://aosp.tuna.tsinghua.edu.cn/kernel/msm.git
stephen@ubuntu:/data/msm$ adb shell
bullhead:/ $ su
bullhead:/ # cat /proc/version
Linux version 3.10.73-gccb927b85f77-00001-gb3a9f915f1fa-dirty (stephen@ubuntu) (gcc version 4.9.x 20150123 (prerelease) (GCC) ) #2 SMP PREEMPT Sat Mar 27 19:41:21 PDT 2021
bullhead:/ #
stephen@ubuntu:/data/msm$ adb shell
bullhead:/ $ su
bullhead:/ # cat /proc/version
Linux version 3.10.73-gccb927b85f77-00001-gb3a9f915f1fa-dirty (stephen@ubuntu) (gcc version 4.9.x 20150123 (prerelease) (GCC) ) #2 SMP PREEMPT Sat Mar 27 19:41:21 PDT 2021
bullhead:/ #
stephen@ubuntu:/data/msm$ git checkout b3a9f915f1fa
warning: refname 'dc40906c97ae' is ambiguous.
Updating files: 100% (47111/47111), done.
Switched to branch 'b3a9f915f1fa'
stephen@ubuntu:/data/msm$ git checkout b3a9f915f1fa
warning: refname 'dc40906c97ae' is ambiguous.
Updating files: 100% (47111/47111), done.
Switched to branch 'b3a9f915f1fa'
stephen@ubuntu:/data/msm$ ls
android           build.config.net_test  drivers   ipc      MAINTAINERS     net             scripts     usr
AndroidKernel.mk  COPYING                firmware  Kbuild   Makefile        output          security    virt
arch              CREDITS                fs        Kconfig  mm              README          sound       vmlinux
block             crypto                 include   kernel   modules.order   REPORTING-BUGS  System.map  vmlinux.o
build.config      Documentation          init      lib      Module.symvers  samples         tools
stephen@ubuntu:/data/msm$ ls
android           build.config.net_test  drivers   ipc      MAINTAINERS     net             scripts     usr
AndroidKernel.mk  COPYING                firmware  Kbuild   Makefile        output          security    virt
arch              CREDITS                fs        Kconfig  mm              README          sound       vmlinux
block             crypto                 include   kernel   modules.order   REPORTING-BUGS  System.map  vmlinux.o
build.config      Documentation          init      lib      Module.symvers  samples         tools
"T (stopped)",          /*   4 */      
"t (tracing stop)",     /*   8 */
"T (stopped)",          /*   4 */      
"t (tracing stop)",     /*   8 */
"S (sleeping)",        /*   4 */
"S (sleeping)",    /*   8 */
"S (sleeping)",        /*   4 */
"S (sleeping)",    /*   8 */
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 */
    "P (parked)",        /* 512 */
};
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 */
    "P (parked)",        /* 512 */
};
static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
                struct pid *pid, struct task_struct *p)
{
    struct user_namespace *user_ns = seq_user_ns(m);
    struct group_info *group_info;
    int g;
    struct fdtable *fdt = NULL;
    const struct cred *cred;
    pid_t ppid = 0, tpid = 0;
    struct task_struct *leader = NULL;
 
    rcu_read_lock();
    if (pid_alive(p)) {
        struct task_struct *tracer = ptrace_parent(p);
        if (tracer)
            tpid = task_pid_nr_ns(tracer, ns);
        ppid = task_tgid_nr_ns(rcu_dereference(p->real_parent), ns);
        leader = p->group_leader;
    }
    cred = get_task_cred(p);
    seq_printf(m,
        "State:\t%s\n"
        "Tgid:\t%d\n"
        "Pid:\t%d\n"
        "PPid:\t%d\n"
        "TracerPid:\t%d\n"
        "Uid:\t%d\t%d\t%d\t%d\n"
        "Gid:\t%d\t%d\t%d\t%d\n",
        get_task_state(p),
        leader ? task_pid_nr_ns(leader, ns) : 0,
        pid_nr_ns(pid, ns),
        ppid, 0,
        from_kuid_munged(user_ns, cred->uid),
        from_kuid_munged(user_ns, cred->euid),
        from_kuid_munged(user_ns, cred->suid),
        from_kuid_munged(user_ns, cred->fsuid),
        from_kgid_munged(user_ns, cred->gid),
        from_kgid_munged(user_ns, cred->egid),
        from_kgid_munged(user_ns, cred->sgid),
        from_kgid_munged(user_ns, cred->fsgid));
 
    task_lock(p);
    if (p->files)
        fdt = files_fdtable(p->files);
    seq_printf(m,
        "FDSize:\t%d\n"
        "Groups:\t",
        fdt ? fdt->max_fds : 0);
    rcu_read_unlock();
 
    group_info = cred->group_info;
    task_unlock(p);
 
    for (g = 0; g < group_info->ngroups; g++)
        seq_printf(m, "%d ",
               from_kgid_munged(user_ns, GROUP_AT(group_info, g)));
    put_cred(cred);
 
    seq_putc(m, '\n');
}
static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
                struct pid *pid, struct task_struct *p)
{
    struct user_namespace *user_ns = seq_user_ns(m);
    struct group_info *group_info;
    int g;
    struct fdtable *fdt = NULL;
    const struct cred *cred;
    pid_t ppid = 0, tpid = 0;
    struct task_struct *leader = NULL;
 
    rcu_read_lock();
    if (pid_alive(p)) {
        struct task_struct *tracer = ptrace_parent(p);
        if (tracer)
            tpid = task_pid_nr_ns(tracer, ns);
        ppid = task_tgid_nr_ns(rcu_dereference(p->real_parent), ns);
        leader = p->group_leader;
    }
    cred = get_task_cred(p);
    seq_printf(m,
        "State:\t%s\n"
        "Tgid:\t%d\n"
        "Pid:\t%d\n"
        "PPid:\t%d\n"
        "TracerPid:\t%d\n"
        "Uid:\t%d\t%d\t%d\t%d\n"
        "Gid:\t%d\t%d\t%d\t%d\n",
        get_task_state(p),
        leader ? task_pid_nr_ns(leader, ns) : 0,
        pid_nr_ns(pid, ns),
        ppid, 0,
        from_kuid_munged(user_ns, cred->uid),
        from_kuid_munged(user_ns, cred->euid),
        from_kuid_munged(user_ns, cred->suid),
        from_kuid_munged(user_ns, cred->fsuid),
        from_kgid_munged(user_ns, cred->gid),
        from_kgid_munged(user_ns, cred->egid),
        from_kgid_munged(user_ns, cred->sgid),
        from_kgid_munged(user_ns, cred->fsgid));
 
    task_lock(p);
    if (p->files)
        fdt = files_fdtable(p->files);
    seq_printf(m,
        "FDSize:\t%d\n"
        "Groups:\t",
        fdt ? fdt->max_fds : 0);
    rcu_read_unlock();
 
    group_info = cred->group_info;
    task_unlock(p);
 
    for (g = 0; g < group_info->ngroups; g++)
        seq_printf(m, "%d ",
               from_kgid_munged(user_ns, GROUP_AT(group_info, g)));
    put_cred(cred);
 
    seq_putc(m, '\n');
}
static int proc_pid_wchan(struct task_struct *task, char *buffer)
{
    unsigned long wchan;
    char symname[KSYM_NAME_LEN];
 
    wchan = get_wchan(task);
 
    if (lookup_symbol_name(wchan, symname) < 0)
        if (!ptrace_may_access(task, PTRACE_MODE_READ))
            return 0;
        else
            return sprintf(buffer, "%lu", wchan);
    else
        return sprintf(buffer, "%s", symname);
}
static int proc_pid_wchan(struct task_struct *task, char *buffer)
{
    unsigned long wchan;
    char symname[KSYM_NAME_LEN];
 
    wchan = get_wchan(task);
 
    if (lookup_symbol_name(wchan, symname) < 0)
        if (!ptrace_may_access(task, PTRACE_MODE_READ))
            return 0;
        else
            return sprintf(buffer, "%lu", wchan);
    else
        return sprintf(buffer, "%s", symname);
}
static int proc_pid_wchan(struct task_struct *task, char *buffer)
{
    unsigned long wchan;
    char symname[KSYM_NAME_LEN];
 
    wchan = get_wchan(task);
 
    if (lookup_symbol_name(wchan, symname) < 0)
        if (!ptrace_may_access(task, PTRACE_MODE_READ))
            return 0;
        else
            return sprintf(buffer, "%lu", wchan);
    else{
        if (strstr(symname, "trace")) {
            return sprintf(buffer, "%s", "sys_epoll_wait");
        }
        return sprintf(buffer, "%s", symname);
    }   
}
static int proc_pid_wchan(struct task_struct *task, char *buffer)
{
    unsigned long wchan;
    char symname[KSYM_NAME_LEN];
 
    wchan = get_wchan(task);
 
    if (lookup_symbol_name(wchan, symname) < 0)
        if (!ptrace_may_access(task, PTRACE_MODE_READ))
            return 0;
        else
            return sprintf(buffer, "%lu", wchan);
    else{
        if (strstr(symname, "trace")) {
            return sprintf(buffer, "%s", "sys_epoll_wait");
        }
        return sprintf(buffer, "%s", symname);
    }   
}
export ANDROID_AARCH64=/data/android-8.0.0_r3/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin
export ARCH=arm64
export SUBARCH=arm64
export PATH=$PATH:$ANDROID_AARCH64
export CROSS_COMPILE=aarch64-linux-android-
`
export ANDROID_AARCH64=/data/android-8.0.0_r3/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin
export ARCH=arm64
export SUBARCH=arm64
export PATH=$PATH:$ANDROID_AARCH64

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2022-6-29 11:11 被爬虫不看学历编辑 ,原因:
上传的附件:
收藏
免费 11
支持
分享
最新回复 (10)
雪    币: 831
活跃值: (2830)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2

欢迎大家关注我的开源项目https://github.com/CreditTone/hooker

最后于 2021-4-4 18:01 被爬虫不看学历编辑 ,原因:
2021-4-4 17:59
0
雪    币: 831
活跃值: (2830)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
hooker是一个基于frida实现的逆向工具包。为逆向开发人员提供统一化的脚本包管理方式、通杀脚本、自动化生成hook脚本、内存漫游探测activity和service和其他任意对象。
2021-4-4 18:00
0
雪    币: 105
活跃值: (4593)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
学到了 谢谢
2021-4-5 18:21
0
雪    币: 277
活跃值: (512)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
厉害
2021-4-6 13:43
0
雪    币: 197
活跃值: (1343)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
感谢分享
2021-4-8 10:42
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
给你点个关注
2021-5-6 10:45
0
雪    币: 1931
活跃值: (442)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
来个编译好的的下载地址呗
2021-5-6 13:39
0
雪    币: 277
活跃值: (512)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
感谢分享
2021-5-29 15:04
0
雪    币: 3525
活跃值: (31011)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
Nexus 5X 在哪里买靠谱啊
2022-4-22 21:53
1
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
11
老哥,我总是出现你说的那个注意二,但是我的PATJH,是在ARRCH 路径申明的后面的
2022-4-25 14:18
0
游客
登录 | 注册 方可回帖
返回
//