初学驱动逆向,笔记一。
来源:互联网 发布:淘宝联盟好吗 编辑:程序博客网 时间: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; }
- 初学驱动逆向,笔记一。
- 初学驱动逆向,笔记二。
- 驱动逆向学习笔记
- orge 初学笔记一
- 初学maven 笔记一
- Git初学笔记(一)
- UE4初学笔记一
- compass 初学笔记一
- 初学C#-----笔记一
- 逆向学习笔记(一)
- Android逆向学习日记(一) 初学smail
- 【android逆向笔记】(一)简单登录逆向
- linux 设备驱动初学(一)
- linux 设备驱动初学(一)
- Linux 驱动编程初学(一)
- 初学Python笔记(一)
- 初学MySQL笔记(一)
- 初学ibatis 学习笔记一
- css超链接
- C++模板
- 解说Win32的窗口子类化
- Android4.0 CalendarProvider一些文档及资料
- Linux 网络编程基础(一) ---------------客户端/服务器的简单实现
- 初学驱动逆向,笔记一。
- .net,c#环境下,Datalist和Repeater的基础用法实例
- 360测试机器的硬件性能得分
- strcpy
- 解决<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" 过长
- Linux挂载FTP服务器目录为本地文件系统
- boost::bind boost::function绑定万能函数测试2(类成员函数和虚函数)
- 12864学习(控制器ST7920)
- 在linux-2.6.29.1内核中修改添加DM9000的驱动