如何获取非内核源码树中给定驱动的ioctl命令整数值
如何获取非内核源码树驱动的IOCTL命令整数值
下面是几种无需修改驱动就能拿到结果的方法:
1. 用户态模拟计算IOCTL宏
_IO、_IOR、_IOW、_IOWR这些定义IOCTL命令的宏,计算规则是公开的,你可以直接在用户态代码里复刻计算逻辑:
- 先明确宏的核心计算逻辑(不同架构下规则基本一致,可参考
<sys/ioctl.h>):
命令值 =(类型字符ASCII值 << 8) | 命令编号 | (结构体大小 << 16) | 方向标识
其中方向标识:_IO是0(无数据),_IOR是1(读数据),_IOW是2(写数据),_IOWR是3(读写数据) - 写个简单的C程序,把目标IOCTL的参数原样代入:
编译时要注意和驱动运行的架构匹配(32位/64位),运行程序就能得到准确的命令值。#include <stdio.h> #include <sys/ioctl.h> /* 必须完全复制驱动里的struct example定义,否则大小计算错误 */ struct example { int val; // 和驱动里一致的其他成员 }; int main() { unsigned int cmd = _IOW('a', 1, struct example*); printf("ioctl_cmd整数值:0x%x(十进制:%u)\n", cmd, cmd); return 0; }
2. 用strace追踪现有或测试程序
如果有调用该驱动的用户态程序,或者能自己写个极简测试程序,用strace就能直接抓出IOCTL命令值:
- 追踪现有程序:
输出里会有类似strace ./your_program_that_uses_driverioctl(3, 0x123456, ...)的行,其中0x123456就是你要的整数值。 - 自己写测试程序(哪怕参数不对,只要命令号计算正确就能被捕获):
编译后用strace运行,就能看到实际发出的IOCTL命令值。#include <fcntl.h> #include <sys/ioctl.h> #include <unistd.h> int main() { int fd = open("/dev/your_device_node", O_RDWR); if (fd != -1) { // 这里命令号按驱动里的宏规则计算,参数随便传个指针就行 ioctl(fd, _IOW('a', 1, void*), NULL); close(fd); } return 0; }
3. 反编译驱动二进制文件
如果能拿到驱动的.ko二进制文件,可以用反编译工具分析:
- 用
objdump或者IDA Pro等工具打开驱动文件,找到处理IOCTL的函数(通常叫xxx_ioctl或xxx_unlocked_ioctl) - 在函数里找
switch(cmd)这类分支判断,case后面的数值就是IOCTL命令的整数值。
内容的提问来源于stack exchange,提问作者Rider X
相关产品推荐
相关产品推荐

