我正在从事我的大学项目,并遇到问题。我的任务是编写一个程序和.dll以拦截Winapi的呼叫。例如,我启动程序,它应该使用SetWindowsHookEx
通过PID注入.dll。我成功地为函数CreateFile
制定了此任务,但是我需要实现多个功能的实现,并允许用户选择要通过命令行参数拦截的函数。
在我的代码中,安装挂钩时我定义回调函数:
HINSTANCE hinst = LoadLibrary(L"ConsoleApplication1.dll");
HOOKPROC addr = (HOOKPROC)GetProcAddress(hinst, "meconnect");
HHOOK handle = SetWindowsHookEx(WH_KEYBOARD, addr, hinst, threadID);
但是,此回调函数中只有三个参数可以启动CallNextHookEx(NULL, code, wParam, lParam)
,似乎我们无法更改它们。
另一个问题是,当我们将.dll注入另一个过程时,我们只能从DLL_PROCESS_ATTACH
节运行任务,因此它不与程序链接,因此我们无法通过参数。
也许解决方案是创建一个临时文件并向它写入参数,然后从.dll读取它,但我希望您能为我提供更优雅的解决方案。我将感谢任何帮助。
您可以为每个钩子使用单独的功能。
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
SetWindowsHookEx(WH_CBT, CBTProc, (HINSTANCE) NULL, GetCurrentThreadId());
SetWindowsHookEx(WH_CALLWNDPROCRET, CallWndRetProc, (HINSTANCE) NULL, GetCurrentThreadId());
break;
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode < 0)
return CallNextHookEx(___cbt_message_hookptr, nCode, wParam, lParam);
// your code here
return CallNextHookEx(___cbt_message_hookptr, nCode, wParam, lParam);
}
LRESULT CALLBACK CallWndRetProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode < 0)
return CallNextHookEx(___callwndprocret_message_hookptr, nCode, wParam, lParam);
// your code here
return CallNextHookEx(___callwndprocret_message_hookptr, nCode, wParam, lParam);
}
为了引用您的DLL_PROCESS_ATTACH
问题,这是截距过程和过程之间的通信的常见问题。
我认为最好的解决方案是将管道用作相互处理的通信机制,BCS是最简单,最优雅的解决方案。
我的建议是,您应该从DLL_PROCESS_ATTACH
启动另一个线程,该线程将通过管道从主应用程序接收命令,以连接某些功能,并且它将通过同一管道将截然的数据发送到主应用程序,您将在其中存档或显示此数据。
假设您在另一侧听了这些数据的东西:
LPTSTR lpszPipename = TEXT("\\.\pipe\payload_datapipe");
CHAR chReadBuf[1024];
DWORD cbRead = 0;
BOOL fResult;
fResult = CallNamedPipe(
lpszPipename, // pipe name
_Message, // message to server
strlen(_Message), // message length
chReadBuf, // buffer to receive reply
sizeof(chReadBuf), // size of read buffer
&cbRead, // number of bytes read
NMPWAIT_NOWAIT);//NMPWAIT_WAIT_FOREVER); // wait;-)
if (!fResult)
{
return;
}
您可以在相关文档页面上找到有关指定管道的更多信息。https://msdn.microsoft.com/en-us/library/windows/desktop/aa365592(v=vs.85)9.aspx