forked from MadrisAkb/Valorant-External
-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.h
217 lines (182 loc) · 5.54 KB
/
utils.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
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
#pragma once
#include <Windows.h>
#include <iostream>
#include <winternl.h>
#include <ntstatus.h>
#include <atomic>
#include <mutex>
#include <TlHelp32.h>
#include <d3d9.h>
#include <dwmapi.h>
#include <xmmintrin.h>
#pragma comment(lib, "ntdll.lib")
#pragma comment(lib, "dwmapi.lib")
typedef enum _KEY_VALUE_INFORMATION_CLASS {
KeyValueBasicInformation,
KeyValueFullInformation,
KeyValuePartialInformation,
KeyValueFullInformationAlign64,
KeyValuePartialInformationAlign64,
KeyValueLayerInformation,
MaxKeyValueInfoClass // MaxKeyValueInfoClass should always be the last enum
} KEY_VALUE_INFORMATION_CLASS;
typedef struct _KEY_VALUE_FULL_INFORMATION {
ULONG TitleIndex;
ULONG Type;
ULONG DataOffset;
ULONG DataLength;
ULONG NameLength;
WCHAR Name[1]; // Variable size
// Data[1]; // Variable size data not declared
} KEY_VALUE_FULL_INFORMATION, * PKEY_VALUE_FULL_INFORMATION;
#ifdef __cplusplus
extern "C++"
{
char _RTL_CONSTANT_STRING_type_check(const char* s);
char _RTL_CONSTANT_STRING_type_check(const WCHAR* s);
// __typeof would be desirable here instead of sizeof.
template <size_t N> class _RTL_CONSTANT_STRING_remove_const_template_class;
template <> class _RTL_CONSTANT_STRING_remove_const_template_class<sizeof(char)> { public: typedef char T; };
template <> class _RTL_CONSTANT_STRING_remove_const_template_class<sizeof(WCHAR)> { public: typedef WCHAR T; };
#define _RTL_CONSTANT_STRING_remove_const_macro(s) \
(const_cast<_RTL_CONSTANT_STRING_remove_const_template_class<sizeof((s)[0])>::T*>(s))
}
#else
char _RTL_CONSTANT_STRING_type_check(const void* s);
#define _RTL_CONSTANT_STRING_remove_const_macro(s) (s)
#endif
#define RTL_CONSTANT_STRING(s) \
{ \
sizeof( s ) - sizeof( (s)[0] ), \
sizeof( s ) / sizeof(_RTL_CONSTANT_STRING_type_check(s)), \
_RTL_CONSTANT_STRING_remove_const_macro(s) \
}
extern "C" {
NTSYSAPI
NTSTATUS
NTAPI
ZwQueryValueKey(
_In_ HANDLE KeyHandle,
_In_ PUNICODE_STRING ValueName,
_In_ KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
_Out_writes_bytes_to_opt_(Length, *ResultLength) PVOID KeyValueInformation,
_In_ ULONG Length,
_Out_ PULONG ResultLength
);
NTSYSAPI
NTSTATUS
NTAPI
ZwClose(
_In_ HANDLE Handle
);
NTSYSAPI
NTSTATUS
NTAPI
ZwOpenKey(
_Out_ PHANDLE KeyHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ POBJECT_ATTRIBUTES ObjectAttributes
);
NTSYSAPI
NTSTATUS
NTAPI
ZwQueryValueKey(
_In_ HANDLE KeyHandle,
_In_ PUNICODE_STRING ValueName,
_In_ KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
_Out_writes_bytes_to_opt_(Length, *ResultLength) PVOID KeyValueInformation,
_In_ ULONG Length,
_Out_ PULONG ResultLength
);
NTSYSAPI
NTSTATUS
NTAPI
ZwSetValueKey(
_In_ HANDLE KeyHandle,
_In_ PUNICODE_STRING ValueName,
_In_opt_ ULONG TitleIndex,
_In_ ULONG Type,
_In_reads_bytes_opt_(DataSize) PVOID Data,
_In_ ULONG DataSize
);
NTSYSAPI NTSTATUS ZwCreateKey(
PHANDLE KeyHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
ULONG TitleIndex,
PUNICODE_STRING Class,
ULONG CreateOptions,
PULONG Disposition
);
}
namespace RegistryUtils
{
__forceinline ULONG GetKeyInfoSize(HANDLE hKey, PUNICODE_STRING Key)
{
NTSTATUS Status;
ULONG KeySize;
Status = ZwQueryValueKey(hKey, Key, KeyValueFullInformation, 0, 0, &KeySize);
if (Status == STATUS_BUFFER_TOO_SMALL || Status == STATUS_BUFFER_OVERFLOW)
return KeySize;
return 0;
}
template <typename type>
__forceinline type ReadRegistry(UNICODE_STRING RegPath, UNICODE_STRING Key)
{
HANDLE hKey;
OBJECT_ATTRIBUTES ObjAttr;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
InitializeObjectAttributes(&ObjAttr, &RegPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
Status = ZwOpenKey(&hKey, KEY_ALL_ACCESS, &ObjAttr);
if (NT_SUCCESS(Status))
{
ULONG KeyInfoSize = GetKeyInfoSize(hKey, &Key);
ULONG KeyInfoSizeNeeded;
if (KeyInfoSize == NULL)
{
ZwClose(hKey);
return 0;
}
PKEY_VALUE_FULL_INFORMATION pKeyInfo = (PKEY_VALUE_FULL_INFORMATION)malloc(KeyInfoSize);
RtlZeroMemory(pKeyInfo, KeyInfoSize);
Status = ZwQueryValueKey(hKey, &Key, KeyValueFullInformation, pKeyInfo, KeyInfoSize, &KeyInfoSizeNeeded);
if (!NT_SUCCESS(Status) || (KeyInfoSize != KeyInfoSizeNeeded))
{
ZwClose(hKey);
free(pKeyInfo);
return 0;
}
ZwClose(hKey);
free(pKeyInfo);
return *(type*)((LONG64)pKeyInfo + pKeyInfo->DataOffset);
}
return 0;
}
__forceinline bool WriteRegistry(UNICODE_STRING RegPath, UNICODE_STRING Key, PVOID Address, ULONG Type, ULONG Size)
{
bool Success = false;
HANDLE hKey;
OBJECT_ATTRIBUTES ObjAttr;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
InitializeObjectAttributes(&ObjAttr, &RegPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
Status = ZwOpenKey(&hKey, KEY_ALL_ACCESS, &ObjAttr);
if (NT_SUCCESS(Status))
{
Status = ZwSetValueKey(hKey, &Key, NULL, Type, Address, Size);
if (NT_SUCCESS(Status))
Success = true;
ZwClose(hKey);
}
else {
Status = ZwCreateKey(&hKey, KEY_ALL_ACCESS, &ObjAttr, 0, &RegPath, 0, 0);
if (NT_SUCCESS(Status))
{
Status = ZwSetValueKey(hKey, &Key, NULL, Type, Address, Size);
if (NT_SUCCESS(Status))
Success = true;
}
ZwClose(hKey);
}
return Success;
}
}