|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
首先是主程序:
#include "stdio.h"
#include "conio.h"
#include "windows.h"
#include <iostream>
#define DEF_DLL_NAME "hookDLL.dll"
#define DEF_HOOKSTART "HookStart"
#define DEF_HOOKSTOP "HookStop"
typedef void(*PFN_HOOKSTART)();//类型定义 PFN_HOOKSTART A 等价于 void(*a)()
typedef void(*PFN_HOOKSTOP)();
void main()
{
//#define DECLARE_HANDLE(name) struct name##__{ int unused; };
//typedef struct name##__ *name;
//DECLARE_HANDLE(HINSTANCE);
//typedef HINSTANCE HMODULE;
HMODULE hDll = NULL;//模块句柄
PFN_HOOKSTART HookStart = NULL;
PFN_HOOKSTOP HookStop = NULL;
unsigned int Error, Error1;
char ch = 0;
hDll = LoadLibraryA(DEF_DLL_NAME);//静态链接
if (hDll <= 0)
{
std::cout << "modole Load failed " << std::endl;
system("pause");
return;
}
else
std::cout << "Load the success.modole address:"<<hDll << std::endl;
try
{
//GetProcAddress如果函数调用成功,返回值是DLL中的输出函数地址。
//如果函数调用失败,返回值是NULL。得到进一步的错误信息,调用函数GetLastError
//第一个参数:包含此函数的DLL模块的句柄。LoadLibrary、AfxLoadLibrary 或者GetModuleHandle函数可以返回此句柄。
//第二个参数:包含函数名的以NULL结尾的字符串,或者指定函数的序数值。
//如果此参数是一个序数值,它必须在一个字的底字节,高字节必须为0。
HookStart = (PFN_HOOKSTART)GetProcAddress(hDll, DEF_HOOKSTART);
if (!HookStart)
throw Error = GetLastError();
HookStop = (PFN_HOOKSTOP)GetProcAddress(hDll, DEF_HOOKSTOP);
if (!HookStop)
throw Error1 = GetLastError();
}
catch (unsigned int)
{
if (!HookStart)
std::cout << "Load failed:" << Error << std::endl;
else if (!HookStop)
std::cout << "Load failed:" << Error1 << std::endl;
return;
}
HookStart();
printf("press 'q' to quit!\n"); //消息循环
while (_getch() != 'q');
HookStop();
FreeLibrary(hDll);
system("pause");
}
下面为HookDLL的代码部分:
#include "stdio.h"
#include "windows.h"
#include <iostream>
#define DEF_PROCSS_NAME "notepad.exe"
HINSTANCE g_hInstance = NULL;
HHOOK g_hHook = NULL;
HWND g_hWnd = NULL;
/*静态链接时,或动态链接时调用LoadLibrary和FreeLibrary都会调用DllMain函数
第二个参数指明了系统调用DLL的原因.
它可能是::
DLL_PROCESS_ATTACH--进程映射
DLL_PROCESS_DETACH--进程卸载
DLL_THREAD_ATTACH--线程映射
DLL_THREAD_DETACH--线程卸载。
*/
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpveserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
std::cout << "HookDll Attach " << std::endl;
g_hInstance = hinstDLL;
break;
case DLL_PROCESS_DETACH:
std::cout << "HookDll Detach " << std::endl;
break;
}
return TRUE;
}
/*
nCode:根据这个数值决定怎样处理消息
code可以是下列值:
HC_ACTION:wParam和lParam包含按键消息
HC_NOREMOVE:wParam和lParam包含按键消息,并且按键消息不能从消息队列中移除(一个被PeekMessage函数调用的请求,指定PM_NOREMOVE标志)
wParam:
按键的虚拟键值消息,例如:VK_F1
lParam:
32位内存,内容描述包括:指定扩展键值,扫描码,上下文,重复次数。
*/
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
char szPath[MAX_PATH] = { 0, };
char *p = NULL;
//MessageBox(NULL, TEXT("来到这里了"), TEXT("HOOK"), MB_OK);
if (nCode = 0)
{
//bit 31: 0=key press,1 = key release
if (!(lParam & 0x80000000))//释放键盘按键时
{
//获取当前进程已加载模块的文件的完整路径,该模块必须由当前进程加载。
GetModuleFileNameA(NULL, szPath, MAX_PATH);
std::cout << szPath << std::endl;
p = strrchr(szPath, '\\');
//比较当前进程名称,若为notepad.exe,则消息不会传递给应用程序(或下一个钩子)
if (!_stricmp(p + 1, DEF_PROCSS_NAME))
{
return 0;
}
}
}
return CallNextHookEx(g_hHook, nCode, wParam, lParam);//调用下一个HOOK函数
}
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport) void HookStart()
{
g_hHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hInstance, 0);
if (g_hHook == NULL)
{
std::cout << "Hook failed" << std::endl;
}
else
std::cout << "Hook success return: " << g_hHook << std::endl;
}
__declspec(dllexport) void HookStop()
{
if (g_hHook)
{
UnhookWindowsHookEx(g_hHook);
g_hHook = NULL;
}
}
#ifdef __cplusplus
}
#endif
|
|