以下操作基于安卓10系统lineageOs 17.1源码研究,手机型号oneplus3 镜像研究测试。

一、安卓内核模块开发编译

安卓系统如何开发内核可加载模块参考以下文章:
 "安卓10源码学习开发定制(11)内核篇之安卓内核可加载模块开发编译"

二、内核系统调用hook原理

内核系统调用hook主要是在内核模块加载的时候,通过修改替换内核系统调用表sys_call_table的系统调用号地址来实现目的。

三、内核源码默认配置修改支持系统调用挂钩功能

  • 为了通过insmod命令加载内核模块,需要增加Android内核可加载内核模块配置的支持。

  • 为了获取sys_call_table导出全局内核符号表的地址需要增加内核符号表导出配置功能。

  • 为了向内核内存空间读写数据,需要禁用Android内核的内存保护。需要关闭CONFIG_STRICT_MEMORY_RWX这个选项来编译内核。

如下是所有相关的配置修改:

# ///ADD START
# 允许通过insmod命令加载模块
CONFIG_MODULES=y
# 允许通过命令rmmod命令卸载内核模块
CONFIG_MODULE_UNLOAD=y
# 关闭内核内存读写保护
CONFIG_STRICT_MEMORY_RWX=n# 打开该配置使符号表中包含所有的函数地址
CONFIG_KALLSYMS=y# 打开该配置方便通过adb shell cat /proc/kallsyms查看内核导出的符号地址
CONFIG_KALLSYMS_ALL=y
# ///ADD END

将以上配置追加到安卓源码内核源文件中,文件路径如下:

home/qiang/lineageOs/kernel/oneplus/msm8996/arch/arm64/configs/lineageos_oneplus3_defconfig

配置好之后编译一次源码,产生内核的编译输出文件。后续编写内核模块需要依赖这些文件来进行编译。

四、获取内核符号表地址

将以上内核源码配置修改之后,编译安卓系统。lineageOs源码编译过程中会自动编译内核源码。内核编译输出目录如下:

/home/qiang/lineageOs/out/target/product/oneplus3/obj/KERNEL_OBJ

在内核编译输出目录找到System.map文件。打开该文件找到system_call_table符号表的地址。如下所示:

qiang@ubuntu:~/lineageOs/out/target/product/oneplus3/obj/KERNEL_OBJ$qiang@ubuntu:~/lineageOs/out/target/product/oneplus3/obj/KERNEL_OBJ$ pwd
/home/qiang/lineageOs/out/target/product/oneplus3/obj/KERNEL_OBJqiang@ubuntu:~/lineageOs/out/target/product/oneplus3/obj/KERNEL_OBJ$ ls -la System.map
-rw-rw-r-- 1 qiang qiang 4946646 2月   3 22:46 System.mapqiang@ubuntu:~/lineageOs/out/target/product/oneplus3/obj/KERNEL_OBJ$ cat System.map  |grep "sys_call_table"ffffffc000093000 T compat_sys_call_table
ffffffc001057000 R sys_call_table

从以上System.map文件可以知道sys_call_table符号地址为:0xffffffc001057000

五、挂钩openat函数模块开发

可加载模块openat hook核心关键代码如下:

//保存内核系统原有的openat函数地址
asmlinkage int (*real_openat)(int, const char __user*,int,umode_t);//保存系统调用表地址
void **sys_call_table;// 替换内核系统调用openat新的new_openat函数
int new_openat(int dirfd, const char __user* pathname, int flags,umode_t modex)
{int ret=-1;//cred 中保存了当前进程的uid pid等信息const struct cred *cred = current_cred();kuid_t uid=cred->uid;int pid=current->pid;int myuid=uid.val;if(myuid>10000){char bufname[256]={0};strncpy_from_user(bufname,pathname,255);//打印日志输出测试printk("openat pathname:%s  uid:%d pid:%d\n",bufname,myuid,pid);}ret= real_openat(dirfd, pathname, flags,modex);return ret;
}//模块加载的时候调用
static int __init hook_init(void){printk("load module success\n");//sys_call_table符号地址sys_call_table=(void*)0xffffffc001057000;printk("sys_call_table %p",(void*)sys_call_table);// 获取openat函数的调用地址real_openat = (void*)(sys_call_table[__NR_openat]);printk("11111111  real_openat %p\n",(void*)real_openat);//替换系统调用表openat函数地址sys_call_table[__NR_openat]=(unsigned long*)new_openat;printk("replace openat finish");return 0;
}

六、测试模块

1. 编译内核模块,本人编译的模块为kernel_hook_openat.ko

安卓系统如何开发内核可加载模块参考以下文章:
        "安卓10源码学习开发定制(11)内核篇之安卓内核可加载模块开发编译"

2. 将内核模块adb push到手机,并用insmod命令加载模块,如下图所示:

3. 打印内核日志验证,日志如下:

4,3927,3837282014,-;load module success
4,3928,3837282027,-;sys_call_table ffffffc00105700011111111  real_openat ffffffc0001db1f8
4,3929,3837282031,-;replace openat finish4,3974,3850163171,-;openat pathname:/system/lib64/libselinux.so  uid:10129 pid:5822
4,3975,3850163867,-;openat pathname:/system/lib64/libcutils.so  uid:10129 pid:5822
4,3976,3850164538,-;openat pathname:/system/lib64/libprocessgroup.so  uid:10129 pid:5822
4,3977,3850164870,-;openat pathname:/system/lib64/libcrypto.so  uid:10129 pid:5822
4,3978,3850165322,-;openat pathname:/system/lib64/libz.so  uid:10129 pid:5822
4,3979,3850165703,-;openat pathname:/system/lib64/libc.so  uid:10129 pid:5822
4,3980,3850167419,-;openat pathname:/system/lib64/libm.so  uid:10129 pid:5822
4,3981,3850167877,-;openat pathname:/system/lib64/libdl.so  uid:10129 pid:5822
4,3982,3850168240,-;openat pathname:/system/lib64/libc++.so  uid:10129 pid:5822
4,3983,3850168565,-;openat pathname:/system/lib64/libpcre2.so  uid:10129 pid:5822
4,3984,3850168795,-;openat pathname:/system/lib64/libpackagelistparser.so  uid:10129 pid:5822
4,3985,3850169027,-;openat pathname:/system/lib64/libbase.so  uid:10129 pid:5822
4,3986,3850169780,-;openat pathname:/system/lib64/libcgrouprc.so  uid:10129 pid:5822
4,3987,3850179680,-;openat pathname:/sys/kernel/mm/transparent_hugepage/enabled  uid:10129 pid:5822
4,3988,3850180250,-;openat pathname:/dev/__properties__/property_info  uid:10129 pid:5822
4,3989,3850180348,-;openat pathname:/dev/__properties__/properties_serial  uid:10129 pid:5822
4,3990,3850180448,-;openat pathname:/dev/__properties__/u:object_r:default_prop:s0  uid:10129 pid:5822
4,3991,3850180496,-;openat pathname:/dev/__properties__/u:object_r:debug_prop:s0  uid:10129 pid:5822
4,3992,3850180572,-;openat pathname:/dev/__properties__/u:object_r:heapprofd_prop:s0  uid:10129 pid:5822
4,3993,3850180722,-;openat pathname:/system/lib64/libnetd_client.so  uid:10129 pid:5822

参考文章:

  • Hooking Android System Calls for Pleasure and Benefit

    https://www.cnblogs.com/lanrenxinxin/p/6289436.html

内核系统调用openat Hook(Android10)相关推荐

  1. 安卓10源码开发定制(23)内核系统调用openat Hook研究测试

    文章首发微信公众号:QDROID88888,欢迎关注交流 以下操作基于安卓10系统lineageOs 17.1源码研究,手机型号oneplus3 镜像研究测试. 一.安卓内核模块开发编译 安卓系统如何 ...

  2. linux内核中获取虚拟地址api,Linux内核-系统调用

    Linux内核-系统调用 1.与内核通信 #系统调用在用户空间进程和硬件设备之间添加了一个中间层 作用:1.为用户空间提供了一种硬件的抽象接口 2.系统调用保证了系统的稳定和安全 3.出于每一个进程都 ...

  3. linux(07)之内核系统调用

    Linux(07)之内核系统调用 Author:Once Day Date:2023年1月7日 漫漫长路,才刚刚开始- 文章目录 Linux(07)之内核系统调用 1.概述 2. 系统调用 2.1 无 ...

  4. linux内核-系统调用execve()

    读者在linux内核-系统调用fork.vfork与clone中已经看到,进程通常是按其父进程的原样复制出来的,在多数情况下,如果复制出来的子进程不能与父进程分道扬镳,走自己的路,那就没多大意义.所以 ...

  5. Linux进程调用execve,linux内核系统调用函数do_execve()解析实例源码

    linux内核系统调用函数do_execve()解析,彻底解析内核调用用户空间代码入口函数do_execve() sys_execve() –> do_execve() /usr/src/lin ...

  6. linux内核-系统调用fork、vfork与clone

    前面已经简要地介绍过fork与clone二者的作用于区别.这里先来看一下二者在程序设计接口上的不同: pid_t fork(void); int clone(int (*fn)(void *), vo ...

  7. Windows内核系统调用分析

    系统调用 进程 --> 调用OS API:OS进程管理 --> 调配进程. 仅从用户进程角度,OS就像是一个被动响应的运行时库.Windows提供了一个系统调用界面作为外层,即Win32A ...

  8. Linux内核系统调用处理过程

    原创作品转载请注明出处 + https://github.com/mengning/linuxkernel/ 学号末三位:168 下载并编译Linux5.0 1 xz -d linux-5.0.1.t ...

  9. linux内核中的hook函数详解,linux内核中的hook函数详解

    在编写linux内核中的网络模块时,用到了钩子函数也就是hook函数.现在来看看linux是如何实现hook函数的. 先介绍一个结构体: struct nf_hook_ops,这个结构体是实现钩子函数 ...

最新文章

  1. 2022-2028年中国粘网胶行业市场深度评估及发展前景规划报告
  2. java mvc数据库 封装_Springmvc对就jdbc封装的操作
  3. 人脸检测-- Face R-FCN + Face R-CNN
  4. Centos7.0-安装docker
  5. netflix 工作原理_Netflix如何在屏幕后面工作?
  6. python执行oracle命令_如何使用cx\U Oracle运行非查询sql命令?
  7. 1562a检测软件_洛达1562a空间音频版评测!!!
  8. python中异或运算_python – 基于ID列表有效计算XOR(^)校验和的方法
  9. Java基础编程练习题
  10. Java 计算月份天数
  11. r7 3700u性能怎么样 相当于英特尔什么水平
  12. 2.(leaflet篇)leaflet加载接入百度地图
  13. 怎么用计算机打出黑人,电脑上怎么打法文
  14. 基于STM32F407四旋翼无人机---MS5611气压计(三)
  15. mysql根据id取模备份_MySQL中取模运算的正负与被模数的符号相同
  16. 微信支付成功后服务器宕机了,今天微信出现大面积宕机,可能与支付宝有关?...
  17. LWN:Fedora关于stack frame的争论!
  18. Windows应用、注册表
  19. 记录:我的秋招求职之路 —— 杭州(Java开发)
  20. 通达oa 2013 php解密,通达OA2013集团版SQL注入+root

热门文章

  1. onblur失焦事件
  2. 建立DNS隧道绕过校园网认证
  3. pageable接口
  4. Postgres -- 报错: org.postgresql.util.PSQLException: 语法错误 在 “user“ 或附近
  5. Elasticsearch入门、Kibana 索引管理(elasticserch-head 插件使用, Kibanan 安装和使用)
  6. Leetcode 5349:安排电影院座位
  7. ViewModel 在 Activity 中的实现原理
  8. 学计算机128g够吗,电脑128G固态硬盘够用吗?
  9. geotools学习(五)影像
  10. 珍惜生命,远离TP大眼睛