├── sample
├── hook
│ ├── hyperhook.lib
│ ├── hook.vcxproj.user
│ ├── pch.cpp
│ ├── hyperhook.h
│ ├── pch.h
│ ├── hook.vcxproj.filters
│ ├── dllmain.cpp
│ └── hook.vcxproj
├── x64
│ └── Release
│ │ ├── hook.dll
│ │ └── lul.exe
├── lul
│ ├── asm.asm
│ ├── lul.vcxproj.user
│ ├── lul.vcxproj.filters
│ ├── lul.cpp
│ ├── lul.vcxproj
│ ├── xorstr.hpp
│ └── peb.h
└── lul.sln
├── README.md
└── qiling
└── analyze.py
/sample/hook/hyperhook.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/momo5502/drm-analysis/HEAD/sample/hook/hyperhook.lib
--------------------------------------------------------------------------------
/sample/x64/Release/hook.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/momo5502/drm-analysis/HEAD/sample/x64/Release/hook.dll
--------------------------------------------------------------------------------
/sample/x64/Release/lul.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/momo5502/drm-analysis/HEAD/sample/x64/Release/lul.exe
--------------------------------------------------------------------------------
/sample/lul/asm.asm:
--------------------------------------------------------------------------------
1 | .code
2 |
3 | InlineNtQueryInformationProcess PROC
4 | mov r10, rcx
5 | mov eax, 19h
6 | syscall
7 | ret
8 | InlineNtQueryInformationProcess ENDP
9 |
10 | end
11 |
--------------------------------------------------------------------------------
/sample/hook/hook.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/sample/lul/lul.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/sample/hook/pch.cpp:
--------------------------------------------------------------------------------
1 | // pch.cpp: Quelldatei, die dem vorkompilierten Header entspricht
2 |
3 | #include "pch.h"
4 |
5 | // Bei der Verwendung vorkompilierter Header ist diese Quelldatei für eine erfolgreiche Kompilierung erforderlich.
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Analyzing modern DRMs
2 | Material acompanying the guest lecture at Ruhr-Universität Bochum.
3 |
4 | ## Slides
5 | * https://docs.google.com/presentation/d/17TXl_pds6BC0Zm2gLUnIZK7BtlGc_TRt/edit
6 |
7 | ## Recording
8 | * https://www.youtube.com/watch?v=AEvpYgzDATA
9 |
10 | ## Links:
11 | * https://qiling.io
12 | * https://github.com/momo5502/hypervisor
13 | * https://hyperdbg.org/
14 |
--------------------------------------------------------------------------------
/sample/hook/hyperhook.h:
--------------------------------------------------------------------------------
1 | #ifndef EXTERN_C
2 | #ifdef __cplusplus
3 | #define EXTERN_C extern "C"
4 | #else
5 | #define EXTERN_C
6 | #endif
7 | #endif
8 |
9 | #ifndef DLL_IMPORT
10 | #define DLL_IMPORT __declspec(dllimport)
11 | #endif
12 |
13 | EXTERN_C DLL_IMPORT
14 | int hyperhook_initialize();
15 |
16 | EXTERN_C DLL_IMPORT
17 | int hyperhook_write(unsigned int process_id, unsigned long long address, const void* data,
18 | unsigned long long size);
19 |
20 | #pragma comment(lib, "hyperhook.lib")
21 |
--------------------------------------------------------------------------------
/sample/hook/pch.h:
--------------------------------------------------------------------------------
1 | // pch.h: Dies ist eine vorkompilierte Headerdatei.
2 | // Die unten aufgeführten Dateien werden nur einmal kompiliert, um die Buildleistung für zukünftige Builds zu verbessern.
3 | // Dies wirkt sich auch auf die IntelliSense-Leistung aus, Codevervollständigung und viele Features zum Durchsuchen von Code eingeschlossen.
4 | // Die hier aufgeführten Dateien werden jedoch ALLE neu kompiliert, wenn mindestens eine davon zwischen den Builds aktualisiert wird.
5 | // Fügen Sie hier keine Dateien hinzu, die häufig aktualisiert werden sollen, da sich so der Leistungsvorteil ins Gegenteil verkehrt.
6 |
7 | #ifndef PCH_H
8 | #define PCH_H
9 |
10 | // Fügen Sie hier Header hinzu, die vorkompiliert werden sollen.
11 | #include "framework.h"
12 |
13 | #endif //PCH_H
14 |
--------------------------------------------------------------------------------
/qiling/analyze.py:
--------------------------------------------------------------------------------
1 | from qiling import Qiling
2 | from qiling.const import QL_VERBOSE
3 |
4 | from unicorn.x86_const import *
5 |
6 | def hook_syscall(ql: Qiling):
7 | ql.log.debug(f'!!! SYSCALL {ql.arch.regs.arch_pc:#x}: {ql.arch.regs.eax:#x}')
8 | return (0, 0)
9 |
10 | def mem_read(ql: Qiling, access: int, address: int, size: int, value: int):
11 | ql.log.debug(f'intercepted a memory read from {address:#x} at {ql.arch.regs.arch_pc:#x}')
12 |
13 | if __name__ == "__main__":
14 | ql = Qiling(["C:\\Users\\mauri\\Desktop\\qiling-sample\\lul.exe"],
15 | "C:\\Users\\mauri\\Desktop\\qiling-sample", verbose=QL_VERBOSE.DEBUG, libcache=True)
16 |
17 | ql.hook_mem_read(mem_read)
18 | ql.hook_insn(hook_syscall, UC_X86_INS_SYSCALL)
19 |
20 | ql.run()
21 |
--------------------------------------------------------------------------------
/sample/lul/lul.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Quelldateien
20 |
21 |
22 |
23 |
24 | Quelldateien
25 |
26 |
27 |
--------------------------------------------------------------------------------
/sample/hook/hook.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Headerdateien
20 |
21 |
22 | Headerdateien
23 |
24 |
25 |
26 |
27 | Quelldateien
28 |
29 |
30 | Quelldateien
31 |
32 |
33 |
--------------------------------------------------------------------------------
/sample/lul.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.9.34723.18
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lul", "lul\lul.vcxproj", "{6061641D-671E-4A1B-BCB9-070D57D87CD0}"
7 | EndProject
8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hook", "hook\hook.vcxproj", "{1C5F4FCF-8744-450F-863D-923716431557}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|x64 = Debug|x64
13 | Debug|x86 = Debug|x86
14 | Release|x64 = Release|x64
15 | Release|x86 = Release|x86
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {6061641D-671E-4A1B-BCB9-070D57D87CD0}.Debug|x64.ActiveCfg = Debug|x64
19 | {6061641D-671E-4A1B-BCB9-070D57D87CD0}.Debug|x64.Build.0 = Debug|x64
20 | {6061641D-671E-4A1B-BCB9-070D57D87CD0}.Debug|x86.ActiveCfg = Debug|Win32
21 | {6061641D-671E-4A1B-BCB9-070D57D87CD0}.Debug|x86.Build.0 = Debug|Win32
22 | {6061641D-671E-4A1B-BCB9-070D57D87CD0}.Release|x64.ActiveCfg = Release|x64
23 | {6061641D-671E-4A1B-BCB9-070D57D87CD0}.Release|x64.Build.0 = Release|x64
24 | {6061641D-671E-4A1B-BCB9-070D57D87CD0}.Release|x86.ActiveCfg = Release|Win32
25 | {6061641D-671E-4A1B-BCB9-070D57D87CD0}.Release|x86.Build.0 = Release|Win32
26 | {1C5F4FCF-8744-450F-863D-923716431557}.Debug|x64.ActiveCfg = Debug|x64
27 | {1C5F4FCF-8744-450F-863D-923716431557}.Debug|x64.Build.0 = Debug|x64
28 | {1C5F4FCF-8744-450F-863D-923716431557}.Debug|x86.ActiveCfg = Debug|Win32
29 | {1C5F4FCF-8744-450F-863D-923716431557}.Debug|x86.Build.0 = Debug|Win32
30 | {1C5F4FCF-8744-450F-863D-923716431557}.Release|x64.ActiveCfg = Release|x64
31 | {1C5F4FCF-8744-450F-863D-923716431557}.Release|x64.Build.0 = Release|x64
32 | {1C5F4FCF-8744-450F-863D-923716431557}.Release|x86.ActiveCfg = Release|Win32
33 | {1C5F4FCF-8744-450F-863D-923716431557}.Release|x86.Build.0 = Release|Win32
34 | EndGlobalSection
35 | GlobalSection(SolutionProperties) = preSolution
36 | HideSolutionNode = FALSE
37 | EndGlobalSection
38 | GlobalSection(ExtensibilityGlobals) = postSolution
39 | SolutionGuid = {8EFF6206-9C12-40B1-9077-FE736627B2A0}
40 | EndGlobalSection
41 | EndGlobal
42 |
--------------------------------------------------------------------------------
/sample/hook/dllmain.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 | #include
3 | #include
4 | #include
5 |
6 | #include "hyperhook.h"
7 | #include "../lul/peb.h"
8 |
9 | NTSTATUS custom_query_process_information_hook(HANDLE,
10 | PROCESSINFOCLASS,
11 | uint8_t* ProcessInformation, ULONG,
12 | PULONG)
13 | {
14 | puts("!!! Hook triggered");
15 |
16 | auto* desired_string = L"C:\\Users\\mauri\\source\\repos\\lul\\x64\\Release\\lul.exe";
17 |
18 | auto* res = reinterpret_cast(ProcessInformation);
19 | res->Buffer = reinterpret_cast(res + 1);
20 | res->Length = wcslen(desired_string) * 2;
21 | res->MaximumLength = res->Length;
22 |
23 | memcpy(res->Buffer, desired_string, res->Length);
24 |
25 | return 0;
26 | }
27 |
28 | std::vector get_jump_bytes(void* address)
29 | {
30 | std::vector bytes{
31 | 0x48, 0xb8, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, // mov rax, 0x1122334455667788
32 | 0xff, 0xe0, // jmp rax
33 | };
34 |
35 | memcpy(bytes.data() + 2, &address, sizeof(address));
36 |
37 | return bytes;
38 | }
39 |
40 | void write_bytes_regularly(void* place, const std::vector& bytes)
41 | {
42 | DWORD old_protect{};
43 | VirtualProtect(place, bytes.size(), PAGE_EXECUTE_READWRITE, &old_protect);
44 |
45 | memcpy(place, bytes.data(), bytes.size());
46 |
47 | VirtualProtect(place, bytes.size(), old_protect, &old_protect);
48 | }
49 |
50 | void write_bytes_with_hypervisor(void* place, const std::vector& bytes)
51 | {
52 | hyperhook_write(GetCurrentProcessId(), reinterpret_cast(place), bytes.data(), bytes.size());
53 | }
54 |
55 | void insert_hook(uint64_t address, void* target, const bool using_hypervisor)
56 | {
57 | auto* place = reinterpret_cast(address);
58 | const auto bytes = get_jump_bytes(target);
59 |
60 | if (using_hypervisor)
61 | {
62 | write_bytes_with_hypervisor(place, bytes);
63 | }
64 | else
65 | {
66 | write_bytes_regularly(place, bytes);
67 | }
68 | }
69 |
70 | void run()
71 | {
72 | puts("");
73 | puts("Hook DLL loaded");
74 | puts("Use hypervisor for hooks? (y/n)");
75 | const auto use_hypervisor = _getch() == 'y';
76 |
77 | if(use_hypervisor)
78 | {
79 | puts("Using hypervisor...");
80 | }else
81 | {
82 | puts("Using regular hooks...");
83 | }
84 |
85 | insert_hook(0x14004FAE8, &custom_query_process_information_hook, use_hypervisor);
86 |
87 | puts("");
88 | }
89 |
90 | BOOL APIENTRY DllMain(HMODULE hModule,
91 | DWORD ul_reason_for_call,
92 | LPVOID lpReserved
93 | )
94 | {
95 | if (ul_reason_for_call == DLL_PROCESS_ATTACH)
96 | {
97 | run();
98 | }
99 |
100 | return TRUE;
101 | }
102 |
--------------------------------------------------------------------------------
/sample/lul/lul.cpp:
--------------------------------------------------------------------------------
1 | #define JM_XORSTR_DISABLE_AVX_INTRINSICS 1
2 |
3 | #include
4 |
5 | #include "peb.h"
6 | #include "xorstr.hpp"
7 |
8 |
9 | #define LOAD_STR(x) (xorstr_(x))
10 |
11 | EXTERN_C IMAGE_DOS_HEADER __ImageBase;
12 |
13 | // Adapt the hash in the compiled binary
14 | volatile uint32_t theHash = 0x12345678;
15 |
16 | // Adapt the value to the desired path
17 | #define EXPECTED_FILENAME LOAD_STR("C:\\Users\\mauri\\source\\repos\\lul\\x64\\Release\\lul.exe")
18 |
19 | extern "C" NTSTATUS __stdcall InlineNtQueryInformationProcess(HANDLE ProcessHandle,
20 | PROCESSINFOCLASS ProcessInformationClass,
21 | PVOID ProcessInformation, ULONG ProcessInformationLength,
22 | PULONG ReturnLength);
23 |
24 | namespace
25 | {
26 | FORCEINLINE bool str_equal(const char* s1, const char* s2)
27 | {
28 | for (size_t i = 0;; ++i)
29 | {
30 | if (s1[i] != s2[i])
31 | {
32 | return false;
33 | }
34 |
35 | if (s1[i] == 0)
36 | {
37 | break;
38 | }
39 | }
40 |
41 | return true;
42 | }
43 |
44 | FORCEINLINE uint32_t jenkins_one_at_a_time_hash(const uint8_t* key, const size_t length)
45 | {
46 | size_t i = 0;
47 | uint32_t hash = 0;
48 | while (i != length)
49 | {
50 | hash += key[i++];
51 | hash += hash << 10;
52 | hash ^= hash >> 6;
53 | }
54 | hash += hash << 3;
55 | hash ^= hash >> 11;
56 | hash += hash << 15;
57 | return hash;
58 | }
59 |
60 | FORCEINLINE std::pair get_text_section()
61 | {
62 | auto* base = reinterpret_cast(&__ImageBase);
63 | auto* nt_headers = reinterpret_cast(base + __ImageBase.e_lfanew);
64 |
65 | auto section = IMAGE_FIRST_SECTION(nt_headers);
66 |
67 | for (uint16_t i = 0; i < nt_headers->FileHeader.NumberOfSections; ++i, ++section)
68 | {
69 | if (str_equal(reinterpret_cast(section->Name), ".text"))
70 | {
71 | return {base + section->VirtualAddress, section->Misc.VirtualSize};
72 | }
73 | }
74 |
75 | return {nullptr, 0};
76 | }
77 |
78 | FORCEINLINE uint32_t compute_text_hash()
79 | {
80 | const auto [addr, size] = get_text_section();
81 | return jenkins_one_at_a_time_hash(addr, size);
82 | }
83 |
84 | FORCEINLINE bool is_integrity_violated()
85 | {
86 | const auto computed = compute_text_hash();
87 |
88 | printf(LOAD_STR("Checksum: %08X\n"), computed);
89 | printf(LOAD_STR("Expected: %08X\n"), theHash);
90 | return computed != theHash;
91 | }
92 |
93 | FORCEINLINE void fill_module_filename(char* buffer, const size_t size)
94 | {
95 | if (size == 0) return;
96 |
97 | char totalBuffer[0x1024];
98 | auto* str = reinterpret_cast(totalBuffer);
99 |
100 | ULONG retLength{0};
101 | const auto res = InlineNtQueryInformationProcess(reinterpret_cast(0xFFFFFFFFFFFFFFFF),
102 | ProcessImageFileNameWin32, &totalBuffer, sizeof(totalBuffer),
103 | &retLength);
104 | if (res != 0)
105 | {
106 | buffer[0] = 0;
107 | return;
108 | }
109 |
110 | size_t i = 0;
111 | for (; i < (str->Length / 2) && i < (size - 1); ++i)
112 | {
113 | buffer[i] = static_cast(str->Buffer[i]);
114 | }
115 |
116 | buffer[i] = 0;
117 | }
118 |
119 | template
120 | FORCEINLINE void fill_module_filename(char (&buffer)[Size])
121 | {
122 | fill_module_filename(buffer, Size);
123 | }
124 |
125 | FORCEINLINE bool was_copied()
126 | {
127 | char filename[MAX_PATH];
128 | fill_module_filename(filename);
129 |
130 | printf(LOAD_STR("Filename: %s\n"), filename);
131 | printf(LOAD_STR("Expected: %s\n"), EXPECTED_FILENAME);
132 |
133 | return !str_equal(filename, EXPECTED_FILENAME);
134 | }
135 |
136 | FORCEINLINE void stuff()
137 | {
138 | puts(LOAD_STR("Loading hook.dll..."));
139 | LoadLibraryA(LOAD_STR("hook.dll"));
140 |
141 | bool valid = true;
142 |
143 | puts("");
144 |
145 | if (is_integrity_violated())
146 | {
147 | puts(LOAD_STR(" -> Integrity violation!"));
148 | valid = false;
149 | }
150 |
151 | puts("");
152 |
153 | if (was_copied())
154 | {
155 | puts(LOAD_STR(" -> You copied the program"));
156 | valid = false;
157 | }
158 |
159 | puts("");
160 |
161 | if (!valid)
162 | {
163 | puts(LOAD_STR("Something's wrong."));
164 | return;
165 |
166 | }
167 |
168 | puts(LOAD_STR("Yay program is running!"));
169 | }
170 |
171 | // This essentially does nothing.
172 | // Its only purpose is to look confusing in IDA to simulate obfuscation.
173 |
174 | template
175 | FORCEINLINE bool decisionMaker(volatile unsigned int* num)
176 | {
177 | if constexpr (Count == 0)
178 | {
179 | return *num == 3;
180 | }
181 |
182 | if constexpr (Count == 1)
183 | {
184 | return *num & 100;
185 | }
186 |
187 | if constexpr (Count > 2)
188 | {
189 | if (*num == 3)
190 | {
191 | *num ^= Count;
192 | return decisionMaker(num);
193 | }
194 |
195 | if constexpr (Count < 5)
196 | {
197 | if (*num > 40)
198 | {
199 | *num = ~Count;
200 | return decisionMaker(num);
201 | }
202 | }
203 |
204 |
205 | if (Count % 4 && *num > 4)
206 | {
207 | constexpr auto newCount = Count >> 1;
208 | return decisionMaker(num);
209 | }
210 |
211 | if (*num % Count == 0)
212 | {
213 | *num = (*num & ~3) ^ ~Count;
214 | return decisionMaker(num);
215 | }
216 |
217 | ++*num;
218 |
219 | return decisionMaker(num) ^ decisionMaker(num);
220 | }
221 |
222 | return true;
223 | }
224 | }
225 |
226 | int main(int argc)
227 | {
228 | if (argc > 3 && decisionMaker<11>((volatile unsigned int*)&argc))
229 | {
230 | return 1;
231 | }
232 |
233 | stuff();
234 |
235 | if (argc > 4 && decisionMaker<7>((volatile unsigned int*)&argc))
236 | {
237 | return 1;
238 | }
239 |
240 | return 0;
241 | }
242 |
--------------------------------------------------------------------------------
/sample/lul/lul.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 | Debug
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | 17.0
23 | Win32Proj
24 | {6061641d-671e-4a1b-bcb9-070d57d87cd0}
25 | lul
26 | 10.0
27 |
28 |
29 |
30 | Application
31 | true
32 | v143
33 | Unicode
34 |
35 |
36 | Application
37 | false
38 | v143
39 | true
40 | Unicode
41 |
42 |
43 | Application
44 | true
45 | v143
46 | Unicode
47 |
48 |
49 | Application
50 | false
51 | v143
52 | true
53 | Unicode
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | Level3
77 | true
78 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
79 | true
80 |
81 |
82 | Console
83 | true
84 |
85 |
86 |
87 |
88 | Level3
89 | true
90 | true
91 | true
92 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
93 | true
94 |
95 |
96 | Console
97 | true
98 | true
99 | true
100 |
101 |
102 |
103 |
104 | Level3
105 | true
106 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
107 | true
108 | stdcpp20
109 |
110 |
111 | Console
112 | true
113 | true
114 | false
115 |
116 |
117 |
118 |
119 | Level3
120 | true
121 | true
122 | true
123 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
124 | true
125 | Speed
126 | stdcpp20
127 | MultiThreadedDebugDLL
128 |
129 |
130 | Console
131 | true
132 | true
133 | true
134 | true
135 | false
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 | Document
144 |
145 |
146 |
147 |
148 |
149 |
150 |
--------------------------------------------------------------------------------
/sample/hook/hook.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 | Debug
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | 17.0
23 | Win32Proj
24 | {1c5f4fcf-8744-450f-863d-923716431557}
25 | hook
26 | 10.0
27 |
28 |
29 |
30 | DynamicLibrary
31 | true
32 | v143
33 | Unicode
34 |
35 |
36 | DynamicLibrary
37 | false
38 | v143
39 | true
40 | Unicode
41 |
42 |
43 | DynamicLibrary
44 | true
45 | v143
46 | Unicode
47 |
48 |
49 | DynamicLibrary
50 | false
51 | v143
52 | true
53 | Unicode
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | Level3
76 | true
77 | WIN32;_DEBUG;HOOK_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
78 | true
79 | Use
80 | pch.h
81 |
82 |
83 | Windows
84 | true
85 | false
86 |
87 |
88 |
89 |
90 | Level3
91 | true
92 | true
93 | true
94 | WIN32;NDEBUG;HOOK_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
95 | true
96 | Use
97 | pch.h
98 |
99 |
100 | Windows
101 | true
102 | true
103 | true
104 | false
105 |
106 |
107 |
108 |
109 | Level3
110 | true
111 | _DEBUG;HOOK_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
112 | true
113 | Use
114 | pch.h
115 | stdcpp20
116 |
117 |
118 | Windows
119 | true
120 | false
121 |
122 |
123 |
124 |
125 | Level3
126 | true
127 | true
128 | true
129 | NDEBUG;HOOK_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
130 | true
131 | Use
132 | pch.h
133 | stdcpp20
134 |
135 |
136 | Windows
137 | true
138 | true
139 | true
140 | false
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 | Create
151 | Create
152 | Create
153 | Create
154 |
155 |
156 |
157 |
158 |
159 |
--------------------------------------------------------------------------------
/sample/lul/xorstr.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 - 2021 Justas Masiulis
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #ifndef JM_XORSTR_HPP
18 | #define JM_XORSTR_HPP
19 |
20 | #if defined(_M_ARM64) || defined(__aarch64__) || defined(_M_ARM) || defined(__arm__)
21 | #include
22 | #elif defined(_M_X64) || defined(__amd64__) || defined(_M_IX86) || defined(__i386__)
23 | #include
24 | #else
25 | #error Unsupported platform
26 | #endif
27 |
28 | #include
29 | #include
30 | #include
31 | #include
32 |
33 | #define xorstr(str) ::jm::xor_string([]() { return str; }, std::integral_constant{}, std::make_index_sequence<::jm::detail::_buffer_size()>{})
34 | #define xorstr_(str) xorstr(str).crypt_get()
35 |
36 | #ifdef _MSC_VER
37 | #define XORSTR_FORCEINLINE __forceinline
38 | #else
39 | #define XORSTR_FORCEINLINE __attribute__((always_inline)) inline
40 | #endif
41 |
42 | namespace jm {
43 |
44 | namespace detail {
45 |
46 | template
47 | XORSTR_FORCEINLINE constexpr std::size_t _buffer_size()
48 | {
49 | return ((Size / 16) + (Size % 16 != 0)) * 2;
50 | }
51 |
52 | template
53 | XORSTR_FORCEINLINE constexpr std::uint32_t key4() noexcept
54 | {
55 | std::uint32_t value = Seed;
56 | for(char c : __TIME__)
57 | value = static_cast((value ^ c) * 16777619ull);
58 | return value;
59 | }
60 |
61 | template
62 | XORSTR_FORCEINLINE constexpr std::uint64_t key8()
63 | {
64 | constexpr auto first_part = key4<2166136261 + S>();
65 | constexpr auto second_part = key4();
66 | return (static_cast(first_part) << 32) | second_part;
67 | }
68 |
69 | // loads up to 8 characters of string into uint64 and xors it with the key
70 | template
71 | XORSTR_FORCEINLINE constexpr std::uint64_t
72 | load_xored_str8(std::uint64_t key, std::size_t idx, const CharT* str) noexcept
73 | {
74 | using cast_type = typename std::make_unsigned::type;
75 | constexpr auto value_size = sizeof(CharT);
76 | constexpr auto idx_offset = 8 / value_size;
77 |
78 | std::uint64_t value = key;
79 | for(std::size_t i = 0; i < idx_offset && i + idx * idx_offset < N; ++i)
80 | value ^=
81 | (std::uint64_t{ static_cast(str[i + idx * idx_offset]) }
82 | << ((i % idx_offset) * 8 * value_size));
83 |
84 | return value;
85 | }
86 |
87 | // forces compiler to use registers instead of stuffing constants in rdata
88 | XORSTR_FORCEINLINE std::uint64_t load_from_reg(std::uint64_t value) noexcept
89 | {
90 | #if defined(__clang__) || defined(__GNUC__)
91 | asm("" : "=r"(value) : "0"(value) :);
92 | return value;
93 | #else
94 | volatile std::uint64_t reg = value;
95 | return reg;
96 | #endif
97 | }
98 |
99 | } // namespace detail
100 |
101 | template
102 | class xor_string;
103 |
104 | template
105 | class xor_string, std::index_sequence> {
106 | #ifndef JM_XORSTR_DISABLE_AVX_INTRINSICS
107 | constexpr static inline std::uint64_t alignment = ((Size > 16) ? 32 : 16);
108 | #else
109 | constexpr static inline std::uint64_t alignment = 16;
110 | #endif
111 |
112 | alignas(alignment) std::uint64_t _storage[sizeof...(Keys)];
113 |
114 | public:
115 | using value_type = CharT;
116 | using size_type = std::size_t;
117 | using pointer = CharT*;
118 | using const_pointer = const CharT*;
119 |
120 | template
121 | XORSTR_FORCEINLINE xor_string(L l, std::integral_constant, std::index_sequence) noexcept
122 | : _storage{ ::jm::detail::load_from_reg((std::integral_constant(Keys, Indices, l())>::value))... }
123 | {}
124 |
125 | XORSTR_FORCEINLINE constexpr size_type size() const noexcept
126 | {
127 | return Size - 1;
128 | }
129 |
130 | XORSTR_FORCEINLINE void crypt() noexcept
131 | {
132 | // everything is inlined by hand because a certain compiler with a certain linker is _very_ slow
133 | #if defined(__clang__)
134 | alignas(alignment)
135 | std::uint64_t arr[]{ ::jm::detail::load_from_reg(Keys)... };
136 | std::uint64_t* keys =
137 | (std::uint64_t*)::jm::detail::load_from_reg((std::uint64_t)arr);
138 | #else
139 | alignas(alignment) std::uint64_t keys[]{ ::jm::detail::load_from_reg(Keys)... };
140 | #endif
141 |
142 | #if defined(_M_ARM64) || defined(__aarch64__) || defined(_M_ARM) || defined(__arm__)
143 | #if defined(__clang__)
144 | ((Indices >= sizeof(_storage) / 16 ? static_cast(0) : __builtin_neon_vst1q_v(
145 | reinterpret_cast(_storage) + Indices * 2,
146 | veorq_u64(__builtin_neon_vld1q_v(reinterpret_cast(_storage) + Indices * 2, 51),
147 | __builtin_neon_vld1q_v(reinterpret_cast(keys) + Indices * 2, 51)),
148 | 51)), ...);
149 | #else // GCC, MSVC
150 | ((Indices >= sizeof(_storage) / 16 ? static_cast(0) : vst1q_u64(
151 | reinterpret_cast(_storage) + Indices * 2,
152 | veorq_u64(vld1q_u64(reinterpret_cast(_storage) + Indices * 2),
153 | vld1q_u64(reinterpret_cast(keys) + Indices * 2)))), ...);
154 | #endif
155 | #elif !defined(JM_XORSTR_DISABLE_AVX_INTRINSICS)
156 | ((Indices >= sizeof(_storage) / 32 ? static_cast(0) : _mm256_store_si256(
157 | reinterpret_cast<__m256i*>(_storage) + Indices,
158 | _mm256_xor_si256(
159 | _mm256_load_si256(reinterpret_cast(_storage) + Indices),
160 | _mm256_load_si256(reinterpret_cast(keys) + Indices)))), ...);
161 |
162 | if constexpr(sizeof(_storage) % 32 != 0)
163 | _mm_store_si128(
164 | reinterpret_cast<__m128i*>(_storage + sizeof...(Keys) - 2),
165 | _mm_xor_si128(_mm_load_si128(reinterpret_cast(_storage + sizeof...(Keys) - 2)),
166 | _mm_load_si128(reinterpret_cast(keys + sizeof...(Keys) - 2))));
167 | #else
168 | ((Indices >= sizeof(_storage) / 16 ? static_cast(0) : _mm_store_si128(
169 | reinterpret_cast<__m128i*>(_storage) + Indices,
170 | _mm_xor_si128(_mm_load_si128(reinterpret_cast(_storage) + Indices),
171 | _mm_load_si128(reinterpret_cast(keys) + Indices)))), ...);
172 | #endif
173 | }
174 |
175 | XORSTR_FORCEINLINE const_pointer get() const noexcept
176 | {
177 | return reinterpret_cast(_storage);
178 | }
179 |
180 | XORSTR_FORCEINLINE pointer get() noexcept
181 | {
182 | return reinterpret_cast(_storage);
183 | }
184 |
185 | XORSTR_FORCEINLINE pointer crypt_get() noexcept
186 | {
187 | // crypt() is inlined by hand because a certain compiler with a certain linker is _very_ slow
188 | #if defined(__clang__)
189 | alignas(alignment)
190 | std::uint64_t arr[]{ ::jm::detail::load_from_reg(Keys)... };
191 | std::uint64_t* keys =
192 | (std::uint64_t*)::jm::detail::load_from_reg((std::uint64_t)arr);
193 | #else
194 | alignas(alignment) std::uint64_t keys[]{ ::jm::detail::load_from_reg(Keys)... };
195 | #endif
196 |
197 | #if defined(_M_ARM64) || defined(__aarch64__) || defined(_M_ARM) || defined(__arm__)
198 | #if defined(__clang__)
199 | ((Indices >= sizeof(_storage) / 16 ? static_cast(0) : __builtin_neon_vst1q_v(
200 | reinterpret_cast(_storage) + Indices * 2,
201 | veorq_u64(__builtin_neon_vld1q_v(reinterpret_cast(_storage) + Indices * 2, 51),
202 | __builtin_neon_vld1q_v(reinterpret_cast(keys) + Indices * 2, 51)),
203 | 51)), ...);
204 | #else // GCC, MSVC
205 | ((Indices >= sizeof(_storage) / 16 ? static_cast(0) : vst1q_u64(
206 | reinterpret_cast(_storage) + Indices * 2,
207 | veorq_u64(vld1q_u64(reinterpret_cast(_storage) + Indices * 2),
208 | vld1q_u64(reinterpret_cast(keys) + Indices * 2)))), ...);
209 | #endif
210 | #elif !defined(JM_XORSTR_DISABLE_AVX_INTRINSICS)
211 | ((Indices >= sizeof(_storage) / 32 ? static_cast(0) : _mm256_store_si256(
212 | reinterpret_cast<__m256i*>(_storage) + Indices,
213 | _mm256_xor_si256(
214 | _mm256_load_si256(reinterpret_cast(_storage) + Indices),
215 | _mm256_load_si256(reinterpret_cast(keys) + Indices)))), ...);
216 |
217 | if constexpr(sizeof(_storage) % 32 != 0)
218 | _mm_store_si128(
219 | reinterpret_cast<__m128i*>(_storage + sizeof...(Keys) - 2),
220 | _mm_xor_si128(_mm_load_si128(reinterpret_cast(_storage + sizeof...(Keys) - 2)),
221 | _mm_load_si128(reinterpret_cast(keys + sizeof...(Keys) - 2))));
222 | #else
223 | ((Indices >= sizeof(_storage) / 16 ? static_cast(0) : _mm_store_si128(
224 | reinterpret_cast<__m128i*>(_storage) + Indices,
225 | _mm_xor_si128(_mm_load_si128(reinterpret_cast(_storage) + Indices),
226 | _mm_load_si128(reinterpret_cast(keys) + Indices)))), ...);
227 | #endif
228 |
229 | return (pointer)(_storage);
230 | }
231 | };
232 |
233 | template
234 | xor_string(L l, std::integral_constant, std::index_sequence) -> xor_string<
235 | std::remove_const_t>,
236 | Size,
237 | std::integer_sequence()...>,
238 | std::index_sequence>;
239 |
240 | } // namespace jm
241 |
242 | #endif // include guard
243 |
--------------------------------------------------------------------------------
/sample/lul/peb.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | typedef _Return_type_success_(return >= 0) LONG NTSTATUS;
6 |
7 | typedef enum _PROCESSINFOCLASS
8 | {
9 | ProcessBasicInformation = 0,
10 | ProcessDebugPort = 7,
11 | ProcessWow64Information = 26,
12 | ProcessImageFileName = 27,
13 | ProcessBreakOnTermination = 29,
14 | ProcessImageFileNameWin32 = 43,
15 | } PROCESSINFOCLASS;
16 |
17 | struct RTL_USER_PROCESS_PARAMETERS;
18 |
19 | typedef struct _LSA_UNICODE_STRING {
20 | USHORT Length;
21 | USHORT MaximumLength;
22 | PWSTR Buffer;
23 | } UNICODE_STRING;
24 |
25 | typedef struct _LDR_MODULE
26 | {
27 | LIST_ENTRY InLoadOrderModuleList;
28 | LIST_ENTRY InMemoryOrderModuleList;
29 | LIST_ENTRY InInitializationOrderModuleList;
30 | PVOID BaseAddress;
31 | PVOID EntryPoint;
32 | ULONG SizeOfImage;
33 | UNICODE_STRING FullDllName;
34 | UNICODE_STRING BaseDllName;
35 | ULONG Flags;
36 | SHORT LoadCount;
37 | SHORT TlsIndex;
38 | LIST_ENTRY HashTableEntry;
39 | ULONG TimeDateStamp;
40 | } LDR_MODULE, *PLDR_MODULE;
41 |
42 | typedef struct _PEB_LDR_DATA
43 | {
44 | ULONG Length;
45 | BOOLEAN Initialized;
46 | HANDLE SsHandle;
47 | LIST_ENTRY InLoadOrderModuleList;
48 | LIST_ENTRY InMemoryOrderModuleList;
49 | LIST_ENTRY InInitializationOrderModuleList;
50 | PVOID EntryInProgress;
51 | BOOLEAN ShutdownInProgress;
52 | HANDLE ShutdownThreadId;
53 | } PEB_LDR_DATA, *PPEB_LDR_DATA;
54 |
55 | #define GDI_HANDLE_BUFFER_SIZE32 34
56 | #define GDI_HANDLE_BUFFER_SIZE GDI_HANDLE_BUFFER_SIZE32
57 | typedef ULONG GDI_HANDLE_BUFFER[GDI_HANDLE_BUFFER_SIZE];
58 |
59 | typedef struct _PEB
60 | {
61 | BOOLEAN InheritedAddressSpace;
62 | BOOLEAN ReadImageFileExecOptions;
63 | BOOLEAN BeingDebugged;
64 |
65 | union
66 | {
67 | BOOLEAN BitField;
68 |
69 | struct
70 | {
71 | BOOLEAN ImageUsesLargePages : 1;
72 | BOOLEAN IsProtectedProcess : 1;
73 | BOOLEAN IsImageDynamicallyRelocated : 1;
74 | BOOLEAN SkipPatchingUser32Forwarders : 1;
75 | BOOLEAN IsPackagedProcess : 1;
76 | BOOLEAN IsAppContainer : 1;
77 | BOOLEAN IsProtectedProcessLight : 1;
78 | BOOLEAN IsLongPathAwareProcess : 1;
79 | };
80 | };
81 |
82 | HANDLE Mutant;
83 |
84 | PVOID ImageBaseAddress;
85 | PPEB_LDR_DATA Ldr;
86 | RTL_USER_PROCESS_PARAMETERS* ProcessParameters;
87 | PVOID SubSystemData;
88 | PVOID ProcessHeap;
89 | PRTL_CRITICAL_SECTION FastPebLock;
90 | PSLIST_HEADER AtlThunkSListPtr;
91 | PVOID IFEOKey;
92 |
93 | union
94 | {
95 | ULONG CrossProcessFlags;
96 |
97 | struct
98 | {
99 | ULONG ProcessInJob : 1;
100 | ULONG ProcessInitializing : 1;
101 | ULONG ProcessUsingVEH : 1;
102 | ULONG ProcessUsingVCH : 1;
103 | ULONG ProcessUsingFTH : 1;
104 | ULONG ProcessPreviouslyThrottled : 1;
105 | ULONG ProcessCurrentlyThrottled : 1;
106 | ULONG ProcessImagesHotPatched : 1; // REDSTONE5
107 | ULONG ReservedBits0 : 24;
108 | };
109 | };
110 |
111 | union
112 | {
113 | PVOID KernelCallbackTable;
114 | PVOID UserSharedInfoPtr;
115 | };
116 |
117 | ULONG SystemReserved;
118 | ULONG AtlThunkSListPtr32;
119 | void* ApiSetMap;
120 | ULONG TlsExpansionCounter;
121 | PVOID TlsBitmap;
122 | ULONG TlsBitmapBits[2]; // TLS_MINIMUM_AVAILABLE
123 |
124 | PVOID ReadOnlySharedMemoryBase;
125 | void* SharedData; // HotpatchInformation
126 | PVOID* ReadOnlyStaticServerData;
127 |
128 | PVOID AnsiCodePageData; // PCPTABLEINFO
129 | PVOID OemCodePageData; // PCPTABLEINFO
130 | PVOID UnicodeCaseTableData; // PNLSTABLEINFO
131 |
132 | ULONG NumberOfProcessors;
133 | ULONG NtGlobalFlag;
134 |
135 | ULARGE_INTEGER CriticalSectionTimeout;
136 | SIZE_T HeapSegmentReserve;
137 | SIZE_T HeapSegmentCommit;
138 | SIZE_T HeapDeCommitTotalFreeThreshold;
139 | SIZE_T HeapDeCommitFreeBlockThreshold;
140 |
141 | ULONG NumberOfHeaps;
142 | ULONG MaximumNumberOfHeaps;
143 | PVOID* ProcessHeaps; // PHEAP
144 |
145 | PVOID GdiSharedHandleTable; // PGDI_SHARED_MEMORY
146 | PVOID ProcessStarterHelper;
147 | ULONG GdiDCAttributeList;
148 |
149 | PRTL_CRITICAL_SECTION LoaderLock;
150 |
151 | ULONG OSMajorVersion;
152 | ULONG OSMinorVersion;
153 | USHORT OSBuildNumber;
154 | USHORT OSCSDVersion;
155 | ULONG OSPlatformId;
156 | ULONG ImageSubsystem;
157 | ULONG ImageSubsystemMajorVersion;
158 | ULONG ImageSubsystemMinorVersion;
159 | KAFFINITY ActiveProcessAffinityMask;
160 | GDI_HANDLE_BUFFER GdiHandleBuffer;
161 | PVOID PostProcessInitRoutine;
162 |
163 | PVOID TlsExpansionBitmap;
164 | ULONG TlsExpansionBitmapBits[32]; // TLS_EXPANSION_SLOTS
165 |
166 | ULONG SessionId;
167 |
168 | ULARGE_INTEGER AppCompatFlags; // KACF_*
169 | ULARGE_INTEGER AppCompatFlagsUser;
170 | PVOID pShimData;
171 | PVOID AppCompatInfo; // APPCOMPAT_EXE_DATA
172 |
173 | UNICODE_STRING CSDVersion;
174 |
175 | void* ActivationContextData;
176 | void* ProcessAssemblyStorageMap;
177 | void* SystemDefaultActivationContextData;
178 | void* SystemAssemblyStorageMap;
179 |
180 | SIZE_T MinimumStackCommit;
181 |
182 | PVOID SparePointers[2]; // 19H1 (previously FlsCallback to FlsHighIndex)
183 | PVOID PatchLoaderData;
184 | PVOID ChpeV2ProcessInfo; // _CHPEV2_PROCESS_INFO
185 |
186 | ULONG AppModelFeatureState;
187 | ULONG SpareUlongs[2];
188 |
189 | USHORT ActiveCodePage;
190 | USHORT OemCodePage;
191 | USHORT UseCaseMapping;
192 | USHORT UnusedNlsField;
193 |
194 | PVOID WerRegistrationData;
195 | PVOID WerShipAssertPtr;
196 |
197 | union
198 | {
199 | PVOID pContextData; // WIN7
200 | PVOID pUnused; // WIN10
201 | PVOID EcCodeBitMap; // WIN11
202 | };
203 |
204 | PVOID pImageHeaderHash;
205 |
206 | union
207 | {
208 | ULONG TracingFlags;
209 |
210 | struct
211 | {
212 | ULONG HeapTracingEnabled : 1;
213 | ULONG CritSecTracingEnabled : 1;
214 | ULONG LibLoaderTracingEnabled : 1;
215 | ULONG SpareTracingBits : 29;
216 | };
217 | };
218 |
219 | ULONGLONG CsrServerReadOnlySharedMemoryBase;
220 | PRTL_CRITICAL_SECTION TppWorkerpListLock;
221 | LIST_ENTRY TppWorkerpList;
222 | PVOID WaitOnAddressHashTable[128];
223 | void* TelemetryCoverageHeader; // REDSTONE3
224 | ULONG CloudFileFlags;
225 | ULONG CloudFileDiagFlags; // REDSTONE4
226 | CHAR PlaceholderCompatibilityMode;
227 | CHAR PlaceholderCompatibilityModeReserved[7];
228 | void* LeapSecondData; // REDSTONE5
229 | union
230 | {
231 | ULONG LeapSecondFlags;
232 |
233 | struct
234 | {
235 | ULONG SixtySecondEnabled : 1;
236 | ULONG Reserved : 31;
237 | };
238 | };
239 |
240 | ULONG NtGlobalFlag2;
241 | ULONGLONG ExtendedFeatureDisableMask; // since WIN11
242 | } PEB, *PPEB;
243 |
244 |
245 | typedef struct _CLIENT_ID
246 | {
247 | HANDLE UniqueProcess;
248 | HANDLE UniqueThread;
249 | } CLIENT_ID, * PCLIENT_ID;
250 |
251 | typedef struct _ACTIVATION_CONTEXT_STACK
252 | {
253 | void* ActiveFrame;
254 | LIST_ENTRY FrameListCache;
255 | ULONG Flags; // ACTIVATION_CONTEXT_STACK_FLAG_*
256 | ULONG NextCookieSequenceNumber;
257 | ULONG StackId;
258 | } ACTIVATION_CONTEXT_STACK, * PACTIVATION_CONTEXT_STACK;
259 |
260 | #define GDI_BATCH_BUFFER_SIZE 310
261 | #define WIN32_CLIENT_INFO_LENGTH 62
262 | #define STATIC_UNICODE_BUFFER_LENGTH 261
263 |
264 | typedef struct _GDI_TEB_BATCH
265 | {
266 | ULONG Offset;
267 | ULONG_PTR HDC;
268 | ULONG Buffer[GDI_BATCH_BUFFER_SIZE];
269 | } GDI_TEB_BATCH, * PGDI_TEB_BATCH;
270 |
271 | typedef struct _TEB
272 | {
273 | NT_TIB NtTib;
274 |
275 | PVOID EnvironmentPointer;
276 | CLIENT_ID ClientId;
277 | PVOID ActiveRpcHandle;
278 | PVOID ThreadLocalStoragePointer;
279 | PPEB ProcessEnvironmentBlock;
280 |
281 | ULONG LastErrorValue;
282 | ULONG CountOfOwnedCriticalSections;
283 | PVOID CsrClientThread;
284 | PVOID Win32ThreadInfo;
285 | ULONG User32Reserved[26];
286 | ULONG UserReserved[5];
287 | PVOID WOW32Reserved;
288 | LCID CurrentLocale;
289 | ULONG FpSoftwareStatusRegister;
290 | PVOID ReservedForDebuggerInstrumentation[16];
291 | #ifdef _WIN64
292 | PVOID SystemReserved1[30];
293 | #else
294 | PVOID SystemReserved1[26];
295 | #endif
296 |
297 | CHAR PlaceholderCompatibilityMode;
298 | BOOLEAN PlaceholderHydrationAlwaysExplicit;
299 | CHAR PlaceholderReserved[10];
300 |
301 | ULONG ProxiedProcessId;
302 | ACTIVATION_CONTEXT_STACK ActivationStack;
303 |
304 | UCHAR WorkingOnBehalfTicket[8];
305 | NTSTATUS ExceptionCode;
306 |
307 | PACTIVATION_CONTEXT_STACK ActivationContextStackPointer;
308 | ULONG_PTR InstrumentationCallbackSp;
309 | ULONG_PTR InstrumentationCallbackPreviousPc;
310 | ULONG_PTR InstrumentationCallbackPreviousSp;
311 | #ifdef _WIN64
312 | ULONG TxFsContext;
313 | #endif
314 |
315 | BOOLEAN InstrumentationCallbackDisabled;
316 | #ifdef _WIN64
317 | BOOLEAN UnalignedLoadStoreExceptions;
318 | #endif
319 | #ifndef _WIN64
320 | UCHAR SpareBytes[23];
321 | ULONG TxFsContext;
322 | #endif
323 | GDI_TEB_BATCH GdiTebBatch;
324 | CLIENT_ID RealClientId;
325 | HANDLE GdiCachedProcessHandle;
326 | ULONG GdiClientPID;
327 | ULONG GdiClientTID;
328 | PVOID GdiThreadLocalInfo;
329 | ULONG_PTR Win32ClientInfo[WIN32_CLIENT_INFO_LENGTH];
330 |
331 | PVOID glDispatchTable[233];
332 | ULONG_PTR glReserved1[29];
333 | PVOID glReserved2;
334 | PVOID glSectionInfo;
335 | PVOID glSection;
336 | PVOID glTable;
337 | PVOID glCurrentRC;
338 | PVOID glContext;
339 |
340 | NTSTATUS LastStatusValue;
341 | UNICODE_STRING StaticUnicodeString;
342 | WCHAR StaticUnicodeBuffer[STATIC_UNICODE_BUFFER_LENGTH];
343 |
344 | PVOID DeallocationStack;
345 | PVOID TlsSlots[TLS_MINIMUM_AVAILABLE];
346 | LIST_ENTRY TlsLinks;
347 |
348 | PVOID Vdm;
349 | PVOID ReservedForNtRpc;
350 | PVOID DbgSsReserved[2];
351 |
352 | ULONG HardErrorMode;
353 | #ifdef _WIN64
354 | PVOID Instrumentation[11];
355 | #else
356 | PVOID Instrumentation[9];
357 | #endif
358 | GUID ActivityId;
359 |
360 | PVOID SubProcessTag;
361 | PVOID PerflibData;
362 | PVOID EtwTraceData;
363 | PVOID WinSockData;
364 | ULONG GdiBatchCount;
365 |
366 | union
367 | {
368 | PROCESSOR_NUMBER CurrentIdealProcessor;
369 | ULONG IdealProcessorValue;
370 |
371 | struct
372 | {
373 | UCHAR ReservedPad0;
374 | UCHAR ReservedPad1;
375 | UCHAR ReservedPad2;
376 | UCHAR IdealProcessor;
377 | };
378 | };
379 |
380 | ULONG GuaranteedStackBytes;
381 | PVOID ReservedForPerf;
382 | PVOID ReservedForOle; // tagSOleTlsData
383 | ULONG WaitingOnLoaderLock;
384 | PVOID SavedPriorityState;
385 | ULONG_PTR ReservedForCodeCoverage;
386 | PVOID ThreadPoolData;
387 | PVOID* TlsExpansionSlots;
388 | #ifdef _WIN64
389 | PVOID DeallocationBStore;
390 | PVOID BStoreLimit;
391 | #endif
392 | ULONG MuiGeneration;
393 | ULONG IsImpersonating;
394 | PVOID NlsCache;
395 | PVOID pShimData;
396 | ULONG HeapData;
397 | HANDLE CurrentTransactionHandle;
398 | void* ActiveFrame;
399 | PVOID FlsData;
400 |
401 | PVOID PreferredLanguages;
402 | PVOID UserPrefLanguages;
403 | PVOID MergedPrefLanguages;
404 | ULONG MuiImpersonation;
405 |
406 | union
407 | {
408 | USHORT CrossTebFlags;
409 | USHORT SpareCrossTebBits : 16;
410 | };
411 |
412 | union
413 | {
414 | USHORT SameTebFlags;
415 |
416 | struct
417 | {
418 | USHORT SafeThunkCall : 1;
419 | USHORT InDebugPrint : 1;
420 | USHORT HasFiberData : 1;
421 | USHORT SkipThreadAttach : 1;
422 | USHORT WerInShipAssertCode : 1;
423 | USHORT RanProcessInit : 1;
424 | USHORT ClonedThread : 1;
425 | USHORT SuppressDebugMsg : 1;
426 | USHORT DisableUserStackWalk : 1;
427 | USHORT RtlExceptionAttached : 1;
428 | USHORT InitialThread : 1;
429 | USHORT SessionAware : 1;
430 | USHORT LoadOwner : 1;
431 | USHORT LoaderWorker : 1;
432 | USHORT SkipLoaderInit : 1;
433 | USHORT SkipFileAPIBrokering : 1;
434 | };
435 | };
436 |
437 | PVOID TxnScopeEnterCallback;
438 | PVOID TxnScopeExitCallback;
439 | PVOID TxnScopeContext;
440 | ULONG LockCount;
441 | LONG WowTebOffset;
442 | PVOID ResourceRetValue;
443 | PVOID ReservedForWdf;
444 | ULONGLONG ReservedForCrt;
445 | GUID EffectiveContainerId;
446 | ULONGLONG LastSleepCounter; // Win11
447 | ULONG SpinCallCount;
448 | ULONGLONG ExtendedFeatureDisableMask;
449 | } TEB, * PTEB;
--------------------------------------------------------------------------------