獲取加載后就自動刪除的驅動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 }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM