- 借用了海风月影的HookApi 0.5的一些思路;
- 又是一个APIHOOK,没什么特别的!能顺利完成任务,没有什么多余的!代码里用到了libdasm,去下载一个吧!
- 做成了一个类,构造对象的时候自动HOOK,析构的时候UnHook,注意一下实例的生存期就可以实现临时hook和全局hook。
使用例子,注意黄色部分:
1 typedef int (WINAPI *__pfnMessageBoxW)(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType);
2
3 int WINAPI MyMessageBoxW(DWORD RetAddr, __pfnMessageBoxW pfnLoadLibraryA, HWND hWnd, LPCWSTR lpText,
4 LPCWSTR lpCaption, UINT uType)
5 {
6 return pfnLoadLibraryA(hWnd,lpText,L"MyMessageBoxW",uType);
7 }
8
9 void Test()
10 {
11 {
12 CApiHook h("user32.dll","MessageBoxW",MyMessageBoxW);
13 MessageBoxW(this->m_hWnd,L"标题应该被修改了",L"标题",MB_OK);
14 }
15 MessageBoxW(this->m_hWnd,L"标题应该没有被修改了",L"标题",MB_OK);
16 }
ApiHook.h
1 #pragma once
2 typedef int (WINAPI *__pfnMessageBoxW)( HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType);
3 class CApiHook
4 {
5 protected:
6 bool m_bHooked;
7 PBYTE m_Stub;
8 int m_ReplaceCodeSize;
9 LPVOID m_pfnAPI;
10 public:
11 CApiHook(LPCTSTR lpLibName,LPCTSTR lpProcName,LPVOID lpHookProc);
12 ~CApiHook(void);
13 bool Hooked();
14 };
15
ApiHook.cpp
1 #include "ApiHook.h"
2 #include "libdasm.h"
3 #pragma comment( lib, "libdasmd.lib" )
4
5 //00 FF3424 push dword ptr [esp]
6 //03 FF3424 push dword ptr [esp]
7 //06 50 push eax
8 //07 E8 00000000 call 0C
9 //0C 58 pop eax
10 //0D 83C0 0E add eax, 0E
11 //10 894424 0C mov dword ptr [esp+C], eax
12 //14 58 pop eax
13 //15 E9 00000000 jmp 1A <== modify
14
15 const BYTE Stub_Temp[]=
16 {
17 //0 1 2 3 4 5 6 7 8 9 a b c d e f
18 0xFF,0x34,0x24,0xFF,0x34,0x24,0x50,0xE8,0x00,0x00,0x00,0x00,0x58,0x83,0xC0,0x0E,
19 0x89,0x44,0x24,0x0C,0x58,0xE9,0x00,0x00,0x00,0x00,0x90,0x90,0x90,0x90,0x90,0x90,
20 // ~~~~~~~~~~~~~~~~~~~
21 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90
22 };
23
24 #define JMP_MY_OFFSET (0x15)
25 #define ORG_HEAD_OFFSET (0x1a)
26 #define STUB_LENGTH (0x30)
27 CApiHook::CApiHook(LPCTSTR lpLibName,LPCTSTR lpProcName,LPVOID lpHookProc)
28 :m_bHooked(false)
29 ,m_Stub(NULL)
30 ,m_ReplaceCodeSize(0)
31 {
32 HMODULE hMod=GetModuleHandle(lpLibName);
33 if(hMod==NULL)
34 {
35 hMod=LoadLibrary(lpLibName);
36 }
37 if(hMod==NULL)
38 {
39 return;//取模块句柄失败
40 }
41 LPVOID pfnAPI;
42 pfnAPI=GetProcAddress(hMod,lpProcName);
43 if(pfnAPI==NULL)
44 {
45 return;//取API地址失败
46 }
47 INSTRUCTION inst;
48 int iReplaceCodeSize=0,il;
49 DWORD RetSize=0;
50 while(iReplaceCodeSize<5)
51 {
52 iReplaceCodeSize+=(il=get_instruction(&inst,(BYTE*)pfnAPI+iReplaceCodeSize,MODE_32));
53 if(il==0)
54 {
55 return;//解析指令失败
56 }
57 }
58 if(iReplaceCodeSize>16)
59 {
60 return;//超出预计的大小
61 }
62 m_Stub=(PBYTE)VirtualAlloc(NULL,STUB_LENGTH,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
63 if(m_Stub==NULL)
64 {
65 return;
66 }
67 __try
68 {
69 memcpy(m_Stub,Stub_Temp,sizeof(Stub_Temp));
70 if(ReadProcessMemory(GetCurrentProcess(),pfnAPI,&m_Stub[ORG_HEAD_OFFSET],iReplaceCodeSize,&RetSize)==0)
71 {
72 return;//保存原始API头失败
73 }
74 DWORD dwDelta;
75 //set my jump
76 dwDelta=(DWORD)lpHookProc-(DWORD)&m_Stub[JMP_MY_OFFSET+5];
77 *(DWORD*)&m_Stub[JMP_MY_OFFSET+1]=dwDelta;
78 //set org jmp
79 m_Stub[ORG_HEAD_OFFSET+iReplaceCodeSize]=0xe9;
80 dwDelta=((DWORD)pfnAPI+iReplaceCodeSize)-(DWORD)&m_Stub[ORG_HEAD_OFFSET+iReplaceCodeSize+5];
81 *(DWORD*)&m_Stub[ORG_HEAD_OFFSET+iReplaceCodeSize+1]=dwDelta;
82
83 //modify API entry
84 BYTE buf[8];
85 dwDelta=(DWORD)&m_Stub[0]-((DWORD)pfnAPI+5);
86 *(DWORD*)&buf[1]=dwDelta;
87 buf[0]=0xe9;
88 if(WriteProcessMemory(GetCurrentProcess(),pfnAPI,buf,5,&RetSize)==0)
89 {
90 return;
91 }
92 m_bHooked=true;
93 m_pfnAPI=pfnAPI;
94 m_ReplaceCodeSize=iReplaceCodeSize;
95 }
96 __finally
97 {
98 if(!Hooked())
99 {
100 VirtualFree(m_Stub,STUB_LENGTH,MEM_RELEASE);
101 m_Stub=NULL;
102 }
103 }
104 }
105
106 CApiHook::~CApiHook(void)
107 {
108 DWORD RetSize=0;
109 if(Hooked())
110 {
111 WriteProcessMemory(GetCurrentProcess(),m_pfnAPI,&m_Stub[ORG_HEAD_OFFSET],m_ReplaceCodeSize,&RetSize);
112 VirtualFree(m_Stub,STUB_LENGTH,MEM_RELEASE);
113 }
114 }
115
116 bool CApiHook::Hooked()
117 {
118 return m_bHooked;
119 }