├── .github └── FUNDING.yml ├── .gitignore ├── Build ├── WinPriv-hash.txt ├── WinPriv.zip ├── build.cmd ├── x64 │ ├── WinPriv.exe │ └── WinPrivCmd.exe └── x86 │ ├── WinPriv.exe │ └── WinPrivCmd.exe ├── DetoursLibrary ├── LICENSE.md ├── x64 │ ├── detours.h │ ├── detours.lib │ ├── detver.h │ ├── syelog.h │ └── syelog.lib └── x86 │ ├── detours.h │ ├── detours.lib │ ├── detver.h │ ├── syelog.h │ └── syelog.lib ├── LICENSE ├── WinPriv.sln ├── WinPriv ├── WinPriv.cpp ├── WinPriv.h ├── WinPriv.ico ├── WinPriv.vcxproj ├── WinPrivLogon.cpp ├── WinPrivMisc.cpp ├── WinPrivResource.h └── WinPrivResource.rc ├── WinPrivCmd └── WinPrivCmd.vcxproj ├── WinPrivLibrary ├── WinPrivLibrary.h ├── WinPrivLibrary.vcxproj ├── WinPrivLibraryDetours.cpp ├── WinPrivLibraryDetoursCom.c └── WinPrivLibraryMain.cpp └── WinPrivShared ├── WinPrivShared.cpp ├── WinPrivShared.h └── WinPrivShared.vcxproj /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: nomorefood 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vs/ 2 | 3 | *.aps 4 | *.exp 5 | *.user 6 | 7 | Build/*/*.lib 8 | Build/*/*.dll 9 | Build/*/Temp/ 10 | -------------------------------------------------------------------------------- /Build/WinPriv-hash.txt: -------------------------------------------------------------------------------- 1 | 2 | Algorithm Hash Path 3 | --------- ---- ---- 4 | SHA256 BBC0A14199BC7D5F76B4C06C488B87E501681D3A4DE950C2330400A23ADF0C57 x64\WinPriv.exe 5 | SHA256 4501AF8D06FE5275CFFEE68921AC49CD3465AEDD39603F52D9D341EED192D54A x64\WinPrivCmd.exe 6 | SHA256 900F900B712E99C0D1F19949E3A4E382D25C1FE42E7439BAF4D51AAF4C4E62C1 x86\WinPriv.exe 7 | SHA256 EE2EFE3AA73EFE8EBC14122B58E6D886AA8CECD8FFD728CC3D014FB28CC4897B x86\WinPrivCmd.exe 8 | SHA256 932CD7BF3628F3B2542E6EA457FFBAC6109768A8D6163C82DBA74D6D90658853 WinPriv.zip 9 | 10 | 11 | 12 | Algorithm Hash Path 13 | --------- ---- ---- 14 | SHA1 A14A7542A33F31EB62F9AB2015F18C048F5E3990 x64\WinPriv.exe 15 | SHA1 7CDC55EDB2EBA7AFB5BCEC3FDD0B470F33DBC5EC x64\WinPrivCmd.exe 16 | SHA1 304B1F9B26D68C5FBBEF545818E184B53D73CBF3 x86\WinPriv.exe 17 | SHA1 0145089D39B3D7A7A500B6B255A1F842714F6105 x86\WinPrivCmd.exe 18 | SHA1 E865592170DAD5B98BFBAA1472EF70FC18BFA683 WinPriv.zip 19 | 20 | 21 | 22 | Algorithm Hash Path 23 | --------- ---- ---- 24 | MD5 2C5B8B4D56C3135202116E85C42354FD x64\WinPriv.exe 25 | MD5 FDEBABF70371307B6C8372E45E4B2CA3 x64\WinPrivCmd.exe 26 | MD5 2D434698F6C0DE67086C0C613D7C96D5 x86\WinPriv.exe 27 | MD5 EDD70ABA380CB92FE3FE5044208B77F1 x86\WinPrivCmd.exe 28 | MD5 C1366BCBD0F86512D4135ACCFBE28497 WinPriv.zip 29 | 30 | 31 | -------------------------------------------------------------------------------- /Build/WinPriv.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NoMoreFood/WinPriv/ea8584c172e4f31ced4fb2eb073562aed09b3b57/Build/WinPriv.zip -------------------------------------------------------------------------------- /Build/build.cmd: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | TITLE Building WinPriv... 3 | CLS 4 | SET PATH=%WINDIR%\system32;%WINDIR%\system32\WindowsPowerShell\v1.0 5 | 6 | :: cert info to use for signing 7 | SET CERT=04F071366E2A3C75B7CABF091B9CF340ABEA22A7 8 | set TSAURL=http://time.certum.pl/ 9 | set LIBNAME=WinPriv 10 | set LIBURL=https://github.com/NoMoreFood/WinPriv 11 | 12 | :: do cleanup 13 | RD /S /Q "%~dp0.vs" >NUL 2>&1 14 | RD /S /Q "%~dp0x86\Temp" >NUL 2>&1 15 | RD /S /Q "%~dp0x64\Temp" >NUL 2>&1 16 | FORFILES /S /P "%~dp0." /M "*.*pdb" /C "CMD /C DEL /Q @path" >NUL 2>&1 17 | FORFILES /S /P "%~dp0." /M "*.*obj" /C "CMD /C DEL /Q @path" >NUL 2>&1 18 | FORFILES /S /P "%~dp0." /M "*.zip" /C "CMD /C DEL /Q @path" >NUL 2>&1 19 | FORFILES /S /P "%~dp0." /M "*.log" /C "CMD /C DEL /Q @path" >NUL 2>&1 20 | FORFILES /S /P "%~dp0." /M "*.lib" /C "CMD /C DEL /Q @path" >NUL 2>&1 21 | FORFILES /S /P "%~dp0." /M "*.dll" /C "CMD /C DEL /Q @path" >NUL 2>&1 22 | FORFILES /S /P "%~dp0." /M "*.bsc" /C "CMD /C DEL /Q @path" >NUL 2>&1 23 | FORFILES /S /P "%~dp0." /M "*.exp" /C "CMD /C DEL /Q @path" >NUL 2>&1 24 | FORFILES /S /P "%~dp0." /M "*.last*" /C "CMD /C DEL /Q @path" >NUL 2>&1 25 | 26 | :: determine 32-bit program files directory 27 | IF DEFINED ProgramFiles SET PX86=%ProgramFiles% 28 | IF DEFINED ProgramFiles(x86) SET PX86=%ProgramFiles(x86)% 29 | 30 | :: setup commands and paths 31 | SET POWERSHELL=POWERSHELL.EXE -NoProfile -NonInteractive -NoLogo 32 | FOR /F "USEBACKQ DELIMS=" %%X IN (`DIR /OD /B /S "%PX86%\Windows Kits\10\SIGNTOOL.exe" ^| FINDSTR x64`) DO SET SIGNTOOL="%%~X" 33 | 34 | :: sign the main executables 35 | SET BINDIR=%~dp0 36 | %SIGNTOOL% sign /sha1 %CERT% /as /fd sha256 /tr %TSAURL% /td sha256 /d %LIBNAME% /du %LIBURL% "%BINDIR%\x86\*.exe" "%BINDIR%\x64\*.exe" 37 | 38 | :: zip up executatables 39 | PUSHD "%BINDIR%" 40 | %POWERSHELL% -Command "Compress-Archive -LiteralPath @('x86','x64') -DestinationPath '%BINDIR%\WinPriv.zip'" 41 | POPD 42 | 43 | :: output hash information 44 | SET HASHFILE=%BINDIR%\WinPriv-hash.txt 45 | IF EXIST "%HASHFILE%" DEL /F "%HASHFILE%" 46 | FOR %%H IN (SHA256 SHA1 MD5) DO %POWERSHELL% -Command ^ 47 | "Get-ChildItem -Include @('*.zip','*.exe') -Path '%BINDIR%' -Recurse | Get-FileHash -Algorithm %%H | Out-File -Append '%HASHFILE%' -Width 256" 48 | %POWERSHELL% -Command "$Data = Get-Content '%HASHFILE%'; $Data.Replace((Get-Item -LiteralPath '%BINDIR%').FullName,'').Trim() | Set-Content '%HASHFILE%'" 49 | 50 | PAUSE -------------------------------------------------------------------------------- /Build/x64/WinPriv.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NoMoreFood/WinPriv/ea8584c172e4f31ced4fb2eb073562aed09b3b57/Build/x64/WinPriv.exe -------------------------------------------------------------------------------- /Build/x64/WinPrivCmd.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NoMoreFood/WinPriv/ea8584c172e4f31ced4fb2eb073562aed09b3b57/Build/x64/WinPrivCmd.exe -------------------------------------------------------------------------------- /Build/x86/WinPriv.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NoMoreFood/WinPriv/ea8584c172e4f31ced4fb2eb073562aed09b3b57/Build/x86/WinPriv.exe -------------------------------------------------------------------------------- /Build/x86/WinPrivCmd.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NoMoreFood/WinPriv/ea8584c172e4f31ced4fb2eb073562aed09b3b57/Build/x86/WinPrivCmd.exe -------------------------------------------------------------------------------- /DetoursLibrary/LICENSE.md: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft Corporation 2 | 3 | All rights reserved. 4 | 5 | # MIT License 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | -------------------------------------------------------------------------------- /DetoursLibrary/x64/detours.h: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Core Detours Functionality (detours.h of detours.lib) 4 | // 5 | // Microsoft Research Detours Package, Version 4.0.1 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | 10 | #pragma once 11 | #ifndef _DETOURS_H_ 12 | #define _DETOURS_H_ 13 | 14 | #define DETOURS_VERSION 0x4c0c1 // 0xMAJORcMINORcPATCH 15 | 16 | ////////////////////////////////////////////////////////////////////////////// 17 | // 18 | 19 | #ifdef DETOURS_INTERNAL 20 | 21 | #define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1 22 | #define _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE 1 23 | 24 | #pragma warning(disable:4068) // unknown pragma (suppress) 25 | 26 | #if _MSC_VER >= 1900 27 | #pragma warning(push) 28 | #pragma warning(disable:4091) // empty typedef 29 | #endif 30 | 31 | // Suppress declspec(dllimport) for the sake of Detours 32 | // users that provide kernel32 functionality themselves. 33 | // This is ok in the mainstream case, it will just cost 34 | // an extra instruction calling some functions, which 35 | // LTCG optimizes away. 36 | // 37 | #define _KERNEL32_ 1 38 | #define _USER32_ 1 39 | 40 | #include 41 | #if (_MSC_VER < 1310) 42 | #else 43 | #pragma warning(push) 44 | #if _MSC_VER > 1400 45 | #pragma warning(disable:6102 6103) // /analyze warnings 46 | #endif 47 | #include 48 | #include 49 | #pragma warning(pop) 50 | #endif 51 | #include 52 | 53 | // Allow Detours to cleanly compile with the MingW toolchain. 54 | // 55 | #ifdef __GNUC__ 56 | #define __try 57 | #define __except(x) if (0) 58 | #include 59 | #include 60 | #endif 61 | 62 | // From winerror.h, as this error isn't found in some SDKs: 63 | // 64 | // MessageId: ERROR_DYNAMIC_CODE_BLOCKED 65 | // 66 | // MessageText: 67 | // 68 | // The operation was blocked as the process prohibits dynamic code generation. 69 | // 70 | #define ERROR_DYNAMIC_CODE_BLOCKED 1655L 71 | 72 | #endif // DETOURS_INTERNAL 73 | 74 | ////////////////////////////////////////////////////////////////////////////// 75 | // 76 | 77 | #undef DETOURS_X64 78 | #undef DETOURS_X86 79 | #undef DETOURS_IA64 80 | #undef DETOURS_ARM 81 | #undef DETOURS_ARM64 82 | #undef DETOURS_BITS 83 | #undef DETOURS_32BIT 84 | #undef DETOURS_64BIT 85 | 86 | #if defined(_X86_) 87 | #define DETOURS_X86 88 | #define DETOURS_OPTION_BITS 64 89 | 90 | #elif defined(_AMD64_) 91 | #define DETOURS_X64 92 | #define DETOURS_OPTION_BITS 32 93 | 94 | #elif defined(_IA64_) 95 | #define DETOURS_IA64 96 | #define DETOURS_OPTION_BITS 32 97 | 98 | #elif defined(_ARM_) 99 | #define DETOURS_ARM 100 | 101 | #elif defined(_ARM64_) 102 | #define DETOURS_ARM64 103 | 104 | #else 105 | #error Unknown architecture (x86, amd64, ia64, arm, arm64) 106 | #endif 107 | 108 | #ifdef _WIN64 109 | #undef DETOURS_32BIT 110 | #define DETOURS_64BIT 1 111 | #define DETOURS_BITS 64 112 | // If all 64bit kernels can run one and only one 32bit architecture. 113 | //#define DETOURS_OPTION_BITS 32 114 | #else 115 | #define DETOURS_32BIT 1 116 | #undef DETOURS_64BIT 117 | #define DETOURS_BITS 32 118 | // If all 64bit kernels can run one and only one 32bit architecture. 119 | //#define DETOURS_OPTION_BITS 32 120 | #endif 121 | 122 | /////////////////////////////////////////////////////////////// Helper Macros. 123 | // 124 | #define DETOURS_STRINGIFY_(x) #x 125 | #define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) 126 | 127 | #define VER_DETOURS_BITS DETOURS_STRINGIFY(DETOURS_BITS) 128 | 129 | ////////////////////////////////////////////////////////////////////////////// 130 | // 131 | 132 | #if (_MSC_VER < 1299) && !defined(__MINGW32__) 133 | typedef LONG LONG_PTR; 134 | typedef ULONG ULONG_PTR; 135 | #endif 136 | 137 | ///////////////////////////////////////////////// SAL 2.0 Annotations w/o SAL. 138 | // 139 | // These definitions are include so that Detours will build even if the 140 | // compiler doesn't have full SAL 2.0 support. 141 | // 142 | #ifndef DETOURS_DONT_REMOVE_SAL_20 143 | 144 | #ifdef DETOURS_TEST_REMOVE_SAL_20 145 | #undef _Analysis_assume_ 146 | #undef _Benign_race_begin_ 147 | #undef _Benign_race_end_ 148 | #undef _Field_range_ 149 | #undef _Field_size_ 150 | #undef _In_ 151 | #undef _In_bytecount_ 152 | #undef _In_count_ 153 | #undef __in_ecount 154 | #undef _In_opt_ 155 | #undef _In_opt_bytecount_ 156 | #undef _In_opt_count_ 157 | #undef _In_opt_z_ 158 | #undef _In_range_ 159 | #undef _In_reads_ 160 | #undef _In_reads_bytes_ 161 | #undef _In_reads_opt_ 162 | #undef _In_reads_opt_bytes_ 163 | #undef _In_reads_or_z_ 164 | #undef _In_z_ 165 | #undef _Inout_ 166 | #undef _Inout_opt_ 167 | #undef _Inout_z_count_ 168 | #undef _Out_ 169 | #undef _Out_opt_ 170 | #undef _Out_writes_ 171 | #undef _Outptr_result_maybenull_ 172 | #undef _Readable_bytes_ 173 | #undef _Success_ 174 | #undef _Writable_bytes_ 175 | #undef _Pre_notnull_ 176 | #endif 177 | 178 | #if defined(_Deref_out_opt_z_) && !defined(_Outptr_result_maybenull_) 179 | #define _Outptr_result_maybenull_ _Deref_out_opt_z_ 180 | #endif 181 | 182 | #if defined(_In_count_) && !defined(_In_reads_) 183 | #define _In_reads_(x) _In_count_(x) 184 | #endif 185 | 186 | #if defined(_In_opt_count_) && !defined(_In_reads_opt_) 187 | #define _In_reads_opt_(x) _In_opt_count_(x) 188 | #endif 189 | 190 | #if defined(_In_opt_bytecount_) && !defined(_In_reads_opt_bytes_) 191 | #define _In_reads_opt_bytes_(x) _In_opt_bytecount_(x) 192 | #endif 193 | 194 | #if defined(_In_bytecount_) && !defined(_In_reads_bytes_) 195 | #define _In_reads_bytes_(x) _In_bytecount_(x) 196 | #endif 197 | 198 | #ifndef _In_ 199 | #define _In_ 200 | #endif 201 | 202 | #ifndef _In_bytecount_ 203 | #define _In_bytecount_(x) 204 | #endif 205 | 206 | #ifndef _In_count_ 207 | #define _In_count_(x) 208 | #endif 209 | 210 | #ifndef __in_ecount 211 | #define __in_ecount(x) 212 | #endif 213 | 214 | #ifndef _In_opt_ 215 | #define _In_opt_ 216 | #endif 217 | 218 | #ifndef _In_opt_bytecount_ 219 | #define _In_opt_bytecount_(x) 220 | #endif 221 | 222 | #ifndef _In_opt_count_ 223 | #define _In_opt_count_(x) 224 | #endif 225 | 226 | #ifndef _In_opt_z_ 227 | #define _In_opt_z_ 228 | #endif 229 | 230 | #ifndef _In_range_ 231 | #define _In_range_(x,y) 232 | #endif 233 | 234 | #ifndef _In_reads_ 235 | #define _In_reads_(x) 236 | #endif 237 | 238 | #ifndef _In_reads_bytes_ 239 | #define _In_reads_bytes_(x) 240 | #endif 241 | 242 | #ifndef _In_reads_opt_ 243 | #define _In_reads_opt_(x) 244 | #endif 245 | 246 | #ifndef _In_reads_opt_bytes_ 247 | #define _In_reads_opt_bytes_(x) 248 | #endif 249 | 250 | #ifndef _In_reads_or_z_ 251 | #define _In_reads_or_z_ 252 | #endif 253 | 254 | #ifndef _In_z_ 255 | #define _In_z_ 256 | #endif 257 | 258 | #ifndef _Inout_ 259 | #define _Inout_ 260 | #endif 261 | 262 | #ifndef _Inout_opt_ 263 | #define _Inout_opt_ 264 | #endif 265 | 266 | #ifndef _Inout_z_count_ 267 | #define _Inout_z_count_(x) 268 | #endif 269 | 270 | #ifndef _Out_ 271 | #define _Out_ 272 | #endif 273 | 274 | #ifndef _Out_opt_ 275 | #define _Out_opt_ 276 | #endif 277 | 278 | #ifndef _Out_writes_ 279 | #define _Out_writes_(x) 280 | #endif 281 | 282 | #ifndef _Outptr_result_maybenull_ 283 | #define _Outptr_result_maybenull_ 284 | #endif 285 | 286 | #ifndef _Writable_bytes_ 287 | #define _Writable_bytes_(x) 288 | #endif 289 | 290 | #ifndef _Readable_bytes_ 291 | #define _Readable_bytes_(x) 292 | #endif 293 | 294 | #ifndef _Success_ 295 | #define _Success_(x) 296 | #endif 297 | 298 | #ifndef _Pre_notnull_ 299 | #define _Pre_notnull_ 300 | #endif 301 | 302 | #ifdef DETOURS_INTERNAL 303 | 304 | #pragma warning(disable:4615) // unknown warning type (suppress with older compilers) 305 | 306 | #ifndef _Benign_race_begin_ 307 | #define _Benign_race_begin_ 308 | #endif 309 | 310 | #ifndef _Benign_race_end_ 311 | #define _Benign_race_end_ 312 | #endif 313 | 314 | #ifndef _Field_size_ 315 | #define _Field_size_(x) 316 | #endif 317 | 318 | #ifndef _Field_range_ 319 | #define _Field_range_(x,y) 320 | #endif 321 | 322 | #ifndef _Analysis_assume_ 323 | #define _Analysis_assume_(x) 324 | #endif 325 | 326 | #endif // DETOURS_INTERNAL 327 | #endif // DETOURS_DONT_REMOVE_SAL_20 328 | 329 | ////////////////////////////////////////////////////////////////////////////// 330 | // 331 | #ifndef GUID_DEFINED 332 | #define GUID_DEFINED 333 | typedef struct _GUID 334 | { 335 | DWORD Data1; 336 | WORD Data2; 337 | WORD Data3; 338 | BYTE Data4[ 8 ]; 339 | } GUID; 340 | 341 | #ifdef INITGUID 342 | #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ 343 | const GUID name \ 344 | = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } 345 | #else 346 | #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ 347 | const GUID name 348 | #endif // INITGUID 349 | #endif // !GUID_DEFINED 350 | 351 | #if defined(__cplusplus) 352 | #ifndef _REFGUID_DEFINED 353 | #define _REFGUID_DEFINED 354 | #define REFGUID const GUID & 355 | #endif // !_REFGUID_DEFINED 356 | #else // !__cplusplus 357 | #ifndef _REFGUID_DEFINED 358 | #define _REFGUID_DEFINED 359 | #define REFGUID const GUID * const 360 | #endif // !_REFGUID_DEFINED 361 | #endif // !__cplusplus 362 | 363 | #ifndef ARRAYSIZE 364 | #define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0])) 365 | #endif 366 | 367 | // 368 | ////////////////////////////////////////////////////////////////////////////// 369 | 370 | #ifdef __cplusplus 371 | extern "C" { 372 | #endif // __cplusplus 373 | 374 | /////////////////////////////////////////////////// Instruction Target Macros. 375 | // 376 | #define DETOUR_INSTRUCTION_TARGET_NONE ((PVOID)0) 377 | #define DETOUR_INSTRUCTION_TARGET_DYNAMIC ((PVOID)(LONG_PTR)-1) 378 | #define DETOUR_SECTION_HEADER_SIGNATURE 0x00727444 // "Dtr\0" 379 | 380 | extern const GUID DETOUR_EXE_RESTORE_GUID; 381 | extern const GUID DETOUR_EXE_HELPER_GUID; 382 | 383 | #define DETOUR_TRAMPOLINE_SIGNATURE 0x21727444 // Dtr! 384 | typedef struct _DETOUR_TRAMPOLINE DETOUR_TRAMPOLINE, *PDETOUR_TRAMPOLINE; 385 | 386 | #ifndef DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS 387 | #define DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS 32 388 | #endif // !DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS 389 | 390 | /////////////////////////////////////////////////////////// Binary Structures. 391 | // 392 | #pragma pack(push, 8) 393 | typedef struct _DETOUR_SECTION_HEADER 394 | { 395 | DWORD cbHeaderSize; 396 | DWORD nSignature; 397 | DWORD nDataOffset; 398 | DWORD cbDataSize; 399 | 400 | DWORD nOriginalImportVirtualAddress; 401 | DWORD nOriginalImportSize; 402 | DWORD nOriginalBoundImportVirtualAddress; 403 | DWORD nOriginalBoundImportSize; 404 | 405 | DWORD nOriginalIatVirtualAddress; 406 | DWORD nOriginalIatSize; 407 | DWORD nOriginalSizeOfImage; 408 | DWORD cbPrePE; 409 | 410 | DWORD nOriginalClrFlags; 411 | DWORD reserved1; 412 | DWORD reserved2; 413 | DWORD reserved3; 414 | 415 | // Followed by cbPrePE bytes of data. 416 | } DETOUR_SECTION_HEADER, *PDETOUR_SECTION_HEADER; 417 | 418 | typedef struct _DETOUR_SECTION_RECORD 419 | { 420 | DWORD cbBytes; 421 | DWORD nReserved; 422 | GUID guid; 423 | } DETOUR_SECTION_RECORD, *PDETOUR_SECTION_RECORD; 424 | 425 | typedef struct _DETOUR_CLR_HEADER 426 | { 427 | // Header versioning 428 | ULONG cb; 429 | USHORT MajorRuntimeVersion; 430 | USHORT MinorRuntimeVersion; 431 | 432 | // Symbol table and startup information 433 | IMAGE_DATA_DIRECTORY MetaData; 434 | ULONG Flags; 435 | 436 | // Followed by the rest of the IMAGE_COR20_HEADER 437 | } DETOUR_CLR_HEADER, *PDETOUR_CLR_HEADER; 438 | 439 | typedef struct _DETOUR_EXE_RESTORE 440 | { 441 | DWORD cb; 442 | DWORD cbidh; 443 | DWORD cbinh; 444 | DWORD cbclr; 445 | 446 | PBYTE pidh; 447 | PBYTE pinh; 448 | PBYTE pclr; 449 | 450 | IMAGE_DOS_HEADER idh; 451 | union { 452 | IMAGE_NT_HEADERS inh; // all environments have this 453 | #ifdef IMAGE_NT_OPTIONAL_HDR32_MAGIC // some environments do not have this 454 | IMAGE_NT_HEADERS32 inh32; 455 | #endif 456 | #ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC // some environments do not have this 457 | IMAGE_NT_HEADERS64 inh64; 458 | #endif 459 | #ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC // some environments do not have this 460 | BYTE raw[sizeof(IMAGE_NT_HEADERS64) + 461 | sizeof(IMAGE_SECTION_HEADER) * DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS]; 462 | #else 463 | BYTE raw[0x108 + sizeof(IMAGE_SECTION_HEADER) * DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS]; 464 | #endif 465 | }; 466 | DETOUR_CLR_HEADER clr; 467 | 468 | } DETOUR_EXE_RESTORE, *PDETOUR_EXE_RESTORE; 469 | 470 | #ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC 471 | C_ASSERT(sizeof(IMAGE_NT_HEADERS64) == 0x108); 472 | #endif 473 | 474 | // The size can change, but assert for clarity due to the muddying #ifdefs. 475 | #ifdef _WIN64 476 | C_ASSERT(sizeof(DETOUR_EXE_RESTORE) == 0x688); 477 | #else 478 | C_ASSERT(sizeof(DETOUR_EXE_RESTORE) == 0x678); 479 | #endif 480 | 481 | typedef struct _DETOUR_EXE_HELPER 482 | { 483 | DWORD cb; 484 | DWORD pid; 485 | DWORD nDlls; 486 | CHAR rDlls[4]; 487 | } DETOUR_EXE_HELPER, *PDETOUR_EXE_HELPER; 488 | 489 | #pragma pack(pop) 490 | 491 | #define DETOUR_SECTION_HEADER_DECLARE(cbSectionSize) \ 492 | { \ 493 | sizeof(DETOUR_SECTION_HEADER),\ 494 | DETOUR_SECTION_HEADER_SIGNATURE,\ 495 | sizeof(DETOUR_SECTION_HEADER),\ 496 | (cbSectionSize),\ 497 | \ 498 | 0,\ 499 | 0,\ 500 | 0,\ 501 | 0,\ 502 | \ 503 | 0,\ 504 | 0,\ 505 | 0,\ 506 | 0,\ 507 | } 508 | 509 | ///////////////////////////////////////////////////////////// Binary Typedefs. 510 | // 511 | typedef BOOL (CALLBACK *PF_DETOUR_BINARY_BYWAY_CALLBACK)( 512 | _In_opt_ PVOID pContext, 513 | _In_opt_ LPCSTR pszFile, 514 | _Outptr_result_maybenull_ LPCSTR *ppszOutFile); 515 | 516 | typedef BOOL (CALLBACK *PF_DETOUR_BINARY_FILE_CALLBACK)( 517 | _In_opt_ PVOID pContext, 518 | _In_ LPCSTR pszOrigFile, 519 | _In_ LPCSTR pszFile, 520 | _Outptr_result_maybenull_ LPCSTR *ppszOutFile); 521 | 522 | typedef BOOL (CALLBACK *PF_DETOUR_BINARY_SYMBOL_CALLBACK)( 523 | _In_opt_ PVOID pContext, 524 | _In_ ULONG nOrigOrdinal, 525 | _In_ ULONG nOrdinal, 526 | _Out_ ULONG *pnOutOrdinal, 527 | _In_opt_ LPCSTR pszOrigSymbol, 528 | _In_opt_ LPCSTR pszSymbol, 529 | _Outptr_result_maybenull_ LPCSTR *ppszOutSymbol); 530 | 531 | typedef BOOL (CALLBACK *PF_DETOUR_BINARY_COMMIT_CALLBACK)( 532 | _In_opt_ PVOID pContext); 533 | 534 | typedef BOOL (CALLBACK *PF_DETOUR_ENUMERATE_EXPORT_CALLBACK)(_In_opt_ PVOID pContext, 535 | _In_ ULONG nOrdinal, 536 | _In_opt_ LPCSTR pszName, 537 | _In_opt_ PVOID pCode); 538 | 539 | typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FILE_CALLBACK)(_In_opt_ PVOID pContext, 540 | _In_opt_ HMODULE hModule, 541 | _In_opt_ LPCSTR pszFile); 542 | 543 | typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK)(_In_opt_ PVOID pContext, 544 | _In_ DWORD nOrdinal, 545 | _In_opt_ LPCSTR pszFunc, 546 | _In_opt_ PVOID pvFunc); 547 | 548 | // Same as PF_DETOUR_IMPORT_FUNC_CALLBACK but extra indirection on last parameter. 549 | typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK_EX)(_In_opt_ PVOID pContext, 550 | _In_ DWORD nOrdinal, 551 | _In_opt_ LPCSTR pszFunc, 552 | _In_opt_ PVOID* ppvFunc); 553 | 554 | typedef VOID * PDETOUR_BINARY; 555 | typedef VOID * PDETOUR_LOADED_BINARY; 556 | 557 | //////////////////////////////////////////////////////////// Transaction APIs. 558 | // 559 | LONG WINAPI DetourTransactionBegin(VOID); 560 | LONG WINAPI DetourTransactionAbort(VOID); 561 | LONG WINAPI DetourTransactionCommit(VOID); 562 | LONG WINAPI DetourTransactionCommitEx(_Out_opt_ PVOID **pppFailedPointer); 563 | 564 | LONG WINAPI DetourUpdateThread(_In_ HANDLE hThread); 565 | 566 | LONG WINAPI DetourAttach(_Inout_ PVOID *ppPointer, 567 | _In_ PVOID pDetour); 568 | 569 | LONG WINAPI DetourAttachEx(_Inout_ PVOID *ppPointer, 570 | _In_ PVOID pDetour, 571 | _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline, 572 | _Out_opt_ PVOID *ppRealTarget, 573 | _Out_opt_ PVOID *ppRealDetour); 574 | 575 | LONG WINAPI DetourDetach(_Inout_ PVOID *ppPointer, 576 | _In_ PVOID pDetour); 577 | 578 | BOOL WINAPI DetourSetIgnoreTooSmall(_In_ BOOL fIgnore); 579 | BOOL WINAPI DetourSetRetainRegions(_In_ BOOL fRetain); 580 | PVOID WINAPI DetourSetSystemRegionLowerBound(_In_ PVOID pSystemRegionLowerBound); 581 | PVOID WINAPI DetourSetSystemRegionUpperBound(_In_ PVOID pSystemRegionUpperBound); 582 | 583 | ////////////////////////////////////////////////////////////// Code Functions. 584 | // 585 | PVOID WINAPI DetourFindFunction(_In_ LPCSTR pszModule, 586 | _In_ LPCSTR pszFunction); 587 | PVOID WINAPI DetourCodeFromPointer(_In_ PVOID pPointer, 588 | _Out_opt_ PVOID *ppGlobals); 589 | PVOID WINAPI DetourCopyInstruction(_In_opt_ PVOID pDst, 590 | _Inout_opt_ PVOID *ppDstPool, 591 | _In_ PVOID pSrc, 592 | _Out_opt_ PVOID *ppTarget, 593 | _Out_opt_ LONG *plExtra); 594 | BOOL WINAPI DetourSetCodeModule(_In_ HMODULE hModule, 595 | _In_ BOOL fLimitReferencesToModule); 596 | PVOID WINAPI DetourAllocateRegionWithinJumpBounds(_In_ LPCVOID pbTarget, 597 | _Out_ PDWORD pcbAllocatedSize); 598 | BOOL WINAPI DetourIsFunctionImported(_In_ PBYTE pbCode, 599 | _In_ PBYTE pbAddress); 600 | 601 | ///////////////////////////////////////////////////// Loaded Binary Functions. 602 | // 603 | HMODULE WINAPI DetourGetContainingModule(_In_ PVOID pvAddr); 604 | HMODULE WINAPI DetourEnumerateModules(_In_opt_ HMODULE hModuleLast); 605 | PVOID WINAPI DetourGetEntryPoint(_In_opt_ HMODULE hModule); 606 | ULONG WINAPI DetourGetModuleSize(_In_opt_ HMODULE hModule); 607 | BOOL WINAPI DetourEnumerateExports(_In_ HMODULE hModule, 608 | _In_opt_ PVOID pContext, 609 | _In_ PF_DETOUR_ENUMERATE_EXPORT_CALLBACK pfExport); 610 | BOOL WINAPI DetourEnumerateImports(_In_opt_ HMODULE hModule, 611 | _In_opt_ PVOID pContext, 612 | _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, 613 | _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK pfImportFunc); 614 | 615 | BOOL WINAPI DetourEnumerateImportsEx(_In_opt_ HMODULE hModule, 616 | _In_opt_ PVOID pContext, 617 | _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, 618 | _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK_EX pfImportFuncEx); 619 | 620 | _Writable_bytes_(*pcbData) 621 | _Readable_bytes_(*pcbData) 622 | _Success_(return != NULL) 623 | PVOID WINAPI DetourFindPayload(_In_opt_ HMODULE hModule, 624 | _In_ REFGUID rguid, 625 | _Out_opt_ DWORD *pcbData); 626 | 627 | _Writable_bytes_(*pcbData) 628 | _Readable_bytes_(*pcbData) 629 | _Success_(return != NULL) 630 | PVOID WINAPI DetourFindPayloadEx(_In_ REFGUID rguid, 631 | _Out_opt_ DWORD *pcbData); 632 | 633 | DWORD WINAPI DetourGetSizeOfPayloads(_In_opt_ HMODULE hModule); 634 | 635 | BOOL WINAPI DetourFreePayload(_In_ PVOID pvData); 636 | ///////////////////////////////////////////////// Persistent Binary Functions. 637 | // 638 | 639 | PDETOUR_BINARY WINAPI DetourBinaryOpen(_In_ HANDLE hFile); 640 | 641 | _Writable_bytes_(*pcbData) 642 | _Readable_bytes_(*pcbData) 643 | _Success_(return != NULL) 644 | PVOID WINAPI DetourBinaryEnumeratePayloads(_In_ PDETOUR_BINARY pBinary, 645 | _Out_opt_ GUID *pGuid, 646 | _Out_ DWORD *pcbData, 647 | _Inout_ DWORD *pnIterator); 648 | 649 | _Writable_bytes_(*pcbData) 650 | _Readable_bytes_(*pcbData) 651 | _Success_(return != NULL) 652 | PVOID WINAPI DetourBinaryFindPayload(_In_ PDETOUR_BINARY pBinary, 653 | _In_ REFGUID rguid, 654 | _Out_ DWORD *pcbData); 655 | 656 | PVOID WINAPI DetourBinarySetPayload(_In_ PDETOUR_BINARY pBinary, 657 | _In_ REFGUID rguid, 658 | _In_reads_opt_(cbData) PVOID pData, 659 | _In_ DWORD cbData); 660 | BOOL WINAPI DetourBinaryDeletePayload(_In_ PDETOUR_BINARY pBinary, _In_ REFGUID rguid); 661 | BOOL WINAPI DetourBinaryPurgePayloads(_In_ PDETOUR_BINARY pBinary); 662 | BOOL WINAPI DetourBinaryResetImports(_In_ PDETOUR_BINARY pBinary); 663 | BOOL WINAPI DetourBinaryEditImports(_In_ PDETOUR_BINARY pBinary, 664 | _In_opt_ PVOID pContext, 665 | _In_opt_ PF_DETOUR_BINARY_BYWAY_CALLBACK pfByway, 666 | _In_opt_ PF_DETOUR_BINARY_FILE_CALLBACK pfFile, 667 | _In_opt_ PF_DETOUR_BINARY_SYMBOL_CALLBACK pfSymbol, 668 | _In_opt_ PF_DETOUR_BINARY_COMMIT_CALLBACK pfCommit); 669 | BOOL WINAPI DetourBinaryWrite(_In_ PDETOUR_BINARY pBinary, _In_ HANDLE hFile); 670 | BOOL WINAPI DetourBinaryClose(_In_ PDETOUR_BINARY pBinary); 671 | 672 | /////////////////////////////////////////////////// Create Process & Load Dll. 673 | // 674 | _Success_(return != NULL) 675 | PVOID WINAPI DetourFindRemotePayload(_In_ HANDLE hProcess, 676 | _In_ REFGUID rguid, 677 | _Out_opt_ DWORD *pcbData); 678 | 679 | typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEA)( 680 | _In_opt_ LPCSTR lpApplicationName, 681 | _Inout_opt_ LPSTR lpCommandLine, 682 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 683 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 684 | _In_ BOOL bInheritHandles, 685 | _In_ DWORD dwCreationFlags, 686 | _In_opt_ LPVOID lpEnvironment, 687 | _In_opt_ LPCSTR lpCurrentDirectory, 688 | _In_ LPSTARTUPINFOA lpStartupInfo, 689 | _Out_ LPPROCESS_INFORMATION lpProcessInformation); 690 | 691 | typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEW)( 692 | _In_opt_ LPCWSTR lpApplicationName, 693 | _Inout_opt_ LPWSTR lpCommandLine, 694 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 695 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 696 | _In_ BOOL bInheritHandles, 697 | _In_ DWORD dwCreationFlags, 698 | _In_opt_ LPVOID lpEnvironment, 699 | _In_opt_ LPCWSTR lpCurrentDirectory, 700 | _In_ LPSTARTUPINFOW lpStartupInfo, 701 | _Out_ LPPROCESS_INFORMATION lpProcessInformation); 702 | 703 | BOOL WINAPI DetourCreateProcessWithDllA(_In_opt_ LPCSTR lpApplicationName, 704 | _Inout_opt_ LPSTR lpCommandLine, 705 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 706 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 707 | _In_ BOOL bInheritHandles, 708 | _In_ DWORD dwCreationFlags, 709 | _In_opt_ LPVOID lpEnvironment, 710 | _In_opt_ LPCSTR lpCurrentDirectory, 711 | _In_ LPSTARTUPINFOA lpStartupInfo, 712 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 713 | _In_ LPCSTR lpDllName, 714 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 715 | 716 | BOOL WINAPI DetourCreateProcessWithDllW(_In_opt_ LPCWSTR lpApplicationName, 717 | _Inout_opt_ LPWSTR lpCommandLine, 718 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 719 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 720 | _In_ BOOL bInheritHandles, 721 | _In_ DWORD dwCreationFlags, 722 | _In_opt_ LPVOID lpEnvironment, 723 | _In_opt_ LPCWSTR lpCurrentDirectory, 724 | _In_ LPSTARTUPINFOW lpStartupInfo, 725 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 726 | _In_ LPCSTR lpDllName, 727 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 728 | 729 | #ifdef UNICODE 730 | #define DetourCreateProcessWithDll DetourCreateProcessWithDllW 731 | #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEW 732 | #else 733 | #define DetourCreateProcessWithDll DetourCreateProcessWithDllA 734 | #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEA 735 | #endif // !UNICODE 736 | 737 | BOOL WINAPI DetourCreateProcessWithDllExA(_In_opt_ LPCSTR lpApplicationName, 738 | _Inout_opt_ LPSTR lpCommandLine, 739 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 740 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 741 | _In_ BOOL bInheritHandles, 742 | _In_ DWORD dwCreationFlags, 743 | _In_opt_ LPVOID lpEnvironment, 744 | _In_opt_ LPCSTR lpCurrentDirectory, 745 | _In_ LPSTARTUPINFOA lpStartupInfo, 746 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 747 | _In_ LPCSTR lpDllName, 748 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 749 | 750 | BOOL WINAPI DetourCreateProcessWithDllExW(_In_opt_ LPCWSTR lpApplicationName, 751 | _Inout_opt_ LPWSTR lpCommandLine, 752 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 753 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 754 | _In_ BOOL bInheritHandles, 755 | _In_ DWORD dwCreationFlags, 756 | _In_opt_ LPVOID lpEnvironment, 757 | _In_opt_ LPCWSTR lpCurrentDirectory, 758 | _In_ LPSTARTUPINFOW lpStartupInfo, 759 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 760 | _In_ LPCSTR lpDllName, 761 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 762 | 763 | #ifdef UNICODE 764 | #define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExW 765 | #else 766 | #define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExA 767 | #endif // !UNICODE 768 | 769 | BOOL WINAPI DetourCreateProcessWithDllsA(_In_opt_ LPCSTR lpApplicationName, 770 | _Inout_opt_ LPSTR lpCommandLine, 771 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 772 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 773 | _In_ BOOL bInheritHandles, 774 | _In_ DWORD dwCreationFlags, 775 | _In_opt_ LPVOID lpEnvironment, 776 | _In_opt_ LPCSTR lpCurrentDirectory, 777 | _In_ LPSTARTUPINFOA lpStartupInfo, 778 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 779 | _In_ DWORD nDlls, 780 | _In_reads_(nDlls) LPCSTR *rlpDlls, 781 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 782 | 783 | BOOL WINAPI DetourCreateProcessWithDllsW(_In_opt_ LPCWSTR lpApplicationName, 784 | _Inout_opt_ LPWSTR lpCommandLine, 785 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 786 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 787 | _In_ BOOL bInheritHandles, 788 | _In_ DWORD dwCreationFlags, 789 | _In_opt_ LPVOID lpEnvironment, 790 | _In_opt_ LPCWSTR lpCurrentDirectory, 791 | _In_ LPSTARTUPINFOW lpStartupInfo, 792 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 793 | _In_ DWORD nDlls, 794 | _In_reads_(nDlls) LPCSTR *rlpDlls, 795 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 796 | 797 | #ifdef UNICODE 798 | #define DetourCreateProcessWithDlls DetourCreateProcessWithDllsW 799 | #else 800 | #define DetourCreateProcessWithDlls DetourCreateProcessWithDllsA 801 | #endif // !UNICODE 802 | 803 | BOOL WINAPI DetourProcessViaHelperA(_In_ DWORD dwTargetPid, 804 | _In_ LPCSTR lpDllName, 805 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 806 | 807 | BOOL WINAPI DetourProcessViaHelperW(_In_ DWORD dwTargetPid, 808 | _In_ LPCSTR lpDllName, 809 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 810 | 811 | #ifdef UNICODE 812 | #define DetourProcessViaHelper DetourProcessViaHelperW 813 | #else 814 | #define DetourProcessViaHelper DetourProcessViaHelperA 815 | #endif // !UNICODE 816 | 817 | BOOL WINAPI DetourProcessViaHelperDllsA(_In_ DWORD dwTargetPid, 818 | _In_ DWORD nDlls, 819 | _In_reads_(nDlls) LPCSTR *rlpDlls, 820 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 821 | 822 | BOOL WINAPI DetourProcessViaHelperDllsW(_In_ DWORD dwTargetPid, 823 | _In_ DWORD nDlls, 824 | _In_reads_(nDlls) LPCSTR *rlpDlls, 825 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 826 | 827 | #ifdef UNICODE 828 | #define DetourProcessViaHelperDlls DetourProcessViaHelperDllsW 829 | #else 830 | #define DetourProcessViaHelperDlls DetourProcessViaHelperDllsA 831 | #endif // !UNICODE 832 | 833 | BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess, 834 | _In_reads_(nDlls) LPCSTR *rlpDlls, 835 | _In_ DWORD nDlls); 836 | 837 | BOOL WINAPI DetourUpdateProcessWithDllEx(_In_ HANDLE hProcess, 838 | _In_ HMODULE hImage, 839 | _In_ BOOL bIs32Bit, 840 | _In_reads_(nDlls) LPCSTR *rlpDlls, 841 | _In_ DWORD nDlls); 842 | 843 | BOOL WINAPI DetourCopyPayloadToProcess(_In_ HANDLE hProcess, 844 | _In_ REFGUID rguid, 845 | _In_reads_bytes_(cbData) LPCVOID pvData, 846 | _In_ DWORD cbData); 847 | _Success_(return != NULL) 848 | PVOID WINAPI DetourCopyPayloadToProcessEx(_In_ HANDLE hProcess, 849 | _In_ REFGUID rguid, 850 | _In_reads_bytes_(cbData) LPCVOID pvData, 851 | _In_ DWORD cbData); 852 | 853 | BOOL WINAPI DetourRestoreAfterWith(VOID); 854 | BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, 855 | _In_ DWORD cbData); 856 | BOOL WINAPI DetourIsHelperProcess(VOID); 857 | VOID CALLBACK DetourFinishHelperProcess(_In_ HWND, 858 | _In_ HINSTANCE, 859 | _In_ LPSTR, 860 | _In_ INT); 861 | 862 | // 863 | ////////////////////////////////////////////////////////////////////////////// 864 | #ifdef __cplusplus 865 | } 866 | #endif // __cplusplus 867 | 868 | /////////////////////////////////////////////////// Type-safe overloads for C++ 869 | // 870 | #if __cplusplus >= 201103L || _MSVC_LANG >= 201103L 871 | #include 872 | 873 | template 874 | struct DetoursIsFunctionPointer : std::false_type {}; 875 | 876 | template 877 | struct DetoursIsFunctionPointer : std::is_function::type> {}; 878 | 879 | template< 880 | typename T, 881 | typename std::enable_if::value, int>::type = 0> 882 | LONG DetourAttach(_Inout_ T *ppPointer, 883 | _In_ T pDetour) noexcept 884 | { 885 | return DetourAttach( 886 | reinterpret_cast(ppPointer), 887 | reinterpret_cast(pDetour)); 888 | } 889 | 890 | template< 891 | typename T, 892 | typename std::enable_if::value, int>::type = 0> 893 | LONG DetourAttachEx(_Inout_ T *ppPointer, 894 | _In_ T pDetour, 895 | _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline, 896 | _Out_opt_ T *ppRealTarget, 897 | _Out_opt_ T *ppRealDetour) noexcept 898 | { 899 | return DetourAttachEx( 900 | reinterpret_cast(ppPointer), 901 | reinterpret_cast(pDetour), 902 | ppRealTrampoline, 903 | reinterpret_cast(ppRealTarget), 904 | reinterpret_cast(ppRealDetour)); 905 | } 906 | 907 | template< 908 | typename T, 909 | typename std::enable_if::value, int>::type = 0> 910 | LONG DetourDetach(_Inout_ T *ppPointer, 911 | _In_ T pDetour) noexcept 912 | { 913 | return DetourDetach( 914 | reinterpret_cast(ppPointer), 915 | reinterpret_cast(pDetour)); 916 | } 917 | 918 | #endif // __cplusplus >= 201103L || _MSVC_LANG >= 201103L 919 | // 920 | ////////////////////////////////////////////////////////////////////////////// 921 | 922 | //////////////////////////////////////////////// Detours Internal Definitions. 923 | // 924 | #ifdef __cplusplus 925 | #ifdef DETOURS_INTERNAL 926 | 927 | #define NOTHROW 928 | // #define NOTHROW (nothrow) 929 | 930 | ////////////////////////////////////////////////////////////////////////////// 931 | // 932 | #if (_MSC_VER < 1299) && !defined(__GNUC__) 933 | #include 934 | typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64; 935 | typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64; 936 | typedef IMAGEHLP_SYMBOL SYMBOL_INFO; 937 | typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO; 938 | 939 | static inline 940 | LONG InterlockedCompareExchange(_Inout_ LONG *ptr, _In_ LONG nval, _In_ LONG oval) 941 | { 942 | return (LONG)::InterlockedCompareExchange((PVOID*)ptr, (PVOID)nval, (PVOID)oval); 943 | } 944 | #else 945 | #pragma warning(push) 946 | #pragma warning(disable:4091) // empty typedef 947 | #include 948 | #pragma warning(pop) 949 | #endif 950 | 951 | #ifdef IMAGEAPI // defined by DBGHELP.H 952 | typedef LPAPI_VERSION (NTAPI *PF_ImagehlpApiVersionEx)(_In_ LPAPI_VERSION AppVersion); 953 | 954 | typedef BOOL (NTAPI *PF_SymInitialize)(_In_ HANDLE hProcess, 955 | _In_opt_ LPCSTR UserSearchPath, 956 | _In_ BOOL fInvadeProcess); 957 | typedef DWORD (NTAPI *PF_SymSetOptions)(_In_ DWORD SymOptions); 958 | typedef DWORD (NTAPI *PF_SymGetOptions)(VOID); 959 | typedef DWORD64 (NTAPI *PF_SymLoadModule64)(_In_ HANDLE hProcess, 960 | _In_opt_ HANDLE hFile, 961 | _In_opt_ LPSTR ImageName, 962 | _In_opt_ LPSTR ModuleName, 963 | _In_ DWORD64 BaseOfDll, 964 | _In_ DWORD SizeOfDll); 965 | typedef BOOL (NTAPI *PF_SymGetModuleInfo64)(_In_ HANDLE hProcess, 966 | _In_ DWORD64 qwAddr, 967 | _Out_ PIMAGEHLP_MODULE64 ModuleInfo); 968 | typedef BOOL (NTAPI *PF_SymFromName)(_In_ HANDLE hProcess, 969 | _In_ LPSTR Name, 970 | _Out_ PSYMBOL_INFO Symbol); 971 | 972 | typedef struct _DETOUR_SYM_INFO 973 | { 974 | HANDLE hProcess; 975 | HMODULE hDbgHelp; 976 | PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx; 977 | PF_SymInitialize pfSymInitialize; 978 | PF_SymSetOptions pfSymSetOptions; 979 | PF_SymGetOptions pfSymGetOptions; 980 | PF_SymLoadModule64 pfSymLoadModule64; 981 | PF_SymGetModuleInfo64 pfSymGetModuleInfo64; 982 | PF_SymFromName pfSymFromName; 983 | } DETOUR_SYM_INFO, *PDETOUR_SYM_INFO; 984 | 985 | PDETOUR_SYM_INFO DetourLoadImageHlp(VOID); 986 | 987 | #endif // IMAGEAPI 988 | 989 | #if defined(_INC_STDIO) && !defined(_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS) 990 | #error detours.h must be included before stdio.h (or at least define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS earlier) 991 | #endif 992 | #define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1 993 | 994 | #ifdef _DEBUG 995 | 996 | int Detour_AssertExprWithFunctionName(int reportType, const char* filename, int linenumber, const char* FunctionName, const char* msg); 997 | 998 | #define DETOUR_ASSERT_EXPR_WITH_FUNCTION(expr, msg) \ 999 | (void) ((expr) || \ 1000 | (1 != Detour_AssertExprWithFunctionName(_CRT_ASSERT, __FILE__, __LINE__,__FUNCTION__, msg)) || \ 1001 | (_CrtDbgBreak(), 0)) 1002 | 1003 | #define DETOUR_ASSERT(expr) DETOUR_ASSERT_EXPR_WITH_FUNCTION((expr), #expr) 1004 | 1005 | #else// _DEBUG 1006 | #define DETOUR_ASSERT(expr) 1007 | #endif// _DEBUG 1008 | 1009 | #ifndef DETOUR_TRACE 1010 | #if DETOUR_DEBUG 1011 | #define DETOUR_TRACE(x) printf x 1012 | #define DETOUR_BREAK() __debugbreak() 1013 | #include 1014 | #include 1015 | #else 1016 | #define DETOUR_TRACE(x) 1017 | #define DETOUR_BREAK() 1018 | #endif 1019 | #endif 1020 | 1021 | #if 1 || defined(DETOURS_IA64) 1022 | 1023 | // 1024 | // IA64 instructions are 41 bits, 3 per bundle, plus 5 bit bundle template => 128 bits per bundle. 1025 | // 1026 | 1027 | #define DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE (3) 1028 | 1029 | #define DETOUR_IA64_TEMPLATE_OFFSET (0) 1030 | #define DETOUR_IA64_TEMPLATE_SIZE (5) 1031 | 1032 | #define DETOUR_IA64_INSTRUCTION_SIZE (41) 1033 | #define DETOUR_IA64_INSTRUCTION0_OFFSET (DETOUR_IA64_TEMPLATE_SIZE) 1034 | #define DETOUR_IA64_INSTRUCTION1_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) 1035 | #define DETOUR_IA64_INSTRUCTION2_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) 1036 | 1037 | C_ASSERT(DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE * DETOUR_IA64_INSTRUCTION_SIZE == 128); 1038 | 1039 | __declspec(align(16)) struct DETOUR_IA64_BUNDLE 1040 | { 1041 | public: 1042 | union 1043 | { 1044 | BYTE data[16]; 1045 | UINT64 wide[2]; 1046 | }; 1047 | 1048 | enum { 1049 | A_UNIT = 1u, 1050 | I_UNIT = 2u, 1051 | M_UNIT = 3u, 1052 | B_UNIT = 4u, 1053 | F_UNIT = 5u, 1054 | L_UNIT = 6u, 1055 | X_UNIT = 7u, 1056 | }; 1057 | struct DETOUR_IA64_METADATA 1058 | { 1059 | ULONG nTemplate : 8; // Instruction template. 1060 | ULONG nUnit0 : 4; // Unit for slot 0 1061 | ULONG nUnit1 : 4; // Unit for slot 1 1062 | ULONG nUnit2 : 4; // Unit for slot 2 1063 | }; 1064 | 1065 | protected: 1066 | static const DETOUR_IA64_METADATA s_rceCopyTable[33]; 1067 | 1068 | UINT RelocateBundle(_Inout_ DETOUR_IA64_BUNDLE* pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; 1069 | 1070 | bool RelocateInstruction(_Inout_ DETOUR_IA64_BUNDLE* pDst, 1071 | _In_ BYTE slot, 1072 | _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; 1073 | 1074 | // 120 112 104 96 88 80 72 64 56 48 40 32 24 16 8 0 1075 | // f. e. d. c. b. a. 9. 8. 7. 6. 5. 4. 3. 2. 1. 0. 1076 | 1077 | // 00 1078 | // f.e. d.c. b.a. 9.8. 7.6. 5.4. 3.2. 1.0. 1079 | // 0000 0000 0000 0000 0000 0000 0000 001f : Template [4..0] 1080 | // 0000 0000 0000 0000 0000 03ff ffff ffe0 : Zero [ 41.. 5] 1081 | // 0000 0000 0000 0000 0000 3c00 0000 0000 : Zero [ 45.. 42] 1082 | // 0000 0000 0007 ffff ffff c000 0000 0000 : One [ 82.. 46] 1083 | // 0000 0000 0078 0000 0000 0000 0000 0000 : One [ 86.. 83] 1084 | // 0fff ffff ff80 0000 0000 0000 0000 0000 : Two [123.. 87] 1085 | // f000 0000 0000 0000 0000 0000 0000 0000 : Two [127..124] 1086 | BYTE GetTemplate() const; 1087 | // Get 4 bit opcodes. 1088 | BYTE GetInst0() const; 1089 | BYTE GetInst1() const; 1090 | BYTE GetInst2() const; 1091 | BYTE GetUnit(BYTE slot) const; 1092 | BYTE GetUnit0() const; 1093 | BYTE GetUnit1() const; 1094 | BYTE GetUnit2() const; 1095 | // Get 37 bit data. 1096 | UINT64 GetData0() const; 1097 | UINT64 GetData1() const; 1098 | UINT64 GetData2() const; 1099 | 1100 | // Get/set the full 41 bit instructions. 1101 | UINT64 GetInstruction(BYTE slot) const; 1102 | UINT64 GetInstruction0() const; 1103 | UINT64 GetInstruction1() const; 1104 | UINT64 GetInstruction2() const; 1105 | void SetInstruction(BYTE slot, UINT64 instruction); 1106 | void SetInstruction0(UINT64 instruction); 1107 | void SetInstruction1(UINT64 instruction); 1108 | void SetInstruction2(UINT64 instruction); 1109 | 1110 | // Get/set bitfields. 1111 | static UINT64 GetBits(UINT64 Value, UINT64 Offset, UINT64 Count); 1112 | static UINT64 SetBits(UINT64 Value, UINT64 Offset, UINT64 Count, UINT64 Field); 1113 | 1114 | // Get specific read-only fields. 1115 | static UINT64 GetOpcode(UINT64 instruction); // 4bit opcode 1116 | static UINT64 GetX(UINT64 instruction); // 1bit opcode extension 1117 | static UINT64 GetX3(UINT64 instruction); // 3bit opcode extension 1118 | static UINT64 GetX6(UINT64 instruction); // 6bit opcode extension 1119 | 1120 | // Get/set specific fields. 1121 | static UINT64 GetImm7a(UINT64 instruction); 1122 | static UINT64 SetImm7a(UINT64 instruction, UINT64 imm7a); 1123 | static UINT64 GetImm13c(UINT64 instruction); 1124 | static UINT64 SetImm13c(UINT64 instruction, UINT64 imm13c); 1125 | static UINT64 GetSignBit(UINT64 instruction); 1126 | static UINT64 SetSignBit(UINT64 instruction, UINT64 signBit); 1127 | static UINT64 GetImm20a(UINT64 instruction); 1128 | static UINT64 SetImm20a(UINT64 instruction, UINT64 imm20a); 1129 | static UINT64 GetImm20b(UINT64 instruction); 1130 | static UINT64 SetImm20b(UINT64 instruction, UINT64 imm20b); 1131 | 1132 | static UINT64 SignExtend(UINT64 Value, UINT64 Offset); 1133 | 1134 | BOOL IsMovlGp() const; 1135 | 1136 | VOID SetInst(BYTE Slot, BYTE nInst); 1137 | VOID SetInst0(BYTE nInst); 1138 | VOID SetInst1(BYTE nInst); 1139 | VOID SetInst2(BYTE nInst); 1140 | VOID SetData(BYTE Slot, UINT64 nData); 1141 | VOID SetData0(UINT64 nData); 1142 | VOID SetData1(UINT64 nData); 1143 | VOID SetData2(UINT64 nData); 1144 | BOOL SetNop(BYTE Slot); 1145 | BOOL SetNop0(); 1146 | BOOL SetNop1(); 1147 | BOOL SetNop2(); 1148 | 1149 | public: 1150 | BOOL IsBrl() const; 1151 | VOID SetBrl(); 1152 | VOID SetBrl(UINT64 target); 1153 | UINT64 GetBrlTarget() const; 1154 | VOID SetBrlTarget(UINT64 target); 1155 | VOID SetBrlImm(UINT64 imm); 1156 | UINT64 GetBrlImm() const; 1157 | 1158 | UINT64 GetMovlGp() const; 1159 | VOID SetMovlGp(UINT64 gp); 1160 | 1161 | VOID SetStop(); 1162 | 1163 | UINT Copy(_Out_ DETOUR_IA64_BUNDLE *pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra = NULL) const; 1164 | }; 1165 | #endif // DETOURS_IA64 1166 | 1167 | #ifdef DETOURS_ARM 1168 | 1169 | #define DETOURS_PFUNC_TO_PBYTE(p) ((PBYTE)(((ULONG_PTR)(p)) & ~(ULONG_PTR)1)) 1170 | #define DETOURS_PBYTE_TO_PFUNC(p) ((PBYTE)(((ULONG_PTR)(p)) | (ULONG_PTR)1)) 1171 | 1172 | #endif // DETOURS_ARM 1173 | 1174 | ////////////////////////////////////////////////////////////////////////////// 1175 | 1176 | #ifdef __cplusplus 1177 | extern "C" { 1178 | #endif // __cplusplus 1179 | 1180 | #define DETOUR_OFFLINE_LIBRARY(x) \ 1181 | PVOID WINAPI DetourCopyInstruction##x(_In_opt_ PVOID pDst, \ 1182 | _Inout_opt_ PVOID *ppDstPool, \ 1183 | _In_ PVOID pSrc, \ 1184 | _Out_opt_ PVOID *ppTarget, \ 1185 | _Out_opt_ LONG *plExtra); \ 1186 | \ 1187 | BOOL WINAPI DetourSetCodeModule##x(_In_ HMODULE hModule, \ 1188 | _In_ BOOL fLimitReferencesToModule); \ 1189 | 1190 | DETOUR_OFFLINE_LIBRARY(X86) 1191 | DETOUR_OFFLINE_LIBRARY(X64) 1192 | DETOUR_OFFLINE_LIBRARY(ARM) 1193 | DETOUR_OFFLINE_LIBRARY(ARM64) 1194 | DETOUR_OFFLINE_LIBRARY(IA64) 1195 | 1196 | #undef DETOUR_OFFLINE_LIBRARY 1197 | 1198 | ////////////////////////////////////////////////////////////////////////////// 1199 | // 1200 | // Helpers for manipulating page protection. 1201 | // 1202 | 1203 | _Success_(return != FALSE) 1204 | BOOL WINAPI DetourVirtualProtectSameExecuteEx(_In_ HANDLE hProcess, 1205 | _In_ PVOID pAddress, 1206 | _In_ SIZE_T nSize, 1207 | _In_ DWORD dwNewProtect, 1208 | _Out_ PDWORD pdwOldProtect); 1209 | 1210 | _Success_(return != FALSE) 1211 | BOOL WINAPI DetourVirtualProtectSameExecute(_In_ PVOID pAddress, 1212 | _In_ SIZE_T nSize, 1213 | _In_ DWORD dwNewProtect, 1214 | _Out_ PDWORD pdwOldProtect); 1215 | 1216 | // Detours must depend only on kernel32.lib, so we cannot use IsEqualGUID 1217 | BOOL WINAPI DetourAreSameGuid(_In_ REFGUID left, _In_ REFGUID right); 1218 | #ifdef __cplusplus 1219 | } 1220 | #endif // __cplusplus 1221 | 1222 | ////////////////////////////////////////////////////////////////////////////// 1223 | 1224 | #define MM_ALLOCATION_GRANULARITY 0x10000 1225 | 1226 | ////////////////////////////////////////////////////////////////////////////// 1227 | 1228 | #endif // DETOURS_INTERNAL 1229 | #endif // __cplusplus 1230 | 1231 | #endif // _DETOURS_H_ 1232 | // 1233 | //////////////////////////////////////////////////////////////// End of File. 1234 | -------------------------------------------------------------------------------- /DetoursLibrary/x64/detours.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NoMoreFood/WinPriv/ea8584c172e4f31ced4fb2eb073562aed09b3b57/DetoursLibrary/x64/detours.lib -------------------------------------------------------------------------------- /DetoursLibrary/x64/detver.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Common version parameters. 4 | // 5 | // Microsoft Research Detours Package, Version 4.0.1 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | 10 | #define _USING_V110_SDK71_ 1 11 | #include "winver.h" 12 | #if 0 13 | #include 14 | #include 15 | #else 16 | #ifndef DETOURS_STRINGIFY 17 | #define DETOURS_STRINGIFY_(x) #x 18 | #define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) 19 | #endif 20 | 21 | #define VER_FILEFLAGSMASK 0x3fL 22 | #define VER_FILEFLAGS 0x0L 23 | #define VER_FILEOS 0x00040004L 24 | #define VER_FILETYPE 0x00000002L 25 | #define VER_FILESUBTYPE 0x00000000L 26 | #endif 27 | #define VER_DETOURS_BITS DETOURS_STRINGIFY(DETOURS_BITS) 28 | -------------------------------------------------------------------------------- /DetoursLibrary/x64/syelog.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Detours Test Program (syelog.h of syelog.lib) 4 | // 5 | // Microsoft Research Detours Package 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | #pragma once 10 | #ifndef _SYELOGD_H_ 11 | #define _SYELOGD_H_ 12 | #include 13 | 14 | #pragma pack(push, 1) 15 | #pragma warning(push) 16 | #pragma warning(disable: 4200) 17 | 18 | ////////////////////////////////////////////////////////////////////////////// 19 | // 20 | // 21 | #define SYELOG_PIPE_NAMEA "\\\\.\\pipe\\syelog" 22 | #define SYELOG_PIPE_NAMEW L"\\\\.\\pipe\\syelog" 23 | #ifdef UNICODE 24 | #define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEW 25 | #else 26 | #define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEA 27 | #endif 28 | 29 | ////////////////////////////////////////////////////////////////////////////// 30 | // 31 | #define SYELOG_MAXIMUM_MESSAGE 4086 // 4096 - sizeof(header stuff) 32 | 33 | typedef struct _SYELOG_MESSAGE 34 | { 35 | USHORT nBytes; 36 | BYTE nFacility; 37 | BYTE nSeverity; 38 | DWORD nProcessId; 39 | FILETIME ftOccurance; 40 | BOOL fTerminate; 41 | CHAR szMessage[SYELOG_MAXIMUM_MESSAGE]; 42 | } SYELOG_MESSAGE, *PSYELOG_MESSAGE; 43 | 44 | 45 | // Facility Codes. 46 | // 47 | #define SYELOG_FACILITY_KERNEL 0x10 // OS Kernel 48 | #define SYELOG_FACILITY_SECURITY 0x20 // OS Security 49 | #define SYELOG_FACILITY_LOGGING 0x30 // OS Logging-internal 50 | #define SYELOG_FACILITY_SERVICE 0x40 // User-mode system daemon 51 | #define SYELOG_FACILITY_APPLICATION 0x50 // User-mode application 52 | #define SYELOG_FACILITY_USER 0x60 // User self-generated. 53 | #define SYELOG_FACILITY_LOCAL0 0x70 // Locally defined. 54 | #define SYELOG_FACILITY_LOCAL1 0x71 // Locally defined. 55 | #define SYELOG_FACILITY_LOCAL2 0x72 // Locally defined. 56 | #define SYELOG_FACILITY_LOCAL3 0x73 // Locally defined. 57 | #define SYELOG_FACILITY_LOCAL4 0x74 // Locally defined. 58 | #define SYELOG_FACILITY_LOCAL5 0x75 // Locally defined. 59 | #define SYELOG_FACILITY_LOCAL6 0x76 // Locally defined. 60 | #define SYELOG_FACILITY_LOCAL7 0x77 // Locally defined. 61 | #define SYELOG_FACILITY_LOCAL8 0x78 // Locally defined. 62 | #define SYELOG_FACILITY_LOCAL9 0x79 // Locally defined. 63 | 64 | // Severity Codes. 65 | // 66 | #define SYELOG_SEVERITY_FATAL 0x00 // System is dead. 67 | #define SYELOG_SEVERITY_ALERT 0x10 // Take action immediately. 68 | #define SYELOG_SEVERITY_CRITICAL 0x20 // Critical condition. 69 | #define SYELOG_SEVERITY_ERROR 0x30 // Error 70 | #define SYELOG_SEVERITY_WARNING 0x40 // Warning 71 | #define SYELOG_SEVERITY_NOTICE 0x50 // Significant condition. 72 | #define SYELOG_SEVERITY_INFORMATION 0x60 // Informational 73 | #define SYELOG_SEVERITY_AUDIT_FAIL 0x66 // Audit Failed 74 | #define SYELOG_SEVERITY_AUDIT_PASS 0x67 // Audit Succeeeded 75 | #define SYELOG_SEVERITY_DEBUG 0x70 // Debugging 76 | 77 | // Logging Functions. 78 | // 79 | VOID SyelogOpen(PCSTR pszIdentifier, BYTE nFacility); 80 | VOID Syelog(BYTE nSeverity, PCSTR pszMsgf, ...); 81 | VOID SyelogV(BYTE nSeverity, PCSTR pszMsgf, va_list args); 82 | VOID SyelogClose(BOOL fTerminate); 83 | 84 | #pragma warning(pop) 85 | #pragma pack(pop) 86 | 87 | #endif // _SYELOGD_H_ 88 | // 89 | ///////////////////////////////////////////////////////////////// End of File. 90 | -------------------------------------------------------------------------------- /DetoursLibrary/x64/syelog.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NoMoreFood/WinPriv/ea8584c172e4f31ced4fb2eb073562aed09b3b57/DetoursLibrary/x64/syelog.lib -------------------------------------------------------------------------------- /DetoursLibrary/x86/detours.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NoMoreFood/WinPriv/ea8584c172e4f31ced4fb2eb073562aed09b3b57/DetoursLibrary/x86/detours.lib -------------------------------------------------------------------------------- /DetoursLibrary/x86/detver.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Common version parameters. 4 | // 5 | // Microsoft Research Detours Package, Version 4.0.1 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | 10 | #define _USING_V110_SDK71_ 1 11 | #include "winver.h" 12 | #if 0 13 | #include 14 | #include 15 | #else 16 | #ifndef DETOURS_STRINGIFY 17 | #define DETOURS_STRINGIFY_(x) #x 18 | #define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) 19 | #endif 20 | 21 | #define VER_FILEFLAGSMASK 0x3fL 22 | #define VER_FILEFLAGS 0x0L 23 | #define VER_FILEOS 0x00040004L 24 | #define VER_FILETYPE 0x00000002L 25 | #define VER_FILESUBTYPE 0x00000000L 26 | #endif 27 | #define VER_DETOURS_BITS DETOURS_STRINGIFY(DETOURS_BITS) 28 | -------------------------------------------------------------------------------- /DetoursLibrary/x86/syelog.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Detours Test Program (syelog.h of syelog.lib) 4 | // 5 | // Microsoft Research Detours Package 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | #pragma once 10 | #ifndef _SYELOGD_H_ 11 | #define _SYELOGD_H_ 12 | #include 13 | 14 | #pragma pack(push, 1) 15 | #pragma warning(push) 16 | #pragma warning(disable: 4200) 17 | 18 | ////////////////////////////////////////////////////////////////////////////// 19 | // 20 | // 21 | #define SYELOG_PIPE_NAMEA "\\\\.\\pipe\\syelog" 22 | #define SYELOG_PIPE_NAMEW L"\\\\.\\pipe\\syelog" 23 | #ifdef UNICODE 24 | #define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEW 25 | #else 26 | #define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEA 27 | #endif 28 | 29 | ////////////////////////////////////////////////////////////////////////////// 30 | // 31 | #define SYELOG_MAXIMUM_MESSAGE 4086 // 4096 - sizeof(header stuff) 32 | 33 | typedef struct _SYELOG_MESSAGE 34 | { 35 | USHORT nBytes; 36 | BYTE nFacility; 37 | BYTE nSeverity; 38 | DWORD nProcessId; 39 | FILETIME ftOccurance; 40 | BOOL fTerminate; 41 | CHAR szMessage[SYELOG_MAXIMUM_MESSAGE]; 42 | } SYELOG_MESSAGE, *PSYELOG_MESSAGE; 43 | 44 | 45 | // Facility Codes. 46 | // 47 | #define SYELOG_FACILITY_KERNEL 0x10 // OS Kernel 48 | #define SYELOG_FACILITY_SECURITY 0x20 // OS Security 49 | #define SYELOG_FACILITY_LOGGING 0x30 // OS Logging-internal 50 | #define SYELOG_FACILITY_SERVICE 0x40 // User-mode system daemon 51 | #define SYELOG_FACILITY_APPLICATION 0x50 // User-mode application 52 | #define SYELOG_FACILITY_USER 0x60 // User self-generated. 53 | #define SYELOG_FACILITY_LOCAL0 0x70 // Locally defined. 54 | #define SYELOG_FACILITY_LOCAL1 0x71 // Locally defined. 55 | #define SYELOG_FACILITY_LOCAL2 0x72 // Locally defined. 56 | #define SYELOG_FACILITY_LOCAL3 0x73 // Locally defined. 57 | #define SYELOG_FACILITY_LOCAL4 0x74 // Locally defined. 58 | #define SYELOG_FACILITY_LOCAL5 0x75 // Locally defined. 59 | #define SYELOG_FACILITY_LOCAL6 0x76 // Locally defined. 60 | #define SYELOG_FACILITY_LOCAL7 0x77 // Locally defined. 61 | #define SYELOG_FACILITY_LOCAL8 0x78 // Locally defined. 62 | #define SYELOG_FACILITY_LOCAL9 0x79 // Locally defined. 63 | 64 | // Severity Codes. 65 | // 66 | #define SYELOG_SEVERITY_FATAL 0x00 // System is dead. 67 | #define SYELOG_SEVERITY_ALERT 0x10 // Take action immediately. 68 | #define SYELOG_SEVERITY_CRITICAL 0x20 // Critical condition. 69 | #define SYELOG_SEVERITY_ERROR 0x30 // Error 70 | #define SYELOG_SEVERITY_WARNING 0x40 // Warning 71 | #define SYELOG_SEVERITY_NOTICE 0x50 // Significant condition. 72 | #define SYELOG_SEVERITY_INFORMATION 0x60 // Informational 73 | #define SYELOG_SEVERITY_AUDIT_FAIL 0x66 // Audit Failed 74 | #define SYELOG_SEVERITY_AUDIT_PASS 0x67 // Audit Succeeeded 75 | #define SYELOG_SEVERITY_DEBUG 0x70 // Debugging 76 | 77 | // Logging Functions. 78 | // 79 | VOID SyelogOpen(PCSTR pszIdentifier, BYTE nFacility); 80 | VOID Syelog(BYTE nSeverity, PCSTR pszMsgf, ...); 81 | VOID SyelogV(BYTE nSeverity, PCSTR pszMsgf, va_list args); 82 | VOID SyelogClose(BOOL fTerminate); 83 | 84 | #pragma warning(pop) 85 | #pragma pack(pop) 86 | 87 | #endif // _SYELOGD_H_ 88 | // 89 | ///////////////////////////////////////////////////////////////// End of File. 90 | -------------------------------------------------------------------------------- /DetoursLibrary/x86/syelog.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NoMoreFood/WinPriv/ea8584c172e4f31ced4fb2eb073562aed09b3b57/DetoursLibrary/x86/syelog.lib -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Bryan Berns 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /WinPriv.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 15 3 | VisualStudioVersion = 15.0.27130.2024 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinPrivLibrary", "WinPrivLibrary\WinPrivLibrary.vcxproj", "{EEDFCE80-EA9C-4AC1-B97B-D72370FAD96F}" 6 | ProjectSection(ProjectDependencies) = postProject 7 | {582D212A-66B9-4E99-A7D3-36B1C249D637} = {582D212A-66B9-4E99-A7D3-36B1C249D637} 8 | EndProjectSection 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinPriv", "WinPriv\WinPriv.vcxproj", "{C9CBD938-2A0F-4D91-81F4-94414751BFBE}" 11 | ProjectSection(ProjectDependencies) = postProject 12 | {582D212A-66B9-4E99-A7D3-36B1C249D637} = {582D212A-66B9-4E99-A7D3-36B1C249D637} 13 | {EEDFCE80-EA9C-4AC1-B97B-D72370FAD96F} = {EEDFCE80-EA9C-4AC1-B97B-D72370FAD96F} 14 | EndProjectSection 15 | EndProject 16 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinPrivCmd", "WinPrivCmd\WinPrivCmd.vcxproj", "{B35AA3D9-40D7-479D-A407-FF3B21FABB0E}" 17 | ProjectSection(ProjectDependencies) = postProject 18 | {582D212A-66B9-4E99-A7D3-36B1C249D637} = {582D212A-66B9-4E99-A7D3-36B1C249D637} 19 | {EEDFCE80-EA9C-4AC1-B97B-D72370FAD96F} = {EEDFCE80-EA9C-4AC1-B97B-D72370FAD96F} 20 | EndProjectSection 21 | EndProject 22 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinPrivShared", "WinPrivShared\WinPrivShared.vcxproj", "{582D212A-66B9-4E99-A7D3-36B1C249D637}" 23 | EndProject 24 | Global 25 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 26 | Release|x64 = Release|x64 27 | Release|x86 = Release|x86 28 | EndGlobalSection 29 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 30 | {EEDFCE80-EA9C-4AC1-B97B-D72370FAD96F}.Release|x64.ActiveCfg = Release|x64 31 | {EEDFCE80-EA9C-4AC1-B97B-D72370FAD96F}.Release|x64.Build.0 = Release|x64 32 | {EEDFCE80-EA9C-4AC1-B97B-D72370FAD96F}.Release|x86.ActiveCfg = Release|Win32 33 | {EEDFCE80-EA9C-4AC1-B97B-D72370FAD96F}.Release|x86.Build.0 = Release|Win32 34 | {C9CBD938-2A0F-4D91-81F4-94414751BFBE}.Release|x64.ActiveCfg = Release|x64 35 | {C9CBD938-2A0F-4D91-81F4-94414751BFBE}.Release|x64.Build.0 = Release|x64 36 | {C9CBD938-2A0F-4D91-81F4-94414751BFBE}.Release|x86.ActiveCfg = Release|Win32 37 | {C9CBD938-2A0F-4D91-81F4-94414751BFBE}.Release|x86.Build.0 = Release|Win32 38 | {B35AA3D9-40D7-479D-A407-FF3B21FABB0E}.Release|x64.ActiveCfg = Release|x64 39 | {B35AA3D9-40D7-479D-A407-FF3B21FABB0E}.Release|x64.Build.0 = Release|x64 40 | {B35AA3D9-40D7-479D-A407-FF3B21FABB0E}.Release|x86.ActiveCfg = Release|Win32 41 | {B35AA3D9-40D7-479D-A407-FF3B21FABB0E}.Release|x86.Build.0 = Release|Win32 42 | {582D212A-66B9-4E99-A7D3-36B1C249D637}.Release|x64.ActiveCfg = Release|x64 43 | {582D212A-66B9-4E99-A7D3-36B1C249D637}.Release|x64.Build.0 = Release|x64 44 | {582D212A-66B9-4E99-A7D3-36B1C249D637}.Release|x86.ActiveCfg = Release|Win32 45 | {582D212A-66B9-4E99-A7D3-36B1C249D637}.Release|x86.Build.0 = Release|Win32 46 | EndGlobalSection 47 | GlobalSection(SolutionProperties) = preSolution 48 | HideSolutionNode = FALSE 49 | EndGlobalSection 50 | GlobalSection(ExtensibilityGlobals) = postSolution 51 | SolutionGuid = {423A1C03-448E-434B-9FE7-3D89AB57ED9C} 52 | EndGlobalSection 53 | EndGlobal 54 | -------------------------------------------------------------------------------- /WinPriv/WinPriv.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Bryan Berns. All rights reserved. 3 | // Licensed under the MIT license. See LICENSE file in the project root for details. 4 | // 5 | 6 | #define _WINSOCKAPI_ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "WinPrivShared.h" 26 | #include "WinPrivResource.h" 27 | 28 | #pragma comment(lib,"rpcrt4.lib") 29 | 30 | extern int LaunchNewLogon(int iArgc, wchar_t *aArgv[]); 31 | extern int LaunchElevated(int iArgc, wchar_t *aArgv[]); 32 | extern std::map GetPrivilegeList(); 33 | extern std::wstring GetWinPrivHelp(); 34 | 35 | bool WriteResourceToFile(const std::wstring& sOutputDirectory, DWORD iResourceId) 36 | { 37 | // locate the resource that has the embedded library 38 | const HRSRC hRes = FindResource(nullptr, MAKEINTRESOURCE(iResourceId), L"RT_RCDATA"); 39 | if (hRes == nullptr) 40 | { 41 | PrintMessage(L"ERROR: Could not locate internal resource data.\n"); 42 | return false; 43 | } 44 | 45 | // load the resource that has the embedded detours library 46 | const HGLOBAL hResourceLoadedX86 = LoadResource(nullptr, hRes); 47 | if (hResourceLoadedX86 == nullptr) 48 | { 49 | PrintMessage(L"ERROR: Could not load internal resource data.\n"); 50 | return false; 51 | } 52 | 53 | // create the library files 54 | const HANDLE hTempFile = CreateFile(sOutputDirectory.c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); 55 | if (hTempFile == INVALID_HANDLE_VALUE) 56 | { 57 | PrintMessage(L"ERROR: Problem creating library file.\n"); 58 | return false; 59 | } 60 | 61 | // write the resource into the temporary file 62 | DWORD wSizeRes = SizeofResource(nullptr, hRes); 63 | if (WriteFile(hTempFile, hResourceLoadedX86, wSizeRes, &wSizeRes, nullptr) == 0) 64 | { 65 | PrintMessage(L"ERROR: Problem writing library file.\n"); 66 | return false; 67 | } 68 | 69 | // close out handles so process can use it 70 | if (CloseHandle(hTempFile) == 0) 71 | { 72 | PrintMessage(L"ERROR: Problem closing library file.\n"); 73 | return false; 74 | } 75 | 76 | return true; 77 | } 78 | 79 | std::wstring GetRunningExecutable() 80 | { 81 | // attempt to get the directory to the path to this executable 82 | std::wstring sThisExecutable; 83 | sThisExecutable.resize(MAX_PATH + 1); 84 | if (GetModuleFileName(nullptr, sThisExecutable.data(), MAX_PATH + 1) == 0) 85 | { 86 | PrintMessage(L"ERROR: Error fetching currently executable path.\n"); 87 | std::exit(0); 88 | return L""; 89 | } 90 | 91 | sThisExecutable.resize(sThisExecutable.find(L'\0')); 92 | return sThisExecutable; 93 | } 94 | 95 | std::wstring GetLocalLibraryPath(bool bIs64Bit) 96 | { 97 | const std::wstring sThisExecutable = GetRunningExecutable(); 98 | 99 | // trim of final path element 100 | const std::wstring sBasePath = sThisExecutable.substr(0, sThisExecutable.find_last_of(L'\\')); 101 | 102 | // return directory name 103 | return sBasePath + (bIs64Bit ? L"\\WinPrivLibrary-64.dll" : L"\\WinPrivLibrary-32.dll"); 104 | } 105 | 106 | int RunProgram(int iArgc, wchar_t *aArgv[]) 107 | { 108 | // get list of all privileges for general use later 109 | std::map vPrivMaps = GetPrivilegeList(); 110 | 111 | // list of privs populated by command line args that will be enabled 112 | std::vector vPrivsToEnable; 113 | 114 | // initialize settings that will be inherited by subprocesses 115 | SetEnvironmentVariable(WINPRIV_EV_PRIVLIST, L""); 116 | SetEnvironmentVariable(WINPRIV_EV_HOST_OVERRIDE, L""); 117 | SetEnvironmentVariable(WINPRIV_EV_MAC_OVERRIDE, L""); 118 | SetEnvironmentVariable(WINPRIV_EV_REG_OVERRIDE, L""); 119 | SetEnvironmentVariable(WINPRIV_EV_BACKUP_RESTORE, L"0"); 120 | SetEnvironmentVariable(WINPRIV_EV_BREAK_LOCKS, L"0"); 121 | SetEnvironmentVariable(WINPRIV_EV_ADMIN_IMPERSONATE, L"0"); 122 | SetEnvironmentVariable(WINPRIV_EV_SERVER_EDITION, L"0"); 123 | SetEnvironmentVariable(WINPRIV_EV_RECORD_CRYPTO, L""); 124 | SetEnvironmentVariable(WINPRIV_EV_SQL_CONNECT_SHOW, L""); 125 | SetEnvironmentVariable(WINPRIV_EV_SQL_CONNECT_SEARCH, L""); 126 | SetEnvironmentVariable(WINPRIV_EV_SQL_CONNECT_REPLACE, L""); 127 | SetEnvironmentVariable(WINPRIV_EV_RELAUNCH_MODE, L"0"); 128 | SetEnvironmentVariable(WINPRIV_EV_PARENT_PID, std::to_wstring(GetCurrentProcessId()).c_str()); 129 | 130 | // registry override parameters populated by command line args 131 | std::wstring sRegistryOverride; 132 | 133 | // host override parameters populated by command line args 134 | std::wstring sHostOverride; 135 | 136 | // target executable and options provided by command line args 137 | std::wstring sProcessParams; 138 | std::wstring sProcess; 139 | 140 | // whether or not to provide execution time 141 | bool bDisplayExecutionTime = false; 142 | 143 | // show mode if selected 144 | WORD iShowWindow = SW_NORMAL; 145 | 146 | // show mode if selected 147 | bool bUseShellExecute = false; 148 | 149 | // whether or not to kill any processes 150 | std::vector vProcessesToKill; 151 | 152 | // read command line from cfg file if it exists 153 | std::wstring sExecutable = GetRunningExecutable(); 154 | std::wstring sCfgPath = sExecutable.substr(0, sExecutable.find_last_of(L".exe") - 3) + L".cfg"; 155 | if (GetFileAttributes(sCfgPath.c_str()) != INVALID_FILE_ATTRIBUTES) 156 | { 157 | std::wifstream oFileStream(sCfgPath); 158 | oFileStream.imbue(std::locale(std::locale::empty(), new std::codecvt_utf8)); 159 | std::wstringstream oStringStream; 160 | oStringStream << oFileStream.rdbuf(); 161 | aArgv = CommandLineToArgvW((L"IGNORE " + oStringStream.str()).c_str(), &iArgc); 162 | } 163 | 164 | // enumerate arguments 165 | for (int iArg = 1; iArg < iArgc; iArg++) 166 | { 167 | // convert to a std string for ease 168 | std::wstring sArg(aArgv[iArg]); 169 | 170 | // as soon as we see one parameter that does not start with 171 | // a slash, then assume we are processing the command to run 172 | if (sArg.c_str()[0] != L'/') 173 | { 174 | if (bUseShellExecute) 175 | { 176 | sProcess = aArgv[iArg++]; 177 | } 178 | 179 | sProcessParams = ArgvToCommandLine(iArg, iArgc - 1, 180 | std::vector({ aArgv, aArgv + iArgc })); 181 | break; 182 | } 183 | 184 | // this switch is only called by winpriv to instructed itself to relaunch 185 | // itself as an elevated process. this is done after establishing a new 186 | // logon following new privs have been granted 187 | else if (_wcsicmp(sArg.c_str(), L"/RelaunchElevated") == 0) 188 | { 189 | // launch as elevated 190 | return LaunchElevated(iArgc, aArgv); 191 | } 192 | 193 | // this switch is only called by winpriv to instruct itself that is has 194 | // been launched with a new, privileged logon and it now should be able 195 | // to launch the target process with the newly acquired privileges. 196 | // this is used to control whether an exit prompt appears in command line 197 | // programs and to prevent infinite relaunching if the new privileges can 198 | // not be enabled 199 | else if (_wcsicmp(sArg.c_str(), L"/RelaunchComplete") == 0) 200 | { 201 | // update relaunch phase to prevent recursion 202 | SetEnvironmentVariable(WINPRIV_EV_RELAUNCH_MODE, L"1"); 203 | } 204 | 205 | // this instructs winpriv to attempt to enable a user-provided list of privs 206 | else if (_wcsicmp(sArg.c_str(), L"/WithPrivs") == 0) 207 | { 208 | // one additional parameter is required 209 | if (iArg + 1 >= iArgc) 210 | { 211 | PrintMessage(L"ERROR: Not enough parameters specified for: %s\n", sArg.c_str()); 212 | return __LINE__; 213 | } 214 | 215 | // tokenize the comma-delimited string and add the privs to the priv vector 216 | std::wstring sPrivString(aArgv[++iArg]); 217 | std::wregex oRegex(L","); 218 | std::wsregex_token_iterator oFirst{ sPrivString.begin(), sPrivString.end(), oRegex, -1 }, oLast; 219 | std::vector vPrivsToAdd({ oFirst, oLast }); 220 | vPrivsToEnable.insert(vPrivsToEnable.end(), vPrivsToAdd.begin(), vPrivsToAdd.end()); 221 | } 222 | 223 | // this instructs winpriv to kill any processes with the specified name 224 | else if (_wcsicmp(sArg.c_str(), L"/KillProcess") == 0) 225 | { 226 | constexpr int iArgsRequired = 1; 227 | 228 | // one additional parameter is required 229 | if (iArg + iArgsRequired >= iArgc) 230 | { 231 | PrintMessage(L"ERROR: Not enough parameters specified for: %s\n", sArg.c_str()); 232 | return __LINE__; 233 | } 234 | 235 | // add to a list or processes to kill 236 | vProcessesToKill.push_back(aArgv[iArg + 1]); 237 | iArg += iArgsRequired; 238 | } 239 | 240 | // this instructs winpriv to write out any temporary dlls into the following directory 241 | else if (_wcsicmp(sArg.c_str(), L"/ExtractLibrary") == 0) 242 | { 243 | if (WriteResourceToFile(GetLocalLibraryPath(false), IDR_RT_RCDATA_X86) == false || 244 | WriteResourceToFile(GetLocalLibraryPath(true), IDR_RT_RCDATA_X64) == false) 245 | { 246 | PrintMessage(L"ERROR: Failed to extract libraries.\n"); 247 | return __LINE__; 248 | } 249 | 250 | return 0; 251 | } 252 | 253 | // instructs winpriv to attempt to enable all privs on the system 254 | else if (_wcsicmp(sArg.c_str(), L"/WithAllPrivs") == 0) 255 | { 256 | for (std::pair tPriv : vPrivMaps) 257 | { 258 | // add privs to list of privs we are going to set 259 | vPrivsToEnable.push_back(tPriv.first); 260 | } 261 | } 262 | 263 | // instructs winpriv to create a list of privs and display it to the user 264 | else if (_wcsicmp(sArg.c_str(), L"/ListPrivs") == 0) 265 | { 266 | // calculate column display size 267 | size_t iColumnSize = 0; 268 | for (std::pair tPriv : vPrivMaps) 269 | { 270 | iColumnSize = max(iColumnSize, tPriv.first.length()); 271 | } 272 | 273 | // format the output into columns 274 | std::wstringstream ss; 275 | ss << std::setiosflags(std::ios::left); 276 | ss << std::setw(iColumnSize + 1ULL) << L"Privilege Constant" << L" " << L"Privilege Description\n"; 277 | ss << std::setw(iColumnSize + 1ULL) << L"==================" << L" " << L"=====================\n"; 278 | for (std::pair tPriv : vPrivMaps) 279 | { 280 | ss << std::setw(iColumnSize + 1ULL) << tPriv.first.c_str() << L" " << tPriv.second.c_str() << L"\n"; 281 | } 282 | 283 | PrintMessage(L"%s", ss.str().c_str()); 284 | return 0; 285 | } 286 | 287 | // instructs winpriv to impersonate the mac address on the system 288 | else if (_wcsicmp(sArg.c_str(), L"/MacOverride") == 0) 289 | { 290 | constexpr int iArgsRequired = 1; 291 | 292 | // one additional parameter is required 293 | if (iArg + iArgsRequired >= iArgc) 294 | { 295 | PrintMessage(L"ERROR: Not enough parameters specified for: %s\n", sArg.c_str()); 296 | return __LINE__; 297 | } 298 | 299 | // format the mac address to a consistent format by removing colons or dashes 300 | std::wstring sMacAddr(aArgv[iArg + 1]); 301 | std::erase(sMacAddr, ':'); 302 | std::erase(sMacAddr, '-'); 303 | SetEnvironmentVariable(WINPRIV_EV_MAC_OVERRIDE, sMacAddr.c_str()); 304 | iArg += iArgsRequired; 305 | } 306 | 307 | // instructs winpriv to override all registry queries for a specific key 308 | else if (_wcsicmp(sArg.c_str(), L"/RegOverride") == 0) 309 | { 310 | constexpr int iArgsRequired = 4; 311 | 312 | // four additional parameters are required 313 | if (iArg + iArgsRequired >= iArgc) 314 | { 315 | PrintMessage(L"ERROR: Not enough parameters specified for: %s\n", sArg.c_str()); 316 | return __LINE__; 317 | } 318 | 319 | // append the registry key override data which should be four params: 320 | // 321 | // currently no error checking is being done for the proper structure 322 | sRegistryOverride += ArgvToCommandLine(iArg + 1, iArg + iArgsRequired, 323 | std::vector({ aArgv, aArgv + iArgc })) + L" "; 324 | iArg += iArgsRequired; 325 | } 326 | 327 | // instructs winpriv to report all accesses of the specified registry key or 328 | // any subkeys as being not found to the target process 329 | else if (_wcsicmp(sArg.c_str(), L"/RegBlock") == 0) 330 | { 331 | constexpr int iArgsRequired = 1; 332 | 333 | // one additional parameter is required 334 | if (iArg + 1 >= iArgc) 335 | { 336 | PrintMessage(L"ERROR: Not enough parameters specified for: %s\n", sArg.c_str()); 337 | return __LINE__; 338 | } 339 | 340 | // this capability is implemented by the registry override code 341 | // block by indicating a winpriv proprietary type called REG_BLOCK 342 | sRegistryOverride += ArgvToCommandLine(iArg + 1, iArg + iArgsRequired, 343 | std::vector({ aArgv, aArgv + iArgc })) + L" N/A REG_BLOCK N/A "; 344 | iArg += iArgsRequired; 345 | } 346 | 347 | 348 | // instructs winpriv to report all accesses of the specified registry key or 349 | // any subkeys as being not found to the target process 350 | else if (_wcsicmp(sArg.c_str(), L"/WindowStyle") == 0) 351 | { 352 | constexpr int iArgsRequired = 1; 353 | 354 | // one additional parameter is required 355 | if (iArg + 1 >= iArgc) 356 | { 357 | PrintMessage(L"ERROR: Not enough parameters specified for: %s\n", sArg.c_str()); 358 | return __LINE__; 359 | } 360 | 361 | // decode the parameter into a windowstyle parameter 362 | std::wstring sWindowStytle(aArgv[iArg + 1]); 363 | if (_wcsicmp(sWindowStytle.c_str(), L"NoActive") == 0) iShowWindow = SW_SHOWNOACTIVATE; 364 | if (_wcsicmp(sWindowStytle.c_str(), L"Minimized") == 0) iShowWindow = SW_SHOWMINIMIZED; 365 | if (_wcsicmp(sWindowStytle.c_str(), L"Maximized") == 0) iShowWindow = SW_SHOWMAXIMIZED; 366 | if (_wcsicmp(sWindowStytle.c_str(), L"MinimizedNoActive") == 0) iShowWindow = SW_SHOWMINNOACTIVE; 367 | if (_wcsicmp(sWindowStytle.c_str(), L"Hidden") == 0) iShowWindow = SW_HIDE; 368 | iArg += iArgsRequired; 369 | } 370 | 371 | // instructs winpriv to override the fips setting on the system 372 | else if (_wcsicmp(sArg.c_str(), L"/FipsOn") == 0 || _wcsicmp(sArg.c_str(), L"/FipsOff") == 0) 373 | { 374 | // implement the fips override using the registry override capability 375 | sRegistryOverride += L"HKLM\\SYSTEM\\CurrentControlSet\\Control\\Lsa\\FipsAlgorithmPolicy "; 376 | sRegistryOverride += L"Enabled "; 377 | sRegistryOverride += L"REG_DWORD "; 378 | sRegistryOverride += (_wcsicmp(sArg.c_str(), L"/FipsOn") == 0) ? L"1 " : L"0 "; 379 | } 380 | 381 | // instructs winpriv to block access to popular group policy areas 382 | else if (_wcsicmp(sArg.c_str(), L"/PolicyBlock") == 0) 383 | { 384 | sRegistryOverride += L"HKCU\\SOFTWARE\\Policies "; 385 | sRegistryOverride += L"N/A REG_BLOCK N/A "; 386 | 387 | sRegistryOverride += L"HKLM\\SOFTWARE\\Policies "; 388 | sRegistryOverride += L"N/A REG_BLOCK N/A "; 389 | 390 | sRegistryOverride += L"HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies "; 391 | sRegistryOverride += L"N/A REG_BLOCK N/A "; 392 | 393 | sRegistryOverride += L"HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies "; 394 | sRegistryOverride += L"N/A REG_BLOCK N/A "; 395 | } 396 | 397 | // instructs winpriv to disable amsi scanning 398 | else if (_wcsicmp(sArg.c_str(), L"/DisableAmsi") == 0) 399 | { 400 | // implement the fips override using the registry override capability 401 | SetEnvironmentVariable(WINPRIV_EV_DISABLE_AMSI, L"1"); 402 | } 403 | 404 | // instructs winpriv to override all host name lookups 405 | else if (_wcsicmp(sArg.c_str(), L"/HostOverride") == 0) 406 | { 407 | constexpr int iArgsRequired = 2; 408 | 409 | // four additional parameters are required 410 | if (iArg + iArgsRequired >= iArgc) 411 | { 412 | PrintMessage(L"ERROR: Not enough parameters specified for: %s\n", sArg.c_str()); 413 | return __LINE__; 414 | } 415 | 416 | // initialize winsock 417 | WSADATA tWSAData; 418 | if (WSAStartup(MAKEWORD(2, 2), &tWSAData) != 0) 419 | { 420 | return __LINE__; 421 | } 422 | 423 | // first lookup the address 424 | PADDRINFOW tResult; 425 | INT iGetAddrInfoResult = GetAddrInfoW(aArgv[iArg + 2], nullptr, nullptr, &tResult); 426 | WSACleanup(); 427 | if (iGetAddrInfoResult != 0) 428 | { 429 | return __LINE__; 430 | } 431 | 432 | // convert the address to a string 433 | WCHAR sAddress[16]; 434 | InetNtop(AF_INET, &((PSOCKADDR_IN)tResult->ai_addr)->sin_addr, sAddress, _countof(sAddress)); 435 | 436 | // append the host override data which should be two params: 437 | // 438 | sHostOverride += std::wstring(aArgv[iArg + 1]) + L" " + sAddress + L" "; 439 | iArg += iArgsRequired; 440 | } 441 | 442 | // instruct winpriv to enable backup and restore privileges and send in 443 | // extra flags to file open/create command to exercise the privileges 444 | else if (_wcsicmp(sArg.c_str(), L"/BypassFileSecurity") == 0) 445 | { 446 | vPrivsToEnable.push_back(SE_RESTORE_NAME); 447 | vPrivsToEnable.push_back(SE_BACKUP_NAME); 448 | vPrivsToEnable.push_back(SE_TAKE_OWNERSHIP_NAME); 449 | vPrivsToEnable.push_back(SE_CHANGE_NOTIFY_NAME); 450 | SetEnvironmentVariable(WINPRIV_EV_BACKUP_RESTORE, L"1"); 451 | } 452 | 453 | // instruct winpriv to break remote file locks if a file operation 454 | // cannot complete due to a remote file lock 455 | else if (_wcsicmp(sArg.c_str(), L"/BreakRemoteLocks") == 0) 456 | { 457 | SetEnvironmentVariable(WINPRIV_EV_BREAK_LOCKS, L"1"); 458 | } 459 | 460 | // instruct winpriv to tell the target process that the current user is 461 | // an admin regardless of security tokens or group memberships 462 | else if (_wcsicmp(sArg.c_str(), L"/AdminImpersonate") == 0) 463 | { 464 | SetEnvironmentVariable(L"__COMPAT_LAYER", L"RunAsInvoker"); 465 | SetEnvironmentVariable(WINPRIV_EV_ADMIN_IMPERSONATE, L"1"); 466 | } 467 | 468 | // instruct winpriv to tell the target process that the current 469 | // operating system is a server operating sysem 470 | else if (_wcsicmp(sArg.c_str(), L"/ServerEdition") == 0) 471 | { 472 | SetEnvironmentVariable(WINPRIV_EV_SERVER_EDITION, L"1"); 473 | } 474 | 475 | // instructs winpriv to record encrypt/decrypt operations 476 | else if (_wcsicmp(sArg.c_str(), L"/RecordCrypto") == 0) 477 | { 478 | constexpr int iArgsRequired = 1; 479 | 480 | // one additional parameter is required 481 | if (iArg + iArgsRequired >= iArgc) 482 | { 483 | PrintMessage(L"ERROR: Not enough parameters specified for: %s\n", sArg.c_str()); 484 | return __LINE__; 485 | } 486 | 487 | // if not 'SHOW' then ensure the passed directory exists 488 | std::wstring sRecordCrypto(aArgv[iArg + 1]); 489 | if (_wcsicmp(sRecordCrypto.c_str(), L"SHOW") != 0) 490 | { 491 | if (CreateDirectory(sRecordCrypto.c_str(), nullptr) == FALSE && 492 | ERROR_ALREADY_EXISTS != GetLastError()) 493 | { 494 | PrintMessage(L"ERROR: Could not create the specified directory for /CrytpoRecord"); 495 | return __LINE__; 496 | } 497 | } 498 | 499 | // store the crypto variable in the environment variable to pass to child 500 | SetEnvironmentVariable(WINPRIV_EV_RECORD_CRYPTO, sRecordCrypto.c_str()); 501 | iArg += iArgsRequired; 502 | } 503 | 504 | // instructs winpriv to show or replace sql connection information 505 | else if (_wcsicmp(sArg.c_str(), L"/SqlConnectShow") == 0) 506 | { 507 | // store the sql connect info in the environment variable to pass to child 508 | SetEnvironmentVariable(WINPRIV_EV_SQL_CONNECT_SHOW, L"1"); 509 | } 510 | 511 | // instructs winpriv to show or replace sql connection information 512 | else if (_wcsicmp(sArg.c_str(), L"/SqlConnectSearchReplace") == 0) 513 | { 514 | constexpr int iArgsRequired = 2; 515 | 516 | // one additional parameter is required 517 | if (iArg + iArgsRequired >= iArgc) 518 | { 519 | PrintMessage(L"ERROR: Not enough parameters specified for: %s\n", sArg.c_str()); 520 | return __LINE__; 521 | } 522 | 523 | // store the sql connect info in the environment variable to pass to child 524 | SetEnvironmentVariable(WINPRIV_EV_SQL_CONNECT_SEARCH, aArgv[iArg + 1]); 525 | SetEnvironmentVariable(WINPRIV_EV_SQL_CONNECT_REPLACE, aArgv[iArg + 2]); 526 | iArg += iArgsRequired; 527 | } 528 | 529 | // instruct winpriv to use the shell execute command to launch the app 530 | else if (_wcsicmp(sArg.c_str(), L"/UseShellExecute") == 0) 531 | { 532 | bUseShellExecute = true; 533 | } 534 | 535 | // instruct winpriv to display process execution time 536 | else if (_wcsicmp(sArg.c_str(), L"/MeasureTime") == 0) 537 | { 538 | bDisplayExecutionTime = true; 539 | } 540 | 541 | // instructs to display help by break from the loop with causes no 542 | // target process to be defined 543 | else if (_wcsicmp(sArg.c_str(), L"/Help") == 0 || _wcsicmp(sArg.c_str(), L"/?") == 0) 544 | { 545 | break; 546 | } 547 | 548 | // invalid parameter 549 | else 550 | { 551 | PrintMessage(L"ERROR: Unrecognized parameter: %s\n", sArg.c_str()); 552 | return __LINE__; 553 | } 554 | } 555 | 556 | // display help if no target was specified 557 | if (bUseShellExecute && sProcess.empty() || 558 | !bUseShellExecute && sProcessParams.empty()) 559 | { 560 | PrintMessage(L"%s",GetWinPrivHelp().c_str()); 561 | return __LINE__; 562 | } 563 | 564 | // setup the registry override and block values to pass to child processes 565 | TrimString(sRegistryOverride, L' '); 566 | SetEnvironmentVariable(WINPRIV_EV_REG_OVERRIDE, sRegistryOverride.c_str()); 567 | 568 | // setup the host override values to pass to child processes 569 | TrimString(sHostOverride, L' '); 570 | SetEnvironmentVariable(WINPRIV_EV_HOST_OVERRIDE, sHostOverride.c_str()); 571 | 572 | // sort privs, remove duplicate privs, and reconstruct into a list of privs 573 | // that can be set as an environment variable and passed to a child process 574 | std::ranges::sort(vPrivsToEnable); 575 | vPrivsToEnable.erase(std::ranges::unique(vPrivsToEnable).begin(), vPrivsToEnable.end()); 576 | std::wstring sPrivsToSetList; 577 | for (std::wstring sPrivToSet : vPrivsToEnable) 578 | { 579 | if (!vPrivMaps.contains(sPrivToSet)) 580 | { 581 | PrintMessage(L"ERROR: Invalid privilege specified: %s\n", sPrivToSet.c_str()); 582 | return __LINE__; 583 | } 584 | 585 | // create a new list to be passed to subprocesses 586 | sPrivsToSetList += sPrivToSet + L","; 587 | } 588 | 589 | // setup priv list environment variable to pass to child processes 590 | TrimString(sPrivsToSetList, L','); 591 | SetEnvironmentVariable(WINPRIV_EV_PRIVLIST, sPrivsToSetList.c_str()); 592 | 593 | // attempt to enable all privileges specified 594 | std::vector vFailedPrivs = EnablePrivs(vPrivsToEnable); 595 | 596 | // grant any privileges that cannot be enabled 597 | if (vFailedPrivs.size() > 0) 598 | { 599 | // ensure we did not get here by means of relaunching as elevated 600 | if (VariableIsSet(WINPRIV_EV_RELAUNCH_MODE, 1)) 601 | { 602 | PrintMessage(L"ERROR: Could not relaunch with privileges.\n"); 603 | return __LINE__; 604 | } 605 | 606 | // adjust local security policy to add the necessary privileges 607 | if (AlterCurrentUserPrivs(vFailedPrivs, TRUE) == FALSE) 608 | { 609 | PrintMessage(L"ERROR: Could not adjust security policy. User may not be an administrator.\n"); 610 | return __LINE__; 611 | } 612 | 613 | // relaunch under a new logon token to acquire the new privs 614 | int iRet = LaunchNewLogon(iArgc, aArgv); 615 | 616 | // restore original privs and return 617 | AlterCurrentUserPrivs(vFailedPrivs, FALSE); 618 | return iRet; 619 | } 620 | 621 | // user the standard temp directory 622 | std::wstring sTempDirectory; 623 | sTempDirectory.resize(MAX_PATH + 1); 624 | if (GetTempPath(MAX_PATH, sTempDirectory.data()) == 0) 625 | { 626 | return __LINE__; 627 | } 628 | sTempDirectory.resize(sTempDirectory.find(L'\0')); 629 | 630 | // ensure temp directory actually exists 631 | if (GetFileAttributes(sTempDirectory.c_str()) == INVALID_FILE_ATTRIBUTES && 632 | CreateDirectory(sTempDirectory.c_str(), nullptr) == 0) 633 | { 634 | PrintMessage(L"ERROR: Could not create temporary directory for library files.\n"); 635 | return __LINE__; 636 | } 637 | 638 | // fetch the default library paths 639 | bool bCleanupLibrary = false; 640 | std::wstring sTempLibraryX86 = GetLocalLibraryPath(false); 641 | std::wstring sTempLibraryX64 = GetLocalLibraryPath(true);; 642 | 643 | if (GetFileAttributes(sTempLibraryX86.c_str()) == INVALID_FILE_ATTRIBUTES || 644 | GetFileAttributes(sTempLibraryX64.c_str()) == INVALID_FILE_ATTRIBUTES) 645 | { 646 | // generate a uuid string to create the temporary file 647 | bCleanupLibrary = true; 648 | RPC_WSTR sUUID; 649 | UUID tUUID; 650 | if (UuidCreate(&tUUID) != RPC_S_OK || 651 | UuidToString(&tUUID, &sUUID) != RPC_S_OK) 652 | { 653 | PrintMessage(L"ERROR: Could not generate name for temporary file.\n"); 654 | return __LINE__; 655 | } 656 | 657 | // generate the files names to use for library names 658 | sTempLibraryX86 = sTempDirectory + L"\\" + reinterpret_cast(sUUID) + L"-32.dll"; 659 | sTempLibraryX64 = sTempDirectory + L"\\" + reinterpret_cast(sUUID) + L"-64.dll"; 660 | 661 | // cleanup the guid structure 662 | RpcStringFree(&sUUID); 663 | 664 | // create the library files 665 | if (WriteResourceToFile(sTempLibraryX86, IDR_RT_RCDATA_X86) == false || 666 | WriteResourceToFile(sTempLibraryX64, IDR_RT_RCDATA_X64) == false) 667 | { 668 | DeleteFile(sTempLibraryX86.c_str()); 669 | DeleteFile(sTempLibraryX64.c_str()); 670 | PrintMessage(L"ERROR: Problem creating temporary library file.\n"); 671 | return __LINE__; 672 | } 673 | } 674 | 675 | // kill any processes requested 676 | for (std::wstring & sProcessName : vProcessesToKill) 677 | { 678 | KillProcess(sProcessName); 679 | } 680 | 681 | STARTUPINFO o_StartInfo; 682 | PROCESS_INFORMATION o_ProcessInfo; 683 | ZeroMemory(&o_ProcessInfo, sizeof(PROCESS_INFORMATION)); 684 | ZeroMemory(&o_StartInfo, sizeof(STARTUPINFO)); 685 | o_StartInfo.cb = sizeof(STARTUPINFO); 686 | 687 | // apply window creation parameters 688 | if (iShowWindow != SW_NORMAL) 689 | { 690 | o_StartInfo.dwFlags |= STARTF_USESHOWWINDOW; 691 | o_StartInfo.wShowWindow = iShowWindow; 692 | } 693 | 694 | // setup shell execute structure if requested 695 | SHELLEXECUTEINFOW o_ShellExecute; 696 | if (bUseShellExecute) 697 | { 698 | ZeroMemory(&o_ShellExecute, sizeof(SHELLEXECUTEINFOW)); 699 | o_ShellExecute.cbSize = sizeof(SHELLEXECUTEINFOW); 700 | o_ShellExecute.fMask = SEE_MASK_NOCLOSEPROCESS; 701 | o_ShellExecute.lpFile = sProcess.c_str(); 702 | o_ShellExecute.nShow = iShowWindow; 703 | o_ShellExecute.lpParameters = sProcessParams.c_str(); 704 | } 705 | 706 | // load the detour library into memory - the main reason we do this 707 | // is so that the create process command below will load the detour library 708 | // that matches the architecture of the target executable 709 | HMODULE hLibrary = LoadLibrary((sizeof(INT_PTR) == sizeof(LONGLONG)) 710 | ? sTempLibraryX64.c_str() : sTempLibraryX86.c_str()); 711 | 712 | // create process and detour 713 | ULONGLONG iTimeStart = GetTickCount64();; 714 | if (bUseShellExecute && ShellExecuteEx(&o_ShellExecute) == FALSE || 715 | !bUseShellExecute && CreateProcess(nullptr, (LPWSTR)sProcessParams.c_str(), nullptr, nullptr, FALSE, 0, nullptr, nullptr, 716 | &o_StartInfo, &o_ProcessInfo) == 0) 717 | { 718 | PrintMessage(L"ERROR: Problem starting target executable: %s\n", sProcessParams.c_str()); 719 | if (bCleanupLibrary) 720 | { 721 | DeleteFile(sTempLibraryX86.c_str()); 722 | DeleteFile(sTempLibraryX64.c_str()); 723 | } 724 | return __LINE__; 725 | } 726 | 727 | // copy process info out of shell execute for waiting 728 | if (bUseShellExecute) o_ProcessInfo.hProcess = o_ShellExecute.hProcess; 729 | 730 | // wait for our process to complete 731 | if (WaitForSingleObject(o_ProcessInfo.hProcess, INFINITE) == WAIT_FAILED) 732 | { 733 | PrintMessage(L"ERROR: Problem waiting for process to complete."); 734 | if (bCleanupLibrary) 735 | { 736 | DeleteFile(sTempLibraryX86.c_str()); 737 | DeleteFile(sTempLibraryX64.c_str()); 738 | } 739 | return __LINE__; 740 | } 741 | 742 | // display execution time if requested 743 | if (bDisplayExecutionTime) 744 | { 745 | ULONGLONG iTimeStop = GetTickCount64(); 746 | PrintMessage(L"Execution Time In Seconds: %.3f", ((double)(iTimeStop - iTimeStart)) / 1000.0); 747 | } 748 | 749 | // fetch process exit code 750 | DWORD iExitCode = 0; 751 | GetExitCodeProcess(o_ProcessInfo.hProcess, &iExitCode); 752 | CloseHandle(o_ProcessInfo.hProcess); 753 | if (o_ProcessInfo.hThread != nullptr) CloseHandle(o_ProcessInfo.hThread); 754 | 755 | // cleanup 756 | if (hLibrary != nullptr) FreeLibrary(hLibrary); 757 | if (bCleanupLibrary) 758 | { 759 | DeleteFile(sTempLibraryX86.c_str()); 760 | DeleteFile(sTempLibraryX64.c_str()); 761 | } 762 | return iExitCode; 763 | } 764 | 765 | // ___ ___ __ __ __ ___ __ 766 | // |__ |\ | | |__) \ / |__) / \ | |\ | | /__` 767 | // |___ | \| | | \ | | \__/ | | \| | .__/ 768 | // 769 | 770 | #ifdef _CONSOLE 771 | int wmain(int iArgc, wchar_t *aArgv[]) 772 | { 773 | RunProgram(iArgc, aArgv); 774 | } 775 | #else 776 | int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ PWSTR pCmdLine, _In_ int nCmdShow) 777 | { 778 | return RunProgram(__argc, __wargv); 779 | } 780 | #endif -------------------------------------------------------------------------------- /WinPriv/WinPriv.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by WinPrivResource.rc 4 | // 5 | #define IDR_RT_RCDATA_X86 101 6 | #define IDR_RT_RCDATA_X64 102 7 | #define IDI_ICON 103 8 | 9 | // Next default values for new objects 10 | // 11 | #ifdef APSTUDIO_INVOKED 12 | #ifndef APSTUDIO_READONLY_SYMBOLS 13 | #define _APS_NEXT_RESOURCE_VALUE 104 14 | #define _APS_NEXT_COMMAND_VALUE 40001 15 | #define _APS_NEXT_CONTROL_VALUE 1001 16 | #define _APS_NEXT_SYMED_VALUE 101 17 | #endif 18 | #endif 19 | -------------------------------------------------------------------------------- /WinPriv/WinPriv.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NoMoreFood/WinPriv/ea8584c172e4f31ced4fb2eb073562aed09b3b57/WinPriv/WinPriv.ico -------------------------------------------------------------------------------- /WinPriv/WinPriv.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Release 6 | Win32 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | {582d212a-66b9-4e99-a7d3-36b1c249d637} 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | {C9CBD938-2A0F-4D91-81F4-94414751BFBE} 39 | Win32Proj 40 | WinPriv 41 | 10.0 42 | WinPriv 43 | 44 | 45 | 46 | Application 47 | false 48 | v143 49 | true 50 | Unicode 51 | 52 | 53 | Application 54 | false 55 | v143 56 | true 57 | Unicode 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | false 73 | $(SolutionDir)Build\$(PlatformTarget)\ 74 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)DetoursLibrary\$(PlatformTarget) 75 | $(SolutionDir)Build\$(PlatformTarget)\Temp\$(ProjectName)\ 76 | 77 | 78 | false 79 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)DetoursLibrary\$(PlatformTarget) 80 | $(SolutionDir)Build\$(PlatformTarget)\ 81 | $(SolutionDir)Build\$(PlatformTarget)\Temp\$(ProjectName)\ 82 | 83 | 84 | 85 | Level3 86 | 87 | 88 | Full 89 | true 90 | true 91 | WIN32;NDEBUG;STRICT;_CRT_SECURE_NO_WARNINGS;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;WINVER=_WIN32_WINNT_WIN7;_WIN32_WINNT=_WIN32_WINNT_WIN7;PROJECT_NAME=L"$(ProjectName)";%(PreprocessorDefinitions) 92 | ..\WinPrivShared 93 | MultiThreaded 94 | true 95 | AnySuitable 96 | None 97 | stdcpp20 98 | stdc17 99 | 100 | 101 | Windows 102 | false 103 | true 104 | true 105 | $(SolutionDir)DetoursLibrary\$(PlatformTarget)\ 106 | $(OutDir)$(TargetName)$(TargetExt) 107 | AsInvoker 108 | true 109 | UseLinkTimeCodeGeneration 110 | kernel32.lib;user32.lib;advapi32.lib;ws2_32.lib;%(AdditionalDependencies) 111 | 112 | 113 | true 114 | true 115 | 116 | 117 | _UNICODE;UNICODE;%(PreprocessorDefinitions) 118 | 119 | 120 | 121 | 122 | Level3 123 | NotUsing 124 | Full 125 | true 126 | true 127 | NDEBUG;STRICT;_CRT_SECURE_NO_WARNINGS;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;WINVER=_WIN32_WINNT_WIN7;_WIN32_WINNT=_WIN32_WINNT_WIN7;PROJECT_NAME=L"$(ProjectName)";%(PreprocessorDefinitions) 128 | ..\WinPrivShared 129 | true 130 | MultiThreaded 131 | AnySuitable 132 | false 133 | false 134 | None 135 | stdcpp20 136 | stdc17 137 | 138 | 139 | Windows 140 | false 141 | true 142 | true 143 | $(SolutionDir)DetoursLibrary\$(PlatformTarget)\ 144 | AsInvoker 145 | true 146 | UseLinkTimeCodeGeneration 147 | kernel32.lib;user32.lib;advapi32.lib;ws2_32.lib;%(AdditionalDependencies) 148 | 149 | 150 | _UNICODE;UNICODE;%(PreprocessorDefinitions) 151 | 152 | 153 | true 154 | true 155 | 156 | 157 | true 158 | 159 | 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /WinPriv/WinPrivLogon.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Bryan Berns. All rights reserved. 3 | // Licensed under the MIT license. See LICENSE file in the project root for details. 4 | // 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "WinPrivShared.h" 12 | 13 | #pragma comment(lib,"credui.lib") 14 | 15 | int LaunchElevated(int iArgc, wchar_t *aArgv[]) 16 | { 17 | // construct a command line containing just the argument passed this executable 18 | const std::wstring sCommand = L"/RelaunchComplete " + ArgvToCommandLine(2, iArgc - 1, 19 | std::vector({ aArgv, aArgv + iArgc })); 20 | 21 | // get the current working directory to pass to the child process 22 | WCHAR sCurrentDir[MAX_PATH + 1]; 23 | _wgetcwd(sCurrentDir, _countof(sCurrentDir)); 24 | 25 | // re-execute the process to run elevated 26 | SHELLEXECUTEINFO tShellExecInfo; 27 | ZeroMemory(&tShellExecInfo, sizeof(SHELLEXECUTEINFO)); 28 | tShellExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); 29 | tShellExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NOZONECHECKS; 30 | tShellExecInfo.hwnd = nullptr; 31 | tShellExecInfo.lpVerb = L"runas"; 32 | tShellExecInfo.lpFile = aArgv[0]; 33 | tShellExecInfo.lpParameters = sCommand.c_str(); 34 | tShellExecInfo.nShow = SW_SHOWNORMAL; 35 | tShellExecInfo.hInstApp = nullptr; 36 | ShellExecuteEx(&tShellExecInfo); 37 | 38 | // wait for completion and return process exit code 39 | WaitForSingleObject(tShellExecInfo.hProcess, INFINITE); 40 | DWORD iExitCode = 0; 41 | GetExitCodeProcess(tShellExecInfo.hProcess, &iExitCode); 42 | return iExitCode; 43 | } 44 | 45 | int LaunchNewLogon(int iArgc, wchar_t *aArgv[]) 46 | { 47 | // setup the interface parameters for credential solicitation solicit credentials from the user 48 | CREDUI_INFO cui; 49 | cui.cbSize = sizeof(CREDUI_INFO); 50 | cui.hwndParent = nullptr; 51 | cui.pszMessageText = L"In order to active the privileges that you requested, " \ 52 | "you must enter your credentials to acquire a new logon token."; 53 | cui.pszCaptionText = L"Enter Your Credentials"; 54 | cui.hbmBanner = nullptr; 55 | 56 | // prompt the user for a set of credentials 57 | VOID * oOutInformation = nullptr; 58 | DWORD iOutInformationSize = 0; 59 | DWORD iAuthPackage = 0; 60 | DWORD iErr = 0; 61 | if ((iErr = CredUIPromptForWindowsCredentials(&cui, 0, &iAuthPackage, nullptr, 0, 62 | &oOutInformation, &iOutInformationSize, nullptr, 0)) != NO_ERROR) 63 | { 64 | PrintMessage(L"A problem occurred while soliciting the credentials.\n"); 65 | return __LINE__; 66 | } 67 | 68 | // decode the credentials 69 | WCHAR sUserName[CREDUI_MAX_USERNAME_LENGTH + 1] = L""; 70 | DWORD iUserName = _countof(sUserName); 71 | WCHAR sPassword[CREDUI_MAX_PASSWORD_LENGTH + 1] = L""; 72 | DWORD iPassword = _countof(sPassword); 73 | if ((iErr = CredUnPackAuthenticationBuffer(CRED_PACK_PROTECTED_CREDENTIALS, 74 | oOutInformation, iOutInformationSize, sUserName, &iUserName, nullptr, nullptr, sPassword, &iPassword)) == FALSE) 75 | { 76 | PrintMessage(L"A problem occurred while decoding the credentials.\n"); 77 | return __LINE__; 78 | } 79 | 80 | // pull apart the domain from the user name 81 | WCHAR sUserNameShort[CREDUI_MAX_USERNAME_LENGTH + 1] = L""; 82 | constexpr DWORD iUserNameShort = _countof(sUserNameShort); 83 | WCHAR sDomainName[CREDUI_MAX_DOMAIN_TARGET_LENGTH + 1] = L""; 84 | constexpr DWORD iDomainName = _countof(sDomainName); 85 | CredUIParseUserName(sUserName, sUserNameShort, iUserNameShort, sDomainName, iDomainName); 86 | 87 | STARTUPINFO o_StartInfo; 88 | PROCESS_INFORMATION o_ProcessInfo; 89 | ZeroMemory(&o_ProcessInfo, sizeof(PROCESS_INFORMATION)); 90 | ZeroMemory(&o_StartInfo, sizeof(STARTUPINFO)); 91 | o_StartInfo.cb = sizeof(STARTUPINFO); 92 | o_StartInfo.dwFlags = STARTF_USESHOWWINDOW; 93 | o_StartInfo.wShowWindow = SW_HIDE; 94 | 95 | // reconstruct a command line with a flag to indicate relaunch 96 | const std::vector sArgs({ aArgv, aArgv + iArgc }); 97 | const std::wstring sCommand = ArgvToCommandLine(0, 0, sArgs) + 98 | L" /RelaunchElevated " + ArgvToCommandLine(1, iArgc - 1, sArgs); 99 | 100 | // get the current working directory to pass to the child process 101 | WCHAR sCurrentDir[MAX_PATH + 1]; 102 | if (_wgetcwd(sCurrentDir, _countof(sCurrentDir)) == nullptr) 103 | { 104 | PrintMessage(L"ERROR: Problem obtaining current directory.\n"); 105 | return __LINE__; 106 | } 107 | 108 | // relaunch process under altered security policy 109 | const LPWSTR sBlock = GetEnvironmentStrings(); 110 | if (CreateProcessWithLogonW(sUserNameShort, sDomainName, sPassword, LOGON_WITH_PROFILE, nullptr, (LPWSTR) sCommand.c_str(), CREATE_UNICODE_ENVIRONMENT, sBlock, 111 | sCurrentDir, &o_StartInfo, &o_ProcessInfo) == 0) 112 | { 113 | PrintMessage(L"ERROR: Problem starting process (%d) (%s).\n", GetLastError(), sCommand.c_str()); 114 | return __LINE__; 115 | } 116 | 117 | // zero out the password from memory 118 | SecureZeroMemory(sPassword, _countof(sPassword)); 119 | 120 | // return process exit code 121 | WaitForSingleObject(o_ProcessInfo.hProcess, INFINITE); 122 | DWORD iExitCode = 0; 123 | GetExitCodeProcess(o_ProcessInfo.hProcess, &iExitCode); 124 | CloseHandle(o_ProcessInfo.hProcess); 125 | CloseHandle(o_ProcessInfo.hThread); 126 | return iExitCode; 127 | } -------------------------------------------------------------------------------- /WinPriv/WinPrivMisc.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Bryan Berns. All rights reserved. 3 | // Licensed under the MIT license. See LICENSE file in the project root for details. 4 | // 5 | 6 | #define UMDF_USING_NTSTATUS 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | std::map GetPrivilegeList() 19 | { 20 | // list of privileges to return 21 | std::map tPrivilegeList; 22 | 23 | // object attributes are reserved, so initialize to zeros. 24 | LSA_OBJECT_ATTRIBUTES ObjectAttributes; 25 | ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes)); 26 | 27 | // get a handle to the policy object. 28 | NTSTATUS iResult = 0; 29 | LSA_HANDLE policyHandle; 30 | if ((iResult = LsaOpenPolicy(nullptr, &ObjectAttributes, 31 | POLICY_VIEW_LOCAL_INFORMATION, &policyHandle)) != STATUS_SUCCESS) 32 | { 33 | // return on error - priv list will be empty 34 | return tPrivilegeList; 35 | } 36 | 37 | // enumerate the privileges that are settable 38 | PPOLICY_PRIVILEGE_DEFINITION buffer = nullptr; 39 | LSA_ENUMERATION_HANDLE enumerationContext = 0; 40 | ULONG countReturned = 0; 41 | while (LsaEnumeratePrivileges(policyHandle, &enumerationContext, 42 | (PVOID *)&buffer, INFINITE, &countReturned) == STATUS_SUCCESS) 43 | { 44 | for (ULONG iPrivIndex = 0; iPrivIndex < countReturned; iPrivIndex++) 45 | { 46 | LPWSTR sDisplayName = nullptr; 47 | DWORD iSize = 0; 48 | DWORD iIden = 0; 49 | 50 | // return privilege display name -- call lookup once to get string size 51 | // and then alloc the string on the next call to get the string 52 | if (LookupPrivilegeDisplayName(nullptr, (LPWSTR)buffer[iPrivIndex].Name.Buffer, nullptr, &iSize, &iIden) == 0 && 53 | LookupPrivilegeDisplayName(nullptr, (LPWSTR)buffer[iPrivIndex].Name.Buffer, 54 | sDisplayName = static_cast(malloc(sizeof(WCHAR) * (++iSize))), &iSize, &iIden) != 0) 55 | { 56 | tPrivilegeList[buffer[iPrivIndex].Name.Buffer] = sDisplayName; 57 | } 58 | 59 | // cleanup 60 | if (sDisplayName == nullptr) free(sDisplayName); 61 | } 62 | 63 | // cleanup 64 | LsaFreeMemory(buffer); 65 | } 66 | 67 | // cleanup 68 | LsaClose(policyHandle); 69 | return tPrivilegeList; 70 | } 71 | 72 | std::wstring GetWinPrivHelp() 73 | { 74 | // a messagebox will garble this help information so simply the help 75 | // for the non-commandline version and defer to commandline for help 76 | if (GetConsoleWindow() == nullptr) 77 | { 78 | return std::wstring(PROJECT_NAME) + 79 | L".exe [optional switches] \n" + 80 | L"\n" + 81 | L"See WinPrivCmd /Help to view optional switch information."; 82 | } 83 | 84 | // command line help 85 | return std::wstring(PROJECT_NAME) + 86 | LR"(.exe [optional switches] 87 | 88 | WinPriv is system administration utility that alters the runtime behavior of 89 | the specified process and its child processes. It does this by loading a 90 | supplemental library into memory to intercept and alter the behavior of 91 | common low-level functions such as registry and file system operations. 92 | 93 | WinPriv can be used for a variety of purposes including testing security 94 | settings without altering system-wide policy, implementing security-related 95 | workarounds on a per-process basis instead of altering system-wide policy, and 96 | taking advantageous of system privileges to perform file system auditing and 97 | reconfiguration. 98 | 99 | WinPriv comes in normal version (WinPriv) and a console version (WinPrivCmd). 100 | The behavior of the subprocess is the same regardless of which version is used. 101 | These versions are provided in case the target program is a console program 102 | in which case you will only be able to get its screen output if you use 103 | WinPrivCmd. Similarly, you may not wish to see the console windows when 104 | targeting a non-console program in which case it may be advantageous to use 105 | WinPriv. 106 | 107 | Optional Switches 108 | ================= 109 | 110 | /RegOverride 111 | 112 | Specifies a registry value to override. Instead of returning the true 113 | registry value for the specified key path and value name, the value 114 | the value specified in this switch is returned. 115 | 116 | Examples: 117 | 118 | /RegOverride HKCU\Software\Demo Enabled REG_DWORD 1 119 | /RegOverride HKLM\Software\Demo UserName REG_SZ "James Bond" 120 | 121 | /RegBlock 122 | 123 | Specified a registry key under which all values will be reported as 124 | non-existent. When the application requests a particular value in the 125 | specified key or one of its subkeys, it will be reported as not found 126 | regardless as to whether it actually exists in the registry. 127 | 128 | Examples: 129 | 130 | /RegBlock HKCU\Software\Demo 131 | 132 | /MacOverride 133 | 134 | Specifies a physical network address that will be returned when the target 135 | application makes a query to the system to provide its MAC addresses. Any 136 | call to GetAdaptersAddresses, GetAdaptersInfo, and NetWkstaTransportEnum 137 | is handled. The hex octets can be delimited by dashes, colons, or nothing. 138 | 139 | Examples: 140 | 141 | /MacOverride 00-11-22-33-44-66 142 | 143 | /HostOverride 144 | 145 | Specifies that any request to obtain the IP address for the specified target 146 | will instead receive the specified replacement IP address. This is done by 147 | intercepting calls to WSALookupServiceNext() which nearly all address 148 | lookups ultimately occur. Be aware due to special security protections, 149 | this will not work for Internet Explorer and programs that use Internet 150 | Explorer libraries but should work for most other processes. 151 | 152 | Examples: 153 | 154 | /HostOverride google.com yahoo.com 155 | /HostOverride google.com 127.0.0.1 156 | 157 | /FipsOn & /FipsOff 158 | 159 | This option will turn cause the system to report that Federal Information 160 | Processing System enforcement is turned on or off, regardless of its current 161 | setting on the system. This operation is a convenience option that actually 162 | uses the /RegOverride functionality on the FIPS-related registry key. 163 | 164 | /PolicyBlock 165 | 166 | This option will cause all registry queries to HKCU\Software\Policies and 167 | HKCU\Software\Policies. This option is convenience option that actually uses 168 | the /RegBlock functionality. 169 | 170 | /BypassFileSecurity 171 | 172 | This option causes the target process to enable the backup and restore 173 | privileges and alters the way the program access files to take advantage of 174 | this extra privileges. When these privileges are enabled, all access 175 | control lists on the file system are ignored. This allows an administrator 176 | to inspect and alter files without changing permissions or taking ownership. 177 | 178 | Effective uses of this option include using command line utilities like 179 | icacls.exe to inspect/alter permissions. Using this with cmd.exe or 180 | powershell.exe also provide a mean to interact with secured areas. 181 | 182 | Examples: 183 | 184 | Access detailed permissions under 'C:\System Volume Information': 185 | WinPrivCmd.exe /BypassFileSecurity icacls.exe 186 | "C:\System Volume Information" /T 187 | 188 | /BreakRemoteLocks 189 | 190 | This option attempts to break remote file locks if a file cannot be accessed 191 | because it is opened by another program remotely. For example, this can be 192 | used to allow programs like robocopy to mirror an area where the destination 193 | system has an in-use file. This option will have no effect if the file is 194 | in-use by a program on the same system where WinPriv is executed. 195 | 196 | /AdminImpersonate 197 | 198 | This option causes any local administrator check using IsUserAnAdmin() or 199 | CheckTokenMembership() to unconditionally succeed regardless if the user is 200 | actually a member of the local administrator group. 201 | 202 | /ServerEdition 203 | 204 | This option causes the most common operating system version information 205 | functions to indicate the that the system is running a server edition of 206 | the operating system. 207 | 208 | /RecordCrypto 209 | 210 | This option records the data being inputted to common Windows encryption 211 | functions and the data being outputted from common Windows decryption 212 | functions. A separate file will be created for each operation in the 213 | specified directory. If 'SHOW' is specified instead of a directory path, 214 | information is outputted to the console and message boxes, depending of the 215 | type of application. 216 | 217 | /SqlConnectShow 218 | 219 | This option will display the ODBC connection parameters immediately before 220 | a connection operation occurs. 221 | 222 | /SqlConnectSearchReplace 223 | 224 | This option performs a search / replace on an ODBC connection string prior 225 | to passing it to the connection Open() function. The search string is 226 | parsed as a regular expression. 227 | 228 | Examples: 229 | 230 | WinPrivCmd.exe /SqlConnectSearchReplace 231 | Provider=SQLOLEDB Provider=SQLNCLI11 LegacyApplication.exe 232 | 233 | /KillProcess 234 | 235 | Kill the process with specified name prior to running the target. This is 236 | useful if the target has logic to prevent multiple execution and needs to 237 | to be terminated before the effects of a WinPriv session can be effective. 238 | 239 | /ExtractLibrary 240 | 241 | This option extracts the embedded 32-bit and 64-bit libraries to the 242 | directory where WinPriv is running. These are normally dynamically extracted 243 | to the users temporary directory. If WinPriv finds these libraries in the 244 | directory where it is running, it will use those instead of writing them 245 | to the temporary directory. 246 | 247 | /WindowStyle