1

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
  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.
| improve this answer | |
  • 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? – Shmuel Fomberg Jul 28 '16 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. – Shmuel Fomberg Jul 31 '16 at 7:29
  • If you can share the EXE we can take a look. – Jason Geffner Jul 31 '16 at 15:16
0

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.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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