6

I would like to prevent loading of malicious DLLs that may be possible through access of the current working directory as described in http://msdn.microsoft.com/en-us/library/ff919712(VS.85).aspx

The solution implemented in our C++ apps was to make a WinAPI call to SetDllDirectory(""), which would effectively remove the current working directory from the Windows DLL loading search path. However, it seems this solution is not available for our Delphi apps because the SetDllDirectory() function doesn't exist.

Is there an equivalent call in Delphi that does the same thing as SetDllDirectory("")? Thanks!

Stephen
  • 61
  • 1
  • 2
  • 1
    If you want to use a function in the Windows API (that is, a function **in Windows**, that looks the same in any language) that is not declared in `Windows.pas`, it is generally really easy to declare it yourself. All you need is the information at the MSDN, where the data types of the argument and result are specified, as is the DLL to look in. In most cases, the types used there can be used even in Delphi as well (such as HBRUSH, HWND, etc.), or you can use an equivalent type (such as `cardinal`, or `THWND`). Just don't forget to set the calling convention to `stdcall`. – Andreas Rejbrand Oct 28 '10 at 21:58

3 Answers3

7

This should do the trick:

function SetDllDirectory(lpPathName:PWideChar): Bool; stdcall; external 'kernel32.dll' name 'SetDllDirectoryW';
Sertac Akyuz
  • 54,131
  • 4
  • 102
  • 169
Jens Mühlenhoff
  • 14,565
  • 6
  • 56
  • 113
  • Keep in mind that you are static-linking to the function, so the app will require at least XP SP1 to run. If you need to run on older versions, then you need to dynamically load the function via GetProcAddress() instead. – Remy Lebeau Oct 29 '10 at 01:13
  • In a pre-Unicode Delphi version function SetDllDirectory(lpPathName:PAnsiChar): Bool; stdcall; external 'kernel32.dll' name 'SetDllDirectoryA'; can be used as well. –  Oct 29 '10 at 07:38
  • @Remy: Technically correct, but if they used SetDllDirectory in their C++ applications before, I guess that would not be a problem. – Jens Mühlenhoff Oct 29 '10 at 08:26
  • @Brian your edit is wrong, Boolean is not the same as a Bool. You can use Bool in Tokyo too, your problem is something else. – Sertac Akyuz Nov 26 '19 at 01:42
  • Bool only compiles if you've included the Windows unit. Boolean compiles whether you've included Windows or not. Maybe edit the supplied code snippet above to add the required uses of the Windows unit, or reinstate the edit which has Boolean instead of Bool. – Brian THOMAS Nov 26 '19 at 10:30
  • 1
    @Brian - No, you can't reinstate the edit which has boolean because it is wrong. Additionally, "uses windows" is too trivial to make into an edit. Additionally you can use LongBool, or declare Bool as an alias, if you don't want to use "windows". – Sertac Akyuz Nov 26 '19 at 14:44
  • Please explain _why_ is it wrong rather than just saying "it's wrong". You cannot deny that the code snippet as supplied _will not compile_ – Brian THOMAS Nov 26 '19 at 15:48
  • @Brian, for an api call you need to use the exact signature as the function is exported but the sizes of the two data types (boolean vs. bool) are different, please see documentation for more detail. Additionally ordinal values that represent true/false are also not identical but most of the times that doesn't cause a problem. – Sertac Akyuz Nov 26 '19 at 17:02
  • Thank you for your patience and your detailed answer. – Brian THOMAS Nov 27 '19 at 09:58
5

Calling SetDllDirectory('') doesn't work? I see that it is declared properly in the latest versions of Windows.pas. If you have a version of Delphi in which it isn't declared, you can upgrade to the latest version of Delphi, or declare it yourself.

Update: And there you go... Jens just posted the declaration.

Allen Bauer
  • 16,657
  • 2
  • 56
  • 74
4
uses DSiWin32;

if not DSiSetDllDirectory('path') then
   ....

DSiSetDllDirectory will also take care of dynamic linking and will fail gracefully on pre-XP SP1 systems.

DSiWin32 is released as a freeware.

gabr
  • 26,580
  • 9
  • 75
  • 141