学习1下mj的驱动 整理1下部分代码

本文介绍360AntiARP驱动的实现细节,包括设备创建、符号链接配置及加载映像通知例程设置。此外,还展示了如何通过修改CR0寄存器禁用写保护,以及使用自旋锁进行代码修改。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 学习1下mj的驱动 整理1下部分代码
争取每天逆向几个函数 慢慢把他搞完
ARP的发包是处于相当底层的地方了 还要花点时间学习1下
#define DEVICE_NAME L"//Device//360AntiARP" //Driver Name
#define LINK_NAME L"//DosDevices//360AntiARP"  //Link Name

#define DEVICE_NAME1002 L"//Device//360AntiARP1002" //Driver Name
#define LINK_NAME1002 L"//DosDevices//360AntiARP1002"  //Link Name
驱动创建DriverEntry
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
{
    NTSTATUS status = STATUS_SUCCESS;
    UNICODE_STRING ustrLinkName;
    UNICODE_STRING ustrDevName;   
    PDEVICE_OBJECT pDevObj;
   
if (*InitSafeBootMode > 0)
{
    //系统处于 Safe Mode.
return  STATUS_UNSUCCESSFUL;
}

    // Create dispatch points for device control, create, close.
    pDriverObj->MajorFunction[IRP_MJ_CREATE] = AntiARPDispatchRoutine;
    pDriverObj->MajorFunction[IRP_MJ_CLOSE] = AntiARPDispatchRoutine;
    pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = AntiARPDispatchRoutine;
    pDriverObj->DriverUnload = DriverUnload;
    //
    dprintf("[360AntiARP] DriverEntry: %S/n",pRegistryString->Buffer);

    // Create dispatch points for device control, create, close.
    pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
    pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
    pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;
    pDriverObj->DriverUnload = DriverUnload;
    //

    RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
   
    status = IoCreateDevice(pDriverObj,
                0,
                &ustrDevName,
                FILE_DEVICE_UNKNOWN,
                0,
                FALSE,
                &pDevObj);

    dprintf("[360AntiARP] Device Name %S",ustrDevName.Buffer);

    if(!NT_SUCCESS(status))
    {
        dprintf("[360AntiARP] IoCreateDevice = 0x%x/n", status);
        return status;
    }

   
    RtlInitUnicodeString(&ustrLinkName, LINK_NAME);

    status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName); 
    if(!NT_SUCCESS(status))
    {
        dprintf("[360AntiARP] IoCreateSymbolicLink = 0x%x/n", status);
        IoDeleteDevice(pDevObj); 
        return status;
    }
   
    dprintf("[360AntiARP] SymbolicLink:%S",ustrLinkName.Buffer);

    RtlInitUnicodeString(&ustrDevName, DEVICE_NAME1002);
   
    status = IoCreateDevice(pDriverObj,
                0,
                &ustrDevName,
                FILE_DEVICE_UNKNOWN,
                0,
                FALSE,
                &pDevObj);

    dprintf("[360AntiARP] Device Name %S",ustrDevName.Buffer);

    if(!NT_SUCCESS(status))
    {
        dprintf("[360AntiARP] IoCreateDevice = 0x%x/n", status);
        return status;
    }

   
    RtlInitUnicodeString(&ustrLinkName, LINK_NAME1002);

    status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName); 
    if(!NT_SUCCESS(status))
    {
        dprintf("[360AntiARP] IoCreateSymbolicLink = 0x%x/n", status);
        IoDeleteDevice(pDevObj); 
        return status;
    }
   
    dprintf("[360AntiARP] SymbolicLink:%S",ustrLinkName.Buffer);

AllocatePool();
PsSetLoadImageNotifyRoutine(NotifyRoutine);
QuerySystemModuleSize();








    return STATUS_SUCCESS;
}

DriverUnload函数
VOID DriverUnload(PDRIVER_OBJECT pDriverObj)
{   
    UNICODE_STRING strLink;
    RtlInitUnicodeString(&strLink, LINK_NAME);
    //
    // Delete the symbolic link
    //
    IoDeleteSymbolicLink(&strLink);
    //
    // Delete the device object
    //
    IoDeleteDevice(pDriverObj->DeviceObject);
    dprintf("[360AntiARP] Unloaded/n");

    //    UNICODE_STRING strLink;
    RtlInitUnicodeString(&strLink, LINK_NAME1002);
    //
    // Delete the symbolic link
    //
    IoDeleteSymbolicLink(&strLink);
    //
    // Delete the device object
    //
    IoDeleteDevice(pDriverObj->DeviceObject);
    dprintf("[360AntiARP] Unloaded/n");
}

NTSTATUS
AntiARPDispatchRoutine(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    NTSTATUS            ntStatus = STATUS_SUCCESS;
    PIO_STACK_LOCATION  irpSp;
    ULONG              CtlCode;
    PVOID              InputBuffer;
    PVOID              OutputBuffer;
    PIO_STATUS_BLOCK    ioStatus;

    ioStatus = &Irp->IoStatus;
    ioStatus->Status = ntStatus;
    ioStatus->Information = 0;

    irpSp = IoGetCurrentIrpStackLocation( Irp );
    CtlCode = irpSp->Parameters.DeviceIoControl.IoControlCode;
    if (irpSp->MajorFunction != IRP_MJ_DEVICE_CONTROL)
    {
        goto End;
    }

    InputBuffer = Irp->AssociatedIrp.SystemBuffer;
    if ((CtlCode & METHOD_NEITHER) == METHOD_NEITHER)
    {
        OutputBuffer = Irp->UserBuffer;
    }
    else
    {
        OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
    }

    AntiARPIoControl(irpSp->FileObject,
        1,
        InputBuffer,
        irpSp->Parameters.DeviceIoControl.InputBufferLength,
        OutputBuffer,
        irpSp->Parameters.DeviceIoControl.OutputBufferLength,
        CtlCode,
        ioStatus,
        DeviceObject);

End:
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return ntStatus;
}
VOID
DisableWriteProtect(
    VOID
    )
{
    __asm
    {
        push    eax
        mov    eax, cr0
        mov    OldCr0, eax
        and    eax, 0FFFEFFFFh
        mov    cr0, eax
        pop    eax
        cli
    }
}

__inline
VOID
EnableWriteProtect(
    VOID
    ) 
{
    __asm
    {
        sti
        push    eax
        mov    eax, OldCr0
        mov    cr0, eax
        pop    eax
    }
}

驱动安装的时候会建立2个设备 并且设置PsSetLoadImageNotifyRoutine监视
接下来hoo了 IoCreateDevice 首先使用1个RtlImageDirectoryEntryToData函数 当然在此之前先用MmGetSystemRoutineAddress获得了函数所在地址 这个函数作用

                            ; RtlImageDirectoryEntryToData
                            ; come form: http://bbs.pediy.com/showthread.php?p=254245
                            ; 反汇编的结果如下:
                            ; DWORD RtlImageDirectoryEntryToData(DWORD imagebase,BOOL bVA,DWORD dwDataDirectoryIndex, DWORD *size);
                            ;
                            ; 其中,imagebase 为模块基址, bVA为真表示函数返回一个VA, 否则函数返回一个PointerToRawData(减去基址就是在文件中的位置),
                            ; dwDataDirectoryIndex为索引值, 从0到f,如0表示导出表。
                            ; size为接受这项数据目录大小的指针。
                            ;
                            ; 如果该索引不存在, 那么函数返回0, 并且不改变size指针的值。

简单的说 就是获取IoCreateDevice 的所在地址不过mj是在模块中搜索的方式获取的
接下来 经过一些VA转换计算 获得真实地址
KeInitializeSpinLock + KfAcquireSpinLock+DisableWriteProtect
修改完毕以后EnableWriteProtect+KfReleaseSpinLock

相关说明 
-------------------------------------------- 
1.3.8同步

  如果驱动程序有可能在某时刻有多个部分在同时运行,比如有中断处理过程,或存在多个设备等,对公共数据或代码的访问就需要同步。方法有:

i)自旋锁(SpinLock)

  驱动程序可以在初始化时调用KeInitializeSpinLock创建该对象。在任何代码段访问被保护的数据之前,先调用 KeAcquireSpinLock试图获得该对象的所有权,如果成功,该段代码被系统提升至 DISPATCH_LEVEL,进行数据访问。访问完毕后须调用KeRelease SpinLock释放所有权,运行级别也被恢复。此方法只适用于同步运行级别小于等于DISP ATCH_LEVEL的代码,主要用于多CPU的情形。此外,还有一种中断自旋锁用于与中断处理过程同步,可以将较低级别的代码提升到需要与之同步的中断 DIRQL。

ii)控制器(Controller)

  该对象主要用于同步一个驱动程序中的多个设备,保证它们能顺序地访问特定的代码或数据。该对象在驱动程序初始化调用 IoCreateController被创建。设备在StartIo过程中调用IoAllocateController请求获得Controller对象的独占权。使用完后调用IoFreeController释放。驱动程序停止时调用IoDeleteController从内存删除该对象。该对象有一个指针ControllerExtension指向一块由驱动程序定义的结构,其中保存有此驱程序的公共数据。

iii)适配器(Adapter)

  该对象用于同步多个设备(不一定在一个驱动程序中)对DMA通道的使用。该对象在系统启动侦测硬件时自动被创建。驱动程序在初始化时调用 HalGetAdapter获得该对象的指针。设备在StartIo过程中调用IoAllocateAdapterChannel请求获得DMA通道的独占权,然后开始传输数据。使用完后调用IoFreeControllerChannel释放DMA通道。

iv)DPC

  由于DPC队列中的对象总是被系统顺序地处理,所以也可以将需要同步的代码做成Dpc过程,需要调用时将相应的DPC对象放到队列的末尾即可。

v)其他

  同用户模式的应用程序类似,驱动程序也可以使用多线程,也提供了一套用来同步的对象,如Event,Mutex,Semaphore,Timer,Thread。其中Event对象可以被命名,不同的驱动程序可以利用同名的Event对象同步对公共数据的访问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值