64 位驱动程序

发布于 2024-12-01 01:44:50 字数 2340 浏览 1 评论 0原文

我有一个在 32 位上运行良好的驱动程序代码。在 64 位上我编译了它并对其进行了数字签名。驱动程序已加载但无法正常工作。驱动程序的主要功能是在回调中向我的程序注册进程创建和终止。所以我有两个 IOCTL 正在工作。代码如下..

NTSTATUS DispatchIoctl(
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP           Irp
    )

{

 NTSTATUS               ntStatus = STATUS_UNSUCCESSFUL;

PIO_STACK_LOCATION     irpStack  = IoGetCurrentIrpStackLocation(Irp);
PDEVICE_EXTENSION      extension = DeviceObject->DeviceExtension;
PPROCESS_CALLBACK_INFO pProcCallbackInfo;
//
// These IOCTL handlers are the set and get interfaces between
// the driver and the user mode app
//
switch(irpStack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_PROCOBSRV_ACTIVATE_MONITORING:
    {
        ntStatus = ActivateMonitoringHanlder( Irp );
        break;
    }
    case IOCTL_PROCOBSRV_GET_PROCINFO:
    {
        if (irpStack->Parameters.DeviceIoControl.OutputBufferLength >=                 sizeof(PROCESS_CALLBACK_INFO))
        {
        pProcCallbackInfo = Irp->AssociatedIrp.SystemBuffer;
        pProcCallbackInfo->hParentId  = extension->hParentId;
        pProcCallbackInfo->hProcessId = extension->hProcessId;
        pProcCallbackInfo->bCreate    = extension->bCreate;

        ntStatus = STATUS_SUCCESS;
        }
        break;
    }

    default:
        break;
}

Irp->IoStatus.Status = ntStatus;
//
// Set number of bytes to copy back to user-mode
//
if(ntStatus == STATUS_SUCCESS)
   Irp->IoStatus.Information = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
else
    Irp->IoStatus.Information = 0;

IoCompleteRequest(Irp, IO_NO_INCREMENT);
return ntStatus;

}

当我调用时

 bReturnCode = ::DeviceIoControl(
                hDriverFile,
                IOCTL_PROCOBSRV_ACTIVATE_MONITORING,
                &activateInfo, 
                sizeof(activateInfo),
                NULL, 
                0,
                &dwBytesReturned,
                NULL
                );

代码成功,但是当我调用

bReturnCode = ::DeviceIoControl(
        m_hDriverFile,
        IOCTL_PROCOBSRV_GET_PROCINFO,
        0, 
        0,
        &callbackInfo, sizeof(callbackInfo),
        &dwBytesReturned,
        &ov
        );

getLastError 时返回 31。任何人都可以帮我解决这个问题。是64位IOCTL结构的问题吗?请帮我找到解决方案。谢谢..

I have a driver code which works good on 32 bit. On 64 bit i compiled it and also digitally signed it. The driver loads but fails to work properly. The main functionality of the driver to to register process creation and termination to my program in call back. So i have two IOCTL working. The code is as follows..

NTSTATUS DispatchIoctl(
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP           Irp
    )

{

 NTSTATUS               ntStatus = STATUS_UNSUCCESSFUL;

PIO_STACK_LOCATION     irpStack  = IoGetCurrentIrpStackLocation(Irp);
PDEVICE_EXTENSION      extension = DeviceObject->DeviceExtension;
PPROCESS_CALLBACK_INFO pProcCallbackInfo;
//
// These IOCTL handlers are the set and get interfaces between
// the driver and the user mode app
//
switch(irpStack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_PROCOBSRV_ACTIVATE_MONITORING:
    {
        ntStatus = ActivateMonitoringHanlder( Irp );
        break;
    }
    case IOCTL_PROCOBSRV_GET_PROCINFO:
    {
        if (irpStack->Parameters.DeviceIoControl.OutputBufferLength >=                 sizeof(PROCESS_CALLBACK_INFO))
        {
        pProcCallbackInfo = Irp->AssociatedIrp.SystemBuffer;
        pProcCallbackInfo->hParentId  = extension->hParentId;
        pProcCallbackInfo->hProcessId = extension->hProcessId;
        pProcCallbackInfo->bCreate    = extension->bCreate;

        ntStatus = STATUS_SUCCESS;
        }
        break;
    }

    default:
        break;
}

Irp->IoStatus.Status = ntStatus;
//
// Set number of bytes to copy back to user-mode
//
if(ntStatus == STATUS_SUCCESS)
   Irp->IoStatus.Information = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
else
    Irp->IoStatus.Information = 0;

IoCompleteRequest(Irp, IO_NO_INCREMENT);
return ntStatus;

}

when i call

 bReturnCode = ::DeviceIoControl(
                hDriverFile,
                IOCTL_PROCOBSRV_ACTIVATE_MONITORING,
                &activateInfo, 
                sizeof(activateInfo),
                NULL, 
                0,
                &dwBytesReturned,
                NULL
                );

The code succeeds but when i call

bReturnCode = ::DeviceIoControl(
        m_hDriverFile,
        IOCTL_PROCOBSRV_GET_PROCINFO,
        0, 
        0,
        &callbackInfo, sizeof(callbackInfo),
        &dwBytesReturned,
        &ov
        );

getLastError returns 31. Can anyone help me with this. Is it a problem of IOCTL structure with 64 bit? Please help me find a solution to this. Thanks..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

少钕鈤記 2024-12-08 01:44:50

如果您没有驱动程序调试经验,请尝试使用跟踪来诊断此问题。将 KdPrint 行添加到代码中所有需要的地方,例如:

case IOCTL_PROCOBSRV_GET_PROCINFO:     
{        
    KdPrint(("IOCTL_PROCOBSRV_GET_PROCINFO. OutputBufferLength = %d\n", irpStack->Parameters.DeviceIoControl.OutputBufferLength));
    KdPrint(("sizeof(PROCESS_CALLBACK_INFO) = %d\n", sizeof(PROCESS_CALLBACK_INFO)));

    if (irpStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(PROCESS_CALLBACK_INFO))         
    {
        pProcCallbackInfo = Irp->AssociatedIrp.SystemBuffer;         
        pProcCallbackInfo->hParentId  = extension->hParentId;         
        pProcCallbackInfo->hProcessId = extension->hProcessId;         
        pProcCallbackInfo->bCreate    = extension->bCreate; 

        KdPrint(("IOCTL_PROCOBSRV_GET_PROCINFO. STATUS_SUCCESS\n"));         
        ntStatus = STATUS_SUCCESS;         
    }         
    break;     
} 

这只是一个示例,将 KdPrint 行添加到所有位置以了解会发生什么。在检查的配置中构建驱动程序,安装它并运行您的程序。请参阅 DbgView 程序中的 KdPrint 输出,并启用 Caprure Kernel 选项。

您可以使用 DbgPrint 而不是 KdPrint,在这种情况下,它也可以在免费驱动程序配置中工作。

编辑:

PROCESS_CALLBACK_INFO 是如何定义的?调用驱动程序的客户端代码是什么?客户端编译为 32 位还是 64 位?在客户端和驱动程序之间传递结构,确保它不包含与位数相关的字段(在 32 位和 64 位中编译时具有相同的大小),并且结构填充相同。

If you don't have driver debugging experience, try to diagnose this problem using trace. Add KdPrint lines to your code in all places where it is necessary, for example:

case IOCTL_PROCOBSRV_GET_PROCINFO:     
{        
    KdPrint(("IOCTL_PROCOBSRV_GET_PROCINFO. OutputBufferLength = %d\n", irpStack->Parameters.DeviceIoControl.OutputBufferLength));
    KdPrint(("sizeof(PROCESS_CALLBACK_INFO) = %d\n", sizeof(PROCESS_CALLBACK_INFO)));

    if (irpStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(PROCESS_CALLBACK_INFO))         
    {
        pProcCallbackInfo = Irp->AssociatedIrp.SystemBuffer;         
        pProcCallbackInfo->hParentId  = extension->hParentId;         
        pProcCallbackInfo->hProcessId = extension->hProcessId;         
        pProcCallbackInfo->bCreate    = extension->bCreate; 

        KdPrint(("IOCTL_PROCOBSRV_GET_PROCINFO. STATUS_SUCCESS\n"));         
        ntStatus = STATUS_SUCCESS;         
    }         
    break;     
} 

This is just a sample, add KdPrint lines to all places to understand what happens. Build the driver in checked configuration, install it and run your program. See KdPrint output in DbgView program, with Caprure Kernel option enabled.

You can use DbgPrint instead of KdPrint, in this case it will work also in free driver configuration.

Edit:

How is PROCESS_CALLBACK_INFO defined? What is client code that calls the driver? Is client compiled as 32 or 64 bit? Passing a structure between client and driver, ensure that it doesn't contain bitness-dependent fields (has the same size when compiled both in 32 and 64 bit), and structure padding is the same.

奢欲 2024-12-08 01:44:50

这里没有太多信息,但您可以随时检查在运行 64 位时编译的用户模式客户端和驱动程序中您自己定义的结构的大小是否相同。可能存在打包/对齐问题,可以通过对结构使用#pragma pack(或您的编译器支持的任何内容)来修复。

作为一般规则,还尝试将检测到的问题的状态代码设置为更具体的值,例如如果您检测到传递的缓冲区太小,则 STATUS_BUFFER_TOO_SMALL 。我怀疑这并不是使用 IOCTL_PROCOBSRV_GET_PROCINFO IOCTL 时出现的实际问题,因为您会收到 Win32 错误 31,但它可以帮助客户解决一般问题。

更新:从您的评论来看,差异实际上似乎不匹配,请尝试用打包包围结构定义,然后确保重新编译客户端和驱动程序。如果您使用 Visual C++ 编译器,示例如下:

#pragma pack(push, 8) // Save current packing and set to 8-byte
typedef struct _PROCESS_CALLBACK_INFO
{
    // Whatever ...
} PROCESS_CALLBACK_INFO;
#pragma pack(pop)  // Restore previous packing

Not too much information here, but you could always check that the size of your own defined structures are the same in the compiled user-mode client and the driver when running 64-bit. There might be packing/alignment issues that can be fixed by using #pragma pack (or whatever your compiler supports) for your structs.

As a general rule also try to set the status code to a more specific value on detected problems, such as e.g. STATUS_BUFFER_TOO_SMALL if you detect that a passed buffer is too small. I suspect that this isn't the actual issue here when using the IOCTL_PROCOBSRV_GET_PROCINFO IOCTL as you are getting back Win32 error 31, but it helps clients to troubleshoot their problems in general.

Update: As the differences actually seem to mismatch judging from your comments, try to surround the struct definitions with packing and then make sure to recompile both the client and driver. Example if you are using the Visual C++ compiler:

#pragma pack(push, 8) // Save current packing and set to 8-byte
typedef struct _PROCESS_CALLBACK_INFO
{
    // Whatever ...
} PROCESS_CALLBACK_INFO;
#pragma pack(pop)  // Restore previous packing
你げ笑在眉眼 2024-12-08 01:44:50

我找到了答案。感谢调试。如前所述,outputBufferLength 小于结构长度,因此驱动程序失败。

outputBufferLength 取决于调用以下函数时传递的结构的大小。

bReturnCode = ::DeviceIoControl(
m_h驱动文件,
IOCTL_PROCOBSRV_GET_PROCINFO,
0,
0,
&callbackInfo, sizeof(callbackInfo),
&dwBytes返回,
&ov
);

所以callbackInfo的大小是12,所以outputBufferLength = 12。结构callbackInfo有DWORD数据成员,对于64位来说必须是DWORD64。当我更改结构中成员的数据类型然后调用 DeviceIOControl 函数时,驱动程序运行良好,并且outputBufferLength = 24 正如预期的那样。感谢您的帮助。

I found the answer. Thanks to the debugging. As mention earlier the outputBufferLength was less than the structure length due to which the driver was failing.

The outputBufferLength depands on the size of the struct you pass while calling the following function..

bReturnCode = ::DeviceIoControl(
m_hDriverFile,
IOCTL_PROCOBSRV_GET_PROCINFO,
0,
0,
&callbackInfo, sizeof(callbackInfo),
&dwBytesReturned,
&ov
);

So callbackInfo size was 12 so the outputBufferLength = 12. The structure callbackInfo has DWORD datamember which for 64 bit had to be DWORD64. When i changed the datatype of the member in the structure and then called the DeviceIOControl function , the driver worked great and the outputBufferLength was = 24 as expected. Thanks for all your help.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文