type
status
date
slug
summary
tags
category
icon
password

rwProcMem33的尝试修复

错误情况

rwProcMem33编译出模块之后,无法进行正常的内存读取/写入。内核版本Linux 5.10.189
notion image

1.找到错误信息

在编译前从源码中打开debug模式的宏,让我们可以用dmesg看到内核的日志。于是发现开始就出现了这样几个错误:
notion image
notion image
notion image
作者写了几个函数,用来自动找到mmap_lock,map_count和cmdline的偏移量,但是三个都失败了。mmap_lock位于mmap_struct结构体中。扩大查找范围至整个结构体,无果。
notion image

2.修复mmap_lock和map_count

查看linux源码,可知mm_stuct的结构。对比作者所写demo,传给驱动的数值是/proc/self/maps文件的行数,驱动收到后然后以mmap_lock为基础,查找前40和后40字节的信息,是否能读出int值与map_count相等。如果相等,则取这个相等位置往后挪动两个int的位置,这里作为绝对偏移。
notion image
那么这个偏移有什么作用呢?如下是使用方式
把这个位置转换成struct rw_semaphore *指针。但这个指针的类型,就是mm结构体里面的mmap_lock的类型。map_count是int,所以往后挪动了一个int,spinlock_t大小和编译相关,但一般是32位,也可以算是int。所以又挪回来了。
notion image
那就直接让accurate offset等于mmap_lock对于mm结构体地址的偏移就完事了
让这个语句中g_mmap_lock_offset_proc_maps=0.
非常简单。注释掉上述自动找offset函数中的for循环,设置标识位为1,偏移为0即可。
对于map_count,采用相同做法即可。在init_map_count_offset函数中,注释掉for循环,并添加以下两行。

3.cmdline_offset修复

如果以上两个修复好了,会发现cmdline offset已经好用了。
这是因为上面两个修复完成,就已经可以读取和写入内存了。而找cmdline offset的时候用到了读取。
notion image
但同时也会发现,找到的offset是0。但他实现的是读物理内存直到读出来和应用传入的命令字符串相同,就判断找到了。不知道是否有用,是否是会变得,所以不改这里。

4.其他相关自动偏移(无需修补)

已经看到这里了,还剩一个自动偏移cred,一起看了吧。
先看实现代码
通过读取/proc/self/status中的进程名称,并将其与任务结构中的可能偏移位置进行比较,以real_cred为基础,找前100,后300字节的内容,直到相等。
运行这段代码发现自动找到偏移量为8.这是正确的,因为根据linux内核源码,cred确实在real_cred后8个字节处
notion image
在Linux内核中,real_credcred 是任务结构(task structure)中的两个成员,分别表示任务的真实凭据和有效凭据。理解它们的区别对理解任务的权限管理非常重要。下面详细解释这两个字段的区别及其用途:
  1. real_cred (Objective and real subjective task credentials)
      • real_cred 表示任务的真实凭据。这些凭据描述了任务实际的身份信息,不会因为临时的权限提升而改变。
      • 通常用于需要确保操作是以任务的真实身份进行的场景,例如,在设置新的权限时,系统会检查real_cred
      • 任务的真实用户ID(real user ID, ruid)、真实组ID(real group ID, rgid)等信息存储在real_cred中。
  1. cred (Effective (overridable) subjective task credentials)
      • cred 表示任务的有效凭据。这些凭据是当前任务在执行期间实际使用的凭据,可能会因为临时权限提升(如通过setuidsetgid系统调用)而改变。
      • 用于大部分权限检查,例如文件访问权限,系统调用权限等。在这些情况下,系统会检查cred中的信息。
      • 任务的有效用户ID(effective user ID, euid)、有效组ID(effective group ID, egid)等信息存储在cred中。

举个例子

假设有一个进程,它的真实用户ID(ruid)是1000,但为了执行某些特权操作,它的有效用户ID(euid)被提升到0(即root用户)。
  • real_cred将始终保持ruid为1000,因为这是进程的真实身份。
  • cred会显示euid为0,因为这是进程当前的有效身份,用于权限检查。
所以我们可以利用setgid的方式改变程序的Gid,并用驱动读取,对比输出结果。

程序输出

至此,大部分功能已经能正常运行了。还剩一个getpid没改,后续再说。
添加如下代码,进行gid的修改以便验证(因为我们要在root下运行测试工具,但是root下运行该程序uid和gid都是0不能直观的看到结果):
编译一下testKo,注释掉物理内存相关的部分(实在是慢的令人发指,但能用)输出如下
 
 
Pixel6Pro编译内核添加rwProcMem33tersafe
Loading...
Lynnette177
Lynnette177
建议开着梯子访问站点。图片是直接从Notion获取的,不开梯子容易看不见图片。
Latest posts
tersafe
2025-8-13
iOS典型反调反越狱app分析
2025-7-28
RPC:遍历android的所有java实例
2025-7-17
写一个Android Hook小框架
2025-6-23
一些macos常用软件破解记录
2025-6-22
iOS网易新闻登录算法逆向
2025-6-22
Announcement
🎉2024.6.9 上线🎉