8

I need to get the address of a Win APi method (FindWindowW) , I'm using the @ operator and the GetProcAddress but both returns differents results.

var
  p1, p2 : Pointer;
begin
  p1:= @Winapi.Windows.FindWindowW;
  p2:=GetProcAddress(GetModuleHandle('user32.dll'), 'FindWindowW');
  ShowMessage(Format('p1 %p p2 %p ', [p1, p2]));
end;

Why the values returned are different?

Salvador
  • 16,132
  • 33
  • 143
  • 245
  • If you need to get the address of a WinAPI or DLL function, you should use `GetProcAddress`, which returns the address of a WinAPI or DLL function. What are you actually trying to accomplish? – Ken White Dec 06 '13 at 03:48
  • I need to hook some WinApi functions. – Salvador Dec 06 '13 at 03:57
  • 1
    The address of the function in the Windows unit is, like all Delhpi functions, known at **compile time**. The address of the function in user32 is known only at **runtime**. So they must be different. And from which you can conclude that the implementation must be a thunk. Another way to think about it is that p1 and p2 are quite clearly in different modules and so of course their addresses are different. Hook p1 and you'll hook your own modules calls to the function in Windows.pas. Hook p2 and you'll hook every module's calls to the function in user32. – David Heffernan Dec 06 '13 at 07:34
  • @DavidHeffernan - it does not **must** be a thunk, a thunk implementation just makes a work of the exe loader easier; without a thunk the loader would have to make a lot of fixups in the process code where dll function is called; with a thunk only the thunk is fixed. – kludg Dec 06 '13 at 07:46
  • 1
    @user addresses of Delphi functions are known at compile time – David Heffernan Dec 06 '13 at 07:47
  • Kind of duplicate of http://stackoverflow.com/questions/5137317/addresses-of-delphi-and-c-winapi-functions-differ-when-they-shouldnt (which is the 2nd *related* question on the right). – Sertac Akyuz Dec 06 '13 at 09:50

1 Answers1

12

Because static linking uses a thunk jump table to call a DLL function.

p2 in your example is the correct address of the FindWindowW function in your process, while p1 is the address of a jump instruction like this

jmp dword ptr [SomeAddress]

where SomeAddress points to the actual address of the FindWindowW function.

kludg
  • 27,213
  • 5
  • 67
  • 118