我想修改Windows API中可用的本机函数,例如CreateWindowEx
或ShowWindow
,以便在使用包含的函数编译应用程序时,它将调用我的函数,执行那里的任务,然后调用原始的本机函数。
换句话说,我想以某种方式代理函数,同时仍使用相同的名称(因此,如果编写的程序是使用本机API编译的,只需添加这些函数就可以修改这些本机函数的方式处理)
HWND WINAPI CreateWindowEx(
__in DWORD dwExStyle,
__in_opt LPCTSTR lpClassName,
__in_opt LPCTSTR lpWindowName,
__in DWORD dwStyle,
__in int x,
__in int y,
__in int nWidth,
__in int nHeight,
__in_opt HWND hWndParent,
__in_opt HMENU hMenu,
__in_opt HINSTANCE hInstance,
__in_opt LPVOID lpParam
) {
//my custom code here....
// done with my custom code... so now I want to run the native function
return CreateWindowEx(dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
}
这(由于显而易见的原因)给出了堆栈溢出,因为它一直在反复调用自身。我想要它做的是,当它被调用时,它运行我创建的自定义函数,然后运行Windows API中可用的本机函数。
我对c ++很新,但是在很多其他语言中,我可以用另一个名称存储对本机函数的引用,然后我可以在我的自定义函数中调用它。 c ++中有没有类似的东西?
答案 0 :(得分:3)
正如我在评论中所写,许多挂钩库的父级可能是微软Detours
现在它不再是免费的,有各种各样的选择。这里有一些比较(链接删除。我不确定它是安全的。尝试谷歌搜索“微软Detours是一个在特定拦截中使用的库”并选择一个源或更简单的Detours Alternatives。
嗯,目前唯一的免费替代方案是http://easyhook.codeplex.com/和http://www.codeproject.com/KB/system/mini_hook_engine.aspx
如果您有兴趣,可以提出一个问题:Detours alternative for Registry interception。
答案 1 :(得分:1)
您的问题的一个解释是您有一个项目,包含源代码,并且您想要更改该项目,以便它使用您自己的某些winapi函数版本。
这是一个可以为每个导入的API函数实现的解决方案。此处的示例适用于ShowWindow
:
#define ShowWindow Deleted_Winapi_ShowWindow // prevent windows.h from defining ShowWindow
#include <windows.h>
#undef ShowWindow
namespace HiddenWinapi
{
extern "C"
{
// Do what windows.h does, but hide it inside a namespace.
WINUSERAPI BOOL WINAPI ShowWindow( __in HWND hWnd, __in int nCmdShow);
}
}
// make your own function to be called instead of the API, and delegate to the actual API in the namespace.
BOOL WINAPI ShowWindow(HWND hwnd, int nCmdShow)
{
// ... do stuff ...
// call the original API
return HiddenWinapi::ShowWindow(hwnd, nCmdShow);
}
要将此解决方案用于CreateWindowEx
,您需要存根实际导入的函数名称(例如CreateWindowExW
),因为CreateWindowEx
只是一个扩展为CreateWindowExW
的宏或CreateWindowExA
。
这是一个用您自己的宏取代宏的解决方案,但我认为在所有情况下最好使用上述解决方案。
#include <windows.h>
#undef CreateWindowEx
// Note that this is a unicode-only version. If your app mixes A and W versions, see
// the solution below for non-macro APIs.
HWND WINAPI CreateWindowEx(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
{
// ... do stuff ...
// call the REAL function.
return CreateWindowExW(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
}
答案 2 :(得分:0)
如果您想自己这样做,最简单的方法是修改PE(可移植可执行文件)标头中的导入地址表。不过,这不是微不足道的。
但是,我相信有一个标准库可以满足你想要的Detours。我自己从来没有使用过那个,因为当我开始这样做的时候它并不存在,所以我有一个 - 不用于公共消费 - 库在我需要的时候通过导入表来实现它。