首页
社区
课程
招聘
[求助]关于使用Windows钩子将dll注入进程结束相关进程的实现
发表于: 2011-4-25 17:27 9082

[求助]关于使用Windows钩子将dll注入进程结束相关进程的实现

2011-4-25 17:27
9082
最近研究一些结束进程的方法,看见一种使用Windows钩子,使用SetWindowsHookEx函数将dll注入到指定进程的手段,可是百般尝试都没有成功.本人对钩子的理解可能有限,不知道有没有哪位高手可以帮忙指点一下思路或者提供源码,在此先行谢过!!

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 692
活跃值: (40)
能力值: ( 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
上传的附件:
2011-4-27 10:50
0
雪    币: 249
活跃值: (71)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
3
非常感谢!!
但是我想的是注入dll后能够关闭指定进程,不知道如何修改
2011-4-27 14:07
0
雪    币: 692
活跃值: (40)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
这个代码中不是写了么,在钩子回调函数中 用::PostQuitMessage(0);我是用这个退出该进程的, 你随便用什么函数退出看自己需要了。
2011-4-27 15:56
0
雪    币: 249
活跃值: (71)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
5
你的程序似乎没有遍历程序的所有线程ID啊
2011-4-28 13:11
0
雪    币: 249
活跃值: (71)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
6
你的程序似乎没有遍历程序的所有线程ID......
2011-4-28 13:12
0
雪    币: 692
活跃值: (40)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
7
楼主啊,我说了 我只是做个简单的测试,举个例子而已,我只是找到了当前进程创建UI的线程id,然后给该线程发送了退出的消息,此时,窗口会关闭,但是有的程序在任务管理器里还是能看到其进程仍存在的。 再说了,没必要遍历进程的所有线程,想结束该进程还不容易么,用个暴利一点的,把::PostQuitMessage(0);改成::TerminateProcess(::GetCurrentProcess(), 0); 进程不就结束了。虽然不推荐这个函数,但是只是说明问题,不做更详细的讨论。

关键是你要理解 回调函数的 代码已经被系统映射到了被挂钩进程的地址空间,该段代码的执行是被挂钩的进程的线程执行的,所以,一个进程 要想自己退出,还不容易么,大不了不算graceful,有点ugly而已。
2011-4-28 15:35
0
雪    币: 0
活跃值: (954)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
8
如果想HOOK 指定的程序的有两种简单通用的办法
1:SMC kernel32.dll 改头到你的区段,然后拖你的DLL启动。
2:给winmm穿马甲,实现部分放在winmm里面,也可以全局HOOK。
2011-4-28 15:54
0
雪    币: 249
活跃值: (71)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
9
不知道能否告诉或者示范一下不硬编码的情况......即输入进程名称退出
2011-5-1 10:51
0
雪    币: 1753
活跃值: (840)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
10
DLL里搞一个栈指针~!
然后FREE掉`!
         多半就挂了`!
搞个NULL指针也可以~!
2011-5-5 22:51
0
游客
登录 | 注册 方可回帖
返回
//