作者:llliu | 来源:互联网 | 2023-05-19 13:43
問題如提在下用C++寫了一個hook.dll檔LRESULT(__stdcallSetHook(HWNDhwnd44,HHOOKhThisHook,DWORDDWord))
問題如提 在下用C++寫了一個hook.dll檔
LRESULT (__stdcall SetHook(HWND hwnd44,HHOOK hThisHook,DWORD DWord))
{
g_hWnd = hwnd4;
hThisHook = ::SetWindowsHookExW( WH_MSGFILTER,MessageProc,NULL,GetWindowThreadProcessId(hwnd4,NULL) ); // GetWindowThreadProcessId(hwnd4,NULL)
if ( hThisHook == NULL )
{
DWORD DWord = GetLastError() ;
MessageBox(NULL, L " 掛勾失敗" , L " 標題視窗掛勾失敗" , MB_OK);
return FALSE ;
}
if ( hThisHook > NULL )
{
MessageBox(NULL, L " 恭喜你掛勾成功" , L " 標題視窗掛勾成功" , MB_OK);
return FALSE ;
}
return TRUE;
};
LRESULT CALLBACK MessageProc( int code,WPARAM wParam,LPARAM lParam)
{
switch (code)
{
case WM_PSD_ENVSTAMPRECT:
lparamvalue = lParam;
};
return TRUE;
};
SetWindowsHookExW 的時候掛勾失敗 用GetLastError 去查看掛勾失敗返回了以下的信息:
錯誤代號1428 0x0594沒有模組控制代碼,無法設定非本機勾點。
請問這個要怎麼解決。
41 个解决方案
SetWindowsHookExW第三个参数设置为MessageProc所在dll的基地址
MessageProc所在dll的基地址 <<< 這個要怎麼找呢?
哪邊可以查到這個
不好意思 我不曉得DllMain 做什麼的 我程式碼裡 沒有寫這個進去...
可以指導我這個DllMain 要在哪裡用嗎?
HMODULE base;
BOOL WINAPI DllMain(
HMODULE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved
)
{
if(fdwReason==1)base=hinstDLL;
return 1;
}
SetWindowsHookEx里面用base
首先确定消息能够被截获
然后lparamvalue=((PMSG)lParam)->lParam;
否则使用WM_CALLWNDPROC和WM_GETMESSAGE
MessageProc是给钩子自动调用的,你去调用它干什么
LPARAM __stdcall GetlParam(void)
{
return lparamvalue;
};
嗨 Lactoferrin大大
不好意思 我直接把你給的代碼加進去 結果回傳值就都變成0 還是怪怪的
沒有解決問題 還有我發現我鉤子卸除的部分好像也寫得怪怪的 希望能針對這兩個部份給予指導一下
這邊是C++的部分
LRESULT (CALLBACK __stdcall MessageProc(int code,WPARAM wParam,LPARAM lParam))
{
switch (code)
{
case WM_PSD_ENVSTAMPRECT:
lparamvalue=((PMSG)lParam)->lParam;
};
return TRUE;
};
LPARAM ( __stdcall GetlParam (void))
{
return lparamvalue;
};
LPARAM (__stdcall ReleaseHook(HHOOK hThisHook)) // <<<<<
{
if(hThisHook)
{
UnhookWindowsHookEx(hThisHook);
hThisHook = NULL;
}
return TRUE;
};
然後下面是我在VB的部分
Declare Function GetlParam Lib "hookps.dll" () As Integer
Declare Function ReleaseHook Lib "hookps.dll" () As Long
Private Sub Button6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button6.Click
TextBox10.Text = GetlParam()
End Sub
Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
ReleaseHook()
End Sub
鉤子注入的部分 已經確定沒有問題了 目前就是回傳值回傳0 的問題 ,還有卸除鉤子時
會出現以下這個錯誤信息:
對 PInvoke 函式 'WindowsApplication1!WindowsApplication1.Form1::ReleaseHook' 的呼叫已使堆疊失去平衡。這可能是因為 Managed PInvoke 簽章和 Unmanaged 目標簽章不相符。請確認 PInvoke 簽章的呼叫慣例及參數與目標 Unmanaged 簽章是否相符。
請問這兩地方要怎麼修改?
下面是我用SPY++ 監控對象時的數據,提供給您做參考一下:
<00059> 000C094A S WM_PSD_ENVSTAMPRECT hDC:00000001 lprcEnvStamp:00000004 [wParam:00000001 lParam:00000004]<00060> 000C094A S WM_PAINT hdc:00000000 [wParam:00000000 lParam:00000000]
<00061> 000C094A S WM_PRINTCLIENT hdc:FB013AA6 uFlags:PRF_CLIENT | PRF_CHILDREN [wParam:FB013AA6 lParam:00000014]
<00062> 000C094A S message:0x2138 [使用者定義:WM_USER+7480] wParam:23014941 lParam:000C094A
<00063> 000C094A R message:0x2138 [使用者定義:WM_USER+7480] lResult:00000010
<00064> 000C094A S message:0x204E [使用者定義:WM_USER+7246] wParam:00000000 lParam:0012E75C
<00065> 000C094A R message:0x204E [使用者定義:WM_USER+7246] lResult:00000000
<00066> 000C094A R WM_PRINTCLIENT lResult:00000000
<00067> 000C094A R WM_PAINT lResult:00000000
<00068> 000C094A R WM_PSD_ENVSTAMPRECT fPreventDraw:False [lResult:00000000]
<00069> 000C094A S WM_PSD_PAGESETUPDLG wPaper:0000 wFlags:0 lppsd:00000000 [wParam:00000000 lParam:00000000]
<00070> 000C094A R WM_PSD_PAGESETUPDLG fPreventDraw:True [lResult:00000004]
<00071> 000C094A S WM_PSD_ENVSTAMPRECT hDC:00000001 lprcEnvStamp:00000005 [wParam:00000001 lParam:00000005]
看来你的安装钩子的线程和触发钩子的线程不在同一进程
因此你应该吧lparamvalue放在一个共享的section中
你vb中ReleaseHook少个参数
你dll里面是
LPARAM (__stdcall ReleaseHook(HHOOK hThisHook))
但vb里面是 Declare Function ReleaseHook Lib "hookps.dll" () As Long
应该是 Declare Function ReleaseHook Lib "hookps.dll" (byval IntPtr hThisHook) As UIntPtr
只要共享lparamvalue,其他的不要共享
你在dll里面把lparam打印出来
用_ltow,MessageBox把lparam和hthishook的值显示出来看看
_ltow,MessageBox 沒用過這個
MessageBox 輸出變數不會用 , 可給個代碼嗎?
wchar_t buf[32];
_ltow((long)hThisHook,buf,16);
MessageBoxW(0,buf,0,0);
_ltow((long)lParam,buf,16);
MessageBoxW(0,buf,0,0);
就像这样
錯誤 1 error C3861: '_ltow': 找不到識別項 c:\users\administrator\desktop\資料夾\hookps\hookps\hookps.cpp 75
_ltow 找不到識別項 這個要怎麼解決阿?
恩 我把這行#include 加進去可以了
以下是我目前的寫法
LRESULT (__stdcall SetHook(HWND hwnd4,HHOOK hThisHook,DWORD DWord))
{
g_hWnd=hwnd4;
//hThisHook= ::SetWindowsHookExA( WH_CALLWNDPROC,(HOOKPROC) PaintHookProc,hDll,GetWindowThreadProcessId(hwnd4,NULL) ); //GetWindowThreadProcessId(hwnd4,NULL)
//hook = ::SetHook(hwnd4);
hThisHook= ::SetWindowsHookExW( WH_MSGFILTER,MessageProc,base,GetWindowThreadProcessId(hwnd4,NULL) ); //GetWindowThreadProcessId(hwnd4,NULL)
//DWORD __stdcall WINAPI GetLastError(void);
if( hThisHook == NULL )
{
//DWORD DWord = GetLastError() ;
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
// Process any inserts in lpMsgBuf.
// ...
// Display the string.
MessageBox( NULL, (LPCTSTR)lpMsgBuf, L"Error", MB_OK | MB_ICONINFORMATION );
// Free the buffer.
LocalFree( lpMsgBuf );
//----------------------------
//-------------------------
MessageBox(NULL, L"Hook failure", L"Title window hook fails", MB_OK);
//DWORD __stdcall WINAPI GetLastError(void);
return TRUE ;
}
if( hThisHook > NULL )
{
MessageBox(NULL, L"Congratulations on your successful hook", L"Linked the success of the title window", MB_OK);
wchar_t buf[32];
_ltow((long)hThisHook,buf,16);
MessageBoxW(0,buf,0,0);
//LPWSTR _ltow(LONG hThisHook,LPWSTR str,INT radix);
//printf( "String of integer %d (radix 10): %s\n", hThisHook, str );
return FALSE ;
}
return TRUE;
};
LRESULT (CALLBACK __stdcall MessageProc(int code,WPARAM wParam,LPARAM lParam))
{
switch (code)
{
case WM_PSD_ENVSTAMPRECT:
lparamvalue=((PMSG)lParam)->lParam;
wchar_t buf[32];
_ltow((long)lParam,buf,16);
MessageBoxW(0,buf,0,0);
};
return TRUE;
};
LPARAM ( __stdcall GetlParam (void))
{
LPARAM lParam=0;
wchar_t buf[32];
_ltow((long)lParam,buf,16);
MessageBoxW(0,buf,0,0);
return lparamvalue;
};
鉤子的返回值都沒有固定
訊息攔跳出 以下這些東西
錯誤
7010423
錯誤
23700b1
錯誤
1210a05
錯誤
2cf0bf9
然後lParam返回數值都是0 這樣應該不是正常的吧 哪邊還需要考慮進去呢? 請求協助
switch (code)
这里不是switch(code)
而是switch(((PMSG)lParam)->message)
如果不能截获,换用WH_CALLWNDPROC和WH_GETMESSAGE
嗨 Lactoferrin大大
我按照了您的建議把switch (code)改成switch(((PMSG)lParam)->message)
不過lParam返回的錯誤訊息依然是0 換了擷取鉤子類別 WH_CALLWNDPROC和WH_GETMESSAGE 也依然返回 0
此時我在懷疑會不會是 LPARAM lParam=0; << 初始值設 0的問題
我試著把設成這樣 LPARAM lParam=5 它訊息攔就會有返回值 5
這是意味著我lParam沒有接受到返回的訊息的原因嗎? 求助了!!
LRESULT (CALLBACK __stdcall MessageProc(int code,WPARAM wParam,LPARAM lParam))
{
switch(((PMSG)lParam)->message)
{
case WM_PSD_ENVSTAMPRECT:
lparamvalue=((PMSG)lParam)->lParam;
};
return lparamvalue;
};
LPARAM ( __stdcall GetlParam (void))
{
wchar_t buf[32];
_ltow((long)lparamvalue,buf,16);
MessageBoxW(0,buf,0,0);
return lparamvalue;
};
我試著把代碼改成這樣 不過似乎也沒用 好像根本沒有接受到信息值...
你MessageProc不正确
应该返回CallNextHookEx(0,code,wParam,lParam);
如果是WH_CALLWNDPROC则PMSG要换成PCWPSTRUCT
Lactoferrin 大大 您的意思是這樣嗎?
LRESULT (CALLBACK __stdcall MessageProc(int code,WPARAM wParam,LPARAM lParam))
{
switch(((PCWPSTRUCT)lParam)->message)
{
case WM_PSD_ENVSTAMPRECT:
lparamvalue=((PCWPSTRUCT)lParam)->lParam;
};
CallNextHookEx(0,code,wParam,lParam);
return TRUE;
};
這樣運行也是返回值0
你把所有代码发到ribonucleic_acid@126.com给我看看
恩 我發過去瞜 我的mail: ctjh900801@gmail.com
怕你沒收到我另外在上傳到skydrive上了
https://skydrive.live.com/redir.aspx?cid=105b2868cb2df559&resid=105B2868CB2DF559!190
哎,列宁同志真勤奋,一版看下来就发现你俩在版聊。。。
G-MAIL 似乎不能調安全設置
不然寄到163信箱吧 我也有163信箱
ctjh900801@163.com
Lactoferrin大大 我收到了
剛測試了一下你的代碼 可以了 好像只有WH_CALLWNDPROC 這個鉤子才能抓得到數值
其他的都不行 這個是直接抓取16進制轉成10進制的數值了 直接省去了我一道麻煩
如果要用其他的鉤子抓看看的話是不是只要把WndProc 換成 MsgProc 就可以了嗎?
像下面這樣:
Protected Overrides Sub MsgProc (ByRef m As System.Windows.Forms.Message)
If m.Msg = &H405 Then
TextBox10.Text = m.LParam.ToString()
TextBox11.Text = m.WParam.ToString()
End If
MyBase.WndProc(m)
End Sub
還有個問題就是下面這一行 0x405 這個數值是怎麼來的阿? 是隨便設的嗎?
PostMessageW(g_myhwnd,0x405,(WPARAM)lParam->hwnd,lParam->lParam);
这里必须叫WndProc,因为是覆盖基类的WndProc,用于过滤所有消息
那个数值可以是0x405和0x7FFF之间任意一个