初学驱动逆向,笔记二。

来源:互联网 发布:淘宝灯具3c认证哪里来 编辑:程序博客网 时间:2024/06/05 17:36

例子: [ \chapter09\StartIOTest ]

本例子的核心代码是HelloDDKStartIO处理过程。

初学驱动逆向,逆向函数还原代码,无壳无花,流程也很简单。

IDA反汇编代码:

void __stdcall HelloDDKStartIO(_DEVICE_OBJECT *DeviceObject, _IRP *Irp)event= _KEVENT ptr -1Chtimeout= _LARGE_INTEGER ptr -0Choldirql= byte ptr -4DeviceObject= dword ptr  8Irp= dword ptr  0Chpush    ebpmov     ebp, espsub     esp, 1Chpush    offset Format     // "Enter HelloDDKStartIO\n"call    _DbgPrint         // KdPrint(("Enter HelloDDKStartIO\n"));add     esp, 4               // 申请空间lea     eax, [ebp+oldirql]   // 取地址push    eax                  // Irqlcall    ds:__imp__IoAcquireCancelSpinLock@4    // IoAcquireCancelSpinLock(oldirql);mov     ecx, [ebp+DeviceObject]mov     edx, [ebp+Irp]cmp     edx, [ecx+14h]        // if(!DeviceObject->CurrentIrp == Irp)jnz     short loc_11034       // 成立跳转loc_110341.loc_11034  // 释放自旋锁mov     dl, [ebp+oldirql]push    edx              // Irqlcall    ds:__imp__IoReleaseCancelSpinLock@4  // IoReleaseCancelSpinLock(oldirql);push    offset aLeaveHelloddks     // "Leave HelloDDKStartIO\n"call    _DbgPrint                  // KdPrint(("Leave HelloDDKStartIO\n"));add     esp, 4jmp     loc_110D02.mov     eax, [ebp+Irp]xor     ecx, ecxmov     cl, [eax+24h]     // Irp->Canceltest    ecx, ecx          // 检测寄存器是否为空   if(Irp->Cancel)jz      short loc_1105    // 跳转3.loc_11050:xor     edx, edxmov     ecx, [ebp+Irp]add     ecx, 38h            // Irp->CancelRoutinecall    ds:__imp_@InterlockedExchange@8    // InterlockedExchange( Irp->CancelRoutine ) mov     al, [ebp+oldirql]push    eax                // Irqlcall    ds:__imp__IoReleaseCancelSpinLock@4   // IoReleaseCancelSpinLock( oldirql )push    0                  // Statepush    0                  // Typelea     ecx, [ebp+event]push    ecx                // Eventcall    ds:__imp__KeInitializeEvent@12   // KeInitializeEvent( &event, 0, 0 )mov     dword ptr [ebp+timeout], 0FE363C80h     // 赋值处理mov     dword ptr [ebp+timeout+4], 0FFFFFFFFh   // 赋值处理lea     edx, [ebp+timeout]push    edx               // Timeoutpush    0                 // Alertablepush    0                 // WaitModepush    0                 // WaitReasonlea     eax, [ebp+event]push    eax               // Objectcall    ds:__imp__KeWaitForSingleObject@20   // KeWaitForSingleObject( &event, 0, 0, 0, &timeout )mov     ecx, [ebp+Irp]mov     dword ptr [ecx+18h], 0     // Irp.IoStatus = 0;mov     edx, [ebp+Irp]mov     dword ptr [edx+1Ch], 0     // 18+1c   Irp.Information = 0;xor     dl, dlmov     ecx, [ebp+Irp]call    ds:__imp_@IofCompleteRequest@8   // IofCompleteRequest(x,x)push    1                 // Cancelablemov     eax, [ebp+DeviceObject]push    eax               // DeviceObjectcall    ds:__imp__IoStartNextPacket@8   // IoStartNextPacket( DeviceObject, 1 )push    offset aLeaveHellodd_0   // "Leave HelloDDKStartIO\n"call    _DbgPrint                // KdPrint(("Leave HelloDDKStartIO\n"));add     esp, 4
逆向代码:  [出错地方:1.变量    2.取地址    3.精简代码    4.Irp->Status结构    5.FALSE<->0 ]

void __stdcall HelloDDKStartIO(_DEVICE_OBJECT *DeviceObject, _IRP *Irp){PIRP oldirql;             // KIRQL oldirql;int timeout;              // LARGE_INTEGER timeout;KEVENT event;KdPrint(("Enter HelloDDKStartIO\n"));IoAcquireCancelSpinLock(oldirql);    // 取地址,(&oldirql)。if(Irp!=DeviceObject->CurrentIrp)     // 精简:if (Irp!=DeviceObject->CurrentIrp||Irp->Cancel){IoReleaseCancelSpinLock(oldirql);KdPrint(("Leave HelloDDKStartIO\n"));if(Irp->Cancel){IoReleaseCancelSpinLock(oldirql);KdPrint(("Leave HelloDDKStartIO\n"));}}InterlockedExchange(Irp->CancelRoutine);   // IoSetCancelRoutine(Irp,NULL);IoReleaseCancelSpinLock(oldirql);KeInitializeEvent(&event, 0, 0);     // KeInitializeEvent(&event,NotificationEvent,FALSE);//赋值LARGE_INTEGER timeout;//赋值timeout.QuadPart = -3*1000*1000*10;KeWaitForSingleObject(&event, 0, 0, 0, &timeout);  // KeWaitForSingleObject(&event,Executive,KernelMode,FALSE,&timeout);Irp->IoStatus.Status = 0;        // #define  STATUS_SUCCESS   0Irp->IoStatus.Information = 0;IofCompleteRequest(Irp);         // IoCompleteRequest(Irp,IO_NO_INCREMENT);IoStartNextPacket( DeviceObject, 1);KdPrint(("Leave HelloDDKStartIO\n"));}
原版代码:
  HelloDDKStartIO(    IN PDEVICE_OBJECT  DeviceObject,    IN PIRP  Irp     ){KIRQL oldirql;KdPrint(("Enter HelloDDKStartIO\n"));//获取cancel自旋锁IoAcquireCancelSpinLock(&oldirql);if (Irp!=DeviceObject->CurrentIrp||Irp->Cancel){//如果当前有正在处理的IRP,则简单的入队列,并直接返回//入队列的工作由系统完成,在StartIO中不用负责IoReleaseCancelSpinLock(oldirql);KdPrint(("Leave HelloDDKStartIO\n"));return;}else{//由于正在处理该IRP,所以不允许调用取消例程//因此将此IRP的取消例程设置为NULLIoSetCancelRoutine(Irp,NULL);IoReleaseCancelSpinLock(oldirql);}KEVENT event;KeInitializeEvent(&event,NotificationEvent,FALSE);//等3秒LARGE_INTEGER timeout;timeout.QuadPart = -3*1000*1000*10;//定义一个3秒的延时,主要是为了模拟该IRP操作需要大概3秒左右时间KeWaitForSingleObject(&event,Executive,KernelMode,FALSE,&timeout);Irp->IoStatus.Status = STATUS_SUCCESS;Irp->IoStatus.Information = 0;// no bytes xferedIoCompleteRequest(Irp,IO_NO_INCREMENT);//在队列中读取一个IRP,并进行StartIoIoStartNextPacket(DeviceObject,TRUE);KdPrint(("Leave HelloDDKStartIO\n"));}


原创粉丝点击