You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

用户态通过IOCTL传递字符串至内核态出现乱码问题求助

问题分析与解决

问题根源

用户态调用DeviceIoControl时,传入的缓冲区长度是strlen(welcome)——这个函数返回的是字符串**不含终止符\0**的字符数。内核态用%s格式打印时,要求字符串必须以\0结尾,否则会持续读取后续内存直到碰到\0,这就导致末尾出现随机乱码;偶尔正常是巧合遇到内存里的\0,完全不可靠。

修复方案

1. 修改用户态代码

将传入的缓冲区长度改为包含终止符的长度,也就是strlen(welcome) + 1,确保内核能拿到完整的带终止符的字符串:

const char* welcome = "Hello from user mode";
// 字符串字面量默认自带\0,无需手动添加
bResult = DeviceIoControl(hDevice, IO_PRINT_MSG_REQUEST, (char*)welcome, strlen(welcome) + 1,
                NULL, 0, &Bytes, NULL);

2. 内核态安全优化(可选)

如果无法确保用户态一定会传入带终止符的字符串,内核态可以主动处理,避免越界:

case IO_PRINT_MSG_REQUEST:
    buffer = irp->AssociatedIrp.SystemBuffer;
    // 获取用户态传入的缓冲区总长度
    ULONG inputLen = IoGetCurrentIrpStackLocation(irp)->Parameters.DeviceIoControl.InputBufferLength;
    if (inputLen > 0 && buffer != NULL) {
        // 手动添加终止符,确保字符串结束
        ((char*)buffer)[inputLen - 1] = '\0';
        DbgPrint("IOCTL HELLO.");
        DbgPrint("Message received : %s\n", buffer);
    }
    // 必须完成IRP的收尾操作
    irp->IoStatus.Status = STATUS_SUCCESS;
    irp->IoStatus.Information = 0;
    IoCompleteRequest(irp, IO_NO_INCREMENT);
    return STATUS_SUCCESS;

注:原内核代码缺少IoCompleteRequest等IRP收尾逻辑,可能引发其他问题,建议补上。

验证效果

修改后内核态打印的字符串会正常终止,稳定显示Message received : Hello from user mode,不会再出现随机乱码。

内容的提问来源于stack exchange,提问作者Cesar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 07:36:19