-
Notifications
You must be signed in to change notification settings - Fork 6
/
WindowsFunction.inc
259 lines (203 loc) · 8.44 KB
/
WindowsFunction.inc
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
#if defined _MemoryEx_WindowsFunction_include_
#endinput
#endif
#define _MemoryEx_WindowsFunction_include_
#include <MemoryEx/Stocks>
#include <MemoryEx/PatternGenerator>
#define MEMORY_EX_WINAPI_MAX_ARGS 10
#define WINAPI_ARGS_COUNT(%0) %0
#define MEMORY_EX_WINAPI_RET_DEFAULT -2
#define MEMORY_EX_WINAPI_INVALID_FUNC -3
enum
{
WINAPI_FLAG_NONE = 0,
WINAPI_FLAG_NEED_RETURN
}
// for import table
#define CALC_STRUCT_OFFSET(%0) view_as<Address>(%0 * 0x04)
#define STRUCT_SIZE(%0) (sizeof(%0) * 0x04)
stock Address WindowsGetPEHeader(Address base)
{
return base + LoadFromAddressEx(base + view_as<Address>(0x3C), NumberType_Int32);
}
stock Address WindowsParsePEBHeader(Address base)
{
return LoadFromAddressEx(WindowsGetPEHeader(base) + view_as<Address>(0x50), NumberType_Int32); // NT->OptionalHeader.SizeOfImage
}
stock void GetWindowsVersion(int& iMajorVer, int& iMinorVer)
{
iMajorVer = LoadFromAddress(view_as<Address>(0x7FFE0000 + 0x26C), NumberType_Int32);
iMinorVer = LoadFromAddress(view_as<Address>(0x7FFE0000 + 0x270), NumberType_Int32);
}
stock Address GetPEB()
{
static Address pPEB;
static int PEBAsm[] =
{
0x64, 0xA1, 0x30, 0x00, 0x00, 0x00, // mov eax, dword ptr fs:[30]
0xC3 // ret
};
if(pPEB != Address_Null)
{
return pPEB;
}
int iOffset = FindSendPropInfo("CBaseEntity", "m_clrRender");
if(iOffset == -1)
{
SetFailState("hm... m_clrRender not found?");
}
int iEntity = CreateEntityByName("trigger_push"); // `trigger_push is a brush entity available in all Source games.` => https://developer.valvesoftware.com/wiki/Trigger_push
Address pEntity = GetEntityAddress(iEntity) + view_as<Address>(iOffset);
SetEntDataArray(iEntity, iOffset, PEBAsm, sizeof(PEBAsm), 1);
StoreToAddress(pEntity, PEBAsm[0], NumberType_Int8); // for => SourceHook::SetMemAccess(addr, sizeof(uint8_t), SH_MEM_READ|SH_MEM_WRITE|SH_MEM_EXEC);
pPEB = ASMSDKCall(pEntity);
AcceptEntityInput(iEntity, "Kill");
return pPEB;
}
stock StringMap WindowsGetDllList(bool bRefresh = false)
{
static StringMap list;
if(list == null)
{
list = new StringMap();
}
else if(bRefresh)
{
list.Clear();
}
else if(list.Size != 0)
{
return list;
}
Address PEB = GetPEB();
if(PEB == Address_Null)
{
return list;
}
char sLibrary[255];
Address pLdrData = view_as<Address>(LoadFromAddress(PEB + view_as<Address>(0x0C), NumberType_Int32)); // PPEB_LDR_DATA pldr_data = *(PPEB_LDR_DATA*)(peb + 0x0C);
Address pLdrCurrent = view_as<Address>(LoadFromAddress(pLdrData + view_as<Address>(0x10), NumberType_Int32) - 0x08); //(PLDR_DATA_TABLE_ENTRY)((UINT)pldr_data->InInitializationOrderModuleList.Blink - 0x08);
//Address pLdrPrev = LoadFromAddress(pLdrData + 0x0C, NumberType_Int32) - 0x08; // pldr_prev = (PMemoryExLoadedTableEntry)((UINT)pldr_data->InLoadOrderModuleList.Flink - 0x08);
Address pLdrFirst = pLdrCurrent;
int iBase;
int tmp[2]; // enum struct hack
do
{
iBase = LoadFromAddress(pLdrCurrent + view_as<Address>(0x20), NumberType_Int32);
if(iBase) // if (pldr_current->DllBase != NULL)
{
ReadUnicodeString(view_as<Address>(LoadFromAddress(pLdrCurrent + view_as<Address>(0x30), NumberType_Int32)), sLibrary, sizeof sLibrary); // pldr_current->FullDllName.Buffer
for(int x = strlen(sLibrary) - 1; x >= 0; x--)
{
if(sLibrary[x] == '\\')
{
strcopy(sLibrary, sizeof sLibrary, sLibrary[x + 1]);
break;
}
sLibrary[x] = CharToLower(sLibrary[x]);
}
tmp[0] = iBase;
tmp[1] = view_as<int>(WindowsParsePEBHeader(view_as<Address>(iBase)));
list.SetArray(sLibrary, tmp, sizeof(tmp));
}
//pLdrPrev = pLdrCurrent;
pLdrCurrent = view_as<Address>(LoadFromAddress(pLdrCurrent + view_as<Address>(0x0C), NumberType_Int32) - 0x08);
}
while(pLdrCurrent != pLdrFirst);
return list;
}
//My thread with an analysis of all this
//https://hlmod.ru/threads/urok-chtenie-import-table-s-pomoschju-sourcepawn.52289/
enum struct ImportDiscription
{
Address originalFirstThunk;
int timeDateStamp;
int forwarderChaine;
Address dllName;
Address firstThunk;
void FillInfo(Address base, Address addr)
{
this.originalFirstThunk = base + view_as<Address>(LoadFromAddress(addr + CALC_STRUCT_OFFSET(ImportDiscription::originalFirstThunk), NumberType_Int32));
this.timeDateStamp = LoadFromAddress(addr + CALC_STRUCT_OFFSET(ImportDiscription::timeDateStamp), NumberType_Int32);
this.forwarderChaine = LoadFromAddress(addr + CALC_STRUCT_OFFSET(ImportDiscription::forwarderChaine), NumberType_Int32);
this.dllName = base + view_as<Address>(LoadFromAddress(addr + CALC_STRUCT_OFFSET(ImportDiscription::dllName), NumberType_Int32));
this.firstThunk = base + view_as<Address>(LoadFromAddress(addr + CALC_STRUCT_OFFSET(ImportDiscription::firstThunk), NumberType_Int32));
}
void GetName(char[] sBuffer, int iMaxLength)
{
ReadString(this.dllName, sBuffer, iMaxLength);
}
}
stock Address GetImportAddressWindows(Address pBase, const char[] sName )
{
Address PE = pBase + view_as<Address>(LoadFromAddress(pBase + view_as<Address>(0x3C), NumberType_Int32));
Address importTable = pBase + view_as<Address>(LoadFromAddress(PE + view_as<Address>(0x80), NumberType_Int32));
Address importTableSize = view_as<Address>(LoadFromAddress(PE + view_as<Address>(0x84), NumberType_Int32));
int iSize = view_as<int>(importTableSize) / STRUCT_SIZE(ImportDiscription);
ImportDiscription disc;
//char sDll[64];
char sFunction[256];
for(int x = 0; x < iSize; x++)
{
Address addr = importTable + view_as<Address>((STRUCT_SIZE(ImportDiscription) * x));
disc.FillInfo(pBase, addr);
//disc.GetName(sDll, sizeof sDll);
for(Address offset = Address_Null; offset >= Address_Null; offset += view_as<Address>(0x04)) // endless cycle
{
Address pFunctionStr = view_as<Address>(LoadFromAddress(disc.originalFirstThunk + offset, NumberType_Int32));
if(pFunctionStr == Address_Null)
{
break;
}
pFunctionStr += pBase;
ReadString(pFunctionStr + view_as<Address>(0x02), sFunction, sizeof sFunction);
if(!strcmp(sName, sFunction))
{
return view_as<Address>(LoadFromAddress(disc.firstThunk + offset, NumberType_Int32));
}
}
}
return Address_Null;
}
/*
.rdata:10047E50 ; Export directory for tier0.dll
.rdata:10047E50 ;
.rdata:10047E50 00 00 00 00 dd 0 ; Characteristics
.rdata:10047E54 20 A2 83 5E dd 5E83A220h ; TimeDateStamp: Tue Mar 31 20:03:44 2020
.rdata:10047E58 00 00 dw 0 ; MajorVersion
.rdata:10047E5A 00 00 dw 0 ; MinorVersion
.rdata:10047E5C C6 94 04 00 dd rva aTier0Dll ; Name
.rdata:10047E60 01 00 00 00 dd 1 ; Base
.rdata:10047E64 3B 02 00 00 dd 23Bh ; NumberOfFunctions
.rdata:10047E68 3B 02 00 00 dd 23Bh ; NumberOfNames
.rdata:10047E6C 78 7E 04 00 dd rva off_10047E78 ; AddressOfFunctions
.rdata:10047E70 64 87 04 00 dd rva off_10048764 ; AddressOfNames
.rdata:10047E74 50 90 04 00 dd rva word_10049050 ; AddressOfNameOrdinals
*/
stock Address GetProcAddressWindows(Address pBase, const char[] sName)
{
Address pExportTable = pBase + LoadFromAddressEx(WindowsGetPEHeader(pBase) + view_as<Address>(0x78), NumberType_Int32);
int iNumFunc = LoadFromAddress(pExportTable + view_as<Address>(0x14), NumberType_Int32);
Address pFunctions = pBase + LoadFromAddressEx(pExportTable + view_as<Address>(0x1C), NumberType_Int32);
Address pNames = pBase + LoadFromAddressEx(pExportTable + view_as<Address>(0x20), NumberType_Int32);
Address pOrdinals = pBase + LoadFromAddressEx(pExportTable + view_as<Address>(0x24), NumberType_Int32);
static char sExport[512];
Address pStr;
int iBytes;
int iStrLen = strlen(sName);
int iOrdinal;
for(int x = 0; x < iNumFunc; x++)
{
pStr = pBase + LoadFromAddressEx(pNames + view_as<Address>(x * 0x04), NumberType_Int32);
iBytes = ReadString(pStr, sExport, sizeof sExport);
if(iBytes == iStrLen)
{
if(!strcmp(sName, sExport))
{
iOrdinal = LoadFromAddress(pOrdinals + view_as<Address>(x * 0x02), NumberType_Int16);
return pBase + LoadFromAddressEx(pFunctions + view_as<Address>(iOrdinal * 0x04), NumberType_Int32);
}
}
}
return Address_Null;
}