学习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对象同步对公共数据的访问。
争取每天逆向几个函数 慢慢把他搞完
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对象同步对公共数据的访问。
相关文章推荐
- mini2440学习之——移植LCD驱动移植代码中相关的修改部分!
- 驱动程序的内存分配(关于锁定驱动代码和数据常驻内存 学习学习红色标记部分)
- 恶意代码--样本分析学习资料整理网络地址
- IOS开发-OC学习-常用功能代码片段整理
- JavaScript学习代码整理(一)
- 【加入自己的部分内容】Linux设备驱动模型学习之基础篇--Kobject.txt翻译
- “机器狗”病毒驱动部分逆向分析注释(C代码)
- 机器学习代码整理pLSA、BoW、DBN、DNN
- Deep Learning(深度学习)代码/课程/学习资料整理
- 各种数据库连接驱动部分代码(固定)
- [文件系统]文件系统学习笔记(十一)——部分代码详解
- 第五部分 linux 按键驱动代码分析
- 小代码 向原文学习 对AVL树的4种情况 用字母标记整理
- 【旧代码整理】代码说明 /project/run.php 部分
- S3C2440裸机学习[2] - LCD驱动原理及代码分析[一]
- busybox init学习及部分代码分析
- c基础部分代码整理
- JAVA学习(十二)__关于JAVA代码里黄色警告线的注意方法(自己整理)
- 【C++再学习】【02】C部分一些整理
- 《第一行代码Java》Java类集框架部分学习笔记与代码