能力值:
( LV6,RANK:90 )
|
-
-
2 楼
利用消息钩子注入dll是很早的事了,我简单建了个工程,简单写了个测试程序,这玩意整的我还注销了一次。
Windows在处理消息时,会先检查是否有钩子挂钩在该消息上,如果没有,就交给程序去处理。如果有钩子在,就调用钩子回调函数,而在检查该钩子的回调函数时,如果,该函数在本程序的进程空间,不管是dll还是exe里,那可以正常访问,如果该函数不在该进程的地址空间,在另一个dll里,那么系统会把该dll映射到该进程的地址空间。再进行后续的处理。
在挂钩消息时,HHOOK SetWindowsHookEx( int idHook,
HOOKPROC lpfn,
HINSTANCE hMod,
DWORD dwThreadId
);
其中idhook可以选择hook的消息类型,我hook了 WH_GETMESSAGE, lpfn 钩子回调函数,hmod就是回调函数所在的模块, dwthreadid 就是该进程的UI线程。如果为0,那就hook了和该进程在同一桌面环境的所有UI进程。我就是因为这个注销了一次。没桌面了。
首先看下dll的代码:
dllmain:
HHOOK g_hook = NULL;
HMODULE g_hmodule = NULL;
LRESULT CALLBACK GetMsgProc(int code, WPARAM wParam, LPARAM lParam);
BOOL set_hook(DWORD thread_id );
void un_hook();
BOOL set_hook(DWORD thread_id = 0)
{
if (g_hook == NULL)
g_hook = ::SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hmodule, thread_id);
else
{
un_hook();
g_hook = ::SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hmodule, thread_id);
}
return (g_hook != NULL);
}
void un_hook()
{
if (g_hook != NULL)
{
::UnhookWindowsHookEx(g_hook);
g_hook = NULL;
}
}
LRESULT CALLBACK GetMsgProc(int code, WPARAM wParam, LPARAM lParam)
{
::PostQuitMessage(0);
return ::CallNextHookEx(g_hook, code, wParam, lParam);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
g_hmodule = hModule;
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
然后是main.cpp的:
#include <iostream>
#include <windows.h>
using namespace std;
typedef BOOL (WINAPI *PFNSET_HOOK)(DWORD thread_id);
int main()
{
HINSTANCE hinstance = NULL;
hinstance = ::LoadLibrary(TEXT("InjectDllByHookMessage.dll"));
if (hinstance != NULL)
{
PFNSET_HOOK pfn_set_hook = (PFNSET_HOOK)::GetProcAddress(hinstance, "set_hook");
if (pfn_set_hook == NULL)
{
::FreeLibrary(hinstance);
cout<<"get set_hook address error"<<endl;
return 0;
}
DWORD thread_id = 0;
DWORD process_id = 0;
thread_id = ::GetWindowThreadProcessId(::FindWindow(NULL, TEXT("QQ2011")), &process_id);
if (pfn_set_hook(thread_id))
cout<<"set hook ok!"<<endl;
else
cout<<"set hook failed"<<endl;
}
return 0;
}
工程附件: DllInjectByHookMessage.rar
|
能力值:
( LV7,RANK:100 )
|
-
-
3 楼
非常感谢!!
但是我想的是注入dll后能够关闭指定进程,不知道如何修改
|
能力值:
( LV6,RANK:90 )
|
-
-
4 楼
这个代码中不是写了么,在钩子回调函数中 用::PostQuitMessage(0);我是用这个退出该进程的, 你随便用什么函数退出看自己需要了。
|
能力值:
( LV7,RANK:100 )
|
-
-
5 楼
你的程序似乎没有遍历程序的所有线程ID啊
|
能力值:
( LV7,RANK:100 )
|
-
-
6 楼
你的程序似乎没有遍历程序的所有线程ID......
|
能力值:
( LV6,RANK:90 )
|
-
-
7 楼
楼主啊,我说了 我只是做个简单的测试,举个例子而已,我只是找到了当前进程创建UI的线程id,然后给该线程发送了退出的消息,此时,窗口会关闭,但是有的程序在任务管理器里还是能看到其进程仍存在的。 再说了,没必要遍历进程的所有线程,想结束该进程还不容易么,用个暴利一点的,把::PostQuitMessage(0);改成::TerminateProcess(::GetCurrentProcess(), 0); 进程不就结束了。虽然不推荐这个函数,但是只是说明问题,不做更详细的讨论。
关键是你要理解 回调函数的 代码已经被系统映射到了被挂钩进程的地址空间,该段代码的执行是被挂钩的进程的线程执行的,所以,一个进程 要想自己退出,还不容易么,大不了不算graceful,有点ugly而已。
|
能力值:
( LV3,RANK:30 )
|
-
-
8 楼
如果想HOOK 指定的程序的有两种简单通用的办法
1:SMC kernel32.dll 改头到你的区段,然后拖你的DLL启动。
2:给winmm穿马甲,实现部分放在winmm里面,也可以全局HOOK。
|
能力值:
( LV7,RANK:100 )
|
-
-
9 楼
不知道能否告诉或者示范一下不硬编码的情况......即输入进程名称退出
|
能力值:
( LV8,RANK:120 )
|
-
-
10 楼
DLL里搞一个栈指针~!
然后FREE掉`!
多半就挂了`!
搞个NULL指针也可以~!
|
|
|