获取加载后就自动删除的驱动SYS文件

最近闲得没事做,想逆几个驱动玩玩,于是就把目标投向了Xuetr,利用Xuetr查询它的驱动文件位置

Xuetr

发现DriverPath里面显示的是驱动的位置,但是驱动文件死活找不到,原来是因为它在加载完驱动之后,马上自删除了该文件,估计是考虑到不想被别有用心的人拿来逆向吧

今天我们的任务就是要来获取这个SYS文件,然后利用IDA来XX,以学习Xuetr里面的一些先进技术

 

一开始想到的方法是既然文件在这个位置出现过,那么我写一个死循环的函数来不断的CopyFile,这样不就可以获取到它的SYS文件么,于是就有了下面的代码

#include <windows.h>
#include <stdio.h>

#define SRC_PATH "C:\\Users\\stefanie\\Desktop\\XueTr.sys"
#define DST_PATH "C:\\Xuetr.SYS"

int main()
{
    while (!CopyFileA(SRC_PATH,DST_PATH,FALSE));
    printf("Copy File success!\n");
    return 0;
}

这样只要这个Console程序退出就知道已经拷贝成功了,注意文件的保存位置是在C盘的根目录下,所以WIN7的话要以管理员运行程序,不然CopyFile会出现Access Denied的错误,还有就是要在文件夹选项中去掉“隐藏系统保护的重要文件”选项才能看到

现在虽然能够获取到SYS文件,但是每次加载一个新的驱动的话就要把上面的SRC_PATH和DST_PATH做一番修改,有没有办法获取到驱动的ImagePath,从而做到一劳永逸呢?

自己写过加载驱动的程序的都知道,首先在HKLM\SYSTEM\CurrentControlSet\Services\键下创建一个名字为驱动名的子健,然后在这个子健中创建一些ValueKey,比如ImagePath,StartType等等,因此如果我们可以从这里入手

 

于是就想到了利用SSDT HOOK来钩住ZwLoadDriver,通过ZwLoadDriver传进来的第一个参数DriverServiceName来读取这个注册表键,然后再进一步的得到ImagePath的值,再利用这个ImagePath来构造我们的DestinationFileName,假设Xuetr的ImagePath为\??\C:\Users\stefanie\Desktop\XueTr.sys,那么我们最终存放的驱动位置就是C:\Xuetr.sys,这些都是在FilterZwLoadDriver中实现的

同样在这个函数里面也实现了拷贝文件的功能,由于WDK中并没有ZwCopyFile等函数,所以自己写了个ZwCopyFile通过打开文件,读取文件,和写入文件的方法来实现

(这种方法有个弊端,就是文件读取的时候,文件内容是读取在驱动的内部缓冲区里面,如果文件过大的话,怕分配不了那么大的空间,内核空间貌似挺宝贵的,当然可以比如每次4K这样子读写,网上有人利用自己生成和发送IRP来进行文件的操作,等我研究好了再回来补充一下~)

 

BTW:这个驱动并没有考虑到要过主防,如果你的机器装了360的话,那么这个方法将会失效,360的HOOKPORT.SYS框架钩住了KiFastCallEntry,同时它也保存了敏感函数比如ZwLoadDriver的原始地址在它的一个索引表里面,虽然你在这里SSDT HOOK了,但是系统调用的必经之路KiFastCallEntry被360给钩住了,当ZwLoadDriver的时候,不是通过读取SSDT来获得它的地址,而是通过查360自己的那张表。。。说的有点拗口。。。别的杀毒软件没有测试过,HIPS应该都会钩住这个函数,所以最好在虚拟机中使用而且是干净的操作系统

 

好了,废话不多说,贴代码了,这份代码同时也为那些不知道在内核中怎么操作注册表和操作文件的新手提供参考

ps:刚在路上突然想到,下面的开关中断是不是应该KeAquireSpinLock一下,因为如果是多核的话,其他的核在读取地址的时候,万一正在修改的话会不会出现BSOD?????

看了某驱动用的是InterLockedExChange来锁住CPU的地址线,应该要加吧。。。

  1 #include <ntifs.h>
  2 
  3 extern ULONG_PTR KeServiceDescriptorTable;
  4 
  5 typedef NTSTATUS (__stdcall *ZWLOADDRIVER)(IN PUNICODE_STRING DriverServiceName);
  6 
  7 ZWLOADDRIVER OriginalZwLoadDriver;
  8 
  9 DRIVER_INITIALIZE DriverEntry;
 10 DRIVER_UNLOAD DriverUnload;
 11 
 12 NTSTATUS ZwCopyFile(PUNICODE_STRING DestinationFileName,PUNICODE_STRING SourceFileName)
 13 {
 14     NTSTATUS status;
 15     HANDLE SourceFileHandle=NULL;
 16     HANDLE DestinationFileHandle=NULL;
 17     OBJECT_ATTRIBUTES ObjectAttributes;
 18     IO_STATUS_BLOCK IoStatusBlock;
 19     FILE_STANDARD_INFORMATION FileInfo;
 20     ULONG AllocationSize;
 21     PVOID FileBuffer=NULL;
 22     BOOLEAN bAllocateInVirtualMemory=FALSE;
 23 
 24     InitializeObjectAttributes(    &ObjectAttributes,
 25                                 SourceFileName,
 26                                 OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
 27                                 NULL,
 28                                 NULL);
 29     status=IoCreateFile(&SourceFileHandle,
 30                         GENERIC_READ|SYNCHRONIZE,
 31                         &ObjectAttributes,
 32                         &IoStatusBlock,
 33                         NULL,
 34                         FILE_ATTRIBUTE_NORMAL,
 35                         FILE_SHARE_READ,
 36                         FILE_OPEN,
 37                         FILE_SYNCHRONOUS_IO_NONALERT,
 38                         NULL,
 39                         0,
 40                         CreateFileTypeNone,
 41                         0,
 42                         IO_NO_PARAMETER_CHECKING);
 43     if (!NT_SUCCESS(status))
 44     {
 45         DbgPrint("IoCreateFile (%wZ) failed,eid=0x%08x\n",SourceFileName,status);
 46         goto cleanup;
 47     }
 48 
 49     //DbgPrint("Open %wZ success!\n",SourceFileName);
 50 
 51     status=ZwQueryInformationFile(
 52                         SourceFileHandle,
 53                         &IoStatusBlock,
 54                         (PVOID)&FileInfo,
 55                         sizeof(FileInfo),
 56                         FileStandardInformation);
 57     if (!NT_SUCCESS(status))
 58     {
 59         DbgPrint("ZwQueryFileInformation (%wZ) failed,eid=0x%08x\n",SourceFileName,status);
 60         goto cleanup;
 61     }
 62 
 63     //DbgPrint("ZwQueryInformationFile success!\n");
 64 
 65     AllocationSize=FileInfo.AllocationSize.LowPart;
 66 
 67     FileBuffer=ExAllocatePoolWithTag(PagedPool,AllocationSize,'CODE');
 68     if (!FileBuffer)
 69     {
 70         status=ZwAllocateVirtualMemory(    (HANDLE)(-1),
 71                                         (PVOID)&FileBuffer,
 72                                         0,
 73                                         &AllocationSize,
 74                                         MEM_COMMIT,
 75                                         PAGE_READWRITE);
 76         if (!NT_SUCCESS(status))
 77         {
 78             DbgPrint("Cannot Allocate Such Large Buffer!\n");
 79             goto cleanup;
 80         }
 81         bAllocateInVirtualMemory=TRUE;
 82     }
 83 
 84     status=ZwReadFile(    SourceFileHandle,
 85                         NULL,
 86                         NULL,
 87                         NULL,
 88                         &IoStatusBlock,
 89                         FileBuffer,
 90                         AllocationSize,
 91                         NULL,
 92                         NULL);
 93 
 94     if (!NT_SUCCESS(status))
 95     {
 96         DbgPrint("ZwReadFile (%wZ) failed,eid=0x%08x\n",SourceFileName,status);
 97         goto cleanup;
 98     }
 99     
100     InitializeObjectAttributes(    &ObjectAttributes,
101         DestinationFileName,
102         OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
103         NULL,
104         NULL);
105     status=IoCreateFile(&DestinationFileHandle,
106                         GENERIC_READ|GENERIC_WRITE,
107                         &ObjectAttributes,
108                         &IoStatusBlock,
109                         NULL,
110                         FILE_ATTRIBUTE_NORMAL,
111                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
112                         FILE_OVERWRITE_IF,
113                         FILE_SYNCHRONOUS_IO_NONALERT,
114                         NULL,
115                         0,
116                         CreateFileTypeNone,
117                         NULL,
118                         IO_NO_PARAMETER_CHECKING);
119     if (!NT_SUCCESS(status))
120     {
121         DbgPrint("IoCreateFile (%wZ) failed,eid=0x%08x\n",DestinationFileName,status);
122         goto cleanup;
123     }
124 
125     status=ZwWriteFile(    DestinationFileHandle,
126                         NULL,
127                         NULL,
128                         NULL,
129                         &IoStatusBlock,
130                         FileBuffer,
131                         AllocationSize,
132                         NULL,
133                         NULL);
134 
135     if (!NT_SUCCESS(status))
136         DbgPrint("ZwWriteFile (%wZ) failed,eid=0x%08x\n",DestinationFileName,status);
137 
138 cleanup:
139     if (bAllocateInVirtualMemory)
140         ZwFreeVirtualMemory((HANDLE)(-1),(PVOID)&FileBuffer,&AllocationSize,MEM_RELEASE);
141     else if(FileBuffer)
142         ExFreePoolWithTag(FileBuffer,'CODE');
143     if(SourceFileHandle)
144         ZwClose(SourceFileHandle);
145     if (DestinationFileHandle)
146         ZwClose(DestinationFileHandle);
147     
148     return status;
149 }
150 
151 NTSTATUS FilterZwLoadDriver(IN PUNICODE_STRING DriverServiceName)
152 {
153     NTSTATUS status;
154     HANDLE ServiceKeyHandle;
155     OBJECT_ATTRIBUTES ObjectAttribute;
156     UNICODE_STRING usValueKey;
157     UNICODE_STRING usDestinationFileName;
158     UNICODE_STRING usSourceFileName;
159     ULONG cbNeeded;
160     PKEY_VALUE_PARTIAL_INFORMATION Info;
161     WCHAR szDestinationFileName[260]=L"\\??\\C:\\";
162     WCHAR *EndPointer;
163 
164     //DbgPrint("SSDT HOOK ZwLoadDriver success!\n");
165 
166     InitializeObjectAttributes(&ObjectAttribute,DriverServiceName,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,NULL,NULL);
167     status=ZwOpenKey(&ServiceKeyHandle,KEY_READ,&ObjectAttribute);
168     if (!NT_SUCCESS(status))
169     {
170         DbgPrint("ZwOpenKey failed,eid=0x%08x!\n",status);
171         return status;
172     }
173 
174     //DbgPrint("ZwOpenKey (%wZ) success!\n",DriverServiceName);
175 
176     RtlInitUnicodeString(&usValueKey,L"ImagePath");
177     ZwQueryValueKey(ServiceKeyHandle,&usValueKey,KeyValuePartialInformation,NULL,0,&cbNeeded);
178     //DbgPrint("cbNeeded=%d\n",cbNeeded);
179 
180     Info=ExAllocatePoolWithTag(PagedPool,cbNeeded,'CODE');
181     status=ZwQueryValueKey(ServiceKeyHandle,&usValueKey,KeyValuePartialInformation,(PVOID)Info,cbNeeded,&cbNeeded);
182     if (!NT_SUCCESS(status))
183     {
184         DbgPrint("ZwQueryValueKey failed,eid=0x%08x\n",status);
185         ExFreePoolWithTag(Info,'CODE');
186         return status;
187     }
188 
189     ZwClose(ServiceKeyHandle);
190     
191     //DbgPrint("Type=%d,ImagePath=%ws,DataLength=%d\n",Info->Type,Info->Data,Info->DataLength);//include UNICODE_NULL_TERMINATOR
192 
193     RtlInitUnicodeString(&usSourceFileName,(PCWSTR)(Info->Data));
194 
195     EndPointer=(WCHAR*)(Info->Data+Info->DataLength);
196 
197     while (*EndPointer!='\\')
198         EndPointer--;
199     memcpy(szDestinationFileName+wcslen(szDestinationFileName),EndPointer+1,((ULONG)(Info->Data)+Info->DataLength-(ULONG)EndPointer));
200 
201     RtlInitUnicodeString(&usDestinationFileName,szDestinationFileName);
202 
203     //DbgPrint("Destination=%wZ\n",&usDestinationFileName);
204 
205     ExFreePoolWithTag(Info,'CODE');
206 
207     status=ZwCopyFile(&usDestinationFileName,&usSourceFileName);
208     if (!NT_SUCCESS(status))
209     {
210         DbgPrint("ZwCopyFile failed,eid=%d!\n",status);
211         return status;
212     }
213 
214     DbgPrint("CopyFile %ws--->%ws success!\n",(&usSourceFileName)->Buffer+wcslen(L"\\??\\"),(&usDestinationFileName)->Buffer+wcslen(L"\\??\\"));
215 
216     DbgPrint("Mission Complete,Congratulations!\n");
217 
218     return (OriginalZwLoadDriver)(DriverServiceName);
219 }
220 
221 VOID SSDT_HOOK_ZwLoadDriver()
222 {
223     __asm
224     {
225         cli
226         push               eax
227         mov                eax, CR0
228         and                eax, 0FFFEFFFFh
229         mov                CR0, eax
230         pop                eax
231     }
232 
233     _asm{
234         mov     ecx, dword ptr [ZwLoadDriver];
235         mov     edx, [ecx+1];
236         mov     eax, dword ptr [KeServiceDescriptorTable];
237         mov     esi, [eax];
238         mov     edx, [esi+edx*4];
239         mov     dword ptr [OriginalZwLoadDriver], edx
240         mov     ecx, [ecx+1]
241         mov     eax, [eax]
242         mov     dword ptr [eax+ecx*4], offset FilterZwLoadDriver;
243     }
244 
245     __asm
246     {
247         push              eax
248         mov               eax, CR0
249         or                eax, NOT 0FFFEFFFFh
250         mov               CR0, eax
251         pop               eax
252         sti
253     }
254 }
255 
256 VOID SSDT_UNHOOK_ZwLoadDriver()
257 {
258     __asm
259     {
260         cli
261         push               eax
262         mov                eax, CR0
263         and                eax, 0FFFEFFFFh
264         mov                CR0, eax
265         pop                eax
266     }
267 
268     _asm{
269 
270         mov     ecx, dword ptr [ZwLoadDriver];
271         mov     edx, [ecx+1];
272         mov     eax, dword ptr [KeServiceDescriptorTable];
273         mov     esi, [eax];
274         mov     ebx, dword ptr [OriginalZwLoadDriver];
275         mov     [esi+edx*4],ebx;
276     }
277 
278     __asm
279     {
280         push              eax
281         mov               eax, CR0
282         or                eax, NOT 0FFFEFFFFh
283         mov               CR0, eax
284         pop               eax
285         sti
286     }
287 }
288 
289 NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegPath)
290 {
291     SSDT_HOOK_ZwLoadDriver();
292     
293     DriverObject->DriverUnload=DriverUnload;
294 
295     return STATUS_SUCCESS;
296 }
297 
298 VOID DriverUnload(PDRIVER_OBJECT DriverObject)
299 {
300     SSDT_UNHOOK_ZwLoadDriver();
301 }
posted @ 2012-11-10 16:40  unixstudio  阅读(4307)  评论(0编辑  收藏  举报