delphidelphi-10-seattleapi-hook

GetWindowThreadProcessId() IAT hooking: How compare "dwProcessID" parameter?


I'm hooking GetWindowThreadProcessId() with sucess using the following code.

Now i want check if dwProcessID parameter corresponds to id of determinated process and in positive case prevent execute original function:

Result := OldGetWindowThreadProcessId(hWnd, dwProcessID);

I tried this, but not worked:

if dwProcessID = 12345 then exit;

Here is my complete code:

library MyLIB;

uses
  Windows,
  ImageHlp;

{$R *.res}

type
  PGetWindowThreadProcessId = function(hWnd: THandle; dwProcessID: DWord)
    : DWord; stdcall;

var
  OldGetWindowThreadProcessId: PGetWindowThreadProcessId;

function HookGetWindowThreadProcessId(hWnd: THandle; dwProcessID: DWord)
  : DWord; stdcall;

begin
  try
    // Check if is some process
  except
    MessageBox(0, 'Error', 'HookGetWindowThreadProcessId Error', 0);
  end;
  Result := OldGetWindowThreadProcessId(hWnd, dwProcessID);
end;

procedure PatchIAT(strMod: PAnsichar; Alt, Neu: Pointer);
var
  pImportDir: pImage_Import_Descriptor;
  size: CardinaL;
  Base: CardinaL;
  pThunk: PDWORD;
begin
  Base := GetModuleHandle(nil);
  pImportDir := ImageDirectoryEntryToData(Pointer(Base), True,
    IMAGE_DIRECTORY_ENTRY_IMPORT, size);
  while pImportDir^.Name <> 0 Do
  begin
    If (lstrcmpiA(PAnsichar(pImportDir^.Name + Base), strMod) = 0) then
    begin
      pThunk := PDWORD(Base + pImportDir^.FirstThunk);
      While pThunk^ <> 0 Do
      begin
        if DWord(Alt) = pThunk^ Then
        begin
          pThunk^ := CardinaL(Neu);
        end;
        Inc(pThunk);
      end;
    end;
    Inc(pImportDir);
  end;
end;

procedure DllMain(reason: Integer);

begin
  case reason of
    DLL_PROCESS_ATTACH:
      begin
        OldGetWindowThreadProcessId := GetProcAddress(GetModuleHandle(user32),
          'GetWindowThreadProcessId');

        PatchIAT(user32, GetProcAddress(GetModuleHandle(user32),
          'GetWindowThreadProcessId'), @HookGetWindowThreadProcessId);

      end;
    DLL_PROCESS_DETACH:
      begin
      end;
  end;
end;

begin
  DllProc := @DllMain;
  DllProc(DLL_PROCESS_ATTACH);

end.

Solution

  • Your PGetWindowThreadProcessId type and HookGetWindowThreadProcessId() function are both declaring the dwProcessID parameter incorrectly. It is an output parameter, so it needs to be declared as either var dwProcessID: DWord or as dwProcessID: PDWord.

    And then you need to call OldGetWindowThreadProcessId() to retrieve the actual PID before you can then compare it to anything. So your requirement of "in positive case prevent execute original function" is not realistic, because you need to execute the original function in order to determine the dwProcessID value to compare with.

    Try this instead:

    type
      PGetWindowThreadProcessId = function(hWnd: THandle; var dwProcessID: DWord): DWord; stdcall;
    
    ...
    
    function HookGetWindowThreadProcessId(hWnd: THandle; var dwProcessID: DWord): DWord; stdcall;
    begin
      Result := OldGetWindowThreadProcessId(hWnd, dwProcessID);
      try
        if dwProcessID = ... then
          ...
      except
        MessageBox(0, 'Error', 'HookGetWindowThreadProcessId Error', 0);
      end;
    end;