首页
社区
课程
招聘
[原创]驱动程序学习笔记(一)(二)(三)(四)(五)
发表于: 2012-3-18 23:25 79068

[原创]驱动程序学习笔记(一)(二)(三)(四)(五)

2012-3-18 23:25
79068
收藏
免费 6
支持
分享
最新回复 (90)
雪    币: 113
活跃值: (100)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
51
3ks,
设备对象的创建必须在DriverEntry的时候嘛?能不能在驱动提供服务,也就是说在dispatch的时候?
2012-3-30 10:20
0
雪    币: 69
活跃值: (242)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wmg
52
很好的东西,谢谢分享!
2012-3-30 11:07
0
雪    币: 220
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
53
可以..........(看雪有点强人所难,非要>=6个字。)
2012-3-30 13:51
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
54
不错不错  学习了
2012-3-30 14:50
0
雪    币: 58
活跃值: (1135)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
55
mark!!!!!!
2012-4-4 19:42
0
雪    币: 114
活跃值: (26)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
56
驱动程序学习笔记五-----键盘记录
这篇笔记拖得有点长,清明放假我堕落了,加上值班一值就24小时,累的回来啥都不想干了。现在把主要过程都发出来。前面已经用WinDbg观察过键盘设备的一些设备和驱动,请看一下回顾
!DevObj   !DrvObj            !DevExt   ObjectName
  8212a030  \Driver\Kbdclass   8212a0e8  KeyboardClass0
  8212ceb8  \Driver\DKbFltr    8212cf70  
> 822d7310  \Driver\i8042prt   822d73c8  
  822dc888  \Driver\ACPI       8239bea0  00000076
位于最上层的是Kbdclass这个驱动对象,而他所关联的则是KeyboardClass0这个设备对象,我们的目的就是过滤传给他的IRP,从中获得
按下的键值,书上说他要找到Kbdclass所有的创建的设备对象,并绑定所有,我觉得忒麻烦了,既然我们都知道这个设备是关乎键盘的,那干嘛费那么多事呢。直接干掉他就是了。这里驱动编程是个问题,一开始我就用记事本直接写,后来写了两个函数在DDK中编译错误那个多啊,实在受不了啊。总是些莫名奇妙的错误,于是我决定在VC++编译环境中写吧,至少还有代码提示功能,加上可以一个一个函数的编译,出错了还知道在哪。叫我总结到了,不能一下子想把整个函数写完,必须一步一步的测试啊。后来整个都写完了,快乐之余将其拖到虚拟机中看一下,结果他毫不留情的甩给我一张蓝脸,我也没找到原因,等我找到原因再将,估计是哪个地方占用资源没有释放。还是现总结一下思路吧。
  书上从击键到内核原理讲了一大堆,反正我是晕晕乎乎的,不就是放个过滤驱动截获IRP吗,然后从缓冲区中读出扫描码不就OK了,说干就干,来分析分析作者的程序,其实不难。
1:找到驱动下所有的设备对象
  其实我自己也写了个读取键盘扫描码的驱动,但是啊就是蓝屏,我想法是这样的,既然我们知道处理键盘功能模块的设备就是驱动Kbdclass下的KeyboardClass0设备,那么我们还找到所有设备干嘛呢,直接绑定这个设备不就ok了?哪需要再找他其他设备一并绑定吗?最终我想法没有成功,因为编译虽成功了,但是总是蓝屏,气的还是像作者那样吧,虽然麻烦些,至少处理没有问题的。
// Kbdclass驱动的名字
#define KBD_DRIVER_NAME  L"\\Driver\\Kbdclass"

// 这个函数是事实存在的,只是文档中没有公开。声明一下
// 就可以直接使用了。
NTSTATUS
ObReferenceObjectByName(
                        PUNICODE_STRING ObjectName,
                        ULONG Attributes,
                        PACCESS_STATE AccessState,
                        ACCESS_MASK DesiredAccess,
                        POBJECT_TYPE ObjectType,
                        KPROCESSOR_MODE AccessMode,
                        PVOID ParseContext,
                        PVOID *Object
                        );
extern POBJECT_TYPE IoDriverObjectType;

//用到的设备扩展
typedef struct _C2P_DEV_EXT
{
    // 这个结构的大小
    ULONG NodeSize;
    // 过滤设备对象
    PDEVICE_OBJECT pFilterDeviceObject;
    // 同时调用时的保护锁
    KSPIN_LOCK IoRequestsSpinLock;
    // 进程间同步处理  
    KEVENT IoInProgressEvent;
    // 绑定的设备对象
    PDEVICE_OBJECT TargetDeviceObject;
    // 绑定前底层设备对象
    PDEVICE_OBJECT LowerDeviceObject;
} C2P_DEV_EXT, *PC2P_DEV_EXT;

//绑定所有设备
NTSTATUS
c2pAttachDevices(
                  IN PDRIVER_OBJECT DriverObject,
                  IN PUNICODE_STRING RegistryPath
                  )
{
    NTSTATUS status = 0;
    UNICODE_STRING uniNtNameString;
    PC2P_DEV_EXT devExt;
    PDEVICE_OBJECT pFilterDeviceObject = NULL;
    PDEVICE_OBJECT pTargetDeviceObject = NULL;
    PDEVICE_OBJECT pLowerDeviceObject = NULL;

    PDRIVER_OBJECT KbdDriverObject = NULL;

    KdPrint(("MyAttach\n"));

    // 初始化一个字符串,就是Kdbclass驱动的名字。
    RtlInitUnicodeString(&uniNtNameString, KBD_DRIVER_NAME);
    // 请参照前面打开设备对象的例子。只是这里打开的是驱动对象。
    status = ObReferenceObjectByName (
        &uniNtNameString,
        OBJ_CASE_INSENSITIVE,
        NULL,
        0,
        IoDriverObjectType,
        KernelMode,
        NULL,
        &KbdDriverObject
        );
    // 如果失败了就直接返回
    if(!NT_SUCCESS(status))
    {
        KdPrint(("MyAttach: Couldn't get the MyTest Device Object\n"));
        return( status );
    }
    else
    {
        // 这个打开需要解应用。早点解除了免得之后忘记。
        ObDereferenceObject(DriverObject);
    }

    // 这是设备链中的第一个设备       
    pTargetDeviceObject = KbdDriverObject->DeviceObject;
    // 现在开始遍历这个设备链
    while (pTargetDeviceObject)
    {
        // 生成一个过滤设备,这是前面读者学习过的。这里的IN宏和OUT宏都是
        // 空宏,只有标志性意义,表明这个参数是一个输入或者输出参数。
        status = IoCreateDevice(
            IN DriverObject,
            IN sizeof(C2P_DEV_EXT),
            IN NULL,
            IN pTargetDeviceObject->DeviceType,
            IN pTargetDeviceObject->Characteristics,
            IN FALSE,
            OUT &pFilterDeviceObject
            );

        // 如果失败了就直接退出。
        if (!NT_SUCCESS(status))
        {
            KdPrint(("MyAttach: Couldn't create the MyFilter Filter Device Object\n"));
            return (status);
        }

        // 绑定。pLowerDeviceObject是绑定之后得到的下一个设备。也就是
        // 前面常常说的所谓真实设备。
        pLowerDeviceObject =
            IoAttachDeviceToDeviceStack(pFilterDeviceObject, pTargetDeviceObject);
        // 如果绑定失败了,放弃之前的操作,退出。
        if(!pLowerDeviceObject)
        {
            KdPrint(("MyAttach: Couldn't attach to MyTest Device Object\n"));
            IoDeleteDevice(pFilterDeviceObject);
            pFilterDeviceObject = NULL;
            return( status );
        }

        // 设备扩展!下面要详细讲述设备扩展的应用。
        devExt = (PC2P_DEV_EXT)(pFilterDeviceObject->DeviceExtension);
        c2pDevExtInit(
            devExt,
            pFilterDeviceObject,
            pTargetDeviceObject,
            pLowerDeviceObject );

        // 下面的操作和前面过滤串口的操作基本一致。这里不再解释了。
        pFilterDeviceObject->DeviceType=pLowerDeviceObject->DeviceType;
        pFilterDeviceObject->Characteristics=pLowerDeviceObject->Characteristics;
        pFilterDeviceObject->StackSize=pLowerDeviceObject->StackSize+1;
        pFilterDeviceObject->Flags |= pLowerDeviceObject->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE) ;
        //next device
        pTargetDeviceObject = pTargetDeviceObject->NextDevice;
    }
    return status;
}

2:有了绑定函数,那么还要解除绑定啊,函数很简单
VOID
c2pDetach(IN PDEVICE_OBJECT pDeviceObject)
{
        PC2P_DEV_EXT devExt;
        BOOLEAN NoRequestsOutstanding = FALSE;
        devExt = (PC2P_DEV_EXT)pDeviceObject->DeviceExtension;
        __try
        {
                __try
                { //从目标设备剥离设备并删除过滤设备
                        IoDetachDevice(devExt->TargetDeviceObject);
                        devExt->TargetDeviceObject = NULL;
                        IoDeleteDevice(pDeviceObject);
                        devExt->pFilterDeviceObject = NULL;
                        DbgPrint(("Detach Finished\n"));
                }
                __except (EXCEPTION_EXECUTE_HANDLER){}
        }
        __finally{}
        return;
}

3:下面看一下驱动入口函数都有哪些东西吧
NTSTATUS DriverEntry(
                     IN PDRIVER_OBJECT DriverObject,
                     IN PUNICODE_STRING RegistryPath
                     )
{
    ULONG i;
    NTSTATUS status;
    KdPrint (("c2p.SYS: entering DriverEntry\n"));

    // 填写所有的分发函数的指针
    for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
    { //通用的分发函数
        DriverObject->MajorFunction[i] = c2pDispatchGeneral;
    }

    // 单独的填写一个Read分发函数。因为要的过滤就是读取来的按键信息
    // 其他的都不重要。这个分发函数单独写。
    DriverObject->MajorFunction[IRP_MJ_READ] = c2pDispatchRead;

    // 单独的填写一个IRP_MJ_POWER函数。这是因为这类请求中间要调用
    // 一个PoCallDriver和一个PoStartNextPowerIrp,比较特殊。
    DriverObject->MajorFunction [IRP_MJ_POWER] = c2pPower;

    // 我们想知道什么时候一个我们绑定过的设备被卸载了(比如从机器上
    // 被拔掉了?)所以专门写一个PNP(即插即用)分发函数
    DriverObject->MajorFunction [IRP_MJ_PNP] = c2pPnP;

    // 卸载函数。
    DriverObject->DriverUnload = c2pUnload;
    gDriverObject = DriverObject;
    // 绑定所有键盘设备
    status =c2pAttachDevices(DriverObject, RegistryPath);

    return status;
}

4:把最普通的那个分发函数先填好吧,这个函数功能简单,就是跳过当前IRP栈,并调用下一个驱动来处理就行了。
TSTATUS c2pDispatchGeneral(
                                 IN PDEVICE_OBJECT DeviceObject,
                                 IN PIRP Irp
                                 )
{
    // 其他的分发函数,直接skip然后用IoCallDriver把IRP发送到真实设备
    // 的设备对象。
    KdPrint(("Other Diapatch!"));
    IoSkipCurrentIrpStackLocation(Irp);
    return IoCallDriver(((PC2P_DEV_EXT)
        DeviceObject->DeviceExtension)->LowerDeviceObject, Irp);
}

5:再把我们不太关心的电源处理函数填好
NTSTATUS c2pPower(
                       IN PDEVICE_OBJECT DeviceObject,
                       IN PIRP Irp
                       )
{
    PC2P_DEV_EXT devExt;
    devExt =
        (PC2P_DEV_EXT)DeviceObject->DeviceExtension;

    PoStartNextPowerIrp( Irp );
    IoSkipCurrentIrpStackLocation( Irp );
    return PoCallDriver(devExt->LowerDeviceObject, Irp );
}

6:把即插即用分发函数也填好
NTSTATUS c2pPnP(
                     IN PDEVICE_OBJECT DeviceObject,
                     IN PIRP Irp
                     )
{
    PC2P_DEV_EXT devExt;
    PIO_STACK_LOCATION irpStack;
    NTSTATUS status = STATUS_SUCCESS;
    KIRQL oldIrql;
    KEVENT event;

    // 获得真实设备。
    devExt = (PC2P_DEV_EXT)(DeviceObject->DeviceExtension);
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    switch (irpStack->MinorFunction)
    {
    case IRP_MN_REMOVE_DEVICE:
        KdPrint(("IRP_MN_REMOVE_DEVICE\n"));

        // 首先把请求发下去
        IoSkipCurrentIrpStackLocation(Irp);
        IoCallDriver(devExt->LowerDeviceObject, Irp);
        // 然后解除绑定。
        IoDetachDevice(devExt->LowerDeviceObject);
        // 删除我们自己生成的虚拟设备。
        IoDeleteDevice(DeviceObject);
        status = STATUS_SUCCESS;
        break;

    default:
        // 对于其他类型的IRP,全部都直接下发即可。
        IoSkipCurrentIrpStackLocation(Irp);
        status = IoCallDriver(devExt->LowerDeviceObject, Irp);
    }
    return status;
}

7:看一下最重要的两个函数,read函数
NTSTATUS c2pDispatchRead(
                              IN PDEVICE_OBJECT DeviceObject,
                              IN PIRP Irp )
{
    NTSTATUS status = STATUS_SUCCESS;
    PC2P_DEV_EXT devExt;
    PIO_STACK_LOCATION currentIrpStack;
    KEVENT waitEvent;
    //初始化同步事件函数
    KeInitializeEvent( &waitEvent, NotificationEvent, FALSE );

        if (Irp->CurrentLocation == 1)
        {
                ULONG ReturnedInformation = 0;
                KdPrint(("Dispatch encountered bogus current location\n"));
                status = STATUS_INVALID_DEVICE_REQUEST;
                Irp->IoStatus.Status = status;
                Irp->IoStatus.Information = ReturnedInformation;
                IoCompleteRequest(Irp, IO_NO_INCREMENT);
                return(status);
        }

    // 全局变量键计数器加1
    gC2pKeyCount++;

    // 得到设备扩展。目的是之后为了获得下一个设备的指针。
    devExt =
        (PC2P_DEV_EXT)DeviceObject->DeviceExtension;

    // 设置回调函数并把IRP传递下去。 之后读的处理也就结束了。
    // 剩下的任务是要等待读请求完成。
    currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
    IoCopyCurrentIrpStackLocationToNext(Irp);
    IoSetCompletionRoutine( Irp, c2pReadComplete,
        DeviceObject, TRUE, TRUE, TRUE );
    return  IoCallDriver( devExt->LowerDeviceObject, Irp );        
}

8:回调例程是在上面read函数中指定的
NTSTATUS c2pReadComplete(
                              IN PDEVICE_OBJECT DeviceObject,
                              IN PIRP Irp,
                              IN PVOID Context
                              )
{
     PIO_STACK_LOCATION IrpSp;
     ULONG buf_len = 0;
     PUCHAR buf = NULL;
     size_t i;

     IrpSp = IoGetCurrentIrpStackLocation( Irp );

     //  如果这个请求是成功的。很显然,如果请求失败了,这么获取
     //   进一步的信息是没意义的。
     if( NT_SUCCESS( Irp->IoStatus.Status ) )
     {
        // 获得读请求完成后输出的缓冲区
        buf = Irp->AssociatedIrp.SystemBuffer;
        // 获得这个缓冲区的长度。一般的说返回值有多长都保存在
        // Information中。
        buf_len = Irp->IoStatus.Information;

        //… 这里可以做进一步的处理。我这里很简单的打印出所有的扫
        // 描码。
        for(i=0;i<buf_len;++i)
        {
            DbgPrint("ctrl2cap: %2x\r\n", buf[i]);
        }
    }
    gC2pKeyCount--;

        if( Irp->PendingReturned )
        {
                IoMarkIrpPending( Irp );
        }
    return Irp->IoStatus.Status;
}

9:坏事也干完了,该卸载我们的函数了,其实整个过程并不难,就是细节处理问题
#define  DELAY_ONE_MICROSECOND  (-10)
#define  DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND*1000)
#define  DELAY_ONE_SECOND (DELAY_ONE_MILLISECOND*1000)

VOID
c2pUnload(IN PDRIVER_OBJECT DriverObject)
{
    PDEVICE_OBJECT DeviceObject;
    PDEVICE_OBJECT OldDeviceObject;
    PC2P_DEV_EXT devExt;

    LARGE_INTEGER        lDelay;
    PRKTHREAD CurrentThread;
    //delay some time
    lDelay = RtlConvertLongToLargeInteger(100 * DELAY_ONE_MILLISECOND);
    CurrentThread = KeGetCurrentThread();
    // 把当前线程设置为低实时模式,以便让它的运行尽量少影响其他程序。
    KeSetPriorityThread(CurrentThread, LOW_REALTIME_PRIORITY);
    //解除引用过的参数,释放资源,不然等着那张蓝脸吧
    UNREFERENCED_PARAMETER(DriverObject);
    KdPrint(("DriverEntry unLoading...\n"));

    // 遍历所有设备并一律解除绑定
    DeviceObject = DriverObject->DeviceObject;
    while (DeviceObject)
    {
        // 解除绑定并删除所有的设备
        c2pDetach(DeviceObject);
        DeviceObject = DeviceObject->NextDevice;
    }
    ASSERT(NULL == DriverObject->DeviceObject);

    while (gC2pKeyCount)
    {//延迟执行线程
        KeDelayExecutionThread(KernelMode, FALSE, &lDelay);
    }
    KdPrint(("DriverEntry unLoad OK!\n"));
    return;
}

10:最后初始化设备扩展结构体的函数,差点忘了写了
NTSTATUS
c2pDevExtInit(
    IN PC2P_DEV_EXT devExt,
    IN PDEVICE_OBJECT pFilterDeviceObject,
    IN PDEVICE_OBJECT pTargetDeviceObject,
    IN PDEVICE_OBJECT pLowerDeviceObject )
{
    memset(devExt, 0, sizeof(C2P_DEV_EXT));
    devExt->NodeSize = sizeof(C2P_DEV_EXT);
    devExt->pFilterDeviceObject = pFilterDeviceObject;
    KeInitializeSpinLock(&(devExt->IoRequestsSpinLock));
    KeInitializeEvent(&(devExt->IoInProgressEvent), NotificationEvent, FALSE);
    devExt->TargetDeviceObject = pTargetDeviceObject;
    devExt->LowerDeviceObject = pLowerDeviceObject;
    return( STATUS_SUCCESS );
}
2012-4-8 15:53
0
雪    币: 114
活跃值: (26)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
57
这篇日记写的粗糙,主要是要赶快继续往下看书,看懂这个没有问题的。
2012-4-8 15:55
0
雪    币: 388
活跃值: (707)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
58
用不了strct的话直接.load一下就行了,例子如下..

kd> !strct
No export strct found
kd> .chain
Extension DLL search Path:
    C:\Program Files\Debugging Tools for Windows (x86)\WINXP;C:\Program Files\Debugging Tools for Windows (x86)\winext;C:\Program Files\Debugging Tools for Windows (x86)\winext\arcade;C:\Program Files\Debugging Tools for Windows (x86)\pri;C:\Program Files\Debugging Tools for Windows (x86);C:\Program Files\Debugging Tools for Windows (x86)\winext\arcade;C:\Program Files\PC Connectivity Solution\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program Files\SinoVoice\jTTS 5.0 Desktop\Bin;C:\Program Files\Microsoft SQL Server\90\Tools\binn\;C:\Program Files\TortoiseSVN\bin;C:\Program Files\Microsoft Platform SDK for Windows XP SP2\Bin\.;C:\Program Files\Microsoft Platform SDK for Windows XP SP2\Bin\WinNT\.;;C:\Program Files\Lua\5.1;C:\Program Files\Lua\5.1\clibs;C:\Program Files\Microsoft Visual Studio\Common\Tools\WinNT;C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin;C:\Program Files\Microsoft Visual Studio\Common\Tools;C:\Program Files\Microsoft Visual Studio\VC98\bin;C:\Program Files\Microsoft Platform SDK for Windows XP SP2\Bin\.;C:\Program Files\Microsoft Platform SDK for Windows XP SP2\Bin\WinNT\.
Extension DLL chain:
    dbghelp: image 6.12.0002.633, API 6.1.6, built Tue Feb 02 04:08:26 2010
        [path: C:\Program Files\Debugging Tools for Windows (x86)\dbghelp.dll]
    ext: image 6.12.0002.633, API 1.0.0, built Tue Feb 02 04:08:31 2010
        [path: C:\Program Files\Debugging Tools for Windows (x86)\winext\ext.dll]
    exts: image 6.12.0002.633, API 1.0.0, built Tue Feb 02 04:08:24 2010
        [path: C:\Program Files\Debugging Tools for Windows (x86)\WINXP\exts.dll]
    kext: image 6.12.0002.633, API 1.0.0, built Tue Feb 02 04:08:22 2010
        [path: C:\Program Files\Debugging Tools for Windows (x86)\winext\kext.dll]
    kdexts: image 6.1.7650.0, API 1.0.0, built Tue Feb 02 04:08:19 2010
        [path: C:\Program Files\Debugging Tools for Windows (x86)\WINXP\kdexts.dll]
kd> .load w2kfre\kdex2x86.dll
kd> !object \driver\i8042prt
Object: 82119330  Type: (821a55b8) Driver
    ObjectHeader: 82119318 (old version)
    HandleCount: 0  PointerCount: 5
    Directory Object: e1022970  Name: i8042prt
kd> .chain
Extension DLL search Path:
    C:\Program Files\Debugging Tools for Windows (x86)\WINXP;C:\Program Files\Debugging Tools for Windows (x86)\winext;C:\Program Files\Debugging Tools for Windows (x86)\winext\arcade;C:\Program Files\Debugging Tools for Windows (x86)\pri;C:\Program Files\Debugging Tools for Windows (x86);C:\Program Files\Debugging Tools for Windows (x86)\winext\arcade;C:\Program Files\PC Connectivity Solution\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program Files\SinoVoice\jTTS 5.0 Desktop\Bin;C:\Program Files\Microsoft SQL Server\90\Tools\binn\;C:\Program Files\TortoiseSVN\bin;C:\Program Files\Microsoft Platform SDK for Windows XP SP2\Bin\.;C:\Program Files\Microsoft Platform SDK for Windows XP SP2\Bin\WinNT\.;;C:\Program Files\Lua\5.1;C:\Program Files\Lua\5.1\clibs;C:\Program Files\Microsoft Visual Studio\Common\Tools\WinNT;C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin;C:\Program Files\Microsoft Visual Studio\Common\Tools;C:\Program Files\Microsoft Visual Studio\VC98\bin;C:\Program Files\Microsoft Platform SDK for Windows XP SP2\Bin\.;C:\Program Files\Microsoft Platform SDK for Windows XP SP2\Bin\WinNT\.
Extension DLL chain:
    w2kfre\kdex2x86.dll: image 3.00.2093.18, API 5.0.5, built Wed Mar 28 16:57:06 2001
        [path: C:\Program Files\Debugging Tools for Windows (x86)\w2kfre\kdex2x86.dll]
    dbghelp: image 6.12.0002.633, API 6.1.6, built Tue Feb 02 04:08:26 2010
        [path: C:\Program Files\Debugging Tools for Windows (x86)\dbghelp.dll]
    ext: image 6.12.0002.633, API 1.0.0, built Tue Feb 02 04:08:31 2010
        [path: C:\Program Files\Debugging Tools for Windows (x86)\winext\ext.dll]
    exts: image 6.12.0002.633, API 1.0.0, built Tue Feb 02 04:08:24 2010
        [path: C:\Program Files\Debugging Tools for Windows (x86)\WINXP\exts.dll]
    kext: image 6.12.0002.633, API 1.0.0, built Tue Feb 02 04:08:22 2010
        [path: C:\Program Files\Debugging Tools for Windows (x86)\winext\kext.dll]
    kdexts: image 6.1.7650.0, API 1.0.0, built Tue Feb 02 04:08:19 2010
        [path: C:\Program Files\Debugging Tools for Windows (x86)\WINXP\kdexts.dll]
kd> !strct _DRIVER_OBJECT 82119330
struct   _DRIVER_OBJECT (sizeof=168)
+00 int16    Type =                              0004
+02 int16    Size =                              00a8
+04 struct   _DEVICE_OBJECT *DeviceObject =      82137398
+08 uint32   Flags =                             00000012
+0c void     *DriverStart =                      F877A000
+10 uint32   DriverSize =                        0000ba00
+14 void     *DriverSection =                    82119DF0
+18 struct   _DRIVER_EXTENSION *DriverExtension =               821193D8
+1c struct   _UNICODE_STRING DriverName
+1c    uint16   Length =                         0020
+1e    uint16   MaximumLength =                  0020
+20    uint16   *Buffer =                        E1648208
+24 struct   _UNICODE_STRING *HardwareDatabase =                8066FFD8
+28 struct   _FAST_IO_DISPATCH *FastIoDispatch =                00000000
+2c function *DriverInit =                       F8783385
+30 function *DriverStartIo =                    F877A974
+34 function *DriverUnload =                     F8780F24
+38 function *MajorFunction[28] =                F877DB1A
                                                 804F4418
                                                 F8780E86
                                                 804F4418
                                                 804F4418
                                                 804F4418
                                                 804F4418
                                                 804F4418
                                                 804F4418
                                                 F877C1F8
                                                 804F4418
                                                 804F4418
                                                 804F4418
                                                 804F4418
                                                 F8780EB9
                                                 F877A89A
                                                 804F4418
                                                 804F4418
                                                 804F4418
                                                 804F4418
                                                 804F4418
                                                 804F4418
                                                 F8781857
                                                 F877DACD
                                                 804F4418
                                                 804F4418
                                                 804F4418
                                                 F877DA00
2012-4-10 11:24
0
雪    币: 2194
活跃值: (1001)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
59
这个要认真看看
2012-4-10 11:57
0
雪    币: 60
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
60
Mark 驱动
2012-4-21 02:33
0
雪    币: 220
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
61
请继续看后半截:“ or a named device object for which a security descriptor is set by a...”
2012-5-3 12:15
0
雪    币: 2155
活跃值: (29)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
62
先顶再看,留个脚印,
2012-5-3 16:58
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
63
很好的笔记,就是我太菜了,看不太懂,留个名先以后仔细学习。
2012-5-4 14:52
0
雪    币: 145
活跃值: (105)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
64
楼主,交个朋友,同在学驱动
2012-5-4 15:21
0
雪    币: 114
活跃值: (26)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
65
学驱动遇到很多问题,交个朋友啊,留下我的qq2454777585
2012-5-7 00:26
0
雪    币: 76
活跃值: (114)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
66
UNICODE_STRING
The UNICODE_STRING structure is used to define Unicode strings.

typedef struct _UNICODE_STRING {
  USHORT  Length;
  USHORT  MaximumLength;
  PWSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

Members
Length
The length in bytes of the string stored in Buffer.
MaximumLength
The length in bytes of Buffer.
Buffer
Pointer to a buffer used to contain a string of wide characters.
楼主 文档是字节大小,不是字符~~~ 菜鸟滤过~~~
2012-5-7 00:56
0
雪    币: 87
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
67
我也是学驱动的,mark
2012-5-29 11:52
0
雪    币: 10
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
68
楼主的这份WINDBG命令很好,我等小菜受益匪浅。
2012-8-19 23:58
0
雪    币: 51
活跃值: (61)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
69
顶  我自己还是先不要碰
2012-9-25 13:34
0
雪    币: 18
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
70
MARK留名,后面慢慢看。
2013-3-15 11:56
0
雪    币: 134
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
71
向楼主学习。。。笔记
2013-3-28 16:12
0
雪    币: 3373
活跃值: (1368)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
72
留印,回家下
2013-3-28 17:40
0
雪    币: 265
活跃值: (56)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
73
多谢分享,说不定那天我就会用的上
2013-6-27 15:08
0
雪    币: 59
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
74
谢谢楼主分享,,写得不错
2014-3-27 20:40
0
雪    币: 680
活跃值: (68)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
75
顶下,看过寒江,楼主总结的不错
2014-3-27 20:43
0
游客
登录 | 注册 方可回帖
返回
//