├── 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; --------------------------------------------------------------------------------