初学驱动逆向,笔记一。

来源:互联网 发布:淘宝联盟好吗 编辑:程序博客网 时间:2024/05/21 22:39

初学驱动逆向,在《windows驱动开发技术详解》中随便找个例子逆逆看 [ \chapter09\SpecialStartIOTest ]。

水平很菜,各路牛人笑过。

逆向该例子的DriverEntry和CreateDevice函数,这两个函数在《windows驱动开发技术详解》的例子中十分常见。

并逆向的本范例驱动的核心部分 HelloDDKRead 函数,没什么技术含量。

经验:需要熟悉各数据结构内部的参数地址,便能方便地理解反汇编中的参数定位,相关结构可以通过WinDBG查看[DRIVER_OBJECT / DEVICE_OBJECT / Irp]。


DriverEntry

NTSTATUS __stdcall DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)public _DriverEntry@8_DriverEntry@8 proc nearstatus= dword ptr -4pDriverObject= dword ptr  8pRegistryPath= dword ptr  0Chpush    ebp         // 保护现场mov     ebp, esppush    ecxpush    offset aEnterDriverent ; "Enter DriverEntry\n"call    _DbgPrint   // KdPrint(("Enter DriverEntry\n"));add     esp, 4      // 申请空间// 填充 Unload 与 IRP// pDriverObject->DriverUnload = HelloDDKUnload;mov     eax, [ebp+pDriverObject]mov     dword ptr [eax+34h], offset ?HelloDDKUnload@@YGXPAU_DRIVER_OBJECT@@@Z ; HelloDDKUnload(_DRIVER_OBJECT *)// pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutin;mov     ecx, [ebp+pDriverObject]mov     dword ptr [ecx+38h], offset ?HelloDDKDispatchRoutin@@YGJPAU_DEVICE_OBJECT@@PAU_IRP@@@Z ; HelloDDKDispatchRoutin(_DEVICE_OBJECT *,_IRP *)// pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutin;mov     edx, [ebp+pDriverObject]mov     dword ptr [edx+40h], offset ?HelloDDKDispatchRoutin@@YGJPAU_DEVICE_OBJECT@@PAU_IRP@@@Z ; HelloDDKDispatchRoutin(_DEVICE_OBJECT *,_IRP *)// pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutin;mov     eax, [ebp+pDriverObject]mov     dword ptr [eax+48h], offset ?HelloDDKDispatchRoutin@@YGJPAU_DEVICE_OBJECT@@PAU_IRP@@@Z ; HelloDDKDispatchRoutin(_DEVICE_OBJECT *,_IRP *)// pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKRead;mov     ecx, [ebp+pDriverObject]mov     dword ptr [ecx+44h], offset ?HelloDDKRead@@YGJPAU_DEVICE_OBJECT@@PAU_IRP@@@Z ; HelloDDKRead(_DEVICE_OBJECT *,_IRP *)// pDriverObject->MajorFunction[IRP_MJ_CLEANUP] = HelloDDKDispatchRoutin;mov     edx, [ebp+pDriverObject]mov     dword ptr [edx+80h], offset ?HelloDDKDispatchRoutin@@YGJPAU_DEVICE_OBJECT@@PAU_IRP@@@Z ; HelloDDKDispatchRoutin(_DEVICE_OBJECT *,_IRP *)// pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HelloDDKDispatchRoutin;mov     eax, [ebp+pDriverObject]mov     dword ptr [eax+70h], offset ?HelloDDKDispatchRoutin@@YGJPAU_DEVICE_OBJECT@@PAU_IRP@@@Z ; HelloDDKDispatchRoutin(_DEVICE_OBJECT *,_IRP *)// pDriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = HelloDDKDispatchRoutin;mov     ecx, [ebp+pDriverObject]mov     dword ptr [ecx+50h], offset ?HelloDDKDispatchRoutin@@YGJPAU_DEVICE_OBJECT@@PAU_IRP@@@Z ; HelloDDKDispatchRoutin(_DEVICE_OBJECT *,_IRP *)// pDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = HelloDDKDispatchRoutin;mov     edx, [ebp+pDriverObject]mov     dword ptr [edx+78h], offset ?HelloDDKDispatchRoutin@@YGJPAU_DEVICE_OBJECT@@PAU_IRP@@@Z ; HelloDDKDispatchRoutin(_DEVICE_OBJECT *,_IRP *)// pDriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HelloDDKDispatchRoutin;mov     eax, [ebp+pDriverObject]mov     dword ptr [eax+94h], offset ?HelloDDKDispatchRoutin@@YGJPAU_DEVICE_OBJECT@@PAU_IRP@@@Z ; HelloDDKDispatchRoutin(_DEVICE_OBJECT *,_IRP *)//  status = CreateDevice(pDriverObject);mov     ecx, [ebp+pDriverObject]push    ecx             ; pDriverObjectcall    ?CreateDevice@@YGJPAU_DRIVER_OBJECT@@@Z ; CreateDevice(_DRIVER_OBJECT *)mov     [ebp+status], eax//  KdPrint((“Leave DriverEntry\n”));push    offset aLeaveDriverent ; "Leave DriverEntry\n"call    _DbgPrint// return status;add     esp, 4mov     eax, [ebp+status]mov     esp, ebp          // 恢复现场pop     ebp               // 恢复现场retn    8_DriverEntry@8 endp源码参考:NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath){NTSTATUS status;KdPrint(("Enter DriverEntry\n"));//设置卸载函数pDriverObject->DriverUnload = HelloDDKUnload;//设置派遣函数pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKRead;pDriverObject->MajorFunction[IRP_MJ_CLEANUP] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HelloDDKDispatchRoutin;//创建驱动设备对象status = CreateDevice(pDriverObject);KdPrint(("Leave DriverEntry\n"));return status;}

CreateDevice

int __stdcall CreateDevice(_DRIVER_OBJECT *pDriverObject)?CreateDevice@@YGJPAU_DRIVER_OBJECT@@@Z proc nearDeviceName= _UNICODE_STRING ptr -24hpDevExt= dword ptr -1ChdevName= _UNICODE_STRING ptr -18hstatus= dword ptr -10hpDevObj= dword ptr -0ChsymLinkName= _UNICODE_STRING ptr -8pDriverObject= dword ptr  8push    ebpmov     ebp, esp              // 保护现场// RtlInitUnicodeString(&devName, "\\Device\\MyDDKDevice");sub     esp, 24h              // 申请空间push    offset SourceString   // "\\Device\\MyDDKDevice"lea     eax, [ebp+devName]push    eax             ; DestinationStringcall    ds:__imp__RtlInitUnicodeString@8 ; RtlInitUnicodeString(x,x)// DeviceName.Length = devName.Lengthmov     ecx, dword ptr [ebp+devName.Length]mov     dword ptr [ebp+DeviceName.Length], ecx// DeviceName.Buffer = devName.Buffermov     edx, [ebp+devName.Buffer]mov     [ebp+DeviceName.Buffer], edx// IoCreateDevice(pDriverObject, sizeof(DEVICE_EXTENSION), &(UNICODE_STRING)DeviceName, FILE_DEVICE_UNKNOWN, 0, TRUE, &pDevObj);lea     eax, [ebp+pDevObj]push    eax             ; DeviceObjectpush    1               ; Exclusivepush    0               ; DeviceCharacteristicspush    22h             ; DeviceTypelea     ecx, [ebp+DeviceName]push    ecx             ; DeviceNamepush    28h             ; DeviceExtensionSizemov     edx, [ebp+pDriverObject]push    edx             ; DriverObjectcall    ds:__imp__IoCreateDevice@28 ; IoCreateDevice(x,x,x,x,x,x,x)// if (!NT_SUCCESS(status)) mov     [ebp+status], eaxcmp     [ebp+status], 0jge     short loc_150E9// FALSEmov     eax, [ebp+pDevObj]    // pDevObjmov     ecx, [eax+1Ch]        // pDevObj->Flagsor      ecx, 4                // Flags |= DO_BUFFERED_IO;mov     edx, [ebp+pDevObj]    // pDevObjmov     [edx+1Ch], ecx        // pDevObj->Flags |= DO_BUFFERED_IO;mov     eax, [ebp+pDevObj]    // pDevObjmov     ecx, [eax+28h]        // pDevObj->DeviceExtensionmov     [ebp+pDevExt], ecx    // pDevExt = pDevObj->DeviceExtension  [格式需要转换]mov     edx, [ebp+pDevExt]mov     eax, [ebp+pDevObj]mov     [edx], eax            // pDevExt->pDevice = pDevObj; [设备拓展的第一个参数,遂无偏移]mov     ecx, [ebp+pDevExt]mov     edx, dword ptr [ebp+devName.Length]mov     [ecx+4], edx          // 设备拓展第二个参数mov     eax, [ebp+devName.Buffer]mov     [ecx+8], eax          // pDevExt->ustrDeviceName = devName;push    14h             ; size_tpush    0               ; intmov     ecx, [ebp+pDevExt]add     ecx, 14h              // 设备拓展第四个参数push    ecx             ; void *call    _memset               // _memset(&pDevExt->device_queue, 0, sizeof(pDevExt->device_queue));add     esp, 0Ch              // 申请空间mov     edx, [ebp+pDevExt]add     edx, 14h              // 设备拓展第四个参数push    edx             ; DeviceQueuecall    ds:__imp__KeInitializeDeviceQueue@4 ; KeInitializeDeviceQueue(x)    // KeInitializeDeviceQueue(&pDevExt->device_queue);push    offset a??Helloddk ; "\\??\\HelloDDK"lea     eax, [ebp+symLinkName]push    eax             ; DestinationStringcall    ds:__imp__RtlInitUnicodeString@8 ; RtlInitUnicodeString(x,x)    // RtlInitUnicodeString(&symLinkName, "\\??\\HelloDDK");mov     ecx, [ebp+pDevExt]mov     edx, dword ptr [ebp+symLinkName.Length]mov     [ecx+0Ch], edxmov     eax, [ebp+symLinkName.Buffer]mov     [ecx+10h], eaxlea     ecx, [ebp+devName]push    ecx             ; DeviceNamelea     edx, [ebp+symLinkName]push    edx             ; SymbolicLinkNamecall    ds:__imp__IoCreateSymbolicLink@8 ; IoCreateSymbolicLink(x,x)    // IoCreateSymbolicLink(&SymbolicLinkName, DevName);// if(!NT_SUCCESS(status))mov     [ebp+status], eaxcmp     [ebp+status], 0jge     short loc_1517C// TRUEmov     eax, [ebp+pDevObj]push    eax             ; DeviceObjectcall    ds:__imp__IoDeleteDevice@4 ; IoDeleteDevice(x)   // IoDeleteDevice(pDevObj);mov     eax, [ebp+status]jmp     short loc_1517E源码参考:NTSTATUS CreateDevice (IN PDRIVER_OBJECTpDriverObject) {NTSTATUS status;PDEVICE_OBJECT pDevObj;PDEVICE_EXTENSION pDevExt;//创建设备名称UNICODE_STRING devName;RtlInitUnicodeString(&devName,L"\\Device\\MyDDKDevice");//创建设备status = IoCreateDevice( pDriverObject,sizeof(DEVICE_EXTENSION),&(UNICODE_STRING)devName,FILE_DEVICE_UNKNOWN,0, TRUE,&pDevObj );if (!NT_SUCCESS(status))return status;pDevObj->Flags |= DO_BUFFERED_IO;pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;pDevExt->pDevice = pDevObj;pDevExt->ustrDeviceName = devName;RtlZeroBytes(&pDevExt->device_queue,sizeof(pDevExt->device_queue));KeInitializeDeviceQueue(&pDevExt->device_queue);//创建符号链接UNICODE_STRING symLinkName;RtlInitUnicodeString(&symLinkName,L"\\??\\HelloDDK");pDevExt->ustrSymLinkName = symLinkName;status = IoCreateSymbolicLink( &symLinkName,&devName );if (!NT_SUCCESS(status)) {IoDeleteDevice( pDevObj );return status;}return STATUS_SUCCESS;}

IRP_MJ_READ

// 第一段:整个函数所有变量的定义。  pDevExt= dword ptr -8           //  堆栈:PDEVICE_EXTENSION   pDevExt    [dword ptr -8]  oldirql= byte ptr -4            //  堆栈:KIRQL   oldirql    [byte ptr -4]  pDevObj= dword ptr  8           //  参数:PDEVICE_OBJECT   pDevObj  pIrp= dword ptr  0Ch            //  参数:PIRP   pIrp    // 第二段:KdPrint(("Enter HelloDDKRead\n"));  push    ebp  mov     ebp, esp               // 保护现场  sub     esp, 8                 // 开拓8个字节的空间  push    offset aEnterHelloddkr // "Enter HelloDDKRead\n"  call    _DbgPrint    // 第三段:PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;  add     esp, 4                    // 开拓4字节空间  mov     eax, [ebp+pDevObj]        // 定位到 pDevObj  mov     ecx, [eax+28h]            // 定位到 pDevObj+28h,即为 pDevObj->DeviceExtension  mov     [ebp+pDevExt], ecx        // 需要加上参数的转换,语句:pDevExt = pDevObj->DeviceExtension;     // 第四段:IoMarkIrpPending(pIrp);   //     #define IoMarkIrpPending( Irp ) ( IoGetCurrentIrpStackLocation( (Irp) )->Control |= SL_PENDING_RETURNED )   //     #define IoGetCurrentIrpStackLocation( Irp ) ( (Irp)->Tail.Overlay.CurrentStackLocation )   mov     edx, [ebp+pIrp]           // 定位到 pIrp  mov     eax, [edx+60h]            // 定位到 pIrp+60h,即为 Irp->Tail.Overlay.CurrentStackLocation  mov     cl, [eax+3]               // 定位到 ->Control  or      cl, 1                     // 或运算,SL_PENDING_RETURNED  0x01  mov     edx, [ebp+pIrp]  mov     eax, [edx+60h]  mov     [eax+3], cl               // 或运算结果赋值给 Irp->Tail.Overlay.CurrentStackLocation    // 第五段:IoSetCancelRoutine(pIrp,OnCancelIRP)   //     #define IoSetCancelRoutine( Irp, NewCancelRoutine ) (  \  //     (PDRIVER_CANCEL) InterlockedExchangePointer( (PVOID *) &(Irp)->CancelRoutine, (PVOID) (NewCancelRoutine) ) )  mov     edx, offset ?OnCancelIRP@@YGXPAU_DEVICE_OBJECT@@PAU_IRP@@@Z     // OnCancelIRP(_DEVICE_OBJECT *,_IRP *)  mov     ecx, [ebp+pIrp]  add     ecx, 38h            // Irp -> CancelRoutine  call    ds:__imp_@InterlockedExchange@8    // InterlockedExchange(x,x)        // 第六段:KeRaiseIrql(DISPATCH_LEVEL, &oldirql)   // #define DISPATCH_LEVEL           2      // Dispatcher level  // #define KeRaiseIrql(a,b)    *(b) = KfRaiseIrql(a)   mov     cl, 2  call    ds:__imp_@KfRaiseIrql@4  // KfRaiseIrql(x)  mov     [ebp+oldirql], al        // 将函数调用结果存入oldirql    // 第七段:KdPrint(("HelloDDKRead irp :%x\n", pIrp));  mov     ecx, [ebp+pIrp]  push    ecx  push    offset aHelloddkreadIr ; "HelloDDKRead irp :%x\n"  call    _DbgPrint    // 第八段:KdPrint(("DeviceQueueEntry:%x\n", pIrp->Tail.Overlay.DeviceQueueEntry));  add     esp, 8  mov     edx, [ebp+pIrp]  add     edx, 40h          // pIrp->40h,即 pIrp->Tail.Overlay.DeviceQueueEntry  push    edx  push    offset aDevicequeueent ; "DeviceQueueEntry:%x\n"  call    _DbgPrint    // 第九段:if (!KeInsertDeviceQueue(&pDevExt->device_queue, &pIrp->Tail.Overlay.DeviceQueueEntry));  add     esp, 8  mov     eax, [ebp+pIrp]  add     eax, 40h           // pIrp->40h,即 pIrp->Tail.Overlay.DeviceQueueEntry  push    eax                // DeviceQueueEntry  mov     ecx, [ebp+pDevExt] // 定位到 pDevExt  add     ecx, 14h           // pDevExt->14h,即是 &pDevExt->device_queue  push    ecx                // DeviceQueue  call    ds:__imp__KeInsertDeviceQueue@8  // KeInsertDeviceQueue(x,x)  and     eax, 0FFh          // 取反  test    eax, eax           // 判断  jnz     short loc_141ED    // 跳转    // 第十段:[判断为真] MyStartIo(pDevObj,pIrp);  mov     edx, [ebp+pIrp]   push    edx              // 参数:pFistIrp  mov     eax, [ebp+pDevObj]   push    eax              // 参数:DeviceObject  call    ?MyStartIo@@YGXPAU_DEVICE_OBJECT@@PAU_IRP@@@Z  // MyStartIo(_DEVICE_OBJECT *,_IRP *)    // 第十一段:[判断为假] KeLowerIrql(oldirql);  mov     cl, [ebp+oldirql]        // 定位参数 oldirql  call    ds:__imp_@KfLowerIrql@4  // KfLowerIrql(x)    // 第十二段:KdPrint(("Leave HelloDDKRead\n"));  push    offset aLeaveHelloddkr  // "Leave HelloDDKRead\n"  call    _DbgPrint    // 返回STATUS_PENDING状态:return STATUS_PENDING;  add     esp, 4  mov     eax, 103h    // #define STATUS_PENDING    ((NTSTATUS)0x00000103L)     // winnt  mov     esp, ebp     // 恢复现场  pop     ebp          // 恢复现场  retn    8  ?HelloDDKRead@@YGJPAU_DEVICE_OBJECT@@PAU_IRP@@@Z endp  源码对照:  NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp)  {      KdPrint(("Enter HelloDDKRead\n"));      PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;            //将IRP设置为挂起      IoMarkIrpPending(pIrp);      IoSetCancelRoutine(pIrp,OnCancelIRP);            KIRQL oldirql;      //提升IRP至DISPATCH_LEVEL      KeRaiseIrql(DISPATCH_LEVEL, &oldirql);      KdPrint(("HelloDDKRead irp :%x\n",pIrp));      KdPrint(("DeviceQueueEntry:%x\n",&pIrp->Tail.Overlay.DeviceQueueEntry));      if (!KeInsertDeviceQueue(&pDevExt->device_queue, &pIrp->Tail.Overlay.DeviceQueueEntry))          MyStartIo(pDevObj,pIrp);            //将IRP降至原来IRQL      KeLowerIrql(oldirql);      KdPrint(("Leave HelloDDKRead\n"));      //返回pending状态      return STATUS_PENDING;  }  











原创粉丝点击