Inline Hook(ring3)的简单C++实现方法

2025-05-27 0 92

C++的Inline Hook代码,采用了备份dll的方法,因此在自定义的函数中可以直接调用在内存中备份的dll代码,而不需要把函数头部改来改去。用SetWindowsHookEx程序的稳定性应该会增加许多。

需要注意的是,例子中没有把原函数的头部几个字节改回去是因为,程序很简单,仅仅测试了效果后便可以退出,没有其他的功能。实际应用中,还要在你注入的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

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

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106
#include <ntifs.h>

#include <windef.h>

#include <stdio.h>

#pragma comment(lib, "psapi.lib")

//BYTE Org_Code[7];// 备份dll法, 因此就可以不需要

BYTE New_Code[7];

HMODULE hDllHandle = NULL; // 被 Hook 的 DLL 句柄

HANDLE hProcess = NULL; // 进程句柄

LPVOID _MessageBoxA = NULL; // MessageBoxA() 原地址

DWORD _ShowMessage = NULL; // 自定义函数地址

void InlineHook();

//void UnInlineHook(); // 备份dll法, 因此就可以不需要

void BackupDll();

// 自定义函数

int WINAPI ShowMessage(HWND, LPTSTR, LPTSTR, UINT);

void main()

{

hProcess = ::GetCurrentProcess();

hDllHandle = ::LoadLibrary("user32.dll");

if (hDllHandle == NULL)

return;

_MessageBoxA = (LPVOID)::GetProcAddress(hDllHandle, "MessageBoxA");

if (_MessageBoxA == NULL)

return;

BackupDll();

InlineHook();

char szText[256];

char szTitle[256];

memset(szText, 0x0, sizeof(szText));

memset(szTitle, 0x0, sizeof(szTitle));

// 下列循环接收来自于用户输入的字符, 并使用 MessageBoxA()

//来显示, 尝试下, 看看发生了什么. :)

while (TRUE)

{

printf("Message Text: ");

scanf("%s", szText);

printf("Message Title: ");

scanf("%s", szTitle);

MessageBoxA(NULL, szText, szTitle, 0);

printf("\\n");

}

return;

}

void InlineHook()

{

DWORD _JmpAddr = (DWORD)ShowMessage;

// 构造新头部代码

New_Code[0] = 0xB8; //

memcpy(&New_Code[1], &_JmpAddr, 4); // mov eax, _JmpAddr

New_Code[5] = 0xFF; //

New_Code[6] = 0xE0; // jmp eax

DWORD dwOldProtect = 0;

// 去内存保护

::VirtualProtect(_MessageBoxA, 7, PAGE_EXECUTE_READWRITE, &dwOldProtect);

// 把新代码写入 MessageBoxA() 的头部, 这也是Inline Hook

//的核心所在.

::WriteProcessMemory(

hProcess,

_MessageBoxA,

New_Code,

sizeof(New_Code),

NULL

);

// 写内存保护

::VirtualProtect(_MessageBoxA, 7, dwOldProtect, &dwOldProtect);

return;

}

/*

void UnInlineHook() // 备份dll法, 因此就可以不需要

{

return;

}

*/

int WINAPI ShowMessage(HWND hWnd, LPTSTR lpText, LPTSTR lpTitle, UINT uType)

{

typedef int WINAPI SHOWMSG(HWND hWnd, LPTSTR lpText, LPTSTR lpTitle, UINT uType);

SHOWMSG *pShowMsg = (SHOWMSG*)_ShowMessage;

// 废弃原先传入的参数, 自己定义对话框文本

char buf[1024];

::wsprintf(buf, "The Text:"%s" was hacked by miku_fl", lpText);

return pShowMsg(hWnd, buf, lpTitle, MB_ICONINFORMATION | MB_TOPMOST);

}

void BackupDll()

{

MODULEINFO Mdl_Info;

LPVOID lpNewDLL = NULL;

// 获取模块信息

::GetModuleInformation(hProcess, hDllHandle, &Mdl_Info, sizeof(Mdl_Info));

// 分配内存空间, 用于备份 dll (这样一来就不需要恢复原头部代码, 调用

//完之后再重新写自定义的头部代码).

lpNewDLL = ::VirtualAllocEx(

hProcess,

NULL,

Mdl_Info.SizeOfImage,

MEM_COMMIT,

PAGE_EXECUTE_READWRITE

);

if (lpNewDLL == NULL)

return;

// 在分配的内存中写入 dll 文件的内容

::WriteProcessMemory(hProcess, lpNewDLL, Mdl_Info.lpBaseOfDll, Mdl_Info.SizeOfImage, NULL);

// 计算自定义函数的地址.

// 公式: 自定义地址 = 原API函数地址 - 模块基址 + 分配内存的基址

_ShowMessage = (DWORD)_MessageBoxA - (DWORD)Mdl_Info.lpBaseOfDll + (DWORD)lpNewDLL;

return;

}

希望本文所述程序实例能对大家有所帮助。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 Inline Hook(ring3)的简单C++实现方法 https://www.kuaiidc.com/75959.html

相关文章

猜你喜欢
发表评论
暂无评论