/
hijack.h
153 lines (134 loc) · 5.46 KB
/
hijack.h
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include <windows.h>
#include <intrin.h>
#include <stdint.h>
namespace hijack
{
#define NOP_FUNC { \
__nop();\
__nop();\
__nop();\
__nop();\
__nop();\
__nop();\
__nop();\
__nop();\
__nop();\
__nop();\
__nop();\
__nop();\
return __COUNTER__;\
}
// 用 __COUNTER__ 来生成一点不一样的代码,避免被 VS 自动合并相同函数
#define EXPORT(api) int __cdecl api() NOP_FUNC
#pragma region 声明导出函数
// 声明导出函数
#pragma comment(linker, "/export:GetFileVersionInfoA=?GetFileVersionInfoA@hijack@@YAHXZ,@1")
#pragma comment(linker, "/export:GetFileVersionInfoByHandle=?GetFileVersionInfoByHandle@hijack@@YAHXZ,@2")
#pragma comment(linker, "/export:GetFileVersionInfoExA=?GetFileVersionInfoExA@hijack@@YAHXZ,@3")
#pragma comment(linker, "/export:GetFileVersionInfoExW=?GetFileVersionInfoExW@hijack@@YAHXZ,@4")
#pragma comment(linker, "/export:GetFileVersionInfoSizeA=?GetFileVersionInfoSizeA@hijack@@YAHXZ,@5")
#pragma comment(linker, "/export:GetFileVersionInfoSizeExA=?GetFileVersionInfoSizeExA@hijack@@YAHXZ,@6")
#pragma comment(linker, "/export:GetFileVersionInfoSizeExW=?GetFileVersionInfoSizeExW@hijack@@YAHXZ,@7")
#pragma comment(linker, "/export:GetFileVersionInfoSizeW=?GetFileVersionInfoSizeW@hijack@@YAHXZ,@8")
#pragma comment(linker, "/export:GetFileVersionInfoW=?GetFileVersionInfoW@hijack@@YAHXZ,@9")
#pragma comment(linker, "/export:VerFindFileA=?VerFindFileA@hijack@@YAHXZ,@10")
#pragma comment(linker, "/export:VerFindFileW=?VerFindFileW@hijack@@YAHXZ,@11")
#pragma comment(linker, "/export:VerInstallFileA=?VerInstallFileA@hijack@@YAHXZ,@12")
#pragma comment(linker, "/export:VerInstallFileW=?VerInstallFileW@hijack@@YAHXZ,@13")
#pragma comment(linker, "/export:VerLanguageNameA=?VerLanguageNameA@hijack@@YAHXZ,@14")
#pragma comment(linker, "/export:VerLanguageNameW=?VerLanguageNameW@hijack@@YAHXZ,@15")
#pragma comment(linker, "/export:VerQueryValueA=?VerQueryValueA@hijack@@YAHXZ,@16")
#pragma comment(linker, "/export:VerQueryValueW=?VerQueryValueW@hijack@@YAHXZ,@17")
EXPORT(GetFileVersionInfoA)
EXPORT(GetFileVersionInfoByHandle)
EXPORT(GetFileVersionInfoExA)
EXPORT(GetFileVersionInfoExW)
EXPORT(GetFileVersionInfoSizeA)
EXPORT(GetFileVersionInfoSizeExA)
EXPORT(GetFileVersionInfoSizeExW)
EXPORT(GetFileVersionInfoSizeW)
EXPORT(GetFileVersionInfoW)
EXPORT(VerFindFileA)
EXPORT(VerFindFileW)
EXPORT(VerInstallFileA)
EXPORT(VerInstallFileW)
EXPORT(VerLanguageNameA)
EXPORT(VerLanguageNameW)
EXPORT(VerQueryValueA)
EXPORT(VerQueryValueW)
}
#pragma endregion
#pragma region 还原导出函数
bool WriteMemory(PBYTE BaseAddress, PBYTE Buffer, DWORD nSize)
{
DWORD ProtectFlag = 0;
if (VirtualProtectEx(GetCurrentProcess(), BaseAddress, nSize, PAGE_EXECUTE_READWRITE, &ProtectFlag))
{
memcpy(BaseAddress, Buffer, nSize);
FlushInstructionCache(GetCurrentProcess(), BaseAddress, nSize);
VirtualProtectEx(GetCurrentProcess(), BaseAddress, nSize, ProtectFlag, &ProtectFlag);
return true;
}
return false;
}
// 还原导出函数
void InstallJMP(PBYTE BaseAddress, uintptr_t Function)
{
if (*BaseAddress == 0xE9)
{
BaseAddress++;
BaseAddress = BaseAddress + *(uint32_t*)BaseAddress + 4;
}
#ifdef _WIN64
BYTE move[] = {0x48, 0xB8};//move rax,xxL);
BYTE jump[] = {0xFF, 0xE0};//jmp rax
WriteMemory(BaseAddress, move, sizeof(move));
BaseAddress += sizeof(move);
WriteMemory(BaseAddress, (PBYTE)&Function, sizeof(uintptr_t));
BaseAddress += sizeof(uintptr_t);
WriteMemory(BaseAddress, jump, sizeof(jump));
#else
BYTE jump[] = {0xE9};
WriteMemory(BaseAddress, jump, sizeof(jump));
BaseAddress += sizeof(jump);
uintptr_t offset = Function - (uintptr_t)BaseAddress - 4;
WriteMemory(BaseAddress, (PBYTE)&offset, sizeof(offset));
#endif // _WIN64
}
#pragma endregion
#pragma region 加载系统dll
void LoadVersion(HINSTANCE hModule)
{
PBYTE pImageBase = (PBYTE)hModule;
PIMAGE_DOS_HEADER pimDH = (PIMAGE_DOS_HEADER)pImageBase;
if (pimDH->e_magic == IMAGE_DOS_SIGNATURE)
{
PIMAGE_NT_HEADERS pimNH = (PIMAGE_NT_HEADERS)(pImageBase + pimDH->e_lfanew);
if (pimNH->Signature == IMAGE_NT_SIGNATURE)
{
PIMAGE_EXPORT_DIRECTORY pimExD = (PIMAGE_EXPORT_DIRECTORY)(pImageBase + pimNH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
DWORD* pName = (DWORD*)(pImageBase + pimExD->AddressOfNames);
DWORD* pFunction = (DWORD*)(pImageBase + pimExD->AddressOfFunctions);
WORD* pNameOrdinals = (WORD*)(pImageBase + pimExD->AddressOfNameOrdinals);
wchar_t szSysDirectory[MAX_PATH + 1];
GetSystemDirectory(szSysDirectory, MAX_PATH);
wchar_t szDLLPath[MAX_PATH + 1];
lstrcpy(szDLLPath, szSysDirectory);
lstrcat(szDLLPath, TEXT("\\version.dll"));
HINSTANCE module = LoadLibrary(szDLLPath);
for (size_t i = 0; i < pimExD->NumberOfNames; i++)
{
uintptr_t Original = (uintptr_t)GetProcAddress(module, (char*)(pImageBase + pName[i]));
if (Original)
{
InstallJMP(pImageBase + pFunction[pNameOrdinals[i]], Original);
}
}
}
}
}
#pragma endregion
void LoadSysDll(HINSTANCE hModule)
{
LoadVersion(hModule);
}