当源代码中引入了其它静态库(.lib),在没有静态Lib源码的前提下。需要修改某个函数的功能。下面一种通过更改函数跳转表的方式为函数打补丁,而不是修改Call指令。这样避免平衡函数栈。
1 #include <Windows.h>
2 #include <stdio.h>
3
4 BYTE arCode[10];
5
6 /*保存原函数指针*/
7 void SaveOldFunctionAddress(void* pFuncAddress)
8 {
9 BOOL bRtn =FALSE;
10 SIZE_T cbRead =0;
11
12 HANDLE hProcess =GetCurrentProcess();
13 bRtn =ReadProcessMemory(hProcess, (unsigned long*)(pFuncAddress), arCode, 5, &cbRead);
14 if( !bRtn )
15 {
16 unsigned long err;
17 err =GetLastError();
18 return;
19 }
20
21 return;
22 }
23
24 unsigned int WriteProcessMemExt(HANDLE hProcess, void *pBaseAddress, BYTE ucCmd, unsigned long dwData)
25 {
26 BYTE aBuf[10];
27 BOOL bRtn;
28 unsigned long cbWrite;
29
30 aBuf[0] =ucCmd;
31 aBuf[1] =(BYTE)(dwData & 0xFF);
32 aBuf[2] =(BYTE)( (dwData & 0xFF00)>>8 );
33 aBuf[3] =(BYTE)( (dwData & 0xFF0000)>>16 );
34 aBuf[4] =(BYTE)( (dwData & 0xFF000000)>>24 );
35 //修改原函数入口处指令,用上面准备的跳转指令修改
36 bRtn =WriteProcessMemory(hProcess, pBaseAddress, aBuf, 5, &cbWrite);
37 if( !bRtn )
38 {
39 unsigned long err;
40 err =GetLastError();
41 printf("%s \r\n", err);
42 }
43
44 return bRtn;
45 }
46
47 BOOL PatchAdd(void* pNewFunc, void* pOldFunc)
48 {
49 HANDLE hProcess =GetCurrentProcess();
50 //计算函数相对原函数的偏移
51 unsigned long ljumpoffset = (unsigned long)pNewFunc - (unsigned long)pOldFunc - 5;
52 BOOL bRtn =WriteProcessMemExt(hProcess, pOldFunc, 0xE9, (unsigned long)ljumpoffset );
53 if( !bRtn )
54 {
55 unsigned long err;
56 err =GetLastError();
57 printf("%s \r\n", err);
58 return FALSE;
59 }
60
61 return TRUE;
62 }
63
64 BOOL PatchDel(void* pOldFunc)
65 {
66 HANDLE hProcess =GetCurrentProcess();
67 BOOL bRtn =WriteProcessMemExt(hProcess, pOldFunc, arCode[0], *(unsigned long*)(arCode+1) );
68 if( !bRtn )
69 {
70 unsigned long err;
71 err =GetLastError();
72 printf("%s \r\n", err);
73 return FALSE;
74 }
75
76 return TRUE;
77 }
78
79 int old_fun(int i)
80 {
81 printf("old function\r\n");
82
83 return 0;
84 }
85
86 int new_fun(int i)
87 {
88 printf("new function\r\n");
89
90 return 0;
91 }
92
93 int main(void)
94 {
95 old_fun(1);
96 //保存原函数地址
97 SaveOldFunctionAddress(old_fun);
98 PatchAdd(new_fun,old_fun);
99 old_fun(1);
100 PatchDel(old_fun);
101 old_fun(1);
102
103 return 0;
104 }
105
为函数打补丁