尝试使用正常的 DetourFunctionWithTrampoline 从 shell32 挂钩 SHGetKnownFolderPath,但它不能。
经查,应用程序使用GetProcAddress加载函数,并使用函数指针。
所以我做了同样的事情,并使用 DetourFunction 进行了钩子,它成功了。
我查看了程序集,发现当我直接调用 SHGetKnownFolderPath 时,它在到达 shell32 之前经历了两次跳转。我不认为它对其他功能这样做。
到底是怎么回事?
分享代码:
#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;
}
在 IDA 中,我看到 CreateFileA:
call ds:__imp__CreateFileA@28 ; CreateFileA(x,x,x,x,x,x,x)
这让我:
.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 ...
另一方面,对于 SHGetKnownFolderPath 我看到:
call j__SHGetKnownFolderPath@16 ; SHGetKnownFolderPath(x,x,x,x)
哪个重定向到:
; __stdcall SHGetKnownFolderPath(x, x, x, x)
j__SHGetKnownFolderPath@16 proc near
jmp _SHGetKnownFolderPath@16 ; SHGetKnownFolderPath(x,x,x,x)
j__SHGetKnownFolderPath@16 endp
哪个重定向到:
; __stdcall SHGetKnownFolderPath(x, x, x, x)
_SHGetKnownFolderPath@16 proc near
jmp ds:__imp__SHGetKnownFolderPath@16 ; SHGetKnownFolderPath(x,x,x,x)
_SHGetKnownFolderPath@16 endp
哪个重定向到:
.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
所以 SHGetKnownFolderPath比 CreateFileA 多了两个跳转。我没有对这个项目做任何事情来让它做到这一点。所以为什么?