首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ Builder >

钩子函数中摘引的全局变量 无法修改

2012-10-14 
钩子函数中引用的全局变量 无法修改?请教各位大牛一个问题:今天我做了一个钩子应用的测试:操作如下:1、通过

钩子函数中引用的全局变量 无法修改?
请教各位大牛一个问题:

今天我做了一个钩子应用的测试:
操作如下:
1、通过主程序获得一个窗口句柄。
2、加载钩子所在的DLL
3、通过调用钩子所在DLL的一个导出函数GetDllHand()得到钩子所在DLL的实例句柄
4、通过调用钩子所在DLL的一个导出函数SetWndHand(HWND ),将获得的窗口句柄传送给钩子DLL的一个全局变量g_hHookedWnd
5、使用SetWindowsHookEx函数加载DLL中的钩子
6、通过调用钩子所在DLL的一个导出函数GetWndHand(HWND *)可以发现,全局变量g_hHookedWnd与当初设置的值没有发生变化
7、但是在触发钩子时,发现 g_hHookedWnd 与初始化时的值是一样的,没有变化。

注:
在DLLMain函数中修改了 g_hHookedWnd值,能够在钩子回调函数中体现。

附代码:
LoadHook.cpp

[code=C/C++][/code]
int APIENTRY _tWinMain(HINSTANCE hInstance,
  HINSTANCE hPrevInstance,
  LPTSTR lpCmdLine,
  int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);

 // TODO: 在此放置代码。
MSG msg;
HACCEL hAccelTable;

// 初始化全局字符串
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_WINLOADHOOK, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);

// 执行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}

hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINLOADHOOK));

int irc=0;
DWORD pid=NULL,tid=NULL;
typedef HMODULE (* GetDllMod)();
typedef int (* SetHookFun)();
typedef int (* SetWndHand)(HWND);
typedef int (* GetWndHand)(HWND *);
typedef HOOKPROC (* HookProc)(int , WPARAM , LPARAM );
HMODULE hDllModHand=NULL;

HINSTANCE hDllHand=LoadLibrary(_T("D:\\study\\WIN32\\HOOK\\HookDll\\debug\\HookDll.dll"));
GetDllMod DllGetMode=(GetDllMod)GetProcAddress(hDllHand,"GetDllHand");
HookProc DllHookProc=(HookProc)GetProcAddress(hDllHand,"KeyBoardProc");
SetWndHand DllSetWndHand=(SetWndHand)GetProcAddress(hDllHand,"SetWndHand");
GetWndHand DllGetWndHand=(GetWndHand)GetProcAddress(hDllHand,"GetWndHand");

hDllModHand=DllGetMode();

EnumWindows(EnumWindowsProc,FALSE);//遍历需要设置的窗口句柄
tid=GetWindowThreadProcessId(g_hHwnd,&pid);//获取挂起窗口主线程ID
DllSetWndHand(g_hHwnd);

HWND wnd2=NULL;
DllGetWndHand(&wnd2);
g_hHook=SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)DllHookProc,
hDllModHand,tid);
HWND wnd3=NULL;
DllGetWndHand(&wnd3);

irc=GetLastError();

// 主消息循环:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

return (int) msg.wParam;
}

HookDll.cpp

HMODULE g_hModule=NULL;
HHOOKg_hHook=NULL;
HWNDg_hHookedWnd=NULL;//挂起进程的窗口句柄
char g_ShowMsg[133]="没到中秋";

extern "C" HMODULE __declspec(dllexport) GetDllHand();
extern "C" int __declspec(dllexport) SetWndHand(HWND hWndHand);
extern "C" int __declspec(dllexport) GetWndHand(HWND *hWndHand);
extern "C" HOOKPROC __declspec(dllexport) KeyBoardProc(int nCode, WPARAM wParam, LPARAM lParam);


HOOKPROC KeyBoardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
int irc=0;

if( nCode==HC_ACTION )
{
switch(wParam)
{
case 'Q':
case 'q':
MessageBox(NULL,TEXT(g_ShowMsg),TEXT(g_ShowMsg),MB_OK);
SetWindowText(g_hHookedWnd,TEXT("Q"));
if (g_hHookedWnd==NULL)
{
MessageBox(NULL,TEXT("null"),TEXT("null"),MB_OK);
}
else
{
SendMessage(g_hHookedWnd,WM_SETTEXT,NULL,(LPARAM)"设置成功");
irc=GetLastError();
}
break;
case 'W':
case 'w':
MessageBox(NULL,TEXT("W"),TEXT("W"),MB_OK);
SetWindowText(g_hHookedWnd,TEXT("W"));


break;
default:
break;
}

}

return (HOOKPROC)CallNextHookEx(g_hHook,nCode,wParam,lParam);
}

BOOL WINAPI DllMain( HMODULE hModule,
  DWORD ul_reason_for_call,
  LPVOID lpReserved
)
{
g_hModule=hModule;
strcpy_s(g_ShowMsg,"中秋");

  return TRUE;
}

int SetWndHand(HWND hWndHand)
{
g_hHookedWnd=hWndHand;
strcpy_s(g_ShowMsg,"欢度中秋");
MessageBox(NULL,g_ShowMsg,g_ShowMsg,MB_OK);

return TRUE;
}

int GetWndHand(HWND *hWndHand)
{
*hWndHand=g_hHookedWnd;

return TRUE;
}

HMODULE GetDllHand()
{
return g_hModule;
}




[解决办法]
以前搞过全局钩子DLL,你的全局变量仍是每一个进程的局部变量,
要真正的全局变量需要借助API全局文件变量,这是通用方法,
另一种是BCB本身的DLL全局办法,可以搜到。

热点排行