1
#include
<
windows.h
>
2
#include
<
stdio.h
>
3
4
//
挂钩指定模块hMod对MessageBoxA的调用
5
BOOL SetHook(HMODULE hMod);
6
//
定义MessageBoxA函数原型
7
typedef
int
(WINAPI
*
PFNMESSAGEBOX)(HWND, LPCSTR, LPCSTR, UINT uType);
8
//
保存MessageBoxA函数的真实地址
9
PROC g_orgProc
=
(PROC)MessageBoxA;
10
11
12
BOOL EnableDebugPrivilege()
13
{
14
BOOL fOk
=
FALSE;
15
HANDLE hToken;
16
17
if
(OpenProcessToken(GetCurrentProcess(),
18
TOKEN_ADJUST_PRIVILEGES,
&
hToken))
19
{
20
TOKEN_PRIVILEGES tp;
21
tp.PrivilegeCount
=
1
;
22
LookupPrivilegeValue(NULL, SE_DEBUG_NAME,
&
tp.Privileges[
0
].Luid);
23
tp.Privileges[
0
].Attributes
=
SE_PRIVILEGE_ENABLED;
24
AdjustTokenPrivileges(hToken, FALSE,
&
tp,
sizeof
(tp), NULL, NULL);
25
fOk
=
(GetLastError()
==
ERROR_SUCCESS);
26
CloseHandle(hToken);
27
}
28
return
fOk;
//
提升成功返回TRUE,失败返回FALSE
29
}
30
31
void
main()
32
{
33
if
(EnableDebugPrivilege())
34
{
35
//
调用原API函数
36
::MessageBox(NULL,
"
原函数
"
,
"
Hook Api
"
,
0
);
37
//
挂钩后再调用
38
SetHook(::GetModuleHandle(NULL));
39
::MessageBox(NULL,
"
原函数
"
,
"
Hook Api
"
,
0
);
40
}
41
42
}
43
44
//
用于替换MessageBoxA的自定义函数
45
int
WINAPI MyMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
46
{
47
return
((PFNMESSAGEBOX)g_orgProc)(hWnd,
"
Hook API Sucess!
"
,
"
OK
"
, uType);
48
return
0
;
49
}
50
51
BOOL SetHook(HMODULE hMod)
52
{
53
IMAGE_DOS_HEADER
*
pDosHeader
=
(IMAGE_DOS_HEADER
*
)hMod;
54
IMAGE_OPTIONAL_HEADER
*
pOptHeader
=
55
(IMAGE_OPTIONAL_HEADER
*
)((BYTE
*
)hMod
+
pDosHeader
->
e_lfanew
+
24
);
56
57
IMAGE_IMPORT_DESCRIPTOR
*
pImportDesc
=
(IMAGE_IMPORT_DESCRIPTOR
*
)
58
((BYTE
*
)hMod
+
pOptHeader
->
DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
59
60
//
在导入表中查找user32.dll模块。因为MessageBoxA函数从user32.dll模块导出
61
while
(pImportDesc
->
FirstThunk)
62
{
63
char
*
pszDllName
=
(
char
*
)((BYTE
*
)hMod
+
pImportDesc
->
Name);
64
if
(lstrcmpiA(pszDllName,
"
user32.dll
"
)
==
0
)
65
{
66
break
;
67
}
68
pImportDesc
++
;
69
}
70
71
if
(pImportDesc
->
FirstThunk)
72
{
73
74
//
一个IMAGE_THUNK_DATA就是一个双字,它指定了一个导入函数
75
//
调入地址表其实是IMAGE_THUNK_DATA结构的数组,也就是DWORD数组
76
IMAGE_THUNK_DATA
*
pThunk
=
(IMAGE_THUNK_DATA
*
)
77
((BYTE
*
)hMod
+
pImportDesc
->
FirstThunk);
78
while
(pThunk
->
u1.Function)
79
{
80
//
lpAddr指向的内存保存了函数的地址
81
DWORD
*
lpAddr
=
(DWORD
*
)
&
(pThunk
->
u1.Function);
82
if
(
*
lpAddr
==
(DWORD)g_orgProc)
83
{
84
DWORD oldProc;
85
BOOL VirSu
=
VirtualProtect(lpAddr,
sizeof
(DWORD),PAGE_READWRITE,
&
oldProc);
86
if
(VirSu
==
TRUE)
87
{
88
//
修改IAT表项,使其指向我们自定义的函数,相当于“*lpAddr = (DWORD)MyMessageBoxA;”
89
DWORD
*
lpNewProc
=
(DWORD
*
)MyMessageBoxA;
90
::WriteProcessMemory(::GetCurrentProcess(),
91
lpAddr,
&
lpNewProc,
sizeof
(DWORD), NULL);
92
}
93
else
94
{
95
MessageBox(NULL,
"
Error!
"
,
"
a
"
,
0
);
96
}
97
return
TRUE;
98
}
99
pThunk
++
;
100
}
101
}
102
return
FALSE;
103
}
#include
<
windows.h
>
2
#include
<
stdio.h
>
3
4
//
挂钩指定模块hMod对MessageBoxA的调用
5
BOOL SetHook(HMODULE hMod);6
//
定义MessageBoxA函数原型
7
typedef
int
(WINAPI
*
PFNMESSAGEBOX)(HWND, LPCSTR, LPCSTR, UINT uType);8
//
保存MessageBoxA函数的真实地址
9
PROC g_orgProc
=
(PROC)MessageBoxA;10
11
12
BOOL EnableDebugPrivilege() 13
{ 14
BOOL fOk
=
FALSE; 15
HANDLE hToken; 16
17
if
(OpenProcessToken(GetCurrentProcess(), 18
TOKEN_ADJUST_PRIVILEGES,
&
hToken)) 19
{ 20
TOKEN_PRIVILEGES tp;21
tp.PrivilegeCount
=
1
; 22
LookupPrivilegeValue(NULL, SE_DEBUG_NAME,
&
tp.Privileges[
0
].Luid); 23
tp.Privileges[
0
].Attributes
=
SE_PRIVILEGE_ENABLED; 24
AdjustTokenPrivileges(hToken, FALSE,
&
tp,
sizeof
(tp), NULL, NULL); 25
fOk
=
(GetLastError()
==
ERROR_SUCCESS); 26
CloseHandle(hToken); 27
}
28
return
fOk;
//
提升成功返回TRUE,失败返回FALSE
29
}
30
31
void
main()32
{33
if
(EnableDebugPrivilege())34
{35
//
调用原API函数
36
::MessageBox(NULL,
"
原函数
"
,
"
Hook Api
"
,
0
);37
//
挂钩后再调用
38
SetHook(::GetModuleHandle(NULL));39
::MessageBox(NULL,
"
原函数
"
,
"
Hook Api
"
,
0
);40
}
41
42
}
43
44
//
用于替换MessageBoxA的自定义函数
45
int
WINAPI MyMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)46
{47
return
((PFNMESSAGEBOX)g_orgProc)(hWnd,
"
Hook API Sucess!
"
,
"
OK
"
, uType);48
return
0
;49
}
50
51
BOOL SetHook(HMODULE hMod)52
{53
IMAGE_DOS_HEADER
*
pDosHeader
=
(IMAGE_DOS_HEADER
*
)hMod;54
IMAGE_OPTIONAL_HEADER
*
pOptHeader
=
55
(IMAGE_OPTIONAL_HEADER
*
)((BYTE
*
)hMod
+
pDosHeader
->
e_lfanew
+
24
);56
57
IMAGE_IMPORT_DESCRIPTOR
*
pImportDesc
=
(IMAGE_IMPORT_DESCRIPTOR
*
)58
((BYTE
*
)hMod
+
pOptHeader
->
DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);59
60
//
在导入表中查找user32.dll模块。因为MessageBoxA函数从user32.dll模块导出
61
while
(pImportDesc
->
FirstThunk)62
{63
char
*
pszDllName
=
(
char
*
)((BYTE
*
)hMod
+
pImportDesc
->
Name);64
if
(lstrcmpiA(pszDllName,
"
user32.dll
"
)
==
0
)65
{66
break
;67
}
68
pImportDesc
++
;69
}
70
71
if
(pImportDesc
->
FirstThunk)72
{73
74
//
一个IMAGE_THUNK_DATA就是一个双字,它指定了一个导入函数75
//
调入地址表其实是IMAGE_THUNK_DATA结构的数组,也就是DWORD数组
76
IMAGE_THUNK_DATA
*
pThunk
=
(IMAGE_THUNK_DATA
*
)77
((BYTE
*
)hMod
+
pImportDesc
->
FirstThunk);78
while
(pThunk
->
u1.Function)79
{80
//
lpAddr指向的内存保存了函数的地址
81
DWORD
*
lpAddr
=
(DWORD
*
)
&
(pThunk
->
u1.Function);82
if
(
*
lpAddr
==
(DWORD)g_orgProc)83
{ 84
DWORD oldProc;85
BOOL VirSu
=
VirtualProtect(lpAddr,
sizeof
(DWORD),PAGE_READWRITE,
&
oldProc);86
if
(VirSu
==
TRUE)87
{88
//
修改IAT表项,使其指向我们自定义的函数,相当于“*lpAddr = (DWORD)MyMessageBoxA;”
89
DWORD
*
lpNewProc
=
(DWORD
*
)MyMessageBoxA;90
::WriteProcessMemory(::GetCurrentProcess(), 91
lpAddr,
&
lpNewProc,
sizeof
(DWORD), NULL);92
}
93
else
94
{95
MessageBox(NULL,
"
Error!
"
,
"
a
"
,
0
);96
}
97
return
TRUE;98
}
99
pThunk
++
;100
}
101
}
102
return
FALSE;103
}
有个郁闷的问题,在2003sp1下,不管是提升进程权限还是修改内存包含属性都成功!debug版本能成功!release就他娘的死不成功!郁闷死,遍寻高手无着落,暂时等着先。。。
本文介绍了一种在Windows环境下通过挂钩API实现自定义消息框显示的方法。具体步骤包括:提升进程调试权限、替换原生MessageBoxA函数为自定义实现、在导入表中找到并修改目标函数地址。
505

被折叠的 条评论
为什么被折叠?



