RtlUnicodeToMultiByteN(FullPath, FullPathLen - 1, &ResultSize, &ProcessDosPathw, BytesInUnicodeString); result = 1; return result; } B00L QueryProcessPathW(IN ULONG PID, OUT wchar_t *outPathff, IN size_t stringwlen) PEPROCESS eprocess= NULL; NTSTATUS status; HANDLE handle; PVOID pbuff; DWORD ReturnLength; PUNICODE_STRING puni imageFilename; ULONG result; result =0; if (PID && outPathW) { status = PsLookupProcessByProcessId(PID, &eprocess); if (NT_SUCCESS(status)) { status = ObOpenObjectByPointer(eprocess, OBJ_KERNEL_HANDLE, NULL, 0, NULL, KernelMode, &ha ndle); if (NT_SUCCESS(status)) { pbuff = ExAllocatePoolWithTag(NonPagedPool, 0x800, 0); if (pbuff) { memset(pbuff, 0, 0x800u); status = ZwQueryInformationProcess(handle, ProcessImageFileName, pbuff, 0x800,&ReturnLe ngth); if (NT_SUCCESS(status)) { puniimageFilename = (PUNICODE_STRING)pbuff; if (puniimageFi1ename->Length >0) { wcsncpy(outPathW, puniimageFi1ename->Buffer, stringwlen); result = 1; ExFreePoolWithTag(pbuff, 0); if (handle) ZwClose(handle); if (eprocess) ObfDereferenceObject(eprocess); Jelse result =0; return result; } HANDLE MyOpenFile(lN PCWSTR ProcessPathw) { HANDLE FileHandle; OBJECT_ATTRIBUTES oa; IO_STATUS_BLOCK iosb={0}; UNICODE_STRING uniProcessPath={0}; NTSTATUS status; int result; result = 0; if (ProcessPathw) { Rt1InitUnicodeString(&uniProcessPath, ProcessPathw); InitializeObjectAttributes(&oa, &uniProcessPath, OBJ_KERNEL_HANDLE|OBJ_CASE_I NSENSITIVE, NULL, NULL); status = IoCreateFi1e(&F i1eHand1e, GENERIC_READ, &oa, &iosb, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, CreateFileTypeNone, NULL, IO_NO_PARAMETER_CHECKING); if (NT_SUCCESS(status)) result = FileHandle; } return result; } BOOL QueryProcessDosPathW(IN PffSTR ProcessPathw, OUT PWSTR ProcessDosPathw, IN size_t stringlen) { HANDLE hFile; NTSTATUS status; PFILE_OBJECT fileobj; POBJECT_NAME_INFORMATION ObjectNameInformation; size_t dosstrlen; int result; result = 0; hFile = MyOpenFile(ProcessPathw); if (hFile) { status = ObReferenceObjectByHandle(hFile, 0, *IoFileObjectType, KernelMode, &fileobj, NUL L); if (NT_SUCCESS(status)) status = IoQueryFileDosDeviceName(fileobj, &ObjectNameInformation); if (NT_SUCCESS(status)) memcpy(ProcessDosPathw, 0bjectNameInformation->Name. Buffer, dosstrlen); if ( fileobj ) ObfDereferenceObject(fileobj); if ( hFile ) ZwClose(hFile); if ( ObjectNameInformation ) ExFreePoolWithTag(ObjectNameInformation, 0); return result; //这里只是做简单路径比较,如果某些进程伪造自己的路径,则无法拦截,因此00管 家还进行PID的判断 ULONG VoteModule(lN PCHAR FullProcessPath, IN PCHAR FullDllPath) { ULONG reslut; int i; CHAR FDLLPATH[MAX_PATH]={0}; reslut=l; //如果不是要保护的进程则返回 if (_strnicmp(FullProcessPath, g_Protectpath, 256)!=0) if (strstr(FDLLPATH,SystemDllPath[i])) //该可疑模块是正常的系统模块 dosstrlen = 0bjectNameInformation->Name. Length; if (dosstrlen < 2*stringlen) result = 1 reslut = 3; return reslut; strncpy(FDLLPATH, FullDllPath, 256); _strupr(FDLLPATH); for (i=0;i<10;i++) reslut = 2; break; if (reslut==2) return reslut; //如果是可疑模块将注入我们要保护的进程 DbgPrint("PREVENT Process Info:[ProcessPath=%s, DLLPath=%s\n]", FullProcessPath, FullDllPath); return reslut; 这里有几点注意: 1、由于挂钩的是win32k.sys的导入函数KeUserModeCallback, 在DriverEntry例程是无法挂钩,因为DriverEntry例程是在system内核线程上下文里, 因为system进程的 SessionId=none,因此在system内核线程是无法访问win32k.sys内存空间,因此我在进行IAT挂钩KeUserModeCallback函数时,使用在IRP_DEVICE_CONTROL的例程,让其切换到一个GUI线程里,这样就可以访问win32k.sys空间,shadow ssdt挂钩必须从system内核线程切换到别的线程上下文里也是这个原因。 2、 KeUserModeCallback 函数的参数 ApiNumber= LOAD_IMAGE_API_NUM 时,是指进程触发 LoadLibrary DLL的状态,通过InputBuffer参数指针可以得到LoadLibrary DLL的名称。 这里注意我是使用的XP SP3系统,使用不同操作系统LOAD_IMAGE_API_NUM,以及 InputBuffer参数偏移到dll名称的距离值是有所不同的,这个请读者注意。 |