您的位置:首页 > 编程语言

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

2008-10-16 17:15 323 查看
学习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对象同步对公共数据的访问。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: