Search code examples
delphidllhookcreatefilesetwindowshookex

CreateFile Hook


I am trying to Create a Hook for CreateFile, so when a process tryies to create a file the hookdll we created will notify the user that: "this process xx.exe trying to create xx.exe, Do you want to proceceed?"

So far i am here, So What i need to modify in this code:

library CreateFileHook;

uses
 Windows, Dialogs, SysUtils;

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

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

var
  JmpCfw, JmpCfa: far_jmp;
  OldCfw, OldCfa: OldCode;
  CfwAdr, CfaAdr: pointer;

function NewCreateFileA(lpFileName: PChar;
                       dwDesiredAccess: DWORD;
                       dwShareMode: DWORD;
                       lpSecurityAttributes: PSecurityAttributes;
                       dwCreationDisposition: DWORD;
                       dwFlagsAndAttributes: DWORD;
                       hTemplateFile: THandle): THandle; stdcall;
var
  file_name: PWideChar;
  name_len: dword;
begin
  name_len := lstrlen(lpFileName) * SizeOf(WideChar) + 2;
  GetMem(file_name, name_len);
  StringToWideChar(lpFileName, file_name, name_len);

  CreateFileW(file_name, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
              dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);

  FreeMem(file_name);
end;

function TrueCreateFileW(lpFileName: PWideChar;
                        dwDesiredAccess: DWORD;
                        dwShareMode: DWORD;
                        lpSecurityAttributes: PSecurityAttributes;
                        dwCreationDisposition: DWORD;
                        dwFlagsAndAttributes: DWORD;
                        hTemplateFile: THandle): THandle; stdcall;
var
Written: dword;
begin
 WriteProcessMemory(INVALID_HANDLE_VALUE, CfwAdr,
                    @OldCfw, SizeOf(OldCode), Written);

 CreateFileW(lpFileName,
             dwDesiredAccess,
             dwShareMode,
             lpSecurityAttributes,
             dwCreationDisposition,
             dwFlagsAndAttributes,
             hTemplateFile);

 WriteProcessMemory(INVALID_HANDLE_VALUE, CfwAdr,
                    @JmpCfw, SizeOf(far_jmp), Written);
end;

function NewCreateFileW(lpFileName: PWideChar;
                       dwDesiredAccess: DWORD;
                       dwShareMode: DWORD;
                       lpSecurityAttributes: PSecurityAttributes;
                       dwCreationDisposition: DWORD;
                       dwFlagsAndAttributes: DWORD;
                       hTemplateFile: THandle): THandle; stdcall;
begin
 TrueCreateFileW(lpFileName,
                 dwDesiredAccess,
                 dwShareMode,
                 lpSecurityAttributes,
                 dwCreationDisposition,
                 dwFlagsAndAttributes,
                 hTemplateFile);
end;

Procedure SetHook();
var
  kernel32: dword;
  Bytes: dword;
begin
  kernel32 := GetModuleHandle('Kernel32.dll');
  CfwAdr  := GetProcAddress(kernel32, 'CreateFileW');
  CfaAdr  := GetProcAddress(kernel32, 'CreateFileA');
  ReadProcessMemory(INVALID_HANDLE_VALUE, CfwAdr, @OldCfw, SizeOf(OldCode), Bytes);
  ReadProcessMemory(INVALID_HANDLE_VALUE, CfaAdr, @OldCfa, SizeOf(OldCode), Bytes);
  JmpCfw.PuhsOp  := $68;
  JmpCfw.PushArg := @NewCreateFileW;
  JmpCfw.RetOp   := $C3;
  JmpCfa.PuhsOp  := $68;
  JmpCfa.PushArg := @NewCreateFileA;
  JmpCfa.RetOp   := $C3;
  WriteProcessMemory(INVALID_HANDLE_VALUE, CfwAdr, @JmpCfw, SizeOf(far_jmp), Bytes);
  WriteProcessMemory(INVALID_HANDLE_VALUE, CfaAdr, @JmpCfa, SizeOf(far_jmp), Bytes);
end;

Procedure Unhook();
var
Bytes: dword;
begin
 WriteProcessMemory(INVALID_HANDLE_VALUE, CfaAdr, @OldCfa, SizeOf(OldCode), Bytes);
 WriteProcessMemory(INVALID_HANDLE_VALUE, CfwAdr, @OldCfw, 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, 'CreateFileHook');
  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();
                         Randomize();
                         SetHook()
                       end;
   DLL_PROCESS_DETACH: UnHook();
 end;
end;

begin
  DllProc := @DLLEntryPoint;
  DLLEntryPoint(DLL_PROCESS_ATTACH);
end.

Solution

  • At a quick glance, I see several problems with this code. Where did you get this from? I don't have a reference handy but I'm pretty sure you can find working examples of what you're trying to do on the web.

    You shouldn't have to use Read/WriteProcessMemory since you're inside the process you're trying to modify - Windows will do copy-on-write for you.

    If you do want/need to use Read/WriteProcessMemory the way to get a handle to use is OpenProcess.

    This hook code is not reentrant - one thread may be exiting ReadFile, restoring the redirect code right before another thread attempt to call it but after that second thread thinks it's just 'repaired' it.

    A cleaner way to do this is to save the pointer in the import address table that points to the function you wish to hook, then modify that to call your hook routine. Now you can use the saved pointer to call the original routine from within the hook.

    Once (if) you get this working, be prepared to see a LOT of calls to CreateFile. CreateFile is used for creating/opening lots of stuff besides physical files, e.g. COM ports, pipes, console buffers, whatnot.