阅读:2348回复:0
Devicelock 安装分析手记 by guaiguaiguan
级别: 驱动小牛
精华: 4 发帖: 243 威望: 250 点 积分: 2500 分 贡献值: 0 点 注册时间:2003-10-11 Devicelock 安装分析手记 今天老板让我安装devicelock,我研究了一番,写出心得与各位共享. 安装包是一个msi文件. 首先我使用Universal Extractor直接从msi文件中抽取了内部文件,发现仍然有一个DLService.exe和一个新的msi文件组成,但是新的msi文件小了很多,DLService.exe文件是一个服务程序要被释放到System32目录. 通过IDA Pro反汇编以及其import的函数表,发现这个函数是一个服务程序,同时它还动态地创建和启动驱动服务,启动完毕后删除注册表项和驱动文件,让你无从查找. 刚好我写了一个文件,注册表,进程监控程序,与其他监控程序有所不同的是当系统或者应用程序调用一些系统服务函数创建进程, 写注册表与自启动程序相关键值,调用ZwLoadDriver安装新的驱动服务或者往WIndows目录写入可执行模块文件时,能够弹出一个对话框又由用户决定是否放行,这样我可以控制它每执行一步,我确认一次. 这样它每向Windows目录复制一个文件,我就先把它复制出来,然后让它继续下一步. 按照这个步骤供获得了5个文件,包括DLService.exe在内,还有DeviceLockDriverHlp.sys DeviceLockDriver0.sys DLTray.EXE DLGPC.DLL. DLTray.EXE文件就不用说了,顾名思义就可以知道它主要完成往任务状态区添加图标,然后和驱动程序进行交互发送命令的. 通过Symbol Link viewer可以看到其创建的两个设备名称device\DeviceLockDriverHlp 和 device\DeviceLockDriver0. DeviceLockDriverHlp.sys 文件小到只有4K,使用IDAPro查看反汇编代码: 其driverentry函数代码如下: mov edi, edi .text:0001082B push ebp .text:0001082C mov ebp, esp .text:0001082E sub esp, 14h .text:00010831 push ebx .text:00010832 push esi .text:00010833 push edi .text:00010834 mov edi, ds:RtlInitUnicodeString .text:0001083A push offset SourceString ; "\\Device\\DeviceLockDriverHlp" .text:0001083F lea eax, [ebp+DeviceName] .text:00010842 xor ebx, ebx .text:00010844 push eax ; DestinationString .text:00010845 mov [ebp+DeviceObject], ebx .text:00010848 call edi ; RtlInitUnicodeString .text:0001084A mov esi, [ebp+DriverObject] .text:0001084D lea eax, [ebp+DeviceObject] .text:00010850 push eax ; DeviceObject .text:00010851 push ebx ; Exclusive .text:00010852 push ebx ; DeviceCharacteristics .text:00010853 push 8790h ; DeviceType .text:00010858 lea eax, [ebp+DeviceName] .text:0001085B push eax ; DeviceName .text:0001085C push ebx ; DeviceExtensionSize .text:0001085D push esi ; DriverObject .text:0001085E call ds:IoCreateDevice .text:00010864 cmp eax, ebx .text:00010866 mov [ebp+DriverObject], eax .text:00010869 jl short loc_108C1 .text:0001086B push offset aDosdevicesDevi ; "\\DosDevices\\DeviceLockDriverHlp" .text:00010870 lea eax, [ebp+SymbolicLinkName] .text:00010873 push eax ; DestinationString .text:00010874 call edi ; RtlInitUnicodeString .text:00010876 lea eax, [ebp+DeviceName] .text:00010879 push eax ; DeviceName .text:0001087A lea eax, [ebp+SymbolicLinkName] .text:0001087D push eax ; SymbolicLinkName .text:0001087E call ds:IoCreateSymbolicLink .text:00010884 cmp eax, ebx .text:00010886 mov [ebp+DriverObject], eax .text:00010889 jl short loc_108C1 .text:0001088B push offset SpinLock ; SpinLock .text:00010890 call ds:KeInitializeSpinLock .text:00010896 push offset NotifyRoutine ; NotifyRoutine .text:0001089B mov dword_10B14, ebx .text:000108A1 call PsSetCreateThreadNotifyRoutine .text:000108A6 mov eax, offset loc_10485 .text:000108AB mov [esi+38h], eax .text:000108AE mov [esi+40h], eax .text:000108B1 mov dword ptr [esi+70h], offset sub_104EC .text:000108B8 mov dword ptr [esi+74h], offset loc_106BC .text:000108BF jmp short loc_108CF .text:000108C1 ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ .text:000108C1 .text:000108C1 loc_108C1: ; CODE XREF: start+40 j .text:000108C1 ; start+60 j .text:000108C1 cmp [ebp+DeviceObject], ebx .text:000108C4 jz short loc_108CF .text:000108C6 push [ebp+DeviceObject] ; DeviceObject .text:000108C9 call ds:IoDeleteDevice .text:000108CF .text:000108CF loc_108CF: ; CODE XREF: start+96 j .text:000108CF ; start+9B j .text:000108CF mov eax, [ebp+DriverObject] .text:000108D2 pop edi .text:000108D3 pop esi .text:000108D4 pop ebx .text:000108D5 leave .text:000108D6 retn 8 通过代码可以看出这个驱动除了创建设备,注册设备调度函数指针外,还注册了进程创建通知回调函数. 其回调函数代码反映它只关心进程的创建,对于进程结束不感兴趣.通过spinlock来检查一个全局地址,接着用回调函数的参数信息调用这个地址函数指针. 顺藤摸瓜还能够找到其dispatch入口地址,如果希望了解它和应用程序之间的通信信息,只好拦截NTSTATUS NewZwDeviceIoControlFile( IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG IoControlCode, IN PVOID InputBuffer OPTIONAL, IN ULONG InputBufferLength, OUT PVOID OutputBuffer OPTIONAL, IN ULONG OutputBufferLength ) { NTSTATUS rc =0; PSHAREMEM pShareMem =(PSHAREMEM) g_SystemVirtualAddress; if(!pShareMem ||!pShareMem->bEnable ) { Hooks_GetStubAddForJmp(DeviceIoControlFile); __asm mov esp,ebp __asm pop ebp __asm jmp eax ASSERT(0); } if(FileHandle == g_hDeviceIOHandle) //调用NTCreateFile比较设备名称参数保存的全局句柄. { if(IoControlCode == 0xxxxxxx && InputBuffer!=NULL && InputBufferLength ==4 ) { if(*((PLONG)InputBuffer) ==1 ){ IoStatusBlock->Information = OutputBufferLength; IoStatusBlock->Status = STATUS_SUCCESS; return STATUS_SUCCESS; } } } Hooks_GetStubAddForJmp(DeviceIoControlFile); __asm mov esp,ebp __asm pop ebp __asm jmp eax ASSERT(0); return rc; /* if( NT_SUCCESS( rc ) ) { if(FileHandle == g_hDeviceIOHandle) { DbgPrint("ZwDeviceIoControlFile : IoControlCode:0x%08X InputBuffer:0x%08X InputBufferLength::0x%08X OutputBuffer::0x%08X OutputBufferLength : 0x%08X Status:: 0x%08X Information: 0x%08X rc:\n", IoControlCode, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, IoStatusBlock->Status, IoStatusBlock->Information, rc); if(InputBufferLength) { DbgPrint("ZwDeviceIoControlFile : InputBufferLength:0x%08X\n",InputBufferLength); PrintBlockEx(InputBuffer,InputBufferLength); } if(OutputBufferLength) { DbgPrint("ZwDeviceIoControlFile : OutputBufferLength:0x%08X\n",OutputBufferLength); PrintBlockEx(OutputBuffer,OutputBufferLength); } } } return rc;*/ } 拦截ZwDeviceIoControlFile函数在返回时不要调用return oldZwDeviceIoControlFile. 因为该函数不一定马上返回,有可能因为overlap被悬挂起来,这样驱动卸载时会死得很难看. 分析比较繁琐,我只是应付差事. wowocock Devicelock 号称可以控制很多设备,不过至少在CDROM控制方面基本就是垃圾,还得靠自己动手...... pilixuanke 我从softIce中看到DeviceLockDriver0.sys与DeviceLockDriverHlp.sys只实现了IRP_MJ_CREATE,IRP_MJ_CLOSE,IRP_MJ_DEVICE_CONTROL以及IRP_MJ_INTERNAL_DEVICE_CONTROL,那么说明控制外部设备部分应该是在其服务程序中进行的吧。 |
|
|