命令字:!ndx.chrdevs !ndx.blkdevs
用法描述:
!ndx.chrdevs :显示字符设备,和cat /proc/devices 显示的Character devices 一致
!ndx.blkdevs :显示块设备,和cat /proc/devices 显示的 Block devices 一致
开发过程:
1.找到关键全局变量
fs\proc\devices.c文件下有相关的遍历和显示回调函数,我们通过显示的回调函数,能找到存放字符设备的全局变量
show回调函数的实现:
字符设备显示函数:
fs\char_dev.c下定义了哈希表chrdevs,它的大小为255。
块设备显示函数:
block\genhd.c下定义了哈希表major_names,它的大小为255.
那么我们遍历这两个指针数组,读取对应结构体字段即可,要准确获取相应字段还需查看内核中的遍历,可以清楚知晓对应的数据结构
2.理清相关数据结构
在devinfo_start,开始获取的时候,有两个宏定义,分别定义了字符设备最大数量和块设备最大数量,均为512。
#define CHRDEV_MAJOR_MAX 512
#ifdef CONFIG_BLOCK
#define BLKDEV_MAJOR_MAX 512
#else
#define BLKDEV_MAJOR_MAX 0
#endif
static void *devinfo_start(struct seq_file *f, loff_t *pos)
{
if (*pos < (BLKDEV_MAJOR_MAX + CHRDEV_MAJOR_MAX))
return pos;
return NULL;
}
再看哈希表结构:
3.读取变量和相关偏移,输出信息
DECLARE_API(chrdevs)
{
ULONG64 ptr_chrdevs = 0;
ULONG read;
GetExpressionEx("lk!chrdevs", &ptr_chrdevs, NULL);
if (ptr_chrdevs == 0) {
dprintf("Failed to get chrdevs address. Please fix symbol.\n");
return;
}
//读取 chrdevs 哈希表
ULONG64 chrdevs[CHRDEV_MAJOR_HASH_SIZE];
ULONG nNameOffset, nMajorOffset, nBaseminorOffset, nMinorctOffset, nNextOffset;
char name[64];
unsigned int baseminor;
int minorct;
ExtReadMemory(ptr_chrdevs, chrdevs, sizeof(chrdevs), &read);
//获取相关字段的偏移
GetFieldOffset("char_device_struct", "name", &nNameOffset);
GetFieldOffset("char_device_struct", "major", &nMajorOffset);
GetFieldOffset("char_device_struct", "baseminor", &nBaseminorOffset);
GetFieldOffset("char_device_struct", "minorct", &nMinorctOffset);
GetFieldOffset("char_device_struct", "next", &nNextOffset);
// 遍历所有可能的主设备号,输出结果
for (int major = 0; major < CHRDEV_MAJOR_MAX; major++) {
int bucket = major % CHRDEV_MAJOR_HASH_SIZE;
ULONG64 device_ptr = chrdevs[bucket];
while (device_ptr != 0) {
unsigned int dev_major = 0;
ExtReadMemory(device_ptr + nMajorOffset, &dev_major, sizeof(dev_major), &read);
if (dev_major == (unsigned int)major) {
ExtReadMemory(device_ptr + nNameOffset, name, sizeof(name), &read);
ExtReadMemory(device_ptr + nBaseminorOffset, &baseminor, sizeof(baseminor), &read);
ExtReadMemory(device_ptr + nMinorctOffset, &minorct, sizeof(minorct), &read);
dprintf("chrdev[%03d]%016llX major:%-8u baseminor:%-10u minorct:%-8d name:%-40.40s\n",
major, device_ptr, dev_major, baseminor, minorct, name);
}
ULONG64 next_ptr = 0;
ExtReadMemory(device_ptr + nNextOffset, &next_ptr, sizeof(next_ptr), &read);
device_ptr = next_ptr;
}
}
}
4.实例测试
!ndx.chrdevs
!ndx.blkdevs
cat /proc/devices
对比发现相同字段是一致的,我们还增添加相关信息的输出。
作者:郭建程 创建时间:2025-09-01 11:31
最后编辑:郭建程 更新时间:2025-09-11 16:05
最后编辑:郭建程 更新时间:2025-09-11 16:05