Hook注入dll文件到所有带窗口的32位程序中

1.在Dll中编写Hook代码,编译为32位

  1. dllmain.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// dllmain.c : Defines the entry point for the DLL application.
#include <windows.h>
#include "Hook.H"

BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MessageBoxA(0, "success load", "title", 1);
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
  1. Hook.h
1
2
3
4
5
6
7
8
9
10
11
12
13
//Hook.h
#pragma once


#define MYWINDAPIEXPORT __declspec(dllexport)

HHOOK g_HookProc; //定义为全局HOOK 返回的钩子过程

void MYWINDAPIEXPORT SetHook();//设置HOOK钩子. //我们的启动函数.导出函数.外部设置HOOK

void MYWINDAPIEXPORT UnHook(); //取消设置HOOK

LRESULT CALLBACK MyProc(int nCode, WPARAM wParam, LPARAM lParam); //设置HOOK过程中需要的回调函数
  1. Hook.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//Hook.c
#include <Windows.h>
#include "Hook.h"

void MYWINDAPIEXPORT SetHook()
{
g_HookProc = SetWindowsHookEx(WH_CBT, MyProc, GetModuleHandle(TEXT("Dll1.dll")), 0); //参数1.HOOK的类型. Hook的回调地址 模块句柄. 线程ID,为0代表是全局钩子

}

void MYWINDAPIEXPORT UnHook() //取消设置HOOK
{
if (NULL != g_HookProc)
UnhookWindowsHookEx(g_HookProc);
}

LRESULT CALLBACK MyProc(int nCode, WPARAM wParam, LPARAM lParam) //我们自己的程序处理
{
/*
执行我们的程序
*/
//MessageBox(NULL, NULL, NULL, NULL);
return CallNextHookEx(g_HookProc, nCode, wParam, lParam); //继续调用钩子过程
}

2.编写C语言程序加载Dll后调用dll中的Hook函数,调用后会将此Dll文件注入到所有有消息的32位程序中(Hook注入期间需要保持加载程序运行)

main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
//main.c
#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include "Hook.h"
#pragma comment(lib,"Dll1.lib")

int main(int argc, char** argv)
{

int ch;
label:
printf("/*************menu**********************\\\n");
printf("/*************select 1 SetHook\\\n");
printf("/*************select 2 UnHook\\\n");
ch = _getch(); // 获取一个字符
if (ch == 27) { // 检查是否为 ESC 键
printf("ESC key pressed. Exiting...\n");
return 0; // 退出循环
}
else if (ch=='1')
{
SetHook();
printf("SetHooked\n");
}
else if (ch == '2')
{
UnHook();
printf("UnHooked\n");
}
else {
printf("You pressed: %c (ASCII: %d)\n", ch, ch);
}
goto label;
return 0;
}

3.开启Hook功能后任意打开一个带窗口的32位进程都会注入

Hook注入dll文件到带窗口的32位特定程序中

1. 编写Dll文件

dllmain.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//dllmain.c
#include <Windows.h>
#include <TlHelp32.h>
#include <tchar.h>

// 指定全局变量
HHOOK global_Hook;

// 判断是否是需要注入的进程
BOOL GetFristModuleName(DWORD Pid, LPCTSTR ExeName)
{
MODULEENTRY32 me32 = { 0 };
me32.dwSize = sizeof(MODULEENTRY32);
HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, Pid);

if (INVALID_HANDLE_VALUE != hModuleSnap)
{
// 先拿到自身进程名称
BOOL bRet = Module32First(hModuleSnap, &me32);

// 对比如果是需要注入进程,则返回真
if (!_tcsicmp(ExeName, (LPCTSTR)me32.szModule))
{
CloseHandle(hModuleSnap);
return TRUE;
}
CloseHandle(hModuleSnap);
return FALSE;
}
CloseHandle(hModuleSnap);
return FALSE;
}


// 设置全局消息回调函数
LRESULT CALLBACK MyProc(int nCode, WPARAM wParam, LPARAM lParam)
{
return CallNextHookEx(global_Hook, nCode, wParam, lParam);
}

// 安装全局钩子 此处的 GetMyDllName()函数 可以是外部其他DLL,可将任意DLL进行注入
extern __declspec(dllexport) void SetHook()
{
global_Hook = SetWindowsHookEx(WH_CBT, MyProc, GetModuleHandle(TEXT("Dll1.dll")), 0);
}

// 卸载全局钩子
extern __declspec(dllexport) void UnHook()
{
if (global_Hook)
{
UnhookWindowsHookEx(global_Hook);
}
}

// DLL 主函数
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
// 当DLL被加载时触发,判断当前自身父进程是否为 InjectDll.exe
BOOL flag = GetFristModuleName(GetCurrentProcessId(), TEXT("InjectDll.exe"));
if (flag == TRUE)
{
MessageBoxA(0, "hello Hook", 0, 0);
}
break;
}
case DLL_THREAD_ATTACH:
{
break;
}
case DLL_THREAD_DETACH:
{
break;
}
case DLL_PROCESS_DETACH:
{
// DLL卸载时自动清理
UnHook();
break;
}
default:
break;
}
return TRUE;
}

2.编写C语言程序加载Dll后调用dll中的Hook函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//main.c
#include <stdio.h>
#include <windows.h>
#include <conio.h>

int main(int argc, char** argv)
{
HMODULE hMod = LoadLibrary(TEXT("C://Dll1.dll"));

int ch;
label:
printf("/*************menu**********************\\\n");
printf("/*************select 1 SetHook\\\n");
printf("/*************select 2 UnHook\\\n");
ch = _getch(); // 获取一个字符
if (ch == 27) { // 检查是否为 ESC 键
printf("ESC key pressed. Exiting...\n");
FreeLibrary(hMod);
return 0;
}
else if (ch == '1')
{

// 挂钩
typedef void(*pSetHook)(void);
pSetHook SetHook = (pSetHook)GetProcAddress(hMod, "SetHook");
SetHook();
printf("SetHooked\n");
}
else if (ch == '2')
{
// 卸载钩子
typedef BOOL(*pUnSetHook)(void);
pUnSetHook UnsetHook = (pUnSetHook)GetProcAddress(hMod, "UnHook");
UnsetHook();
printf("UnHooked\n");
}
else {
printf("You pressed: %c (ASCII: %d)\n", ch, ch);
}
goto label;


return 0;
}

3.开启Hook功能后任意打开一个带窗口的32位进程都会注入,只有匹配的进程才会执行功能