forked from noah-/d2bs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Offset.cpp
124 lines (99 loc) · 3.74 KB
/
Offset.cpp
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
#define _DEFINE_VARS
#define __D2PTRS_ONCE_
#include "D2Ptrs.h"
#undef __D2PTRS_H__
#define __D2PTRS_LIST_
#include "D2Ptrs.h"
#include "Patch.h"
#include "D2BS.h"
#ifndef ArraySize
#define ArraySize(x) (sizeof((x)) / sizeof((x)[0]))
#endif
void DefineOffsets() {
DWORD** p = (DWORD**)d2ptrs_list;
do {
**p = GetDllOffset(**p);
} while (ptrdiff_t(++p) < ((ptrdiff_t)d2ptrs_list) + sizeof(d2ptrs_list));
}
DWORD GetDllOffset(char* DllName, int Offset) {
HMODULE hMod = GetModuleHandle(NULL);
if (Offset < 0)
return (DWORD)GetProcAddress(hMod, (LPCSTR)(-Offset));
return ((DWORD)hMod) + Offset;
}
DWORD GetDllOffset(int num) {
static char* dlls[] = {"D2Client.DLL", "D2Common.DLL", "D2Gfx.DLL", "D2Lang.DLL", "D2Win.DLL", "D2Net.DLL", "D2Game.DLL",
"D2Launch.DLL", "Fog.DLL", "BNClient.DLL", "Storm.DLL", "D2Cmp.DLL", "D2Multi.DLL"};
if ((num & 0xff) > 12)
return 0;
return GetDllOffset(dlls[num & 0xff], num >> 8);
}
void InstallPatches() {
for (int x = 0; x < ArraySize(Patches); x++) {
Patches[x].bOldCode = new BYTE[Patches[x].dwLen];
::ReadProcessMemory(GetCurrentProcess(), (void*)Patches[x].dwAddr, Patches[x].bOldCode, Patches[x].dwLen, NULL);
Patches[x].pFunc(Patches[x].dwAddr, Patches[x].dwFunc, Patches[x].dwLen);
}
}
void RemovePatches() {
for (int x = 0; x < ArraySize(Patches); x++) {
WriteBytes((void*)Patches[x].dwAddr, Patches[x].bOldCode, Patches[x].dwLen);
delete[] Patches[x].bOldCode;
}
}
void InstallConditional() {
for (int x = 0; x < ArraySize(Conditional); x++) {
if (Conditional[x].enabled == NULL || *Conditional[x].enabled != TRUE) {
continue;
}
Conditional[x].bOldCode = new BYTE[Conditional[x].dwLen];
::ReadProcessMemory(GetCurrentProcess(), (void*)Conditional[x].dwAddr, Conditional[x].bOldCode, Conditional[x].dwLen, NULL);
Conditional[x].pFunc(Conditional[x].dwAddr, Conditional[x].dwFunc, Conditional[x].dwLen);
}
}
void RemoveConditional() {
for (int x = 0; x < ArraySize(Conditional); x++) {
if (Conditional[x].enabled == NULL || *Conditional[x].enabled != TRUE)
continue;
WriteBytes((void*)Conditional[x].dwAddr, Conditional[x].bOldCode, Conditional[x].dwLen);
delete[] Conditional[x].bOldCode;
}
}
BOOL WriteBytes(void* pAddr, void* pData, DWORD dwLen) {
DWORD dwOld;
if (!VirtualProtect(pAddr, dwLen, PAGE_READWRITE, &dwOld))
return FALSE;
::memcpy(pAddr, pData, dwLen);
return VirtualProtect(pAddr, dwLen, dwOld, &dwOld);
}
void FillBytes(void* pAddr, BYTE bFill, DWORD dwLen) {
BYTE* bCode = new BYTE[dwLen];
::memset(bCode, bFill, dwLen);
WriteBytes(pAddr, bCode, dwLen);
delete[] bCode;
}
void InterceptLocalCode(BYTE bInst, DWORD pAddr, DWORD pFunc, DWORD dwLen) {
BYTE* bCode = new BYTE[dwLen];
::memset(bCode, 0x90, dwLen);
DWORD dwFunc = pFunc - (pAddr + 5);
bCode[0] = bInst;
*(DWORD*)&bCode[1] = dwFunc;
WriteBytes((void*)pAddr, bCode, dwLen);
delete[] bCode;
}
void PatchCall(DWORD dwAddr, DWORD dwFunc, DWORD dwLen) {
InterceptLocalCode(INST_CALL, dwAddr, dwFunc, dwLen);
}
void PatchJmp(DWORD dwAddr, DWORD dwFunc, DWORD dwLen) {
InterceptLocalCode(INST_JMP, dwAddr, dwFunc, dwLen);
}
void PatchBytes(DWORD dwAddr, DWORD dwValue, DWORD dwLen) {
BYTE* bCode = new BYTE[dwLen];
::memset(bCode, (BYTE)dwValue, dwLen);
WriteBytes((LPVOID)dwAddr, bCode, dwLen);
delete[] bCode;
}
PatchHook* RetrievePatchHooks(PINT pBuffer) {
*pBuffer = ArraySize(Patches);
return &Patches[0];
}