Tried to hook SHGetKnownFolderPath from shell32, using the normal DetourFunctionWithTrampoline, and it could not.

Investigating, it seen that the application use GetProcAddress to load the function, and use the function pointer.

So I did the same, and hooked using DetourFunction, and it succeed.

I looked on the assembly, and it seen that when I call SHGetKnownFolderPath directly it goes through two jumps before reaching shell32. I don't think that it does that for other functions.

What is going on?

Sharing code:

#include "stdafx.h"
#include "windows.h"
#include "FileAPI.h"
#include "Shlobj.h"

int main()
    HANDLE hFile = CreateFileA(NULL, 0, 0, NULL, 0, 0, NULL);
    SHGetKnownFolderPath(FOLDERID_LocalAppDataLow, 0, NULL, NULL);
    return 0;

Looking in IDA, I see for CreateFileA:

call    ds:__imp__CreateFileA@28 ; CreateFileA(x,x,x,x,x,x,x)

Which takes me to:

.idata:0041B000 ; HANDLE __stdcall CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
.idata:0041B000                 extrn __imp__CreateFileA@28:dword ; CODE XREF: _main+2Ep
.idata:0041B000                                         ; DATA XREF: _main+2Er ...

On the other hand, for SHGetKnownFolderPath I see:

call    j__SHGetKnownFolderPath@16 ; SHGetKnownFolderPath(x,x,x,x)

Which redirect to:

; __stdcall SHGetKnownFolderPath(x, x, x, x)
j__SHGetKnownFolderPath@16 proc near
jmp     _SHGetKnownFolderPath@16 ; SHGetKnownFolderPath(x,x,x,x)
j__SHGetKnownFolderPath@16 endp

Which redirect to:

; __stdcall SHGetKnownFolderPath(x, x, x, x)
_SHGetKnownFolderPath@16 proc near
jmp     ds:__imp__SHGetKnownFolderPath@16 ; SHGetKnownFolderPath(x,x,x,x)
_SHGetKnownFolderPath@16 endp

Which redirect to:

.idata:0041B09C ; __declspec(dllimport) __stdcall SHGetKnownFolderPath(x, x, x, x)
.idata:0041B09C                 extrn __imp__SHGetKnownFolderPath@16:dword
.idata:0041B09C                                         ; DATA XREF: SHGetKnownFolderPath(x,x,x,x)r

So SHGetKnownFolderPath have two more jumps then CreateFileA. I did nothing to the project to make it do it. so why?

2 Answers 2

  1. DetourFunction() is from an older version of Detours. Probably best to upgrade to the latest version of the library. (The equivalent function is now DetourAttach().)
  2. If you're using DetourFunction(SHGetKnownFolderPath, Hook), the value for the first parameter is probably pointing to a compiler-created stub for the real SHGetKnownFolderPath() function. Instead, you should use DetourFunction(GetProcAddress(GetModuleHandle("shell32.dll"), "SHGetKnownFolderPath"), Hook) to ensure that you're using the actual address of the exported API function.
  • But why? Why did the compiler decided to make a stub for this function? I don't have this problem with CreateFileA for example. Is that special treatment for shell32? linker flag? Commented Jul 28, 2016 at 18:56
  • That explain one jump, not why I see TWO jumps. Also, it doesn't explain why CreateFileA does have this problem, in the same program. Commented Jul 31, 2016 at 7:29
  • If you can share the EXE we can take a look. Commented Jul 31, 2016 at 15:16

I found out that SHGetKnownFolderPath does not have a declspec(dllimport) flag in the definition in the header file.
Adding it made it identical to the CreateFile call.

Without it, the compiler made a stub for the unknown function, and the linker made his own stub because of incremental linking, and only then forward the call to the DLL.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.