├── LICENSE.md ├── README.md ├── UPGDSED.sha256 ├── bin ├── changelog.txt └── patch.exe └── src ├── bcd.c ├── bcd.h ├── cui ├── cui.c └── cui.h ├── global.h ├── main.c ├── minirtl ├── _filename.c ├── _filename.h ├── _strcat.c ├── _strcmp.c ├── _strcmpi.c ├── _strcpy.c ├── _strend.c ├── _strlen.c ├── _strncmp.c ├── _strncmpi.c ├── _strncpy.c ├── cmdline.c ├── cmdline.h ├── minirtl.h ├── rtltypes.h └── strtoi.c ├── ntdll └── ntos.h ├── patch.sln ├── patch.vcxproj ├── patch.vcxproj.filters ├── patch.vcxproj.user ├── patterns.h ├── pgos.manifest ├── res.rc ├── resource.h ├── scan.c ├── scan.h ├── sup.c ├── sup.h ├── symdll.rc ├── symdll ├── dbghelp.dll └── symsrv.dll └── tests └── BadRkDemo ├── Installer ├── installer.sln ├── installer.vcxproj ├── installer.vcxproj.filters ├── installer.vcxproj.user ├── main.c ├── minirtl │ ├── _filename.c │ ├── _filename.h │ ├── _strcat.c │ ├── _strcpy.c │ ├── _strend.c │ ├── _strlen.c │ ├── cmdline.c │ ├── cmdline.h │ ├── minirtl.h │ ├── rtltypes.h │ ├── strtoul.c │ └── ultohex.c └── ntos.h └── drv ├── dummy.sln └── dummy ├── dummy.vcxproj ├── dummy.vcxproj.filters ├── dummy.vcxproj.user ├── main.c └── main.h /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 EP_X0FF & Fyyre 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # UPGDSED 3 | 4 | ## Universal PatchGuard and Driver Signature Enforcement Disable 5 | 6 | 7 | # System Requirements 8 | 9 | x64 Windows, supported versions: 10 | 11 | * Windows 7 SP1 12 | * Windows 8 13 | * Windows 8.1 14 | * Windows 10 (TH1/TH2/RS1/RS2/RS3) 15 | 16 | Administrative privilege is required. 17 | 18 | In case of EFI boot SecureBoot must be disabled. 19 | 20 | # WARNING 21 | 22 | Using this program might render your computer into an unbootable state. 23 | 24 | Source code provided AS-IS in help it will be useful BUT WITHOUT WARRANTY OF ANY KIND. 25 | 26 | ANY USE OF THE SOFTWARE IS ENTIRELY AT YOUR OWN RISK. 27 | 28 | # Install 29 | 30 | Run patch.exe elevated. 31 | 32 | 33 | # Uninstall 34 | 35 | In elevated command prompt type bcdedit /delete < patch guard disable entry id > 36 | 37 | Navigate to Windows\System32 folder and delete ntkrnlmp.exe, osloader.exe (BIOS boot) or osloader.efi (EFI boot) 38 | 39 | 40 | # Build 41 | 42 | UPGDSED comes with full source code. 43 | In order to build from source you need Microsoft Visual Studio 2015 and later versions. 44 | 45 | # Deprecation 46 | 47 | The project has been deprecated in 2018. No further updates (or plans on them) are available. If you still need PatchGuard disable refer to these repositories (alphabetical order): 48 | 49 | * EfiGuard, https://github.com/Mattiwatti/EfiGuard 50 | * Shark, https://github.com/9176324/Shark 51 | 52 | This repository is kept read-only for historical purposes. 53 | 54 | # References 55 | 56 | * Bypassing PatchGuard on Windows x64 by Skywing, http://www.uninformed.org/?v=3&a=3&t=sumry 57 | * Disable PatchGuard - the easy/lazy way by Fyyre, http://fyyre.ru/vault/bootloader.txt 58 | * Disable PatchGuard - updated for Win7 & Win8 by Fyyre, http://fyyre.ru/vault/bootloader_v2.txt 59 | * bootkit_fasm - disables PG/DS via MBR bootkit by Fyyre, http://fyyre.ru/vault/bootkit_fasm.7z 60 | * Kernel Patch Protection, https://en.wikipedia.org/wiki/Kernel_Patch_Protection 61 | * Driver Signing Policy, https://msdn.microsoft.com/en-us/windows/hardware/drivers/install/kernel-mode-code-signing-policy--windows-vista-and-later- 62 | 63 | # Authors 64 | * EP_X0FF, https://github.com/hfiref0x 65 | * Fyyre, http://fyyre.ru 66 | 67 | (c) 2017 - 2018 UPGDSED Project 68 | -------------------------------------------------------------------------------- /UPGDSED.sha256: -------------------------------------------------------------------------------- 1 | 508b4bdf3c519096e98d95ddfed9a1b525289b4dc54af4cbe9690906f50f324c *bin\changelog.txt 2 | 469953521e9b64eac07f02fecf3488406c65ec1f3d5c182363c8ba0664a4b640 *bin\patch.exe 3 | 281396e694d957097612a2243cab42ae7f990224449a946e46e85ccf690b93a9 *src\bcd.c 4 | 1a5c59198373d6fc739a62597c5f33c0607da4100560f61dacebad57437cd531 *src\bcd.h 5 | 73771d877dd18c30aff0b00fe0726fb9b24792d2d1cf9f95d1b9284e286911eb *src\global.h 6 | 551e71f31205064b59b26bf04089d39f21769ef49cdbb193f12eda04ccb4db47 *src\main.c 7 | b21b677d9cfec6a1102cfbfa7e78dea78239269b14984076c57233884ce48d95 *src\patch.sln 8 | e152bcc18230cbbc1924b542c98d785694bacd47f714bca4ab5e4281de4dbe99 *src\patch.vcxproj 9 | 89223c8879e04c7a546a07d08d1aa0a6381fc8338578f5eef449af4245a3de2d *src\patch.vcxproj.filters 10 | 0e97128d7d18f40574bb08e651687b51d1eb8cd3d97378966276988bed960aa9 *src\patch.vcxproj.user 11 | 9b5ce6dbe8a5686cfc8eadf7260eee82ffab34b2dc4aa560eb5c92bef48ec71d *src\patterns.h 12 | 860931b0b676c8b2f59c46b0a634343f5bf0f79e5df4c91907f2e8adcf2ca5dd *src\pgos.manifest 13 | e4cf629ed15a490803b468af8bce6308a266aae298e33a160bdbbe3cbc802755 *src\res.rc 14 | 1b51ea0e6941e984a841ad9dd077d0e41483ab9fcdbdc68ced20d31d3de18113 *src\resource.h 15 | 70b6a09f839d08263e8e06b88a6fce1aeb614ec2a75cfea51057ea94fb56379c *src\scan.c 16 | 3516e99c64ed8260d51a939c4031c20f913cfd81af7328125445b5cd7c390813 *src\scan.h 17 | eb34a71d06f225d282a320c3168caba5b7fcbc6ebe0ebad0b87cc637726fd2e8 *src\sup.c 18 | c6848eb925efef40e56fd42845cb40396e698df97ef91eb25c8ef147771503ce *src\sup.h 19 | 1e41d203ca1f57570d69c08a998dfd963797eaf187988def59baf3e9f7282a16 *src\symdll.rc 20 | fd402164324f58787b4704dea81c3939839b23726bd8ae9ec9f1d6b055ce21a8 *src\cui\cui.c 21 | a022ca87e83f398f35fe0ee1fbaf2c84d7ffdcd53aab7d2acb0315a1a2c62699 *src\cui\cui.h 22 | 893b90b942372928009bad64f166c7018701497e4f7cd1753cdc44f76da06707 *src\minirtl\cmdline.c 23 | bd6fe82852c4fcdfab559defa33ea394b752a4e4a5ac0653ae20c4a94b0175ed *src\minirtl\cmdline.h 24 | 107245437ed86b6f1e839b2d3d9bbadb3d9980046cb5c7001f985fed3627962f *src\minirtl\minirtl.h 25 | 33c3d3a56aa12c41ab8e388e581b88fed6a9c59961e86c7c508612373ed93266 *src\minirtl\rtltypes.h 26 | ca0b7a38be2f3f63a69aca6da7b3a62a59fcefee92de00e9796f68d4a2a23158 *src\minirtl\strtoi.c 27 | c1405b280bacc7566ccd041a74461de3f8496128fd71e39368905cf8d95268f6 *src\minirtl\_filename.c 28 | 9e3f1386bfb64dbaa3cbb12fd3bf51c734872c2fdf15cf1aaeca52a515767519 *src\minirtl\_filename.h 29 | 83772aa217508279294d91af5cfabec9b5e00b836a2e2f5fe37cf1ebc2905a52 *src\minirtl\_strcat.c 30 | 2a67c7690ec6df8e233207116b0e4fe76c02ae43595d9e606e123572b6ac88a1 *src\minirtl\_strcmp.c 31 | ef1b18997ea473ac8d516ef60efc64b9175418b8f078e088d783fdaef2544969 *src\minirtl\_strcmpi.c 32 | 969b35213fa23ff50a169e5498a97f28bc6f5820b447b78ec9dc6910dd8cc3e8 *src\minirtl\_strcpy.c 33 | 27159b8ff67d3f8e6c7fdb4b57b9f57f899bdfedf92cf10276269245c6f4e066 *src\minirtl\_strend.c 34 | 60f19c6b805801e13824c4d9d44748da8245cd936971411d3d36b873121888eb *src\minirtl\_strlen.c 35 | 97e0720ed22d2d99e8148aab7ab2cb2cc3df278225669828b2d8d4d9ef856d94 *src\minirtl\_strncmp.c 36 | 87cc72bb8e3f1534bee09ee278ecd928d975ebb94aeffc767b67249815a0bf3a *src\minirtl\_strncmpi.c 37 | 0434d69daa20fbf87d829ffc17e43dcc2db3386aff434af888011fdec2f645a4 *src\minirtl\_strncpy.c 38 | d50ade6e4f9a4fab3797dd74fa8c9b58c7df044ace04cb964ba7accade38ad11 *src\ntdll\ntos.h 39 | 6e58fcf4d763022b1f79a3c448eb2ebd8ad1c15df3acf58416893f1cbc699026 *src\symdll\dbghelp.dll 40 | e11e0f7804bfc485b19103a940be3d382f31c1378caca0c63076e27797d7553f *src\symdll\symsrv.dll 41 | bdcb69fc13e93c15937bcfe00d39d0d3d5fe51283a5eb3c83e3b6248fa9ddc75 *src\tests\BadRkDemo\drv\dummy.sln 42 | 15bfb5e8dbb73a9669609685f7b33d34f6eec0d4d67bdb21df48eb3ae3d2e566 *src\tests\BadRkDemo\drv\dummy\dummy.vcxproj 43 | f53e8133a9d12b751445ed57f4574bbeba722d26096196f544ed1794adf699f4 *src\tests\BadRkDemo\drv\dummy\dummy.vcxproj.filters 44 | ecaea9f7f50535be80fdd27b5563c8e7b99b368ce3ac35ccd0dc4f31dd6af30b *src\tests\BadRkDemo\drv\dummy\dummy.vcxproj.user 45 | ea5f7433505e21f1825b2096b3143cfd074623fdf138858099e4af49295b9051 *src\tests\BadRkDemo\drv\dummy\main.c 46 | a078af2ab338dd358c28944199c34ecd5ce2fccfd7080fa58be09c913780f5dc *src\tests\BadRkDemo\drv\dummy\main.h 47 | 4e849ba817a3d2d24c2d6e37ce1f7188e9dca1d482d2adf6a23138383867f2f8 *src\tests\BadRkDemo\Installer\installer.sln 48 | ae0355a1de35472bf66c23b2122e51b22e9e66a5d60446cb55db3c503191b468 *src\tests\BadRkDemo\Installer\installer.vcxproj 49 | 4bea8c4f167a8a8bd0a8499a78de18f28a4355a76f0b8d943510d46e959ac300 *src\tests\BadRkDemo\Installer\installer.vcxproj.filters 50 | 9be6b472cad60f691c9e05591b585be2c70d09a71c3a022e5aa562f203c1a3c4 *src\tests\BadRkDemo\Installer\installer.vcxproj.user 51 | 7cf28203ee08cf59dfd5a4ef63596058fd37019bab7001c778d368a7f88ba73d *src\tests\BadRkDemo\Installer\main.c 52 | 882237a27cfa1076a81b48f87a10e39f343bcf64c14463abfe8c03b1edb3648c *src\tests\BadRkDemo\Installer\ntos.h 53 | 893b90b942372928009bad64f166c7018701497e4f7cd1753cdc44f76da06707 *src\tests\BadRkDemo\Installer\minirtl\cmdline.c 54 | bd6fe82852c4fcdfab559defa33ea394b752a4e4a5ac0653ae20c4a94b0175ed *src\tests\BadRkDemo\Installer\minirtl\cmdline.h 55 | 107245437ed86b6f1e839b2d3d9bbadb3d9980046cb5c7001f985fed3627962f *src\tests\BadRkDemo\Installer\minirtl\minirtl.h 56 | b9de99d3447bb1a125cb92aa1b3f9b56a59522436f1a1a97f23aac9cee90341c *src\tests\BadRkDemo\Installer\minirtl\rtltypes.h 57 | 092ca38b44518f596d8e7cb1331c8023260faa9f55dac4b301d6186c32392294 *src\tests\BadRkDemo\Installer\minirtl\strtoul.c 58 | f81c975acd016c97776dd3a8e3218e148682b0336ff3fcd77fad6d9b86ddf107 *src\tests\BadRkDemo\Installer\minirtl\ultohex.c 59 | c33ae617894dab67759bf5d5d3c21d7d6d3c0a04cf346b1f7df8ef50f24f12b4 *src\tests\BadRkDemo\Installer\minirtl\_filename.c 60 | 9e3f1386bfb64dbaa3cbb12fd3bf51c734872c2fdf15cf1aaeca52a515767519 *src\tests\BadRkDemo\Installer\minirtl\_filename.h 61 | 83772aa217508279294d91af5cfabec9b5e00b836a2e2f5fe37cf1ebc2905a52 *src\tests\BadRkDemo\Installer\minirtl\_strcat.c 62 | 969b35213fa23ff50a169e5498a97f28bc6f5820b447b78ec9dc6910dd8cc3e8 *src\tests\BadRkDemo\Installer\minirtl\_strcpy.c 63 | 27159b8ff67d3f8e6c7fdb4b57b9f57f899bdfedf92cf10276269245c6f4e066 *src\tests\BadRkDemo\Installer\minirtl\_strend.c 64 | 60f19c6b805801e13824c4d9d44748da8245cd936971411d3d36b873121888eb *src\tests\BadRkDemo\Installer\minirtl\_strlen.c 65 | -------------------------------------------------------------------------------- /bin/changelog.txt: -------------------------------------------------------------------------------- 1 | Changes since v1.0.0 release 2 | 3 | v1.2.1 Mar 29, 2018 4 | Addressing Windows 7 KB4088875/KB4100480 changes, issue #18 5 | 6 | v1.2.0 Nov 01, 2017 7 | Experimental Windows 10 RS3 support 8 | Switch to signatures if symbols failed 9 | 10 | v1.1.3 Sept 11, 2017 11 | Changed the way program store symbols 12 | 13 | v1.1.2 July 28, 2017 14 | Hotfix for issue #5 and request implementation for #6 15 | 16 | v1.1.1 June 28, 2017 17 | command -nf removed and now has default effect 18 | added command -pf to patch only fibercontext (for tests) 19 | fixed infinite loop while scanning for existing bcd entry if application failed to open bcd store 20 | 21 | v1.1.0 May 11, 2017 22 | Added command line switch -nf 23 | 24 | - This switch will tell program to use PatchGuard initialization points patch instead of PatchGuard initialization routine patch. With this switch program will modify KeInitAdm64SpecificState (calls KiFilterFiberContext via SEH), ExpLicenseWatchInitWorker (calls KiFilterFiberContext by pointer from PCR->PRCB.HalReserved[0] 25 | 26 | Added check if patched boot entry already exist 27 | 28 | - If patched boot entry already exist then program will warn user and cancel it execution. You need manually remove this entry to use patch again. Run cmd elevated, type bcdedit, locate patched entry guid, delete it with bcdedit /delete 29 | -------------------------------------------------------------------------------- /bin/patch.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hfiref0x/UPGDSED/86442a3c40cb62b10e24c5978bad9ad74815a765/bin/patch.exe -------------------------------------------------------------------------------- /src/bcd.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2017 4 | * 5 | * TITLE: BCD.C 6 | * 7 | * VERSION: 1.11 8 | * 9 | * DATE: 28 June 2017 10 | * 11 | * Boot Configuration Data related routines. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | #include "global.h" 20 | 21 | /* 22 | * BcdRtlStrToUl 23 | * 24 | * Purpose: 25 | * 26 | * wcstoul simplified. 27 | * 28 | */ 29 | unsigned long BcdRtlStrToUl(wchar_t *s) 30 | { 31 | unsigned long long a = 0; 32 | wchar_t c; 33 | 34 | if (s == 0) 35 | return 0; 36 | 37 | while (*s != 0) { 38 | c = *s; 39 | if (_isdigit_w(c)) 40 | a = (a * 10) + (c - L'0'); 41 | else 42 | break; 43 | 44 | if (a > ULONG_MAX) 45 | return ULONG_MAX; 46 | 47 | s++; 48 | } 49 | return (unsigned long)a; 50 | } 51 | 52 | /* 53 | * BcdOpenKey 54 | * 55 | * Purpose: 56 | * 57 | * Open store key. 58 | * 59 | */ 60 | NTSTATUS BcdOpenKey( 61 | _In_opt_ HANDLE hRootKey, 62 | _In_ LPWSTR KeyName, 63 | _In_ ACCESS_MASK DesiredAccess, 64 | _Out_ HANDLE *hKey 65 | ) 66 | { 67 | OBJECT_ATTRIBUTES Obja; 68 | UNICODE_STRING usName; 69 | NTSTATUS Status = STATUS_UNSUCCESSFUL; 70 | 71 | usName.Buffer = NULL; 72 | usName.Length = 0; 73 | usName.MaximumLength = 0; 74 | RtlInitUnicodeString(&usName, KeyName); 75 | InitializeObjectAttributes(&Obja, &usName, OBJ_CASE_INSENSITIVE, hRootKey, NULL); 76 | Status = NtOpenKey(hKey, DesiredAccess, &Obja); 77 | return Status; 78 | } 79 | 80 | /* 81 | * BcdReadValue 82 | * 83 | * Purpose: 84 | * 85 | * Read given value to output buffer. 86 | * Returned Buffer must be released with RtlFreeHeap after use. 87 | * 88 | */ 89 | NTSTATUS BcdReadValue( 90 | _In_ HANDLE hKey, 91 | _In_ LPWSTR ValueName, 92 | _Out_ PVOID *Buffer, 93 | _Out_ ULONG *BufferSize 94 | ) 95 | { 96 | KEY_VALUE_PARTIAL_INFORMATION *kvpi; 97 | UNICODE_STRING usName; 98 | NTSTATUS Status = STATUS_UNSUCCESSFUL; 99 | ULONG Length = 0; 100 | PVOID CopyBuffer = NULL; 101 | 102 | *Buffer = NULL; 103 | *BufferSize = 0; 104 | 105 | usName.Buffer = NULL; 106 | usName.Length = 0; 107 | usName.MaximumLength = 0; 108 | 109 | RtlInitUnicodeString(&usName, ValueName); 110 | Status = NtQueryValueKey(hKey, &usName, KeyValuePartialInformation, NULL, 0, &Length); 111 | if (Status == STATUS_BUFFER_TOO_SMALL) { 112 | 113 | kvpi = RtlAllocateHeap(NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, Length); 114 | if (kvpi) { 115 | 116 | Status = NtQueryValueKey(hKey, &usName, KeyValuePartialInformation, kvpi, Length, &Length); 117 | if (NT_SUCCESS(Status)) { 118 | 119 | CopyBuffer = RtlAllocateHeap(NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, kvpi->DataLength); 120 | if (CopyBuffer) { 121 | RtlCopyMemory(CopyBuffer, kvpi->Data, kvpi->DataLength); 122 | *Buffer = CopyBuffer; 123 | *BufferSize = kvpi->DataLength; 124 | Status = STATUS_SUCCESS; 125 | } 126 | else 127 | { 128 | Status = STATUS_NO_MEMORY; 129 | } 130 | 131 | } 132 | RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, kvpi); 133 | } 134 | else { 135 | Status = STATUS_NO_MEMORY; 136 | } 137 | } 138 | 139 | return Status; 140 | } 141 | 142 | /* 143 | * BcdIsSystemStoreCandidate 144 | * 145 | * Purpose: 146 | * 147 | * Check if store marked as "System". 148 | * 149 | */ 150 | BOOLEAN BcdIsSystemStoreCandidate( 151 | _In_ HANDLE hKey 152 | ) 153 | { 154 | BOOLEAN bResult = FALSE; 155 | PDWORD Value = NULL; 156 | ULONG Length = 0; 157 | NTSTATUS Status; 158 | 159 | Status = BcdReadValue(hKey, L"System", &Value, &Length); 160 | if (NT_SUCCESS(Status)) { 161 | 162 | if (Length == sizeof(DWORD)) { 163 | bResult = (*Value == 1); 164 | } 165 | 166 | RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, Value); 167 | } 168 | 169 | return bResult; 170 | } 171 | 172 | /* 173 | * BcdIsSystemStore 174 | * 175 | * Purpose: 176 | * 177 | * Perform validation of given store to be System store type. 178 | * 179 | */ 180 | NTSTATUS BcdIsSystemStore( 181 | _In_ HANDLE hRootKey, 182 | _In_ LPWSTR KeyName, 183 | _Out_ PBOOL Result 184 | ) 185 | { 186 | ULONG Length = 0; 187 | NTSTATUS Status = STATUS_UNSUCCESSFUL; 188 | HANDLE hKey = NULL, hSubKey = NULL; 189 | PDWORD Value; 190 | 191 | if (Result) 192 | *Result = FALSE; 193 | 194 | hKey = NULL; 195 | Status = BcdOpenKey(hRootKey, KeyName, KEY_READ, &hKey); 196 | if (NT_SUCCESS(Status)) { 197 | 198 | hSubKey = NULL; 199 | Status = BcdOpenKey(hKey, L"Description", KEY_READ, &hSubKey); 200 | if (NT_SUCCESS(Status)) { 201 | 202 | // 203 | // Is this system store candidate? 204 | // 205 | if (BcdIsSystemStoreCandidate(hSubKey)) { 206 | Length = 0; 207 | Value = NULL; 208 | Status = BcdReadValue(hSubKey, L"TreatAsSystem", &Value, &Length); 209 | if (NT_SUCCESS(Status)) { 210 | 211 | if (Length == sizeof(DWORD)) { 212 | if (*Value == 1) { 213 | *Result = TRUE; 214 | Status = STATUS_SUCCESS; 215 | } 216 | } 217 | 218 | RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, Value); 219 | } 220 | else { 221 | Status = STATUS_INVALID_VARIANT; 222 | } 223 | } 224 | NtClose(hSubKey); 225 | } 226 | NtClose(hKey); 227 | } 228 | return Status; 229 | } 230 | 231 | /* 232 | * BcdFindEntryGuid 233 | * 234 | * Purpose: 235 | * 236 | * Enumerate subkeys for Objects root key and lookup given guid. 237 | * 238 | */ 239 | BOOL BcdFindEntryGuid( 240 | _In_ HANDLE hRootKey, 241 | _In_ LPWSTR EntryGuid 242 | ) 243 | { 244 | BOOL bResult = FALSE, bCond = FALSE; 245 | NTSTATUS Status; 246 | ULONG Length = 0, cSubKeys, SubIndex = 0; 247 | SIZE_T Size; 248 | HANDLE hKey; 249 | 250 | KEY_FULL_INFORMATION ki; 251 | KEY_BASIC_INFORMATION *kbi; 252 | 253 | do { 254 | 255 | hKey = NULL; 256 | Status = BcdOpenKey(hRootKey, L"Objects", KEY_READ, &hKey); 257 | if (!NT_SUCCESS(Status)) 258 | break; 259 | 260 | Status = NtQueryKey( 261 | hKey, 262 | KeyFullInformation, 263 | (PVOID)&ki, 264 | sizeof(KEY_FULL_INFORMATION), 265 | &Length); 266 | 267 | if ((Status != STATUS_SUCCESS) && (Status != STATUS_BUFFER_OVERFLOW)) 268 | break; 269 | 270 | cSubKeys = ki.SubKeys; 271 | Size = sizeof(KEY_BASIC_INFORMATION) + ki.MaxNameLen + 2; 272 | 273 | kbi = RtlAllocateHeap( 274 | NtCurrentPeb()->ProcessHeap, 275 | 0, 276 | Size); 277 | 278 | if (kbi) { 279 | 280 | do { 281 | RtlSecureZeroMemory(kbi, Size); 282 | Status = NtEnumerateKey(hKey, SubIndex, KeyBasicInformation, kbi, (ULONG)Size, &Length); 283 | 284 | if (Status == STATUS_NO_MORE_ENTRIES) 285 | break; 286 | 287 | if (!NT_SUCCESS(Status)) 288 | break; 289 | 290 | if (kbi->NameLength > ki.MaxNameLen + 2) 291 | break; 292 | 293 | if (_strcmpi(kbi->Name, EntryGuid) == 0) { 294 | bResult = TRUE; 295 | break; 296 | } 297 | 298 | SubIndex++; 299 | cSubKeys--; 300 | 301 | } while (cSubKeys); 302 | RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, kbi); 303 | } 304 | 305 | } while (bCond); 306 | 307 | if (hKey) NtClose(hKey); 308 | 309 | return bResult; 310 | } 311 | 312 | /* 313 | * BcdPatchEntryAlreadyExist 314 | * 315 | * Purpose: 316 | * 317 | * Check if patch entry already created. 318 | * 319 | */ 320 | BOOL BcdPatchEntryAlreadyExist( 321 | _In_ LPWSTR EntryGuid, 322 | _Out_ PBOOL Result 323 | ) 324 | { 325 | BOOL IsSystemStore = FALSE, bCond = FALSE; 326 | BOOL bSuccess = FALSE; 327 | HANDLE hKey, hSubKey; 328 | ULONG SubIndex = 0, Length = 0, cSubKeys = 0, tmp; 329 | SIZE_T Size; 330 | NTSTATUS Status; 331 | 332 | KEY_FULL_INFORMATION ki; 333 | KEY_BASIC_INFORMATION *kbi; 334 | 335 | if (Result) 336 | *Result = FALSE; 337 | 338 | do { 339 | 340 | // 341 | // Open Machine root key. 342 | // 343 | 344 | hKey = NULL; 345 | Status = BcdOpenKey(NULL, L"\\Registry\\Machine", KEY_READ, &hKey); 346 | if (!NT_SUCCESS(Status)) 347 | break; 348 | 349 | RtlSecureZeroMemory(&ki, sizeof(KEY_FULL_INFORMATION)); 350 | 351 | // 352 | // Query number of top level keys. 353 | // 354 | Status = NtQueryKey( 355 | hKey, 356 | KeyFullInformation, 357 | (PVOID)&ki, 358 | sizeof(KEY_FULL_INFORMATION), 359 | &Length); 360 | 361 | if ((Status != STATUS_SUCCESS) && (Status != STATUS_BUFFER_OVERFLOW)) 362 | break; 363 | 364 | if ((ki.MaxNameLen == 0) || (ki.SubKeys == 0)) 365 | break; 366 | 367 | // 368 | // Allocate memory for keys enumeration. 369 | // 370 | cSubKeys = ki.SubKeys; 371 | Size = sizeof(KEY_BASIC_INFORMATION) + ki.MaxNameLen + 2; 372 | 373 | kbi = RtlAllocateHeap( 374 | NtCurrentPeb()->ProcessHeap, 375 | 0, 376 | Size); 377 | 378 | if (kbi) { 379 | 380 | do { 381 | RtlSecureZeroMemory(kbi, Size); 382 | Status = NtEnumerateKey(hKey, SubIndex, KeyBasicInformation, kbi, (ULONG)Size, &Length); 383 | 384 | if (Status == STATUS_NO_MORE_ENTRIES) 385 | break; 386 | 387 | if (!NT_SUCCESS(Status)) 388 | break; 389 | 390 | // 391 | // Buffer overflow. 392 | // 393 | if (kbi->NameLength > ki.MaxNameLen + 2) 394 | break; 395 | 396 | // 397 | // Validate BCD key name. 398 | // 399 | // Name format: 400 | // BCD + XXXXXXXXUL 401 | // 402 | if (_strncmpi_w(kbi->Name, L"BCD", 3) == 0) { 403 | tmp = BcdRtlStrToUl(&kbi->Name[3]); 404 | // 405 | // Conversion error, wrong key. 406 | // 407 | if (tmp == ULONG_MAX) { 408 | SubIndex++; 409 | cSubKeys--; 410 | continue; 411 | } 412 | 413 | // 414 | // Check if this key is system store. 415 | // 416 | if (!NT_SUCCESS(BcdIsSystemStore(hKey, kbi->Name, &IsSystemStore))) { 417 | SubIndex++; 418 | cSubKeys--; 419 | continue; 420 | } 421 | 422 | if (IsSystemStore) { 423 | 424 | hSubKey = NULL; 425 | Status = BcdOpenKey(hKey, kbi->Name, KEY_READ, &hSubKey); 426 | if (NT_SUCCESS(Status)) { 427 | 428 | *Result = BcdFindEntryGuid(hSubKey, EntryGuid); 429 | bSuccess = TRUE; 430 | 431 | NtClose(hSubKey); 432 | } 433 | break; 434 | } 435 | 436 | } 437 | 438 | SubIndex++; 439 | cSubKeys--; 440 | 441 | } while (cSubKeys); 442 | 443 | RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, kbi); 444 | } 445 | 446 | } while (bCond); 447 | 448 | if (hKey) NtClose(hKey); 449 | 450 | return bSuccess; 451 | } 452 | 453 | /* 454 | * BcdCreatePatchEntry 455 | * 456 | * Purpose: 457 | * 458 | * Create new BCD Entry and write settings to it. 459 | * 460 | */ 461 | BOOL BcdCreatePatchEntry( 462 | _In_ ULONG BuildNumber 463 | ) 464 | { 465 | BOOL bCond = FALSE, bResult = FALSE; 466 | DWORD ExitCode; 467 | SIZE_T Length, CmdLength; 468 | WCHAR szCommand[MAX_PATH * 3]; 469 | 470 | RtlSecureZeroMemory(szCommand, sizeof(szCommand)); 471 | 472 | _snwprintf_s(szCommand, 473 | MAX_PATH, 474 | MAX_PATH, 475 | TEXT("%ws\\%ws "), 476 | g_szSystemDirectory, 477 | BCDEDIT_EXE); 478 | 479 | Length = _strlen(szCommand); 480 | if (Length <= BCDEDIT_LENGTH) 481 | return FALSE; 482 | 483 | CmdLength = Length - BCDEDIT_LENGTH; 484 | 485 | cuiPrintText(g_ConOut, TEXT("Patch: Executing BCDEDIT commands"), g_ConsoleOutput, TRUE); 486 | 487 | do { 488 | 489 | // 490 | // Set bootmgr option 491 | // Commented for bitlocker compatibility. 492 | // 493 | /* _strcat(szCommand, TEXT("-set {bootmgr} nointegritychecks 1")); 494 | cuiPrintText(g_ConOut, &szCommand[CmdLength], g_ConsoleOutput, TRUE); 495 | 496 | if (!supRunProcessWithParamsAndWait(szCommand, &ExitCode)) 497 | break; 498 | 499 | if (ExitCode != 0) 500 | break;*/ 501 | 502 | // 503 | // Create new entry. 504 | // 505 | szCommand[Length] = 0; 506 | _strcat(szCommand, TEXT("-create ")); 507 | _strcat(szCommand, BCD_PATCH_ENTRY_GUID); 508 | _strcat(szCommand, TEXT(" -d \"Patch Guard Disabled\" -application OSLOADER")); 509 | cuiPrintText(g_ConOut, &szCommand[CmdLength], g_ConsoleOutput, TRUE); 510 | 511 | if (!supRunProcessWithParamsAndWait(szCommand, &ExitCode)) 512 | break; 513 | 514 | if (ExitCode != 0) 515 | break; 516 | 517 | // 518 | // Set device partition. 519 | // 520 | szCommand[Length] = 0; 521 | _strcat(szCommand, TEXT("-set ")); 522 | _strcat(szCommand, BCD_PATCH_ENTRY_GUID); 523 | _strcat(szCommand, TEXT(" device partition=")); 524 | _strcat(szCommand, g_szDeviceParition); 525 | cuiPrintText(g_ConOut, &szCommand[CmdLength], g_ConsoleOutput, TRUE); 526 | 527 | if (!supRunProcessWithParamsAndWait(szCommand, &ExitCode)) 528 | break; 529 | 530 | if (ExitCode != 0) 531 | break; 532 | 533 | // 534 | // Set osdevice partition. 535 | // 536 | szCommand[Length] = 0; 537 | _strcat(szCommand, TEXT("-set ")); 538 | _strcat(szCommand, BCD_PATCH_ENTRY_GUID); 539 | _strcat(szCommand, TEXT(" osdevice partition=")); 540 | _strcat(szCommand, g_szDeviceParition); 541 | cuiPrintText(g_ConOut, &szCommand[CmdLength], g_ConsoleOutput, TRUE); 542 | 543 | if (!supRunProcessWithParamsAndWait(szCommand, &ExitCode)) 544 | break; 545 | 546 | if (ExitCode != 0) 547 | break; 548 | 549 | // 550 | // Set systemroot. 551 | // 552 | szCommand[Length] = 0; 553 | _strcat(szCommand, TEXT("-set ")); 554 | _strcat(szCommand, BCD_PATCH_ENTRY_GUID); 555 | _strcat(szCommand, TEXT(" systemroot \\Windows")); 556 | cuiPrintText(g_ConOut, &szCommand[CmdLength], g_ConsoleOutput, TRUE); 557 | 558 | if (!supRunProcessWithParamsAndWait(szCommand, &ExitCode)) 559 | break; 560 | 561 | if (ExitCode != 0) 562 | break; 563 | 564 | // 565 | // Set osloader path. 566 | // 567 | szCommand[Length] = 0; 568 | _strcat(szCommand, TEXT("-set ")); 569 | _strcat(szCommand, BCD_PATCH_ENTRY_GUID); 570 | _strcat(szCommand, TEXT(" path \\Windows\\system32\\")); 571 | 572 | if (g_IsEFI) { 573 | _strcat(szCommand, OSLOAD_EFI); 574 | } 575 | else { 576 | _strcat(szCommand, OSLOAD_EXE); 577 | } 578 | cuiPrintText(g_ConOut, &szCommand[CmdLength], g_ConsoleOutput, TRUE); 579 | 580 | if (!supRunProcessWithParamsAndWait(szCommand, &ExitCode)) 581 | break; 582 | 583 | if (ExitCode != 0) 584 | break; 585 | 586 | // 587 | // Set kernel. 588 | // 589 | szCommand[Length] = 0; 590 | _strcat(szCommand, TEXT("-set ")); 591 | _strcat(szCommand, BCD_PATCH_ENTRY_GUID); 592 | _strcat(szCommand, TEXT(" kernel ")); 593 | _strcat(szCommand, NTOSKRNMP_EXE); 594 | cuiPrintText(g_ConOut, &szCommand[CmdLength], g_ConsoleOutput, TRUE); 595 | 596 | if (!supRunProcessWithParamsAndWait(szCommand, &ExitCode)) 597 | break; 598 | 599 | if (ExitCode != 0) 600 | break; 601 | 602 | // 603 | // Set recoveryenabled. 604 | // 605 | szCommand[Length] = 0; 606 | _strcat(szCommand, TEXT("-set ")); 607 | _strcat(szCommand, BCD_PATCH_ENTRY_GUID); 608 | _strcat(szCommand, TEXT(" recoveryenabled 0")); 609 | cuiPrintText(g_ConOut, &szCommand[CmdLength], g_ConsoleOutput, TRUE); 610 | 611 | if (!supRunProcessWithParamsAndWait(szCommand, &ExitCode)) 612 | break; 613 | 614 | if (ExitCode != 0) 615 | break; 616 | 617 | // 618 | // Set Nx. 619 | // 620 | szCommand[Length] = 0; 621 | _strcat(szCommand, TEXT("-set ")); 622 | _strcat(szCommand, BCD_PATCH_ENTRY_GUID); 623 | _strcat(szCommand, TEXT(" nx OptIn")); 624 | cuiPrintText(g_ConOut, &szCommand[CmdLength], g_ConsoleOutput, TRUE); 625 | 626 | if (!supRunProcessWithParamsAndWait(szCommand, &ExitCode)) 627 | break; 628 | 629 | if (ExitCode != 0) 630 | break; 631 | 632 | // 633 | // Set nointegritychecks for our GUID entry. 634 | // 635 | szCommand[Length] = 0; 636 | _strcat(szCommand, TEXT("-set ")); 637 | _strcat(szCommand, BCD_PATCH_ENTRY_GUID); 638 | _strcat(szCommand, TEXT(" nointegritychecks 1")); 639 | cuiPrintText(g_ConOut, &szCommand[CmdLength], g_ConsoleOutput, TRUE); 640 | 641 | if (!supRunProcessWithParamsAndWait(szCommand, &ExitCode)) 642 | break; 643 | 644 | if (ExitCode != 0) 645 | break; 646 | 647 | // 648 | // Set inherit bootloader settings. 649 | // 650 | szCommand[Length] = 0; 651 | _strcat(szCommand, TEXT("-set ")); 652 | _strcat(szCommand, BCD_PATCH_ENTRY_GUID); 653 | _strcat(szCommand, TEXT(" inherit {bootloadersettings}")); 654 | cuiPrintText(g_ConOut, &szCommand[CmdLength], g_ConsoleOutput, TRUE); 655 | 656 | if (!supRunProcessWithParamsAndWait(szCommand, &ExitCode)) 657 | break; 658 | 659 | if (ExitCode != 0) 660 | break; 661 | 662 | // 663 | // Set display order. 664 | // 665 | szCommand[Length] = 0; 666 | _strcat(szCommand, TEXT("-displayorder ")); 667 | _strcat(szCommand, BCD_PATCH_ENTRY_GUID); 668 | _strcat(szCommand, TEXT(" -addlast")); 669 | cuiPrintText(g_ConOut, &szCommand[CmdLength], g_ConsoleOutput, TRUE); 670 | 671 | if (!supRunProcessWithParamsAndWait(szCommand, &ExitCode)) 672 | break; 673 | 674 | if (ExitCode != 0) 675 | break; 676 | 677 | // 678 | // Set timeout. 679 | // 680 | szCommand[Length] = 0; 681 | _strcat(szCommand, TEXT("-timeout 10")); 682 | cuiPrintText(g_ConOut, &szCommand[CmdLength], g_ConsoleOutput, TRUE); 683 | 684 | if (!supRunProcessWithParamsAndWait(szCommand, &ExitCode)) 685 | break; 686 | 687 | if (ExitCode != 0) 688 | break; 689 | 690 | // 691 | // Set bootmenupolicy to Legacy for everything above Windows 7 SP1 692 | // 693 | if (BuildNumber > 7601) { 694 | szCommand[Length] = 0; 695 | _strcat(szCommand, TEXT("-set bootmenupolicy legacy")); 696 | cuiPrintText(g_ConOut, &szCommand[CmdLength], g_ConsoleOutput, TRUE); 697 | if (!supRunProcessWithParamsAndWait(szCommand, &ExitCode)) 698 | break; 699 | 700 | if (ExitCode != 0) 701 | break; 702 | } 703 | 704 | // 705 | // Disable PEAUTH autostart. 706 | // 707 | cuiPrintText(g_ConOut, 708 | TEXT("Patch: Setting PeAuth service to manual start"), 709 | g_ConsoleOutput, 710 | TRUE); 711 | 712 | if (!supDisablePeAuthAutoStart()) { 713 | supShowError(GetLastError(), 714 | TEXT("Could not set PeAuth service to manual start")); 715 | } 716 | else { 717 | cuiPrintText(g_ConOut, 718 | TEXT("Patch: PeAuth service set to manual start"), 719 | g_ConsoleOutput, 720 | TRUE); 721 | } 722 | 723 | bResult = TRUE; 724 | 725 | } while (bCond); 726 | 727 | 728 | return bResult; 729 | } 730 | -------------------------------------------------------------------------------- /src/bcd.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2017 4 | * 5 | * TITLE: BCD.H 6 | * 7 | * VERSION: 1.10 8 | * 9 | * DATE: 11 May 2017 10 | * 11 | * Common header file for the bcd support routines. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | #pragma once 20 | 21 | #define BCD_PATCH_ENTRY_GUID TEXT("{71A3C7FC-F751-4982-AEC1-E958357E6813}") 22 | 23 | BOOL BcdPatchEntryAlreadyExist( 24 | _In_ LPWSTR EntryGuid, 25 | _Out_ PBOOL Result); 26 | 27 | BOOL BcdCreatePatchEntry( 28 | _In_ ULONG BuildNumber); 29 | -------------------------------------------------------------------------------- /src/cui/cui.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2016 - 2017 4 | * 5 | * TITLE: CUI.C 6 | * 7 | * VERSION: 1.02 8 | * 9 | * DATE: 21 Apr 2017 10 | * 11 | * Console output. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | #include "global.h" 20 | 21 | /* 22 | * cuiClrScr 23 | * 24 | * Purpose: 25 | * 26 | * Clear screen. 27 | * 28 | */ 29 | VOID cuiClrScr( 30 | _In_ HANDLE hConsole 31 | ) 32 | { 33 | COORD coordScreen; 34 | DWORD cCharsWritten; 35 | DWORD dwConSize; 36 | CONSOLE_SCREEN_BUFFER_INFO csbi; 37 | 38 | coordScreen.X = 0; 39 | coordScreen.Y = 0; 40 | 41 | if (!GetConsoleScreenBufferInfo(hConsole, &csbi)) 42 | return; 43 | 44 | dwConSize = csbi.dwSize.X * csbi.dwSize.Y; 45 | 46 | if (!FillConsoleOutputCharacter(hConsole, TEXT(' '), 47 | dwConSize, coordScreen, &cCharsWritten)) 48 | return; 49 | 50 | if (!GetConsoleScreenBufferInfo(hConsole, &csbi)) 51 | return; 52 | 53 | if (!FillConsoleOutputAttribute(hConsole, csbi.wAttributes, 54 | dwConSize, coordScreen, &cCharsWritten)) 55 | return; 56 | 57 | SetConsoleCursorPosition(hConsole, coordScreen); 58 | } 59 | 60 | /* 61 | * cuiPrintText 62 | * 63 | * Purpose: 64 | * 65 | * Output text to the console or file. 66 | * 67 | */ 68 | VOID cuiPrintText( 69 | _In_ HANDLE hOutConsole, 70 | _In_ LPWSTR lpText, 71 | _In_ BOOL ConsoleOutputEnabled, 72 | _In_ BOOL UseReturn 73 | ) 74 | { 75 | SIZE_T consoleIO; 76 | DWORD bytesIO; 77 | LPWSTR Buffer; 78 | 79 | if (lpText == NULL) 80 | return; 81 | 82 | consoleIO = _strlen(lpText); 83 | if ((consoleIO == 0) || (consoleIO > MAX_PATH * 4)) 84 | return; 85 | 86 | consoleIO = consoleIO * sizeof(WCHAR) + 4 + sizeof(UNICODE_NULL); 87 | Buffer = (LPWSTR)RtlAllocateHeap(RtlGetCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, consoleIO); 88 | if (Buffer) { 89 | 90 | _strcpy(Buffer, lpText); 91 | if (UseReturn) _strcat(Buffer, TEXT("\r\n")); 92 | 93 | consoleIO = _strlen(Buffer); 94 | 95 | if (ConsoleOutputEnabled != FALSE) { 96 | WriteConsole(hOutConsole, Buffer, (DWORD)consoleIO, &bytesIO, NULL); 97 | } 98 | else { 99 | WriteFile(hOutConsole, Buffer, (DWORD)(consoleIO * sizeof(WCHAR)), &bytesIO, NULL); 100 | } 101 | RtlFreeHeap(RtlGetCurrentPeb()->ProcessHeap, 0, Buffer); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/cui/cui.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2016 - 2017 4 | * 5 | * TITLE: CUI.H 6 | * 7 | * VERSION: 1.02 8 | * 9 | * DATE: 21 Apr 2017 10 | * 11 | * Common header file for console ui. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | #pragma once 20 | 21 | VOID cuiClrScr( 22 | _In_ HANDLE hConsole); 23 | 24 | VOID cuiPrintText( 25 | _In_ HANDLE hOutConsole, 26 | _In_ LPWSTR lpText, 27 | _In_ BOOL ConsoleOutputEnabled, 28 | _In_ BOOL UseReturn); 29 | -------------------------------------------------------------------------------- /src/global.h: -------------------------------------------------------------------------------- 1 | 2 | /******************************************************************************* 3 | * 4 | * (C) COPYRIGHT AUTHORS, 2017 - 2018 5 | * 6 | * TITLE: GLOBAL.H 7 | * 8 | * VERSION: 1.21 9 | * 10 | * DATE: 29 Mar 2018 11 | * 12 | * Common header file for the project. 13 | * 14 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 15 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 16 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 17 | * PARTICULAR PURPOSE. 18 | * 19 | *******************************************************************************/ 20 | #pragma once 21 | 22 | #if !defined UNICODE 23 | #error ANSI build is not supported 24 | #endif 25 | 26 | #if (_MSC_VER >= 1900) 27 | #ifdef _DEBUG 28 | #pragma comment(lib, "vcruntimed.lib") 29 | #pragma comment(lib, "ucrtd.lib") 30 | #else 31 | #pragma comment(lib, "libvcruntime.lib") 32 | #endif 33 | #endif 34 | 35 | //disable nonmeaningful warnings. 36 | #pragma warning(disable: 4005) // macro redefinition 37 | #pragma warning(disable: 4055) // %s : from data pointer %s to function pointer %s 38 | #pragma warning(disable: 4091) //'typedef ': ignored on left of '' when no variable is declared 39 | #pragma warning(disable: 4152) // nonstandard extension, function/data pointer conversion in expression 40 | #pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union 41 | #pragma warning(disable: 6102) // Using %s from failed function call at line %u 42 | #pragma warning(disable: 6320) // exception-filter expression is the constant EXCEPTION_EXECUTE_HANDLER 43 | 44 | #include 45 | #include 46 | #include 47 | #include "resource.h" 48 | #include "ntdll\ntos.h" 49 | #include "minirtl\minirtl.h" 50 | #include "minirtl\rtltypes.h" 51 | #include "minirtl\_filename.h" 52 | #include "minirtl\cmdline.h" 53 | #include "cui\cui.h" 54 | 55 | #pragma comment(lib, "version.lib") 56 | 57 | //source filenames 58 | #define WINLOAD_EXE L"winload.exe" 59 | #define WINLOAD_EFI L"winload.efi" 60 | #define NTOSKRNL_EXE L"ntoskrnl.exe" 61 | 62 | //destination filenames 63 | #define OSLOAD_EXE L"osloader.exe" 64 | #define OSLOAD_EFI L"osloader.efi" 65 | #define NTOSKRNMP_EXE L"ntkrnlmp.exe" 66 | 67 | #define BCDEDIT_EXE L"bcdedit.exe" 68 | #define BCDEDIT_LENGTH sizeof(BCDEDIT_EXE) / sizeof(WCHAR) 69 | 70 | #define CONTINUE_CMD L"CONTINUE" 71 | 72 | #define PROGRAMTITLE L"UPGDSED v1.2.1" 73 | #define PROGRAMFULLNAME L"Universal PatchGuard and Driver Signature Enforcement Disable" 74 | 75 | #define MAX_PATCH_COUNT 10 76 | 77 | #define MIN_SUPPORTED_NT_BUILD 7601 //Windows 7 SP1 78 | #define MAX_SUPPORTED_NT_BUILD 16299 //Windows 10 RS3 79 | 80 | typedef struct _PATCH_CONTEXT { 81 | ULONG_PTR AddressOfPatch; 82 | PVOID PatchData; 83 | ULONG SizeOfPatch; 84 | } PATCH_CONTEXT, *PPATCH_CONTEXT; 85 | 86 | typedef struct _SYMBOL_ENTRY { 87 | struct _SYMBOL_ENTRY *Next; 88 | LPWSTR Name; 89 | DWORD64 Address; 90 | } SYMBOL_ENTRY, *PSYMBOL_ENTRY; 91 | 92 | //basic runtime from ntdll 93 | 94 | typedef int(__cdecl *fnptr_snwprintf_s)( 95 | wchar_t *buffer, 96 | size_t sizeOfBuffer, 97 | size_t count, 98 | const wchar_t *format, 99 | ... 100 | ); 101 | 102 | #include "sup.h" 103 | #include "scan.h" 104 | #include "bcd.h" 105 | 106 | extern HANDLE g_ConOut; 107 | extern BOOL g_IsEFI; 108 | extern BOOL g_ConsoleOutput; 109 | extern WCHAR g_szTempDirectory[MAX_PATH + 1]; 110 | extern WCHAR g_szSystemDirectory[MAX_PATH + 1]; 111 | extern WCHAR g_szDeviceParition[MAX_PATH + 1]; 112 | extern fnptr_snwprintf_s _snwprintf_s; 113 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2017 - 2018 4 | * 5 | * TITLE: MAIN.C 6 | * 7 | * VERSION: 1.21 8 | * 9 | * DATE: 29 Mar 2018 10 | * 11 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 12 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 13 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 14 | * PARTICULAR PURPOSE. 15 | * 16 | *******************************************************************************/ 17 | #include "global.h" 18 | 19 | fnptr_snwprintf_s _snwprintf_s; 20 | 21 | HANDLE g_ConOut = NULL; 22 | HANDLE g_ConIn = NULL; 23 | BOOL g_ConsoleOutput = FALSE; 24 | BOOL g_IsEFI = FALSE; 25 | WCHAR g_BE = 0xFEFF; 26 | 27 | WCHAR g_szTempDirectory[MAX_PATH + 1]; 28 | WCHAR g_szSystemDirectory[MAX_PATH + 1]; 29 | WCHAR g_szDeviceParition[MAX_PATH + 1]; 30 | 31 | // 32 | // Ntoskrnl patch points 33 | // 34 | 35 | //dse 36 | PATCH_CONTEXT SeValidateImageData; 37 | PATCH_CONTEXT SepInitializeCodeIntegrity; 38 | 39 | //pg macro call 40 | PATCH_CONTEXT CcInitializeBcbProfiler; 41 | 42 | //pg initializer 43 | PATCH_CONTEXT KiFilterFiberContext; 44 | 45 | //pg initialization points 46 | PATCH_CONTEXT KeInitAmd64SpecificState; //seh->KiFilterFiberContext 47 | PATCH_CONTEXT ExpLicenseWatchInitWorker; //pcr->prcb->KiFilterFiberContext 48 | 49 | // 50 | // Winload patch points 51 | // 52 | 53 | //image validation 54 | PATCH_CONTEXT ImgpValidateImageHash; 55 | 56 | 57 | /* 58 | * ScanNtos 59 | * 60 | * Purpose: 61 | * 62 | * Search for required patterns in ntoskrnl.exe. 63 | * 64 | */ 65 | BOOLEAN ScanNtos( 66 | _In_ BOOLEAN EnableFiberContextPatch 67 | ) 68 | { 69 | BOOLEAN bCond = FALSE, bResult = FALSE, fUseSymbols = FALSE; 70 | ULONG MajorVersion = 0, MinorVersion = 0, BuildNumber = 0, Revision = 0; 71 | 72 | PBYTE DllBase = NULL; 73 | SIZE_T DllVirtualSize; 74 | IMAGE_NT_HEADERS *NtHeaders; 75 | 76 | WCHAR szBuffer[MAX_PATH * 2]; 77 | WCHAR szVersion[MAX_PATH]; 78 | 79 | 80 | do { 81 | 82 | 83 | #ifndef _DEBUG 84 | _strcpy(szBuffer, g_szTempDirectory); 85 | _strcat(szBuffer, NTOSKRNMP_EXE); 86 | #else 87 | //_strcpy(szBuffer, L"D:\\dumps\\pgos\\6.1.7601.18471\\ntoskrnl.exe"); 88 | //_strcpy(szBuffer, L"D:\\dumps\\pgos\\6.1.7601.23418\\ntoskrnl.exe"); 89 | _strcpy(szBuffer, L"D:\\dumps\\pgos\\6.1.7601.24059\\ntoskrnl.exe"); 90 | //_strcpy(szBuffer, L"D:\\dumps\\pgos\\6.2.9200.16384\\ntoskrnl.exe"); 91 | //_strcpy(szBuffer, L"D:\\dumps\\pgos\\6.3.9600.18589\\ntoskrnl.exe"); 92 | //_strcpy(szBuffer, L"D:\\dumps\\pgos\\10.0.10240.16384\\ntoskrnl.exe"); 93 | //_strcpy(szBuffer, L"D:\\dumps\\pgos\\10.0.10586.0\\ntoskrnl.exe"); 94 | //_strcpy(szBuffer, L"D:\\dumps\\pgos\\10.0.14393.0\\ntoskrnl.exe"); 95 | //_strcpy(szBuffer, L"D:\\dumps\\pgos\\10.0.15063.0\\ntoskrnl.exe"); 96 | //_strcpy(szBuffer, L"D:\\dumps\\pgos\\10.0.16299.15\\ntoskrnl.exe"); 97 | #endif 98 | 99 | if (!supGetBinaryVersionNumbers( 100 | szBuffer, 101 | &MajorVersion, 102 | &MinorVersion, 103 | &BuildNumber, 104 | &Revision)) 105 | { 106 | supShowError(ERROR_VERSION_PARSE_ERROR, TEXT("Cannot query ntoskrnl version information")); 107 | break; 108 | } 109 | 110 | // 111 | // Output ntorknrl version. 112 | // 113 | RtlSecureZeroMemory(szVersion, sizeof(szVersion)); 114 | 115 | _snwprintf_s(szVersion, MAX_PATH, MAX_PATH, L"Patch: Ntoskrnl version: %lu.%lu.%lu.%lu\n", 116 | MajorVersion, 117 | MinorVersion, 118 | BuildNumber, 119 | Revision); 120 | 121 | cuiPrintText(g_ConOut, szVersion, g_ConsoleOutput, TRUE); 122 | 123 | // 124 | // Map ntos image. 125 | // 126 | DllBase = supMapFile(szBuffer, &DllVirtualSize); 127 | if (DllBase == NULL) { 128 | supShowError(GetLastError(), TEXT("Cannot map ntos file")); 129 | break; 130 | } 131 | 132 | NtHeaders = RtlImageNtHeader(DllBase); 133 | 134 | fUseSymbols = (BOOLEAN)SymbolsLoadForFile(szBuffer, (DWORD64)DllBase); 135 | 136 | if (fUseSymbols != TRUE) { 137 | supShowError(GetLastError(), TEXT("Cannot load symbols for the ntoskrnl, signatures now used")); 138 | } 139 | 140 | // 141 | // Scan for SeValidateImageData 142 | // 143 | if (!QuerySeValidateImageDataOffset( 144 | BuildNumber, 145 | Revision, 146 | DllBase, 147 | DllVirtualSize, 148 | NtHeaders, 149 | &SeValidateImageData)) 150 | { 151 | supShowError(ERROR_CAN_NOT_COMPLETE, TEXT("Cannot query SeValidateImageData offset")); 152 | break; 153 | } 154 | 155 | _snwprintf_s(szBuffer, MAX_PATH * 2, MAX_PATH, TEXT("-> SeValidateImageData\t\t%08llX"), //-V111 156 | SeValidateImageData.AddressOfPatch); 157 | cuiPrintText(g_ConOut, szBuffer, g_ConsoleOutput, TRUE); 158 | 159 | // 160 | // Scan for CcInitializeBcbProfiler 161 | // 162 | if (!QueryCcInitializeBcbProfilerOffset( 163 | BuildNumber, 164 | Revision, 165 | DllBase, 166 | DllVirtualSize, 167 | NtHeaders, 168 | &CcInitializeBcbProfiler)) 169 | { 170 | supShowError(ERROR_CAN_NOT_COMPLETE, TEXT("Cannot query CcInitializeBcbProfiler offset")); 171 | break; 172 | } 173 | 174 | _snwprintf_s(szBuffer, MAX_PATH * 2, MAX_PATH, TEXT("-> CcInitializeBcbProfiler\t%08llX"), //-V111 175 | CcInitializeBcbProfiler.AddressOfPatch); 176 | cuiPrintText(g_ConOut, szBuffer, g_ConsoleOutput, TRUE); 177 | 178 | // 179 | // Scan for KiFilterFiberContext if enabled by command. 180 | // 181 | if (EnableFiberContextPatch) { 182 | 183 | if (!QueryKiFilterFiberContextOffset( 184 | BuildNumber, 185 | Revision, 186 | DllBase, 187 | DllVirtualSize, 188 | NtHeaders, 189 | &KiFilterFiberContext)) 190 | { 191 | supShowError(ERROR_CAN_NOT_COMPLETE, TEXT("Cannot query KiFilterFiberContext offset")); 192 | break; 193 | } 194 | 195 | _snwprintf_s(szBuffer, MAX_PATH * 2, MAX_PATH, TEXT("-> KiFilterFiberContext\t\t%08llX"), //-V111 196 | KiFilterFiberContext.AddressOfPatch); 197 | cuiPrintText(g_ConOut, szBuffer, g_ConsoleOutput, TRUE); 198 | 199 | } 200 | else { 201 | 202 | // 203 | // KiFilterFiberContext patch disabled. 204 | // 205 | // Scan for KeInitAmd64SpecificState 206 | // 207 | if (!QueryKeInitAmd64SpecificStateOffset( 208 | BuildNumber, 209 | Revision, 210 | DllBase, 211 | DllVirtualSize, 212 | NtHeaders, 213 | &KeInitAmd64SpecificState)) 214 | { 215 | supShowError(ERROR_CAN_NOT_COMPLETE, TEXT("Cannot query KeInitAmd64SpecificState offset")); 216 | break; 217 | } 218 | 219 | _snwprintf_s(szBuffer, MAX_PATH * 2, MAX_PATH, TEXT("-> KeInitAmd64SpecificState\t%08llX"), //-V111 220 | KeInitAmd64SpecificState.AddressOfPatch); 221 | cuiPrintText(g_ConOut, szBuffer, g_ConsoleOutput, TRUE); 222 | 223 | // 224 | // Scan for ExpLicenseWatchInitWorker 225 | // Not exist on Windows 7. 226 | // 227 | if (BuildNumber > 7601) { 228 | 229 | if (!QueryExpLicenseWatchInitWorkerOffset( 230 | BuildNumber, 231 | Revision, 232 | DllBase, 233 | DllVirtualSize, 234 | NtHeaders, 235 | &ExpLicenseWatchInitWorker)) 236 | { 237 | supShowError(ERROR_CAN_NOT_COMPLETE, TEXT("Cannot query ExpLicenseWatchInitWorker offset")); 238 | break; 239 | } 240 | _snwprintf_s(szBuffer, MAX_PATH * 2, MAX_PATH, TEXT("-> ExpLicenseWatchInitWorker\t%08llX"), //-V111 241 | ExpLicenseWatchInitWorker.AddressOfPatch); 242 | cuiPrintText(g_ConOut, szBuffer, g_ConsoleOutput, TRUE); 243 | 244 | } 245 | 246 | } 247 | 248 | // 249 | //Scan for SepInitializeCodeIntegrity 250 | // 251 | if (!QuerySepInitializeCodeIntegrityOffset( 252 | BuildNumber, 253 | Revision, 254 | DllBase, 255 | DllVirtualSize, 256 | NtHeaders, 257 | &SepInitializeCodeIntegrity)) 258 | { 259 | supShowError(ERROR_CAN_NOT_COMPLETE, TEXT("Cannot query SepInitializeCodeIntegrity offset")); 260 | break; 261 | } 262 | 263 | _snwprintf_s(szBuffer, MAX_PATH * 2, MAX_PATH, TEXT("-> SepInitializeCodeIntegrity\t%08llX"), //-V111 264 | SepInitializeCodeIntegrity.AddressOfPatch); 265 | cuiPrintText(g_ConOut, szBuffer, g_ConsoleOutput, TRUE); 266 | 267 | bResult = TRUE; 268 | 269 | } while (bCond); 270 | 271 | if (fUseSymbols) 272 | SymbolsUnload((DWORD64)DllBase); 273 | 274 | if (DllBase != NULL) 275 | NtUnmapViewOfSection(NtCurrentProcess(), DllBase); 276 | 277 | return bResult; 278 | } 279 | 280 | /* 281 | * ScanWinload 282 | * 283 | * Purpose: 284 | * 285 | * Search for required patterns in winload.exe/winload.efi. 286 | * 287 | */ 288 | BOOLEAN ScanWinload( 289 | VOID 290 | ) 291 | { 292 | BOOLEAN bCond = FALSE, bResult = FALSE; 293 | ULONG MajorVersion = 0, MinorVersion = 0, BuildNumber = 0, Revision = 0; 294 | 295 | PBYTE DllBase = NULL; 296 | SIZE_T DllVirtualSize; 297 | IMAGE_NT_HEADERS *NtHeaders; 298 | 299 | WCHAR szBuffer[MAX_PATH * 2]; 300 | WCHAR szVersion[MAX_PATH]; 301 | 302 | 303 | do { 304 | 305 | #ifndef _DEBUG 306 | _strcpy(szBuffer, g_szTempDirectory); 307 | if (g_IsEFI != FALSE) { 308 | _strcat(szBuffer, OSLOAD_EFI); 309 | } 310 | else { 311 | _strcat(szBuffer, OSLOAD_EXE); 312 | } 313 | #else 314 | //_strcpy(szBuffer, L"D:\\dumps\\pgos\\6.1.7601.23418\\winload.exe"); 315 | //_strcpy(szBuffer, L"D:\\dumps\\pgos\\6.2.9200.16384\\winload.exe"); 316 | //_strcpy(szBuffer, L"D:\\dumps\\pgos\\6.3.9600.18589\\winload.exe"); 317 | //_strcpy(szBuffer, L"D:\\dumps\\pgos\\10.0.10240.16384\\winload.exe"); 318 | //_strcpy(szBuffer, L"D:\\dumps\\pgos\\10.0.10586.0\\winload.exe"); 319 | //_strcpy(szBuffer, L"D:\\dumps\\pgos\\10.0.14393.0\\winload.exe"); 320 | //_strcpy(szBuffer, L"D:\\dumps\\pgos\\10.0.15063.0\\winload.exe"); 321 | _strcpy(szBuffer, L"D:\\dumps\\pgos\\10.0.16299.15\\winload.exe"); 322 | #endif 323 | 324 | if (!supGetBinaryVersionNumbers( 325 | szBuffer, 326 | &MajorVersion, 327 | &MinorVersion, 328 | &BuildNumber, 329 | &Revision)) 330 | { 331 | supShowError(ERROR_VERSION_PARSE_ERROR, TEXT("Cannot query winload build number")); 332 | break; 333 | } 334 | 335 | // 336 | // Output winload version. 337 | // 338 | RtlSecureZeroMemory(szVersion, sizeof(szVersion)); 339 | 340 | _snwprintf_s(szVersion, MAX_PATH, MAX_PATH, L"Patch: Winload version: %lu.%lu.%lu.%lu\n", 341 | MajorVersion, 342 | MinorVersion, 343 | BuildNumber, 344 | Revision); 345 | 346 | cuiPrintText(g_ConOut, szVersion, g_ConsoleOutput, TRUE); 347 | 348 | // 349 | // Map winload image. 350 | // 351 | DllBase = supMapFile(szBuffer, &DllVirtualSize); 352 | if (DllBase == NULL) { 353 | supShowError(GetLastError(), TEXT("Cannot map winload file")); 354 | break; 355 | } 356 | 357 | NtHeaders = RtlImageNtHeader(DllBase); 358 | 359 | // 360 | // First attempt via symbols 361 | // 362 | if (SymbolsLoadForFile(szBuffer, (DWORD64)DllBase)) { 363 | 364 | if (QueryImgpValidateImageHashOffsetSymbols( 365 | DllBase, 366 | NtHeaders, 367 | &ImgpValidateImageHash)) 368 | { 369 | _snwprintf_s(szBuffer, MAX_PATH * 2, MAX_PATH, TEXT("-> ImgpValidateImageHash\t%08llX"), //-V111 370 | ImgpValidateImageHash.AddressOfPatch); 371 | 372 | cuiPrintText(g_ConOut, szBuffer, g_ConsoleOutput, TRUE); 373 | bResult = TRUE; 374 | } 375 | else { 376 | supShowError(ERROR_CAN_NOT_COMPLETE, TEXT("Cannot query ImgpValidateImageHash offset using symbols")); 377 | } 378 | SymbolsUnload((DWORD64)DllBase); 379 | } 380 | else { 381 | supShowError(GetLastError(), TEXT("Cannot load symbols for the winload")); 382 | } 383 | 384 | // 385 | // If something wrong with symbols lookup try signatures scan. 386 | // 387 | if (bResult == FALSE) { 388 | cuiPrintText(g_ConOut, TEXT("Patch: Running signature scan for ImgpValidateImageHash"), g_ConsoleOutput, TRUE); 389 | 390 | bResult = QueryImgpValidateImageHashOffsetSignatures( 391 | BuildNumber, 392 | Revision, 393 | DllBase, 394 | DllVirtualSize, 395 | NtHeaders, 396 | &ImgpValidateImageHash); 397 | 398 | if (bResult) { 399 | _snwprintf_s(szBuffer, MAX_PATH * 2, MAX_PATH, TEXT("-> ImgpValidateImageHash\t%08llX"), //-V111 400 | ImgpValidateImageHash.AddressOfPatch); 401 | 402 | cuiPrintText(g_ConOut, szBuffer, g_ConsoleOutput, TRUE); 403 | } 404 | else { 405 | supShowError(ERROR_CAN_NOT_COMPLETE, TEXT("Cannot query ImgpValidateImageHash offset using signatures")); 406 | } 407 | } 408 | 409 | } while (bCond); 410 | 411 | if (DllBase != NULL) 412 | NtUnmapViewOfSection(NtCurrentProcess(), DllBase); 413 | 414 | return bResult; 415 | } 416 | 417 | /* 418 | * ModifyFilesAndMove 419 | * 420 | * Purpose: 421 | * 422 | * Write changes to files and move them to system32 directory. 423 | * 424 | */ 425 | BOOLEAN ModifyFilesAndMove( 426 | _In_ BOOLEAN EnableFiberContextPatch 427 | ) 428 | { 429 | ULONG NumberOfPatches; 430 | SIZE_T DestLength; 431 | ULONG_PTR PatchContext[MAX_PATCH_COUNT]; 432 | WCHAR szBuffer[MAX_PATH * 2]; 433 | WCHAR szDest[MAX_PATH * 2]; 434 | 435 | _strcpy(szDest, g_szSystemDirectory); 436 | _strcat(szDest, TEXT("\\")); 437 | DestLength = _strlen(szDest); 438 | 439 | // 440 | // ntoskrnl 441 | // 442 | _strcpy(szBuffer, g_szTempDirectory); 443 | _strcat(szBuffer, NTOSKRNMP_EXE); 444 | _strcat(szDest, NTOSKRNMP_EXE); 445 | 446 | NumberOfPatches = 0; 447 | PatchContext[NumberOfPatches++] = (ULONG_PTR)&SeValidateImageData; 448 | PatchContext[NumberOfPatches++] = (ULONG_PTR)&CcInitializeBcbProfiler; 449 | PatchContext[NumberOfPatches++] = (ULONG_PTR)&SepInitializeCodeIntegrity; 450 | 451 | if (EnableFiberContextPatch) { 452 | PatchContext[NumberOfPatches++] = (ULONG_PTR)&KiFilterFiberContext; 453 | } 454 | else { 455 | PatchContext[NumberOfPatches++] = (ULONG_PTR)&KeInitAmd64SpecificState; 456 | PatchContext[NumberOfPatches++] = (ULONG_PTR)&ExpLicenseWatchInitWorker; 457 | } 458 | 459 | if (!supPatchFile(szBuffer, (ULONG_PTR*)&PatchContext, NumberOfPatches)) 460 | return FALSE; 461 | 462 | if (!MoveFileEx(szBuffer, 463 | szDest, 464 | MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) 465 | { 466 | return FALSE; 467 | } 468 | 469 | // 470 | // winload 471 | // 472 | szDest[DestLength] = 0; 473 | _strcpy(szBuffer, g_szTempDirectory); 474 | if (g_IsEFI != FALSE) { 475 | _strcat(szDest, OSLOAD_EFI); 476 | _strcat(szBuffer, OSLOAD_EFI); 477 | } 478 | else { 479 | _strcat(szDest, OSLOAD_EXE); 480 | _strcat(szBuffer, OSLOAD_EXE); 481 | } 482 | 483 | PatchContext[0] = (ULONG_PTR)&ImgpValidateImageHash; 484 | 485 | if (!supPatchFile(szBuffer, (ULONG_PTR*)&PatchContext, 1)) 486 | return FALSE; 487 | 488 | if (!MoveFileEx(szBuffer, 489 | szDest, 490 | MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) 491 | { 492 | return FALSE; 493 | } 494 | 495 | return TRUE; 496 | } 497 | 498 | /* 499 | * PatchMain 500 | * 501 | * Purpose: 502 | * 503 | * Program Main routine. 504 | * 505 | */ 506 | UINT PatchMain() 507 | { 508 | BOOL AlreadyInstalled = FALSE; 509 | BOOLEAN bCond = FALSE; 510 | BOOLEAN bEnabled = FALSE; 511 | BOOLEAN EnableFiberContextPatch = FALSE; 512 | DWORD l = 0; 513 | FIRMWARE_TYPE FirmwareType; 514 | OSVERSIONINFO osver; 515 | INPUT_RECORD inp1; 516 | CONSOLE_SCREEN_BUFFER_INFO csbi; 517 | 518 | ULONG NtBuildNumber = 0; 519 | 520 | WCHAR szBuffer[MAX_PATH * 2]; 521 | 522 | RtlSecureZeroMemory(&osver, sizeof(osver)); 523 | osver.dwOSVersionInfoSize = sizeof(osver); 524 | RtlGetVersion(&osver); 525 | 526 | g_ConOut = GetStdHandle(STD_OUTPUT_HANDLE); 527 | if (g_ConOut == INVALID_HANDLE_VALUE) 528 | return (UINT)-1; 529 | 530 | g_ConIn = GetStdHandle(STD_INPUT_HANDLE); 531 | if (g_ConIn == INVALID_HANDLE_VALUE) 532 | return (UINT)-2; 533 | 534 | g_ConsoleOutput = TRUE; 535 | if (!GetConsoleMode(g_ConOut, &l)) { 536 | g_ConsoleOutput = FALSE; 537 | } 538 | 539 | do { 540 | 541 | SetConsoleMode(g_ConOut, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_OUTPUT); 542 | if (g_ConsoleOutput == FALSE) { 543 | WriteFile(g_ConOut, &g_BE, sizeof(WCHAR), &l, NULL); 544 | } 545 | 546 | cuiClrScr(g_ConOut); 547 | cuiPrintText(g_ConOut, PROGRAMFULLNAME, g_ConsoleOutput, TRUE); 548 | 549 | // 550 | // Detect compat mode, compare PEB fields data with ntoskrnl hardcoded values. 551 | // 552 | if (!supQueryNtBuildNumber(&NtBuildNumber)) { 553 | cuiPrintText(g_ConOut, 554 | TEXT("\n\rCannot query NtBuildNumber value, abort.\n\r"), 555 | g_ConsoleOutput, 556 | TRUE); 557 | 558 | break; 559 | } 560 | 561 | if (osver.dwBuildNumber != NtBuildNumber) { 562 | 563 | _strcpy(szBuffer, TEXT("\n\rApplication Compatibility Mode is active.\n\rDisable it for this application.")); 564 | 565 | cuiPrintText(g_ConOut, 566 | szBuffer, 567 | g_ConsoleOutput, 568 | TRUE); 569 | 570 | break; 571 | } 572 | 573 | // 574 | // Check if patch already installed. 575 | // 576 | if (BcdPatchEntryAlreadyExist(BCD_PATCH_ENTRY_GUID, &AlreadyInstalled)) { 577 | 578 | if (AlreadyInstalled) { 579 | 580 | RtlSecureZeroMemory(szBuffer, sizeof(szBuffer)); 581 | _strcpy(szBuffer, TEXT("Patch: Boot entry already present, remove it to run this patch again if needed.\n\r")); 582 | _strcat(szBuffer, TEXT("Removal: Launch elevated command prompt and use the following command ->\n\r")); 583 | _strcat(szBuffer, TEXT("bcdedit /delete ")); 584 | _strcat(szBuffer, BCD_PATCH_ENTRY_GUID); 585 | 586 | cuiPrintText(g_ConOut, 587 | szBuffer, 588 | g_ConsoleOutput, 589 | TRUE); 590 | 591 | break; 592 | } 593 | } 594 | 595 | // 596 | // Query optional command. 597 | // Enable KiFilterFiberContext patch and don't use instead two PG initialization points patch. 598 | // Required for tests. 599 | // 600 | l = 0; 601 | RtlSecureZeroMemory(szBuffer, sizeof(szBuffer)); 602 | GetCommandLineParam(GetCommandLine(), 1, (LPWSTR)&szBuffer, MAX_PATH * sizeof(WCHAR), &l); 603 | EnableFiberContextPatch = (_strcmpi(szBuffer, TEXT("-pf")) == 0); 604 | 605 | // 606 | // Warn user. 607 | // 608 | csbi.wAttributes = 0; 609 | GetConsoleScreenBufferInfo(g_ConOut, &csbi); 610 | SetConsoleTextAttribute(g_ConOut, FOREGROUND_RED | BACKGROUND_INTENSITY); 611 | _strcpy(szBuffer, TEXT("\n\rWARNING: Using this tool might render your PC to an unbootable state.\r\n")); 612 | _strcat(szBuffer, TEXT("If you want to continue type CONTINUE (all uppercase) and press Enter\r\n")); 613 | cuiPrintText(g_ConOut, szBuffer, g_ConsoleOutput, TRUE); 614 | SetConsoleTextAttribute(g_ConOut, csbi.wAttributes); 615 | 616 | #ifndef _DEBUG 617 | l = 0; 618 | RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer)); 619 | ReadConsole(g_ConIn, &szBuffer, MAX_PATH, &l, NULL); 620 | if (_strncmp(szBuffer, CONTINUE_CMD, _strlen(CONTINUE_CMD)) != 0) 621 | break; 622 | #endif 623 | 624 | // 625 | // Query boot state 626 | // 627 | FirmwareType = FirmwareTypeUnknown; 628 | if (!supGetFirmwareType(&FirmwareType)) { 629 | supShowError(GetLastError(), TEXT("Cannot query firmware type.")); 630 | break; 631 | } 632 | if ((FirmwareType != FirmwareTypeBios) && 633 | (FirmwareType != FirmwareTypeUefi)) 634 | { 635 | supShowError(ERROR_UNSUPPORTED_TYPE, TEXT("Unsupported firmware type.")); 636 | break; 637 | } 638 | g_IsEFI = (FirmwareType == FirmwareTypeUefi); 639 | if (g_IsEFI) { 640 | // 641 | // Retrieve SecureBoot state. 642 | // 643 | if (supSecureBootEnabled(&bEnabled)) { 644 | if (bEnabled != FALSE) { 645 | 646 | supShowError(ERROR_UNSUPPORTED_TYPE, 647 | TEXT("SecureBoot enabled. Disable it before using this program.")); 648 | 649 | break; 650 | } 651 | } 652 | } 653 | 654 | _strcpy(szBuffer, PROGRAMTITLE); 655 | if (g_IsEFI) 656 | _strcat(szBuffer, TEXT(" * EFI Boot")); 657 | else 658 | _strcat(szBuffer, TEXT(" * Legacy Boot")); 659 | 660 | SetConsoleTitle(szBuffer); 661 | 662 | // 663 | // Output current Windoze version 664 | // 665 | RtlSecureZeroMemory(szBuffer, sizeof(szBuffer)); 666 | _snwprintf_s(szBuffer, MAX_PATH, MAX_PATH, L"Patch: Windows Version: %lu.%lu.%lu, %ws\n", 667 | osver.dwMajorVersion, 668 | osver.dwMinorVersion, 669 | osver.dwBuildNumber, 670 | (g_IsEFI != FALSE) ? TEXT("EFI") : TEXT("LegacyBIOS")); 671 | 672 | cuiPrintText(g_ConOut, szBuffer, g_ConsoleOutput, TRUE); 673 | 674 | // 675 | // Check unsupported version. 676 | // 677 | if ((osver.dwBuildNumber < (DWORD)MIN_SUPPORTED_NT_BUILD) || 678 | (osver.dwBuildNumber > (DWORD)MAX_SUPPORTED_NT_BUILD)) 679 | { 680 | cuiPrintText(g_ConOut, TEXT("Patch: Unsupported Windows version."), g_ConsoleOutput, TRUE); 681 | break; 682 | } 683 | 684 | // 685 | // Get %TEMP% folder. 686 | // 687 | RtlSecureZeroMemory(&g_szTempDirectory, sizeof(g_szTempDirectory)); 688 | if (ExpandEnvironmentStrings(TEXT("%temp%\\"), g_szTempDirectory, MAX_PATH) == 0) { 689 | supShowError(GetLastError(), TEXT("Cannot expand %TEMP% variable.")); 690 | break; 691 | } 692 | 693 | // 694 | // Get device partition. 695 | // 696 | RtlSecureZeroMemory(&g_szDeviceParition, sizeof(g_szDeviceParition)); 697 | if (ExpandEnvironmentStrings(TEXT("%SYSTEMDRIVE%"), g_szDeviceParition, MAX_PATH) == 0) { 698 | supShowError(GetLastError(), TEXT("Cannot expand %SYSTEMDRIVE% variable.")); 699 | break; 700 | } 701 | 702 | // 703 | // Get System32 directory 704 | // 705 | RtlSecureZeroMemory(&g_szSystemDirectory, sizeof(g_szSystemDirectory)); 706 | GetSystemDirectory(g_szSystemDirectory, MAX_PATH); 707 | 708 | // 709 | // Check BCDEDIT 710 | // 711 | _snwprintf_s(szBuffer, 712 | MAX_PATH, 713 | MAX_PATH, 714 | TEXT("%s\\%s"), 715 | g_szSystemDirectory, 716 | BCDEDIT_EXE); 717 | 718 | if (!PathFileExists(szBuffer)) { 719 | cuiPrintText(g_ConOut, TEXT("Patch: Error, bcdedit.exe not found."), g_ConsoleOutput, TRUE); 720 | break; 721 | } 722 | 723 | // 724 | // Extract DbgHelp and SymSrv to %TEMP% 725 | // 726 | if (!supExtractSymDllsToTemp()) { 727 | cuiPrintText(g_ConOut, TEXT("Patch: Cannot extract symbol dlls to the %TEMP% folder."), g_ConsoleOutput, TRUE); 728 | cuiPrintText(g_ConOut, TEXT("Patch: Make sure %TEMP% folder is writeable."), g_ConsoleOutput, TRUE); 729 | break; 730 | } 731 | else { 732 | cuiPrintText(g_ConOut, TEXT("Patch: Symbol dlls extracted successfully."), g_ConsoleOutput, TRUE); 733 | } 734 | 735 | // 736 | // Load DbgHelp and SymSrv and init all required pointers. 737 | // 738 | if (!InitDbgHelp()) { 739 | supShowError(ERROR_OPERATION_ABORTED, TEXT("Cannot initialize dbghelp.")); 740 | break; 741 | } 742 | else { 743 | cuiPrintText(g_ConOut, TEXT("Patch: Dbghelp initialized."), g_ConsoleOutput, TRUE); 744 | } 745 | 746 | // 747 | // Copy ntoskrnl & winload to %TEMP% as preparation for patch. 748 | // 749 | cuiPrintText(g_ConOut, TEXT("Patch: Copy files to %TEMP%."), g_ConsoleOutput, TRUE); 750 | if (!supMakeCopyToTemp(g_IsEFI)) { 751 | cuiPrintText(g_ConOut, TEXT("Patch: Cannot copy files to the %TEMP% folder."), g_ConsoleOutput, TRUE); 752 | break; 753 | } 754 | else { 755 | cuiPrintText(g_ConOut, TEXT("Patch: Copy success."), g_ConsoleOutput, TRUE); 756 | } 757 | 758 | // 759 | // Scan ntoskrnl for patch patterns. 760 | // 761 | cuiPrintText(g_ConOut, TEXT("Patch: Scanning ntoskrnl for patterns.\n"), g_ConsoleOutput, TRUE); 762 | if (!ScanNtos(EnableFiberContextPatch)) { 763 | cuiPrintText(g_ConOut, TEXT("Patch: Cannot locate patch offsets for ntoskrnl."), g_ConsoleOutput, TRUE); 764 | break; 765 | } 766 | else { 767 | cuiPrintText(g_ConOut, TEXT("\nPatch: Ntoskrnl scan complete."), g_ConsoleOutput, TRUE); 768 | } 769 | 770 | // 771 | // Scan winload for patch patterns. 772 | // 773 | cuiPrintText(g_ConOut, TEXT("Patch: Scanning winload for patterns.\n"), g_ConsoleOutput, TRUE); 774 | if (!ScanWinload()) { 775 | cuiPrintText(g_ConOut, TEXT("Patch: Cannot locate patch offsets for winload."), g_ConsoleOutput, TRUE); 776 | break; 777 | } 778 | else { 779 | cuiPrintText(g_ConOut, TEXT("\nPatch: Winload scan complete."), g_ConsoleOutput, TRUE); 780 | } 781 | 782 | #ifdef _DEBUG 783 | return 0; 784 | #endif 785 | 786 | // 787 | // Modify files and move them to %systemroot%\system32. 788 | // 789 | if (!ModifyFilesAndMove(EnableFiberContextPatch)) { 790 | supShowError(GetLastError(), TEXT("\nModifyFilesAndMove failed")); 791 | break; 792 | } 793 | else { 794 | cuiPrintText(g_ConOut, TEXT("\nPatch: ModifyFilesAndMove succeed"), g_ConsoleOutput, TRUE); 795 | } 796 | 797 | // 798 | // Setup new BCD entry. 799 | // 800 | if (!BcdCreatePatchEntry(osver.dwBuildNumber)) { 801 | supShowError(GetLastError(), TEXT("\nBcdCreatePatchEntry failed")); 802 | break; 803 | } 804 | else { 805 | cuiPrintText(g_ConOut, TEXT("\nPatch: BcdCreatePatchEntry succeed"), g_ConsoleOutput, TRUE); 806 | } 807 | 808 | } while (bCond); 809 | 810 | cuiPrintText(g_ConOut, TEXT("Patch: Press Enter to exit"), g_ConsoleOutput, TRUE); 811 | 812 | RtlSecureZeroMemory(&inp1, sizeof(inp1)); 813 | ReadConsoleInput(g_ConIn, &inp1, 1, &l); 814 | ReadConsole(g_ConIn, &szBuffer, sizeof(g_BE), &l, NULL); 815 | 816 | cuiPrintText(g_ConOut, TEXT("Patch: Exit"), g_ConsoleOutput, TRUE); 817 | 818 | return 0; 819 | } 820 | 821 | /* 822 | * main 823 | * 824 | * Purpose: 825 | * 826 | * Program entry point. 827 | * 828 | */ 829 | void main() 830 | { 831 | HMODULE hNtdll; 832 | UINT err = 0; 833 | 834 | __security_init_cookie(); 835 | 836 | hNtdll = GetModuleHandle(L"ntdll.dll"); 837 | if (hNtdll) { 838 | _snwprintf_s = (fnptr_snwprintf_s)GetProcAddress(hNtdll, "_snwprintf_s"); 839 | if (_snwprintf_s) { 840 | err = PatchMain(); 841 | } 842 | } 843 | 844 | ExitProcess(err); 845 | } 846 | -------------------------------------------------------------------------------- /src/minirtl/_filename.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "minirtl.h" 3 | 4 | char *_filename_a(const char *f) 5 | { 6 | char *p = (char *)f; 7 | 8 | if (f == 0) 9 | return 0; 10 | 11 | while (*f != (char)0) { 12 | if (*f == '\\') 13 | p = (char *)f + 1; 14 | f++; 15 | } 16 | return p; 17 | } 18 | 19 | wchar_t *_filename_w(const wchar_t *f) 20 | { 21 | wchar_t *p = (wchar_t *)f; 22 | 23 | if (f == 0) 24 | return 0; 25 | 26 | while (*f != (wchar_t)0) { 27 | if (*f == (wchar_t)'\\') 28 | p = (wchar_t *)f + 1; 29 | f++; 30 | } 31 | return p; 32 | } 33 | 34 | char *_fileext_a(const char *f) 35 | { 36 | char *p = 0; 37 | 38 | if (f == 0) 39 | return 0; 40 | 41 | while (*f != (char)0) { 42 | if (*f == '.') 43 | p = (char *)f; 44 | f++; 45 | } 46 | 47 | if (p == 0) 48 | p = (char *)f; 49 | 50 | return p; 51 | } 52 | 53 | wchar_t *_fileext_w(const wchar_t *f) 54 | { 55 | wchar_t *p = 0; 56 | 57 | if (f == 0) 58 | return 0; 59 | 60 | while (*f != (wchar_t)0) { 61 | if (*f == (wchar_t)'.') 62 | p = (wchar_t *)f; 63 | f++; 64 | } 65 | 66 | if (p == 0) 67 | p = (wchar_t *)f; 68 | 69 | return p; 70 | } 71 | 72 | char *_filename_noext_a(char *dest, const char *f) 73 | { 74 | char *p, *l, *dot; 75 | 76 | if ((f == 0) || (dest == 0)) 77 | return 0; 78 | 79 | p = _filename_a(f); 80 | if (p == 0) 81 | return 0; 82 | 83 | dot = _strend_a(p); 84 | if (dot == 0) 85 | return 0; 86 | 87 | l = p; 88 | 89 | while (*l != (char)0) 90 | { 91 | if (*l == '.') 92 | dot = l; 93 | l++; 94 | } 95 | 96 | while (p0) ); 26 | 27 | return (int)(c1 - c2); 28 | } 29 | 30 | int _strncmp_w(const wchar_t *s1, const wchar_t *s2, size_t cchars) 31 | { 32 | wchar_t c1, c2; 33 | 34 | if ( s1==s2 ) 35 | return 0; 36 | 37 | if ( s1==0 ) 38 | return -1; 39 | 40 | if ( s2==0 ) 41 | return 1; 42 | 43 | if ( cchars==0 ) 44 | return 0; 45 | 46 | do { 47 | c1 = *s1; 48 | c2 = *s2; 49 | s1++; 50 | s2++; 51 | cchars--; 52 | } while ( (c1 != 0) && (c1 == c2) && (cchars>0) ); 53 | 54 | return (int)(c1 - c2); 55 | } 56 | -------------------------------------------------------------------------------- /src/minirtl/_strncmpi.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | int _strncmpi_a(const char *s1, const char *s2, size_t cchars) 4 | { 5 | char c1, c2; 6 | 7 | if ( s1==s2 ) 8 | return 0; 9 | 10 | if ( s1==0 ) 11 | return -1; 12 | 13 | if ( s2==0 ) 14 | return 1; 15 | 16 | if ( cchars==0 ) 17 | return 0; 18 | 19 | do { 20 | c1 = locase_a(*s1); 21 | c2 = locase_a(*s2); 22 | s1++; 23 | s2++; 24 | cchars--; 25 | } while ( (c1 != 0) && (c1 == c2) && (cchars>0) ); 26 | 27 | return (int)(c1 - c2); 28 | } 29 | 30 | int _strncmpi_w(const wchar_t *s1, const wchar_t *s2, size_t cchars) 31 | { 32 | wchar_t c1, c2; 33 | 34 | if ( s1==s2 ) 35 | return 0; 36 | 37 | if ( s1==0 ) 38 | return -1; 39 | 40 | if ( s2==0 ) 41 | return 1; 42 | 43 | if ( cchars==0 ) 44 | return 0; 45 | 46 | do { 47 | c1 = locase_w(*s1); 48 | c2 = locase_w(*s2); 49 | s1++; 50 | s2++; 51 | cchars--; 52 | } while ( (c1 != 0) && (c1 == c2) && (cchars>0) ); 53 | 54 | return (int)(c1 - c2); 55 | } 56 | -------------------------------------------------------------------------------- /src/minirtl/_strncpy.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | char *_strncpy_a(char *dest, size_t ccdest, const char *src, size_t ccsrc) 4 | { 5 | char *p; 6 | 7 | if ( (dest==0) || (src==0) || (ccdest==0) ) 8 | return dest; 9 | 10 | ccdest--; 11 | p = dest; 12 | 13 | while ( (*src!=0) && (ccdest>0) && (ccsrc>0) ) { 14 | *p = *src; 15 | p++; 16 | src++; 17 | ccdest--; 18 | ccsrc--; 19 | } 20 | 21 | *p = 0; 22 | return dest; 23 | } 24 | 25 | wchar_t *_strncpy_w(wchar_t *dest, size_t ccdest, const wchar_t *src, size_t ccsrc) 26 | { 27 | wchar_t *p; 28 | 29 | if ( (dest==0) || (src==0) || (ccdest==0) ) 30 | return dest; 31 | 32 | ccdest--; 33 | p = dest; 34 | 35 | while ( (*src!=0) && (ccdest>0) && (ccsrc>0) ) { 36 | *p = *src; 37 | p++; 38 | src++; 39 | ccdest--; 40 | ccsrc--; 41 | } 42 | 43 | *p = 0; 44 | return dest; 45 | } 46 | -------------------------------------------------------------------------------- /src/minirtl/cmdline.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | BOOL GetCommandLineParamW( 4 | IN LPCWSTR CmdLine, 5 | IN ULONG ParamIndex, 6 | OUT LPWSTR Buffer, 7 | IN ULONG BufferSize, 8 | OUT PULONG ParamLen 9 | ) 10 | { 11 | ULONG c, plen = 0; 12 | TCHAR divider; 13 | 14 | if (ParamLen != NULL) 15 | *ParamLen = 0; 16 | 17 | if (CmdLine == NULL) { 18 | if ((Buffer != NULL) && (BufferSize > 0)) 19 | *Buffer = 0; 20 | return FALSE; 21 | } 22 | 23 | for (c = 0; c <= ParamIndex; c++) { 24 | plen = 0; 25 | 26 | while (*CmdLine == ' ') 27 | CmdLine++; 28 | 29 | switch (*CmdLine) { 30 | case 0: 31 | goto zero_term_exit; 32 | 33 | case '"': 34 | CmdLine++; 35 | divider = '"'; 36 | break; 37 | 38 | default: 39 | divider = ' '; 40 | } 41 | 42 | while ((*CmdLine != '"') && (*CmdLine != divider) && (*CmdLine != 0)) { 43 | plen++; 44 | if (c == ParamIndex) 45 | if ((plen < BufferSize) && (Buffer != NULL)) { 46 | *Buffer = *CmdLine; 47 | Buffer++; 48 | } 49 | CmdLine++; 50 | } 51 | 52 | if (*CmdLine != 0) 53 | CmdLine++; 54 | } 55 | 56 | zero_term_exit: 57 | 58 | if ((Buffer != NULL) && (BufferSize > 0)) 59 | *Buffer = 0; 60 | 61 | if (ParamLen != NULL) 62 | *ParamLen = plen; 63 | 64 | if (plen < BufferSize) 65 | return TRUE; 66 | else 67 | return FALSE; 68 | } 69 | 70 | BOOL GetCommandLineParamA( 71 | IN LPCSTR CmdLine, 72 | IN ULONG ParamIndex, 73 | OUT LPSTR Buffer, 74 | IN ULONG BufferSize, 75 | OUT PULONG ParamLen 76 | ) 77 | { 78 | ULONG c, plen = 0; 79 | TCHAR divider; 80 | 81 | if (CmdLine == NULL) 82 | return FALSE; 83 | 84 | if (ParamLen != NULL) 85 | *ParamLen = 0; 86 | 87 | for (c = 0; c <= ParamIndex; c++) { 88 | plen = 0; 89 | 90 | while (*CmdLine == ' ') 91 | CmdLine++; 92 | 93 | switch (*CmdLine) { 94 | case 0: 95 | goto zero_term_exit; 96 | 97 | case '"': 98 | CmdLine++; 99 | divider = '"'; 100 | break; 101 | 102 | default: 103 | divider = ' '; 104 | } 105 | 106 | while ((*CmdLine != '"') && (*CmdLine != divider) && (*CmdLine != 0)) { 107 | plen++; 108 | if (c == ParamIndex) 109 | if ((plen < BufferSize) && (Buffer != NULL)) { 110 | *Buffer = *CmdLine; 111 | Buffer++; 112 | } 113 | CmdLine++; 114 | } 115 | 116 | if (*CmdLine != 0) 117 | CmdLine++; 118 | } 119 | 120 | zero_term_exit: 121 | 122 | if ((Buffer != NULL) && (BufferSize > 0)) 123 | *Buffer = 0; 124 | 125 | if (ParamLen != NULL) 126 | *ParamLen = plen; 127 | 128 | if (plen < BufferSize) 129 | return TRUE; 130 | else 131 | return FALSE; 132 | } 133 | 134 | char *ExtractFilePathA(const char *FileName, char *FilePath) 135 | { 136 | char *p = (char *)FileName, *p0 = (char *)FileName; 137 | 138 | if ((FileName == 0) || (FilePath == 0)) 139 | return 0; 140 | 141 | while (*FileName != 0) { 142 | if (*FileName == '\\') 143 | p = (char *)FileName + 1; 144 | FileName++; 145 | } 146 | 147 | while (p0 < p) { 148 | *FilePath = *p0; 149 | FilePath++; 150 | p0++; 151 | } 152 | 153 | *FilePath = 0; 154 | 155 | return FilePath; 156 | } 157 | 158 | wchar_t *ExtractFilePathW(const wchar_t *FileName, wchar_t *FilePath) 159 | { 160 | wchar_t *p = (wchar_t *)FileName, *p0 = (wchar_t *)FileName; 161 | 162 | if ((FileName == 0) || (FilePath == 0)) 163 | return 0; 164 | 165 | while (*FileName != 0) { 166 | if (*FileName == '\\') 167 | p = (wchar_t *)FileName + 1; 168 | FileName++; 169 | } 170 | 171 | while (p0 < p) { 172 | *FilePath = *p0; 173 | FilePath++; 174 | p0++; 175 | } 176 | 177 | *FilePath = 0; 178 | 179 | return FilePath; 180 | } 181 | -------------------------------------------------------------------------------- /src/minirtl/cmdline.h: -------------------------------------------------------------------------------- 1 | #ifndef _CMDLINEH_ 2 | #define _CMDLINEH_ 3 | 4 | BOOL GetCommandLineParamW( 5 | IN LPCWSTR CmdLine, 6 | IN ULONG ParamIndex, 7 | OUT LPWSTR Buffer, 8 | IN ULONG BufferSize, 9 | OUT PULONG ParamLen 10 | ); 11 | 12 | BOOL GetCommandLineParamA( 13 | IN LPCSTR CmdLine, 14 | IN ULONG ParamIndex, 15 | OUT LPSTR Buffer, 16 | IN ULONG BufferSize, 17 | OUT PULONG ParamLen 18 | ); 19 | 20 | char *ExtractFilePathA(const char *FileName, char *FilePath); 21 | wchar_t *ExtractFilePathW(const wchar_t *FileName, wchar_t *FilePath); 22 | 23 | #ifdef UNICODE 24 | 25 | #define ExtractFilePath ExtractFilePathW 26 | #define GetCommandLineParam GetCommandLineParamW 27 | 28 | #else // ANSI 29 | 30 | #define ExtractFilePath ExtractFilePathA 31 | #define GetCommandLineParam GetCommandLineParamA 32 | 33 | #endif 34 | 35 | #endif /* _CMDLINEH_ */ 36 | -------------------------------------------------------------------------------- /src/minirtl/minirtl.h: -------------------------------------------------------------------------------- 1 | /* 2 | Module name: 3 | minirtl.h 4 | 5 | Description: 6 | header for string handling and conversion routines 7 | 8 | Date: 9 | 1 Mar 2015 10 | */ 11 | 12 | #ifndef _MINIRTL_ 13 | #define _MINIRTL_ 14 | 15 | // string copy/concat/length 16 | 17 | char *_strend_a(const char *s); 18 | wchar_t *_strend_w(const wchar_t *s); 19 | 20 | char *_strcpy_a(char *dest, const char *src); 21 | wchar_t *_strcpy_w(wchar_t *dest, const wchar_t *src); 22 | 23 | char *_strcat_a(char *dest, const char *src); 24 | wchar_t *_strcat_w(wchar_t *dest, const wchar_t *src); 25 | 26 | char *_strncpy_a(char *dest, size_t ccdest, const char *src, size_t ccsrc); 27 | wchar_t *_strncpy_w(wchar_t *dest, size_t ccdest, const wchar_t *src, size_t ccsrc); 28 | 29 | size_t _strlen_a(const char *s); 30 | size_t _strlen_w(const wchar_t *s); 31 | 32 | // comparing 33 | 34 | int _strcmp_a(const char *s1, const char *s2); 35 | int _strcmp_w(const wchar_t *s1, const wchar_t *s2); 36 | 37 | int _strncmp_a(const char *s1, const char *s2, size_t cchars); 38 | int _strncmp_w(const wchar_t *s1, const wchar_t *s2, size_t cchars); 39 | 40 | int _strcmpi_a(const char *s1, const char *s2); 41 | int _strcmpi_w(const wchar_t *s1, const wchar_t *s2); 42 | 43 | int _strncmpi_a(const char *s1, const char *s2, size_t cchars); 44 | int _strncmpi_w(const wchar_t *s1, const wchar_t *s2, size_t cchars); 45 | 46 | char *_strstr_a(const char *s, const char *sub_s); 47 | wchar_t *_strstr_w(const wchar_t *s, const wchar_t *sub_s); 48 | 49 | char *_strstri_a(const char *s, const char *sub_s); 50 | wchar_t *_strstri_w(const wchar_t *s, const wchar_t *sub_s); 51 | 52 | // conversion of integer types to string, returning string length 53 | 54 | size_t ultostr_a(unsigned long x, char *s); 55 | size_t ultostr_w(unsigned long x, wchar_t *s); 56 | 57 | size_t ultohex_a(unsigned long x, char *s); 58 | size_t ultohex_w(unsigned long x, wchar_t *s); 59 | 60 | size_t itostr_a(int x, char *s); 61 | size_t itostr_w(int x, wchar_t *s); 62 | 63 | size_t i64tostr_a(signed long long x, char *s); 64 | size_t i64tostr_w(signed long long x, wchar_t *s); 65 | 66 | size_t u64tostr_a(unsigned long long x, char *s); 67 | size_t u64tostr_w(unsigned long long x, wchar_t *s); 68 | 69 | size_t u64tohex_a(unsigned long long x, char *s); 70 | size_t u64tohex_w(unsigned long long x, wchar_t *s); 71 | 72 | // string to integers conversion 73 | 74 | unsigned long strtoul_a(char *s); 75 | unsigned long strtoul_w(wchar_t *s); 76 | 77 | unsigned long long strtou64_a(char *s); 78 | unsigned long long strtou64_w(wchar_t *s); 79 | 80 | unsigned long hextoul_a(char *s); 81 | unsigned long hextoul_w(wchar_t *s); 82 | 83 | int strtoi_a(char *s); 84 | int strtoi_w(wchar_t *s); 85 | 86 | signed long long strtoi64_a(char *s); 87 | signed long long strtoi64_w(wchar_t *s); 88 | 89 | unsigned long long hextou64_a(char *s); 90 | unsigned long long hextou64_w(wchar_t *s); 91 | 92 | /* =================================== */ 93 | 94 | #ifdef UNICODE 95 | 96 | #define _strend _strend_w 97 | #define _strcpy _strcpy_w 98 | #define _strcat _strcat_w 99 | #define _strlen _strlen_w 100 | #define _strncpy _strncpy_w 101 | 102 | #define _strcmp _strcmp_w 103 | #define _strncmp _strncmp_w 104 | #define _strcmpi _strcmpi_w 105 | #define _strncmpi _strncmpi_w 106 | #define _strstr _strstr_w 107 | #define _strstri _strstri_w 108 | 109 | #define ultostr ultostr_w 110 | #define ultohex ultohex_w 111 | #define itostr itostr_w 112 | #define i64tostr i64tostr_w 113 | #define u64tostr u64tostr_w 114 | #define u64tohex u64tohex_w 115 | 116 | #define strtoul strtoul_w 117 | #define hextoul hextoul_w 118 | #define strtoi strtoi_w 119 | #define strtoi64 strtoi64_w 120 | #define strtou64 strtou64_w 121 | #define hextou64 hextou64_w 122 | 123 | #else // ANSI 124 | 125 | #define _strend _strend_a 126 | #define _strcpy _strcpy_a 127 | #define _strcat _strcat_a 128 | #define _strlen _strlen_a 129 | #define _strncpy _strncpy_a 130 | #define _strcmp _strcmp_a 131 | 132 | #define _strcmp _strcmp_a 133 | #define _strncmp _strncmp_a 134 | #define _strcmpi _strcmpi_a 135 | #define _strncmpi _strncmpi_a 136 | #define _strstr _strstr_a 137 | #define _strstri _strstri_a 138 | 139 | #define ultostr ultostr_a 140 | #define ultohex ultohex_a 141 | #define itostr itostr_a 142 | #define i64tostr i64tostr_a 143 | #define u64tostr u64tostr_a 144 | #define u64tohex u64tohex_a 145 | 146 | #define strtoul strtoul_a 147 | #define hextoul hextoul_a 148 | #define strtoi strtoi_a 149 | #define strtoi64 strtoi64_a 150 | #define strtou64 strtou64_a 151 | #define hextou64 hextou64_a 152 | 153 | #endif 154 | 155 | #endif /* _MINIRTL_ */ 156 | -------------------------------------------------------------------------------- /src/minirtl/rtltypes.h: -------------------------------------------------------------------------------- 1 | #ifndef _WCHAR_T_DEFINED 2 | typedef unsigned short wchar_t; 3 | #define _WCHAR_T_DEFINED 4 | #endif /* _WCHAR_T_DEFINED */ 5 | 6 | #ifndef _SIZE_T_DEFINED 7 | #ifdef _WIN64 8 | typedef unsigned __int64 size_t; 9 | #else /* _WIN64 */ 10 | typedef __w64 unsigned int size_t; 11 | #endif /* _WIN64 */ 12 | #define _SIZE_T_DEFINED 13 | #endif /* _SIZE_T_DEFINED */ 14 | 15 | __forceinline char locase_a(char c) 16 | { 17 | if ((c >= 'A') && (c <= 'Z')) 18 | return c + 0x20; 19 | else 20 | return c; 21 | } 22 | 23 | __forceinline wchar_t locase_w(wchar_t c) 24 | { 25 | if ((c >= 'A') && (c <= 'Z')) 26 | return c + 0x20; 27 | else 28 | return c; 29 | } 30 | 31 | __forceinline char byteabs(char x) { 32 | if (x < 0) 33 | return -x; 34 | return x; 35 | } 36 | 37 | __forceinline int _isdigit_a(char x) { 38 | return ((x >= '0') && (x <= '9')); 39 | } 40 | 41 | __forceinline int _isdigit_w(wchar_t x) { 42 | return ((x >= L'0') && (x <= L'9')); 43 | } 44 | -------------------------------------------------------------------------------- /src/minirtl/strtoi.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | int strtoi_a(char *s) 4 | { 5 | int a = 0, sign; 6 | char c; 7 | 8 | if (s == 0) 9 | return 0; 10 | 11 | switch (*s) { 12 | case '-': 13 | s++; 14 | sign = -1; 15 | break; 16 | 17 | case '+': 18 | s++; 19 | sign = 1; 20 | break; 21 | 22 | default: 23 | sign = 1; 24 | } 25 | 26 | while (*s != 0) { 27 | c = *s; 28 | if (_isdigit_a(c)) 29 | a = (a*10) + (c-'0'); 30 | else 31 | break; 32 | s++; 33 | } 34 | return a*sign; 35 | } 36 | 37 | int strtoi_w(wchar_t *s) 38 | { 39 | int a = 0, sign; 40 | wchar_t c; 41 | 42 | if (s == 0) 43 | return 0; 44 | 45 | switch (*s) { 46 | case L'-': 47 | s++; 48 | sign = -1; 49 | break; 50 | 51 | case L'+': 52 | s++; 53 | sign = 1; 54 | break; 55 | 56 | default: 57 | sign = 1; 58 | } 59 | 60 | while (*s != 0) { 61 | c = *s; 62 | if (_isdigit_w(c)) 63 | a = (a*10)+(c-L'0'); 64 | else 65 | break; 66 | s++; 67 | } 68 | return a*sign; 69 | } 70 | -------------------------------------------------------------------------------- /src/patch.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "patch", "patch.vcxproj", "{DF610C2D-FC85-4A27-B7C9-1AB3C9AECDC5}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {DF610C2D-FC85-4A27-B7C9-1AB3C9AECDC5}.Debug|x64.ActiveCfg = Debug|x64 15 | {DF610C2D-FC85-4A27-B7C9-1AB3C9AECDC5}.Debug|x64.Build.0 = Debug|x64 16 | {DF610C2D-FC85-4A27-B7C9-1AB3C9AECDC5}.Release|x64.ActiveCfg = Release|x64 17 | {DF610C2D-FC85-4A27-B7C9-1AB3C9AECDC5}.Release|x64.Build.0 = Release|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /src/patch.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | {DF610C2D-FC85-4A27-B7C9-1AB3C9AECDC5} 15 | Win32Proj 16 | patch 17 | 8.1 18 | 19 | 20 | 21 | Application 22 | true 23 | v140 24 | Unicode 25 | 26 | 27 | Application 28 | false 29 | v140 30 | true 31 | Unicode 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | true 47 | .\output\$(Platform)\$(Configuration)\ 48 | .\output\$(Platform)\$(Configuration)\ 49 | AllRules.ruleset 50 | 51 | 52 | false 53 | .\output\$(Platform)\$(Configuration)\ 54 | .\output\$(Platform)\$(Configuration)\ 55 | AllRules.ruleset 56 | true 57 | 58 | 59 | 60 | 61 | 62 | Level4 63 | Disabled 64 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 65 | true 66 | CompileAsC 67 | $(ProjectDir);%(AdditionalIncludeDirectories) 68 | 69 | 70 | Console 71 | true 72 | main 73 | 74 | 75 | true 76 | 77 | 78 | 79 | 80 | Level4 81 | 82 | 83 | MaxSpeed 84 | true 85 | true 86 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 87 | true 88 | true 89 | Guard 90 | CompileAsC 91 | true 92 | $(ProjectDir);%(AdditionalIncludeDirectories) 93 | MultiThreaded 94 | true 95 | 96 | 97 | Console 98 | true 99 | true 100 | false 101 | main 102 | true 103 | RequireAdministrator 104 | 105 | 106 | true 107 | 108 | 109 | pgos.manifest 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /src/patch.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {3df015f1-5af2-456d-8c09-72359a4f335c} 18 | 19 | 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | minirtl 29 | 30 | 31 | minirtl 32 | 33 | 34 | minirtl 35 | 36 | 37 | minirtl 38 | 39 | 40 | minirtl 41 | 42 | 43 | Source Files 44 | 45 | 46 | minirtl 47 | 48 | 49 | minirtl 50 | 51 | 52 | minirtl 53 | 54 | 55 | minirtl 56 | 57 | 58 | Source Files 59 | 60 | 61 | minirtl 62 | 63 | 64 | Source Files 65 | 66 | 67 | minirtl 68 | 69 | 70 | 71 | 72 | Header Files 73 | 74 | 75 | minirtl 76 | 77 | 78 | minirtl 79 | 80 | 81 | Header Files 82 | 83 | 84 | Header Files 85 | 86 | 87 | Header Files 88 | 89 | 90 | Header Files 91 | 92 | 93 | minirtl 94 | 95 | 96 | Header Files 97 | 98 | 99 | Header Files 100 | 101 | 102 | minirtl 103 | 104 | 105 | Header Files 106 | 107 | 108 | 109 | 110 | Resource Files 111 | 112 | 113 | Resource Files 114 | 115 | 116 | -------------------------------------------------------------------------------- /src/patch.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -nf 5 | WindowsLocalDebugger 6 | 7 | -------------------------------------------------------------------------------- /src/patterns.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2017 - 2018 4 | * 5 | * TITLE: PATTERNS.H 6 | * 7 | * VERSION: 1.21 8 | * 9 | * DATE: 29 Mar 2018 10 | * 11 | * Search patterns and patches header file. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | 20 | #pragma once 21 | 22 | // 23 | // pd - patch data 24 | // pt - patch lookup pattern 25 | // 26 | 27 | //******************************************************** 28 | // 29 | // Search/Patch patterns for SeValidateImageData 30 | // 31 | //******************************************************** 32 | 33 | // Patch data for SeValidateImageData STATUS_SUCCESS 34 | unsigned char pdSeValidateImageData[] = { 0x0, 0x0, 0x0, 0x0 }; 35 | 36 | // Patch data for SeValidateImageData (return STATUS_SUCCESS) 37 | // xor eax, eax 38 | // retn 39 | unsigned char pdSeValidateImageData_2[] = { 0x33, 0xC0, 0xC3 }; 40 | 41 | // 42 | // sub rsp, 28h 43 | // xor eax eax 44 | // cmp 45 | // 46 | unsigned char ptSevalidateImageData_760X[] = { 0x48, 0x83, 0xEC, 0x28, 0x33, 0xC0, 0x38, 0x05 }; 47 | 48 | //mov eax, STATUS_INVALID_IMAGE_HASH 49 | unsigned char ptSeValidateImageData_9200[] = { 0xCC, 0x90, 0x90, 0xB8, 0x28, 0x04, 0x00, 0xC0 }; 50 | unsigned char ptSeValidateImageData_9600_16299[] = { 0xB8, 0x28, 0x04, 0x00, 0xC0 }; 51 | 52 | unsigned char ptSeValidateImageData_2_9600_14393[] = { 0xB8, 0x28, 0x04, 0x00, 0xC0, 0xC3 }; 53 | unsigned char ptSeValidateImageData_2_15063_16299[] = { 0xB8, 0x28, 0x04, 0x00, 0xC0, 0xEB }; 54 | 55 | #define ptSkipBytesSeValidateImageData_7601 1 56 | #define ptSkipBytesSeValidateImageData_9200 4 57 | #define ptSkipBytesSeValidateImageData_9600_16299 1 58 | 59 | 60 | //******************************************************** 61 | // 62 | // Search/Patch patterns for CcInitializeBcbProfiler 63 | // 64 | //******************************************************** 65 | 66 | //always in INIT 67 | //Patch data for CcInitializeBcbProfiler 68 | //mov al, 1 69 | //retn 70 | unsigned char pdCcInitializeBcbProfiler[] = { 0xB0, 0x01, 0xC3 }; 71 | 72 | //Windows 7 73 | unsigned char ptCcInitializeBcbProfiler_7601[] = { 74 | 0x44, 0x89, 0x44, 0x24, 0x18, 0x89, 0x54, 0x24, 75 | 0x10, 0x89, 0x4C, 0x24, 0x08, 0x53, 0x55, 0x56 76 | }; 77 | 78 | //Windows 8 79 | unsigned char ptCcInitializeBcbProfiler_9200[] = { 80 | 0xFF, 0xF5, 0x53, 0x56, 0x57, 0x41, 0x54, 0x41, 81 | 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x8B, 0xEC 82 | }; 83 | 84 | //Windows 8.1 85 | unsigned char ptCcInitializeBcbProfiler_9600[] = { 86 | 0x40, 0x55, 0x53, 0x56, 0x57, 0x41, 0x54, 0x41, 87 | 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x8B, 0xEC, 88 | 0x48, 0x83, 0xEC, 0x58, 0xA0 89 | }; 90 | 91 | //Windows 10+ 92 | unsigned char ptCcInitializeBcbProfiler_10240_16299[] = { 93 | 0x40, 0x55, 0x53, 0x56, 0x57, 0x41, 0x54, 0x41, 94 | 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x8D, 0x6C, 95 | 0x24, 0xE1, 0x48, 0x81, 0xEC, 0xB8, 0x00, 0x00, 96 | 0x00 97 | }; 98 | 99 | //******************************************************** 100 | // 101 | // Search/Patch patterns for KiFilterFiberContext 102 | // 103 | //******************************************************** 104 | 105 | 106 | //Patch data for KiFilterFiberContext 107 | //mov al, 1 108 | //retn 109 | unsigned char pdKiFilterFiberContext[] = { 0xB0, 0x01, 0xC3 }; 110 | 111 | //Windows 7 112 | unsigned char ptKiFilterFiberContext_7601[] = { 113 | 0x48, 0x89, 0x5C, 0x24, 0x08, 0x48, 0x89, 114 | 0x6C, 0x24, 0x10, 0x48, 0x89, 0x74, 0x24, 115 | 0x18, 0x57, 0x41, 0x54, 0x41, 0x55, 0x48, 116 | 0x83, 0xEC, 0x20, 0xFA 117 | }; 118 | 119 | //Windows 8 120 | unsigned char ptKiFilterFiberContext_9200[] = { 121 | 0x48, 0x8B, 0xC4, 0x48, 0x89, 0x58, 0x08, 122 | 0x48, 0x89, 0x68, 0x10, 0x48, 0x89, 0x70, 123 | 0x18, 0x48, 0x89, 0x78, 0x20, 0x41, 0x54, 124 | 0x41, 0x55, 0x41, 0x56, 0x48, 0x83, 0xEC, 125 | 0x30, 0x48, 0x8B, 0xF1, 0xFA 126 | }; 127 | 128 | //Windows 8.1 129 | unsigned char ptKiFilterFiberContext_9600[] = { 130 | 0x48, 0x8B, 0xC4, 0x48, 0x89, 0x58, 0x08, 131 | 0x48, 0x89, 0x68, 0x10, 0x48, 0x89, 0x70, 132 | 0x18, 0x48, 0x89, 0x78, 0x20, 0x41, 0x54, 133 | 0x41, 0x55, 0x41, 0x56, 0x48, 0x83, 0xEC, 134 | 0x30, 0x48, 0x8B, 0xF1 135 | }; 136 | 137 | //Windows 10 TH's 138 | unsigned char ptKiFilterFiberContext_10240_10586[] = { 139 | 0x48, 0x8B, 0xC4, 0x48, 0x89, 0x58, 0x08, 140 | 0x48, 0x89, 0x68, 0x10, 0x48, 0x89, 0x70, 141 | 0x18, 0x48, 0x89, 0x78, 0x20, 0x41, 0x55, 142 | 0x41, 0x56, 0x41, 0x57, 0x48, 0x83, 0xEC, 143 | 0x30, 0x48, 0x8B, 0xF1 144 | }; 145 | 146 | //Windows 10 RS1/RS2 147 | unsigned char ptKiFilterFiberContext_14393_15063[] = { 148 | 0x40, 0x53, 0x55, 0x56, 0x57, 0x41, 0x55, 149 | 0x41, 0x56, 0x41, 0x57, 0x48, 0x83, 0xEC, 150 | 0x40, 0x48, 0x8B 151 | }; 152 | 153 | //Windows 10 RS3 154 | unsigned char ptKiFilterFiberContext_16299[] = { 155 | 0x48, 0x89, 0x5C, 0x24, 0x08, 0x55, 0x56, 156 | 0x57, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 157 | 0x41, 0x57, 0x48, 0x8D, 0x6C, 0x24, 0xD9, 158 | 0x48, 0x81, 0xEC, 0x90, 0x00, 0x00, 0x00 159 | }; 160 | 161 | //******************************************************** 162 | // 163 | // Search/Patch patterns for KeInitAmd64SpecificState 164 | // 165 | //******************************************************** 166 | 167 | 168 | //Patch data for KeInitAmd64SpecificState 169 | //xor eax, eax 170 | //retn 171 | unsigned char pdKeInitAmd64SpecificState[] = { 0x33, 0xC0, 0xC3 }; 172 | 173 | //Windows 7 174 | unsigned char ptKeInitAmd64SpecificState_7601[] = { 0x48, 0x83, 0xEC, 0x28, 0x0F, 0xB6 }; 175 | 176 | //Windows 8/8.1/10 (TH1/TH2/RS1/RS2/RS3) 177 | unsigned char ptKeInitAmd64SpecificState_9200_16299[] = { 0x48, 0x83, 0xEC, 0x28, 0x83, 0x3D }; 178 | 179 | //******************************************************** 180 | // 181 | // Search/Patch patterns for ExpLicenseWatchInitWorker 182 | // 183 | //******************************************************** 184 | 185 | 186 | //Patch data for ExpLicenseWatchInitWorker 187 | //xor eax, eax 188 | //retn 189 | unsigned char pdExpLicenseWatchInitWorker[] = { 0x33, 0xC0, 0xC3 }; 190 | 191 | 192 | //Windows 8, Windows 10 RS2 193 | unsigned char ptExpLicenseWatchInitWorker1[] = { 0x48, 0x83, 0xEC, 0x38, 0x48, 0x8B, 0x05 }; 194 | 195 | //Windows 8.1/10 TH1/TH2/RS1/RS3 196 | unsigned char ptExpLicenseWatchInitWorker2[] = { 0x40, 0x53, 0x48, 0x83, 0xEC, 0x30, 0x48, 0x8B, 0x05 }; 197 | 198 | 199 | //******************************************************** 200 | // 201 | // Search/Patch patterns for SepInitializeCodeIntegrity 202 | // 203 | //******************************************************** 204 | 205 | 206 | //Always in PAGE 207 | //Patch data for SepInitializeCodeIntegrity 208 | unsigned char pdSepInitializeCodeIntegrity[] = { 0x31, 0xC9 }; 209 | 210 | // 211 | // Signature patterns for function scan. 212 | // 213 | 214 | //mov ecx, edi 215 | //call 216 | unsigned char ptSepInitializeCodeIntegrity_7601[] = { 0x8B, 0xCF, 0xE8 }; 217 | 218 | //mov ecx, edi 219 | //mov rbx, 220 | unsigned char ptSepInitializeCodeIntegrity_9200_14393[] = { 0x8B, 0xCF, 0x48 }; 221 | 222 | //mov ecx, esi 223 | //mov rbx, 224 | unsigned char ptSepInitializeCodeIntegrity_15063[] = { 0x8B, 0xCE, 0x48 }; 225 | 226 | //mov ecx, edi 227 | //call 228 | unsigned char ptSepInitializeCodeIntegrity_16299[] = { 0x8B, 0xCF, 0xFF }; 229 | 230 | // 231 | // Signature patterns for function itself. 232 | // 233 | 234 | //Windows 7 235 | unsigned char ptSepInitializeCodeIntegrity2_7601[] = { 236 | 0x48, 0x3B, 0xC3, 0x74, 0x52, 0x48, 0x39, 237 | 0x98, 0x98, 0x00, 0x00, 0x00, 0x74, 0x40 238 | }; 239 | 240 | //Windows 8/8.1 241 | unsigned char ptSepInitializeCodeIntegrity2_9200_9600[] = { 242 | 0x48, 0x89, 0x5C, 0x24, 0x08, 0x57, 243 | 0x48, 0x83, 0xEC, 0x20, 0xBF, 0x06, 244 | 0x00, 0x00, 0x00 245 | }; 246 | 247 | //Windows 10 TH1/TH2 248 | unsigned char ptSepInitializeCodeIntegrity2_10240_10586[] = { 249 | 0x48, 0x89, 0x5C, 0x24, 0x08, 0x57, 250 | 0x48, 0x83, 0xEC, 0x20, 0xBB, 0x98, 251 | 0x00, 0x00, 0x00 252 | }; 253 | 254 | //Windows 10 RS1 255 | unsigned char ptSepInitializeCodeIntegrity2_14393[] = { 256 | 0x48, 0x89, 0x5C, 0x24, 0x08, 0x57, 257 | 0x48, 0x83, 0xEC, 0x20, 0xBB, 0xA8, 258 | 0x00, 0x00, 0x00 259 | }; 260 | 261 | //Windows 10 RS2 262 | unsigned char ptSepInitializeCodeIntegrity2_15063[] = { 263 | 0x48, 0x89, 0x5C, 0x24, 0x08, 0x48, 264 | 0x89, 0x74, 0x24, 0x10, 0x57, 0x48, 265 | 0x83, 0xEC, 0x20, 0xBB, 0xC0, 0x00, 266 | 0x00, 0x00 267 | }; 268 | 269 | //Windows 10 RS3 270 | unsigned char ptSepInitializeCodeIntegrity2_16299[] = { 271 | 0x48, 0x89, 0x5C, 0x24, 0x08, 0x57, 272 | 0x48, 0x83, 0xEC, 0x20, 0xBB, 0xC0, 273 | 0x00, 0x00, 0x00 274 | }; 275 | 276 | //******************************************************** 277 | // 278 | // Search/Patch patterns for ImgpValidateImageHash 279 | // 280 | //******************************************************** 281 | 282 | //xor eax, eax 283 | //retn 284 | unsigned char pdImgpValidateImageHash[] = { 0x33, 0xC0, 0xC3 }; 285 | 286 | // 287 | // Winload.EXE/Winload.EFI 288 | // 289 | unsigned char ptImgpValidateImageHash_7601[] = { 290 | 0x48, 0x89, 0x5C, 0x24, 0x08, 0x48, 0x89, 0x6C, 0x24, 0x10, 0x48, 0x89, 0x74, 0x24, 0x18, 291 | 0x57, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x81, 0xEC, 0xB0, 0x00, 0x00 292 | }; 293 | 294 | unsigned char ptImgpValidateImageHash_9200[] = { 295 | 0x48, 0x89, 0x5C, 0x24, 0x08, 0x48, 0x89, 0x74, 0x24, 0x10, 0x48, 0x89, 0x7C, 0x24, 0x18, 296 | 0x55, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x8D, 0x6C, 0x24, 0x90 297 | }; 298 | 299 | unsigned char ptImgpValidateImageHash_9600[] = { 300 | 0x48, 0x89, 0x5C, 0x24, 0x10, 0x4C, 0x89, 0x4C, 0x24, 0x20, 0x48, 0x89, 0x4C, 0x24, 0x08, 0x55, 301 | 0x56, 0x57, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x8D, 0x6C, 0x24, 0x80 302 | }; 303 | 304 | unsigned char ptImgpValidateImageHash_10240[] = { 305 | 0x48, 0x8B, 0xC4, 0x48, 0x89, 0x58, 0x20, 0x44, 0x89, 0x40, 0x18, 0x48, 0x89, 0x50, 0x10, 0x48, 306 | 0x89, 0x48, 0x08, 0x55, 0x56, 0x57, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x8D, 307 | 0xA8, 0x08, 0xFF, 0xFF 308 | }; 309 | 310 | unsigned char ptImgpValidateImageHash_10586[] = { 311 | 0x48, 0x8B, 0xC4, 0x48, 0x89, 0x58, 0x08, 0x44, 0x89, 0x40, 0x18, 0x48, 0x89, 0x50, 0x10, 0x55, 312 | 0x56, 0x57, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x8D, 0xA8, 0xE8, 0xFE, 0xFF, 0xFF 313 | }; 314 | 315 | unsigned char ptImgpValidateImageHash_14393[] = { 316 | 0x48, 0x8B, 0xC4, 0x4C, 0x89, 0x48, 0x20, 0x44, 0x89, 0x40, 0x18, 0x48, 0x89, 0x50, 0x10, 0x48, 317 | 0x89, 0x48, 0x08, 0x55, 0x53, 0x56, 0x57, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 318 | 0x8D, 0xA8, 0x98, 0xFE, 0xFF, 0xFF 319 | }; 320 | 321 | unsigned char ptImgpValidateImageHash_15063[] = { 322 | 0x48, 0x8B, 0xC4, 0x4C, 0x89, 0x48, 0x20, 0x44, 0x89, 0x40, 0x18, 0x48, 0x89, 0x50, 0x10, 0x48, 323 | 0x89, 0x48, 0x08, 0x55, 0x53, 0x56, 0x57, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 324 | 0x8D, 0xA8, 0x78, 0xFE, 0xFF, 0xFF 325 | }; 326 | 327 | unsigned char ptImgpValidateImageHash_16299[] = { 328 | 0x48, 0x8B, 0xC4, 0x4C, 0x89, 0x48, 0x20, 0x44, 0x89, 0x40, 0x18, 0x48, 0x89, 0x50, 0x10, 0x48, 329 | 0x89, 0x48, 0x08, 0x55, 0x53, 0x56, 0x57, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 330 | 0x8D, 0xA8, 0xA8, 0xFE, 0xFF, 0xFF 331 | }; 332 | -------------------------------------------------------------------------------- /src/pgos.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | Universal PatchGuard and Driver Signature Enforcement Disable 10 | 11 | 12 | 13 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/res.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hfiref0x/UPGDSED/86442a3c40cb62b10e24c5978bad9ad74815a765/src/res.rc -------------------------------------------------------------------------------- /src/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by res.rc 4 | 5 | #define IDR_DBGHELP 100 6 | #define IDR_SYMSRV 101 7 | 8 | // Next default values for new objects 9 | // 10 | #ifdef APSTUDIO_INVOKED 11 | #ifndef APSTUDIO_READONLY_SYMBOLS 12 | #define _APS_NEXT_RESOURCE_VALUE 101 13 | #define _APS_NEXT_COMMAND_VALUE 40001 14 | #define _APS_NEXT_CONTROL_VALUE 1001 15 | #define _APS_NEXT_SYMED_VALUE 101 16 | #endif 17 | #endif 18 | -------------------------------------------------------------------------------- /src/scan.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2017 - 2018 4 | * 5 | * TITLE: SCAN.H 6 | * 7 | * VERSION: 1.21 8 | * 9 | * DATE: 29 Mar 2018 10 | * 11 | * Header file for image scan routine prototypes and definitions. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | #include "global.h" 20 | 21 | PVOID FindPattern( 22 | CONST PBYTE Buffer, 23 | SIZE_T BufferSize, 24 | CONST PBYTE Pattern, 25 | SIZE_T PatternSize); 26 | 27 | BOOL InitDbgHelp( 28 | VOID); 29 | 30 | BOOL SymbolsLoadForFile( 31 | _In_ LPWSTR lpFileName, 32 | _In_ DWORD64 ImageBase); 33 | 34 | VOID SymbolsUnload( 35 | _In_ DWORD64 DllBase); 36 | 37 | DWORD64 SymbolAddressFromName( 38 | _In_ LPWSTR lpszName); 39 | 40 | typedef DWORD(WINAPI *pfnSymSetOptions)( 41 | _In_ DWORD SymOptions 42 | ); 43 | 44 | typedef BOOL(WINAPI *pfnSymInitializeW)( 45 | _In_ HANDLE hProcess, 46 | _In_opt_ PCWSTR UserSearchPath, 47 | _In_ BOOL fInvadeProcess); 48 | 49 | typedef DWORD64(WINAPI *pfnSymLoadModuleExW)( 50 | _In_ HANDLE hProcess, 51 | _In_opt_ HANDLE hFile, 52 | _In_opt_ PCWSTR ImageName, 53 | _In_opt_ PCWSTR ModuleName, 54 | _In_ DWORD64 BaseOfDll, 55 | _In_ DWORD DllSize, 56 | _In_opt_ PMODLOAD_DATA Data, 57 | _In_opt_ DWORD Flags); 58 | 59 | typedef BOOL(WINAPI *pfnSymEnumSymbolsW)( 60 | _In_ HANDLE hProcess, 61 | _In_ ULONG64 BaseOfDll, 62 | _In_opt_ PCWSTR Mask, 63 | _In_ PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, 64 | _In_opt_ PVOID UserContext); 65 | 66 | typedef BOOL(WINAPI *pfnSymUnloadModule64)( 67 | _In_ HANDLE hProcess, 68 | _In_ DWORD64 BaseOfDll); 69 | 70 | typedef BOOL(WINAPI *pfnSymCleanup)( 71 | _In_ HANDLE hProcess); 72 | 73 | typedef BOOL(WINAPI *pfnSymFromAddrW)( 74 | _In_ HANDLE hProcess, 75 | _In_ DWORD64 Address, 76 | _Out_opt_ PDWORD64 Displacement, 77 | _Inout_ PSYMBOL_INFOW Symbol); 78 | 79 | typedef BOOL(WINAPI *pfnSymGetSymbolFileW)( 80 | _In_opt_ HANDLE hProcess, 81 | _In_opt_ PCTSTR SymPath, 82 | _In_ PCTSTR ImageFile, 83 | _In_ DWORD Type, 84 | _Out_ PTSTR SymbolFile, 85 | _In_ size_t cSymbolFile, 86 | _Out_ PTSTR DbgFile, 87 | _In_ size_t cDbgFile); 88 | 89 | BOOLEAN QueryKeInitAmd64SpecificStateOffset( 90 | _In_ ULONG BuildNumber, 91 | _In_ ULONG Revision, 92 | _In_ PBYTE DllBase, 93 | _In_ SIZE_T DllVirtualSize, 94 | _In_ IMAGE_NT_HEADERS *NtHeaders, 95 | _Inout_ PATCH_CONTEXT *KeInitAmd64SpecificState); 96 | 97 | BOOLEAN QueryExpLicenseWatchInitWorkerOffset( 98 | _In_ ULONG BuildNumber, 99 | _In_ ULONG Revision, 100 | _In_ PBYTE DllBase, 101 | _In_ SIZE_T DllVirtualSize, 102 | _In_ IMAGE_NT_HEADERS *NtHeaders, 103 | _Inout_ PATCH_CONTEXT *ExpLicenseWatchInitWorker); 104 | 105 | BOOLEAN QueryKiFilterFiberContextOffset( 106 | _In_ ULONG BuildNumber, 107 | _In_ ULONG Revision, 108 | _In_ PBYTE DllBase, 109 | _In_ SIZE_T DllVirtualSize, 110 | _In_ IMAGE_NT_HEADERS *NtHeaders, 111 | _Inout_ PATCH_CONTEXT *KiFilterFiberContext); 112 | 113 | BOOLEAN QueryCcInitializeBcbProfilerOffset( 114 | _In_ ULONG BuildNumber, 115 | _In_ ULONG Revision, 116 | _In_ PBYTE DllBase, 117 | _In_ SIZE_T DllVirtualSize, 118 | _In_ IMAGE_NT_HEADERS *NtHeaders, 119 | _Inout_ PATCH_CONTEXT *CcInitializeBcbProfiler); 120 | 121 | BOOLEAN QuerySeValidateImageDataOffset( 122 | _In_ ULONG BuildNumber, 123 | _In_ ULONG Revision, 124 | _In_ PBYTE DllBase, 125 | _In_ SIZE_T DllVirtualSize, 126 | _In_ IMAGE_NT_HEADERS *NtHeaders, 127 | _Inout_ PATCH_CONTEXT *SeValidateImageData); 128 | 129 | BOOLEAN QuerySepInitializeCodeIntegrityOffset( 130 | _In_ ULONG BuildNumber, 131 | _In_ ULONG Revision, 132 | _In_ PBYTE DllBase, 133 | _In_ SIZE_T DllVirtualSize, 134 | _In_ IMAGE_NT_HEADERS *NtHeaders, 135 | _Inout_ PATCH_CONTEXT *SepInitializeCodeIntegrity); 136 | 137 | BOOLEAN QueryImgpValidateImageHashOffsetSymbols( 138 | _In_ PBYTE DllBase, 139 | _In_ IMAGE_NT_HEADERS *NtHeaders, 140 | _Inout_ PATCH_CONTEXT *ImgpValidateImageHash); 141 | 142 | BOOLEAN QueryImgpValidateImageHashOffsetSignatures( 143 | _In_ ULONG BuildNumber, 144 | _In_ ULONG Revision, 145 | _In_ PBYTE DllBase, 146 | _In_ SIZE_T DllVirtualSize, 147 | _In_ IMAGE_NT_HEADERS *NtHeaders, 148 | _Inout_ PATCH_CONTEXT *ImgpValidateImageHash); 149 | -------------------------------------------------------------------------------- /src/sup.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2017 4 | * 5 | * TITLE: SUP.C 6 | * 7 | * VERSION: 1.20 8 | * 9 | * DATE: 20 Oct 2017 10 | * 11 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 12 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 13 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 14 | * PARTICULAR PURPOSE. 15 | * 16 | *******************************************************************************/ 17 | #include "global.h" 18 | 19 | /* 20 | * supShowError 21 | * 22 | * Purpose: 23 | * 24 | * Display detailed last error to user. 25 | * 26 | */ 27 | VOID supShowError( 28 | _In_ DWORD LastError, 29 | _In_ LPWSTR Msg 30 | ) 31 | { 32 | LPWSTR lpMsgBuf = NULL; 33 | WCHAR szErrorMsg[MAX_PATH * 2]; 34 | 35 | if (FormatMessage( 36 | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 37 | NULL, LastError, 38 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 39 | (LPWSTR)&lpMsgBuf, 0, NULL)) 40 | { 41 | RtlSecureZeroMemory(&szErrorMsg, sizeof(szErrorMsg)); 42 | _snwprintf_s(szErrorMsg, MAX_PATH * 2, MAX_PATH, TEXT("\n\rPatch: %ws: %ws"), Msg, lpMsgBuf); 43 | LocalFree(lpMsgBuf); 44 | cuiPrintText(g_ConOut, szErrorMsg, g_ConsoleOutput, TRUE); 45 | } 46 | } 47 | 48 | /* 49 | * supEnablePrivilege 50 | * 51 | * Purpose: 52 | * 53 | * Enable/Disable given privilege. 54 | * 55 | * Return FALSE on any error. 56 | * 57 | */ 58 | BOOL supEnablePrivilege( 59 | _In_ DWORD PrivilegeName, 60 | _In_ BOOL fEnable 61 | ) 62 | { 63 | BOOL bResult = FALSE; 64 | NTSTATUS status; 65 | HANDLE hToken; 66 | TOKEN_PRIVILEGES TokenPrivileges; 67 | 68 | status = NtOpenProcessToken( 69 | GetCurrentProcess(), 70 | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, 71 | &hToken); 72 | 73 | if (!NT_SUCCESS(status)) { 74 | return bResult; 75 | } 76 | 77 | TokenPrivileges.PrivilegeCount = 1; 78 | TokenPrivileges.Privileges[0].Luid.LowPart = PrivilegeName; 79 | TokenPrivileges.Privileges[0].Luid.HighPart = 0; 80 | TokenPrivileges.Privileges[0].Attributes = (fEnable) ? SE_PRIVILEGE_ENABLED : 0; 81 | status = NtAdjustPrivilegesToken(hToken, FALSE, &TokenPrivileges, 82 | sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, NULL); 83 | if (status == STATUS_NOT_ALL_ASSIGNED) { 84 | status = STATUS_PRIVILEGE_NOT_HELD; 85 | } 86 | bResult = NT_SUCCESS(status); 87 | NtClose(hToken); 88 | return bResult; 89 | } 90 | 91 | /* 92 | * supGetFirmwareType 93 | * 94 | * Purpose: 95 | * 96 | * Query current machine firmware type. 97 | * 98 | */ 99 | BOOLEAN supGetFirmwareType( 100 | _Out_ FIRMWARE_TYPE *FirmwareType 101 | ) 102 | { 103 | NTSTATUS Status; 104 | ULONG returnedLength = 0; 105 | SYSTEM_BOOT_ENVIRONMENT_INFORMATION sbei; 106 | 107 | RtlSecureZeroMemory(&sbei, sizeof(sbei)); 108 | Status = NtQuerySystemInformation( 109 | SystemBootEnvironmentInformation, 110 | &sbei, 111 | sizeof(sbei), 112 | &returnedLength); 113 | 114 | if (FirmwareType) 115 | *FirmwareType = sbei.FirmwareType; 116 | 117 | SetLastError(RtlNtStatusToDosError(Status)); 118 | 119 | return NT_SUCCESS(Status); 120 | } 121 | 122 | /* 123 | * supSecureBootEnabled 124 | * 125 | * Purpose: 126 | * 127 | * Return FALSE on any error and TRUE on success query. 128 | * 129 | */ 130 | BOOLEAN supSecureBootEnabled( 131 | _Out_ PBOOLEAN Enabled 132 | ) 133 | { 134 | BOOLEAN SecureBootEnabled = FALSE; 135 | 136 | if (supEnablePrivilege(SE_SYSTEM_ENVIRONMENT_PRIVILEGE, TRUE)) { 137 | 138 | GetFirmwareEnvironmentVariable(L"SecureBoot", 139 | L"{8be4df61-93ca-11d2-aa0d-00e098032b8c}", &SecureBootEnabled, sizeof(BOOLEAN)); 140 | 141 | supEnablePrivilege(SE_SYSTEM_ENVIRONMENT_PRIVILEGE, FALSE); 142 | } 143 | 144 | *Enabled = SecureBootEnabled; 145 | return TRUE; 146 | } 147 | 148 | /* 149 | * supGetBinaryVersionNumbers 150 | * 151 | * Purpose: 152 | * 153 | * Return version numbers from version info. 154 | * 155 | */ 156 | _Success_(return == TRUE) 157 | BOOL supGetBinaryVersionNumbers( 158 | _In_ LPWSTR lpFileName, 159 | _Out_opt_ ULONG *MajorVersion, 160 | _Out_opt_ ULONG *MinorVersion, 161 | _Out_opt_ ULONG *Build, 162 | _Out_opt_ ULONG *Revision 163 | ) 164 | { 165 | BOOL bResult = FALSE; 166 | DWORD dwHandle, dwSize; 167 | PVOID vinfo = NULL; 168 | UINT Length; 169 | VS_FIXEDFILEINFO *pFileInfo; 170 | 171 | dwHandle = 0; 172 | dwSize = GetFileVersionInfoSize(lpFileName, &dwHandle); 173 | if (dwSize) { 174 | vinfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize); 175 | if (vinfo) { 176 | if (GetFileVersionInfo(lpFileName, 0, dwSize, vinfo)) { 177 | bResult = VerQueryValue(vinfo, TEXT("\\"), (LPVOID *)&pFileInfo, (PUINT)&Length); 178 | if (bResult) { 179 | if (MajorVersion) 180 | *MajorVersion = HIWORD(pFileInfo->dwFileVersionMS); 181 | if (MinorVersion) 182 | *MinorVersion = LOWORD(pFileInfo->dwFileVersionMS); 183 | if (Build) 184 | *Build = HIWORD(pFileInfo->dwFileVersionLS); 185 | if (Revision) 186 | *Revision = LOWORD(pFileInfo->dwFileVersionLS); 187 | } 188 | } 189 | HeapFree(GetProcessHeap(), 0, vinfo); 190 | } 191 | } 192 | return bResult; 193 | } 194 | 195 | /* 196 | * supLookupImageSectionByNameULONG 197 | * 198 | * Purpose: 199 | * 200 | * Lookup section pointer and size for ulong size section name. 201 | * 202 | */ 203 | PVOID supLookupImageSectionByNameULONG( 204 | _In_ ULONG SectionName, 205 | _In_ PVOID DllBase, 206 | _Out_ PULONG SectionSize 207 | ) 208 | { 209 | BOOLEAN bFound = FALSE; 210 | ULONG i; 211 | PVOID Section; 212 | IMAGE_NT_HEADERS *NtHeaders = RtlImageNtHeader(DllBase); 213 | IMAGE_SECTION_HEADER *SectionTableEntry; 214 | 215 | if (SectionSize) 216 | *SectionSize = 0; 217 | 218 | SectionTableEntry = (PIMAGE_SECTION_HEADER)((PCHAR)NtHeaders + 219 | sizeof(ULONG) + 220 | sizeof(IMAGE_FILE_HEADER) + 221 | NtHeaders->FileHeader.SizeOfOptionalHeader); 222 | 223 | // 224 | // Locate section. 225 | // 226 | i = NtHeaders->FileHeader.NumberOfSections; 227 | while (i > 0) { 228 | if (*(PULONG)SectionTableEntry->Name == SectionName) 229 | if (SectionTableEntry->Name[4] == 0) { 230 | bFound = TRUE; 231 | break; 232 | } 233 | i -= 1; 234 | SectionTableEntry += 1; 235 | } 236 | 237 | // 238 | // Section not found, abort scan. 239 | // 240 | if (!bFound) 241 | return NULL; 242 | 243 | Section = (PVOID)((ULONG_PTR)DllBase + SectionTableEntry->VirtualAddress); 244 | if (SectionSize) 245 | *SectionSize = SectionTableEntry->Misc.VirtualSize; 246 | 247 | return Section; 248 | } 249 | 250 | /* 251 | * supMakeCopyToTemp 252 | * 253 | * Purpose: 254 | * 255 | * Copy required files to %temp%. 256 | * 257 | */ 258 | BOOLEAN supMakeCopyToTemp( 259 | _In_ BOOL IsEFI 260 | ) 261 | { 262 | SIZE_T l, k; 263 | WCHAR szSource[MAX_PATH * 2]; 264 | WCHAR szDest[MAX_PATH * 2]; 265 | 266 | _strcpy(szSource, USER_SHARED_DATA->NtSystemRoot); 267 | _strcat(szSource, L"\\system32\\"); 268 | l = _strlen(szSource); 269 | _strcat(szSource, NTOSKRNL_EXE); 270 | 271 | _strcpy(szDest, g_szTempDirectory); 272 | k = _strlen(szDest); 273 | _strcat(szDest, NTOSKRNMP_EXE); 274 | 275 | if (!CopyFile(szSource, szDest, FALSE)) 276 | return FALSE; 277 | 278 | if (IsEFI != FALSE) { 279 | _strcpy(&szSource[l], WINLOAD_EFI); 280 | _strcpy(&szDest[k], OSLOAD_EFI); 281 | } 282 | else { 283 | _strcpy(&szSource[l], WINLOAD_EXE); 284 | _strcpy(&szDest[k], OSLOAD_EXE); 285 | } 286 | if (!CopyFile(szSource, szDest, FALSE)) 287 | return FALSE; 288 | 289 | return TRUE; 290 | } 291 | 292 | /* 293 | * supMapFile 294 | * 295 | * Purpose: 296 | * 297 | * Map file into memory and return pointer to section describing mapping. 298 | * Caller free memory with NtUnmapViewOfSection after use. 299 | * 300 | */ 301 | PVOID supMapFile( 302 | _In_ LPWSTR lpFileName, 303 | _Out_ PSIZE_T VirtualSize 304 | ) 305 | { 306 | BOOLEAN bCond = FALSE, bSuccess = FALSE; 307 | NTSTATUS status; 308 | HANDLE hFile = NULL, hSection = NULL; 309 | PBYTE DllBase = NULL; 310 | SIZE_T DllVirtualSize; 311 | OBJECT_ATTRIBUTES attr; 312 | UNICODE_STRING usFileName; 313 | IO_STATUS_BLOCK iosb; 314 | 315 | RtlSecureZeroMemory(&usFileName, sizeof(usFileName)); 316 | 317 | if (VirtualSize) 318 | *VirtualSize = 0; 319 | 320 | do { 321 | 322 | if (!RtlDosPathNameToNtPathName_U(lpFileName, &usFileName, NULL, NULL)) { 323 | SetLastError(ERROR_INVALID_PARAMETER); 324 | break; 325 | } 326 | 327 | InitializeObjectAttributes(&attr, &usFileName, 328 | OBJ_CASE_INSENSITIVE, NULL, NULL); 329 | RtlSecureZeroMemory(&iosb, sizeof(iosb)); 330 | 331 | status = NtCreateFile(&hFile, SYNCHRONIZE | FILE_READ_DATA, 332 | &attr, &iosb, NULL, 0, FILE_SHARE_READ, FILE_OPEN, 333 | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); 334 | 335 | if (!NT_SUCCESS(status)) { 336 | SetLastError(RtlNtStatusToDosError(status)); 337 | break; 338 | } 339 | 340 | status = NtCreateSection(&hSection, SECTION_ALL_ACCESS, NULL, 341 | NULL, PAGE_READONLY, SEC_IMAGE, hFile); 342 | if (!NT_SUCCESS(status)) { 343 | SetLastError(RtlNtStatusToDosError(status)); 344 | break; 345 | } 346 | 347 | DllBase = NULL; 348 | DllVirtualSize = 0; 349 | status = NtMapViewOfSection(hSection, NtCurrentProcess(), &DllBase, 350 | 0, 0, NULL, &DllVirtualSize, ViewUnmap, 0, PAGE_READONLY); 351 | if (!NT_SUCCESS(status)) { 352 | SetLastError(RtlNtStatusToDosError(status)); 353 | break; 354 | } 355 | 356 | bSuccess = TRUE; 357 | 358 | if (VirtualSize) 359 | *VirtualSize = DllVirtualSize; 360 | 361 | } while (bCond); 362 | 363 | if (usFileName.Buffer != NULL) 364 | RtlFreeUnicodeString(&usFileName); 365 | 366 | if (hSection != NULL) 367 | NtClose(hSection); 368 | 369 | if (hFile != NULL) 370 | NtClose(hFile); 371 | 372 | if (bSuccess == FALSE) { 373 | if (DllBase != NULL) 374 | NtUnmapViewOfSection(NtCurrentProcess(), DllBase); 375 | } 376 | 377 | return DllBase; 378 | } 379 | 380 | /* 381 | * supLdrQueryResourceData 382 | * 383 | * Purpose: 384 | * 385 | * Load resource by given id (win32 FindResource, SizeofResource, LockResource). 386 | * 387 | */ 388 | PBYTE supLdrQueryResourceData( 389 | _In_ ULONG_PTR ResourceId, 390 | _In_ PVOID DllHandle, 391 | _In_ PULONG DataSize 392 | ) 393 | { 394 | NTSTATUS status; 395 | ULONG_PTR IdPath[3]; 396 | IMAGE_RESOURCE_DATA_ENTRY *DataEntry; 397 | PBYTE Data = NULL; 398 | ULONG SizeOfData = 0; 399 | 400 | if (DllHandle != NULL) { 401 | 402 | IdPath[0] = (ULONG_PTR)RT_RCDATA; //type 403 | IdPath[1] = ResourceId; //id 404 | IdPath[2] = 0; //lang 405 | 406 | status = LdrFindResource_U(DllHandle, (ULONG_PTR*)&IdPath, 3, &DataEntry); 407 | if (NT_SUCCESS(status)) { 408 | status = LdrAccessResource(DllHandle, DataEntry, &Data, &SizeOfData); 409 | if (NT_SUCCESS(status)) { 410 | if (DataSize) { 411 | *DataSize = SizeOfData; 412 | } 413 | } 414 | } 415 | } 416 | return Data; 417 | } 418 | 419 | /* 420 | * supExtractSymDllsToTemp 421 | * 422 | * Purpose: 423 | * 424 | * Extract DbgHelp, SymSrv dlls from application resource to %temp%. 425 | * 426 | */ 427 | BOOL supExtractSymDllsToTemp( 428 | VOID 429 | ) 430 | { 431 | BOOL bResult = FALSE, bCond = FALSE; 432 | 433 | SIZE_T Length = 0; 434 | HANDLE hFile; 435 | HINSTANCE hInstance = GetModuleHandle(NULL); 436 | PVOID Resource; 437 | ULONG DataSize, bytesIO; 438 | 439 | WCHAR szExtractFileName[MAX_PATH * 2]; 440 | 441 | do { 442 | 443 | DataSize = 0; 444 | Resource = supLdrQueryResourceData( 445 | IDR_DBGHELP, 446 | hInstance, 447 | &DataSize); 448 | 449 | if (Resource == NULL) { 450 | SetLastError(ERROR_RESOURCE_NAME_NOT_FOUND); 451 | return FALSE; 452 | } 453 | 454 | _strcpy(szExtractFileName, g_szTempDirectory); 455 | Length = _strlen(szExtractFileName); 456 | _strcat(szExtractFileName, TEXT("dbghelp.dll")); 457 | 458 | hFile = CreateFile(szExtractFileName, GENERIC_WRITE, 459 | 0, NULL, CREATE_ALWAYS, 0, NULL); 460 | if (hFile != INVALID_HANDLE_VALUE) { 461 | bResult = WriteFile(hFile, Resource, DataSize, &bytesIO, NULL); 462 | CloseHandle(hFile); 463 | } 464 | if (!bResult) 465 | break; 466 | 467 | DataSize = 0; 468 | Resource = supLdrQueryResourceData( 469 | IDR_SYMSRV, 470 | hInstance, 471 | &DataSize); 472 | 473 | if (Resource == NULL) { 474 | SetLastError(ERROR_RESOURCE_NAME_NOT_FOUND); 475 | return FALSE; 476 | } 477 | 478 | szExtractFileName[Length] = 0; 479 | _strcat(szExtractFileName, TEXT("symsrv.dll")); 480 | hFile = CreateFile(szExtractFileName, GENERIC_WRITE, 481 | 0, NULL, CREATE_ALWAYS, 0, NULL); 482 | if (hFile != INVALID_HANDLE_VALUE) { 483 | bResult = WriteFile(hFile, Resource, DataSize, &bytesIO, NULL); 484 | CloseHandle(hFile); 485 | } 486 | 487 | } while (bCond); 488 | 489 | return bResult; 490 | } 491 | 492 | /* 493 | * supChkSum 494 | * 495 | * Purpose: 496 | * 497 | * Calculate partial checksum for given buffer. 498 | * 499 | */ 500 | USHORT supChkSum( 501 | ULONG PartialSum, 502 | PUSHORT Source, 503 | ULONG Length 504 | ) 505 | { 506 | while (Length--) { 507 | PartialSum += *Source++; 508 | PartialSum = (PartialSum >> 16) + (PartialSum & 0xffff); 509 | } 510 | return (USHORT)(((PartialSum >> 16) + PartialSum) & 0xffff); 511 | } 512 | 513 | /* 514 | * supCheckSumMappedFile 515 | * 516 | * Purpose: 517 | * 518 | * Calculate PE file checksum and set it in PE header. 519 | * 520 | */ 521 | BOOLEAN supCheckSumMappedFile( 522 | _In_ PVOID BaseAddress, 523 | _In_ ULONG FileLength 524 | ) 525 | { 526 | PUSHORT AdjustSum; 527 | PIMAGE_NT_HEADERS NtHeaders; 528 | USHORT PartialSum; 529 | ULONG HeaderSum; 530 | ULONG CheckSum; 531 | 532 | HeaderSum = 0; 533 | PartialSum = supChkSum(0, (PUSHORT)BaseAddress, (FileLength + 1) >> 1); 534 | 535 | NtHeaders = RtlImageNtHeader(BaseAddress); 536 | if (NtHeaders != NULL) { 537 | HeaderSum = NtHeaders->OptionalHeader.CheckSum; 538 | AdjustSum = (PUSHORT)(&NtHeaders->OptionalHeader.CheckSum); 539 | PartialSum -= (PartialSum < AdjustSum[0]); 540 | PartialSum -= AdjustSum[0]; 541 | PartialSum -= (PartialSum < AdjustSum[1]); 542 | PartialSum -= AdjustSum[1]; 543 | CheckSum = (ULONG)PartialSum + FileLength; 544 | NtHeaders->OptionalHeader.CheckSum = CheckSum; 545 | return TRUE; 546 | } 547 | return FALSE; 548 | } 549 | 550 | /* 551 | * supPatchFile 552 | * 553 | * Purpose: 554 | * 555 | * Modify binary with patches. 556 | * 557 | */ 558 | BOOL supPatchFile( 559 | _In_ LPWSTR lpFileName, 560 | _In_ ULONG_PTR *PatchContext, 561 | _In_ ULONG NumberOfPatches 562 | ) 563 | { 564 | BOOLEAN bResult = FALSE, bCond = FALSE; 565 | ULONG i; 566 | DWORD bytesIO, k, lastError = ERROR_SUCCESS; 567 | HANDLE hFile = INVALID_HANDLE_VALUE; 568 | 569 | PBYTE FileBuffer = NULL; 570 | LARGE_INTEGER li; 571 | 572 | PATCH_CONTEXT *Context; 573 | 574 | do { 575 | 576 | // 577 | // Read file to buffer. 578 | // 579 | hFile = CreateFile( 580 | lpFileName, 581 | GENERIC_READ, 582 | 0, 583 | NULL, 584 | OPEN_EXISTING, 585 | 0, 586 | NULL); 587 | 588 | if (hFile == INVALID_HANDLE_VALUE) { 589 | lastError = GetLastError(); 590 | break; 591 | } 592 | 593 | li.QuadPart = 0; 594 | if (!GetFileSizeEx(hFile, &li)) { 595 | lastError = GetLastError(); 596 | break; 597 | } 598 | 599 | FileBuffer = (PBYTE)HeapAlloc(GetProcessHeap(), 600 | HEAP_ZERO_MEMORY, li.LowPart); 601 | 602 | if (FileBuffer == NULL) { 603 | lastError = GetLastError(); 604 | break; 605 | } 606 | 607 | if (!ReadFile(hFile, FileBuffer, li.LowPart, &bytesIO, NULL)) { 608 | lastError = GetLastError(); 609 | break; 610 | } 611 | 612 | CloseHandle(hFile); 613 | hFile = INVALID_HANDLE_VALUE; 614 | 615 | __try { 616 | 617 | // 618 | // Patch binary. 619 | // 620 | for (i = 0; i < NumberOfPatches; i++) { 621 | 622 | Context = (PATCH_CONTEXT*)PatchContext[i]; 623 | RtlCopyMemory( 624 | &FileBuffer[Context->AddressOfPatch], 625 | Context->PatchData, 626 | Context->SizeOfPatch); 627 | 628 | } 629 | } 630 | __except (EXCEPTION_EXECUTE_HANDLER) { 631 | lastError = GetExceptionCode(); 632 | break; 633 | } 634 | 635 | // 636 | // Update PE header checksum. 637 | // 638 | if (!supCheckSumMappedFile(FileBuffer, li.LowPart)) { 639 | lastError = ERROR_DATA_CHECKSUM_ERROR; 640 | break; 641 | } 642 | 643 | // 644 | // Overwrite file. 645 | // 646 | hFile = CreateFile( 647 | lpFileName, 648 | GENERIC_WRITE, 649 | 0, 650 | NULL, 651 | CREATE_ALWAYS, 652 | FILE_FLAG_WRITE_THROUGH, 653 | NULL); 654 | 655 | if (hFile == INVALID_HANDLE_VALUE) { 656 | lastError = GetLastError(); 657 | break; 658 | } 659 | 660 | k = 0; 661 | if (!WriteFile(hFile, FileBuffer, bytesIO, &k, NULL)) { 662 | lastError = GetLastError(); 663 | break; 664 | } 665 | 666 | CloseHandle(hFile); 667 | hFile = INVALID_HANDLE_VALUE; 668 | 669 | bResult = (k == bytesIO); 670 | lastError = ERROR_SUCCESS; 671 | 672 | } while (bCond); 673 | 674 | if (FileBuffer) 675 | HeapFree(GetProcessHeap(), 0, FileBuffer); 676 | 677 | if (hFile != INVALID_HANDLE_VALUE) 678 | CloseHandle(hFile); 679 | 680 | SetLastError(lastError); 681 | return bResult; 682 | } 683 | 684 | /* 685 | * supRunProcessWithParamsAndWait 686 | * 687 | * Purpose: 688 | * 689 | * Start process with given arguments and wait until it close. 690 | * 691 | */ 692 | BOOL supRunProcessWithParamsAndWait( 693 | _In_ LPWSTR lpszParameters, 694 | _Out_ PDWORD ExitCode 695 | ) 696 | { 697 | BOOL bResult = FALSE; 698 | LPWSTR pszBuffer = NULL; 699 | SIZE_T ccb; 700 | 701 | STARTUPINFO si; 702 | PROCESS_INFORMATION pi; 703 | 704 | if (ExitCode) 705 | *ExitCode = (DWORD)-1; 706 | 707 | if (lpszParameters == NULL) 708 | return bResult; 709 | 710 | ccb = (1 + _strlen(lpszParameters)) * sizeof(WCHAR); 711 | pszBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ccb); 712 | if (pszBuffer == NULL) 713 | return bResult; 714 | 715 | _strcpy(pszBuffer, lpszParameters); 716 | 717 | RtlSecureZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); 718 | RtlSecureZeroMemory(&si, sizeof(STARTUPINFO)); 719 | si.cb = sizeof(STARTUPINFO); 720 | GetStartupInfo(&si); 721 | 722 | bResult = CreateProcess(NULL, 723 | pszBuffer, 724 | NULL, 725 | NULL, 726 | FALSE, 727 | CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS, 728 | NULL, 729 | NULL, 730 | &si, 731 | &pi); 732 | 733 | if (bResult) { 734 | CloseHandle(pi.hThread); 735 | WaitForSingleObject(pi.hProcess, INFINITE); 736 | GetExitCodeProcess(pi.hProcess, ExitCode); 737 | CloseHandle(pi.hProcess); 738 | } 739 | 740 | HeapFree(GetProcessHeap(), 0, pszBuffer); 741 | 742 | return bResult; 743 | } 744 | 745 | /* 746 | * supDisablePeAuthAutoStart 747 | * 748 | * Purpose: 749 | * 750 | * Change PEAUTH service startup type from Auto to OnDemand. 751 | * 752 | */ 753 | BOOL supDisablePeAuthAutoStart( 754 | VOID 755 | ) 756 | { 757 | BOOL bResult = FALSE; 758 | DWORD lastError = 0; 759 | SC_HANDLE Manager; 760 | SC_HANDLE Service; 761 | 762 | Manager = OpenSCManager( 763 | NULL, 764 | NULL, 765 | SC_MANAGER_ALL_ACCESS); 766 | 767 | if (Manager) { 768 | 769 | Service = OpenService( 770 | Manager, 771 | TEXT("PEAUTH"), 772 | SERVICE_CHANGE_CONFIG); 773 | if (Service) { 774 | 775 | bResult = ChangeServiceConfig( 776 | Service, 777 | SERVICE_NO_CHANGE, 778 | SERVICE_DEMAND_START, 779 | SERVICE_NO_CHANGE, 780 | NULL, 781 | NULL, 782 | NULL, 783 | NULL, 784 | NULL, 785 | NULL, 786 | NULL); 787 | 788 | lastError = GetLastError(); 789 | 790 | CloseServiceHandle(Service); 791 | } 792 | CloseServiceHandle(Manager); 793 | } 794 | 795 | SetLastError(lastError); 796 | return bResult; 797 | } 798 | 799 | /* 800 | * supQueryNtBuildNumber 801 | * 802 | * Purpose: 803 | * 804 | * Query NtBuildNumber value from ntoskrnl image. 805 | * 806 | */ 807 | BOOL supQueryNtBuildNumber( 808 | _Inout_ PULONG BuildNumber 809 | ) 810 | { 811 | BOOL bResult = FALSE; 812 | HMODULE hModule; 813 | PVOID Ptr; 814 | WCHAR szBuffer[MAX_PATH * 2]; 815 | 816 | RtlSecureZeroMemory(szBuffer, sizeof(szBuffer)); 817 | _strcpy(szBuffer, USER_SHARED_DATA->NtSystemRoot); 818 | _strcat(szBuffer, L"\\system32\\ntoskrnl.exe"); 819 | 820 | hModule = LoadLibraryEx(szBuffer, NULL, DONT_RESOLVE_DLL_REFERENCES); 821 | if (hModule == NULL) 822 | return bResult; 823 | 824 | #pragma warning(push) 825 | #pragma warning(disable: 4054)//code to data 826 | Ptr = (PVOID)GetProcAddress(hModule, "NtBuildNumber"); 827 | #pragma warning(pop) 828 | if (Ptr) { 829 | *BuildNumber = (*(PULONG)Ptr & 0xffff); 830 | bResult = TRUE; 831 | } 832 | FreeLibrary(hModule); 833 | return bResult; 834 | } 835 | -------------------------------------------------------------------------------- /src/sup.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2017 4 | * 5 | * TITLE: SUP.H 6 | * 7 | * VERSION: 1.20 8 | * 9 | * DATE: 20 Oct 2017 10 | * 11 | * Common header file for the program support routines. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | #pragma once 20 | 21 | VOID supShowError( 22 | _In_ DWORD LastError, 23 | _In_ LPWSTR Msg); 24 | 25 | _Success_(return == TRUE) 26 | BOOL supGetBinaryVersionNumbers( 27 | _In_ LPWSTR lpFileName, 28 | _Out_opt_ ULONG *MajorVersion, 29 | _Out_opt_ ULONG *MinorVersion, 30 | _Out_opt_ ULONG *Build, 31 | _Out_opt_ ULONG *Revision); 32 | 33 | BOOL supEnablePrivilege( 34 | _In_ DWORD PrivilegeName, 35 | _In_ BOOL fEnable); 36 | 37 | BOOLEAN supGetFirmwareType( 38 | _Out_ FIRMWARE_TYPE *FirmwareType); 39 | 40 | BOOLEAN supSecureBootEnabled( 41 | _Out_ PBOOLEAN Enabled); 42 | 43 | PVOID supLookupImageSectionByNameULONG( 44 | _In_ ULONG SectionName, 45 | _In_ PVOID DllBase, 46 | _Out_ PULONG SectionSize); 47 | 48 | BOOLEAN supMakeCopyToTemp( 49 | _In_ BOOL IsEFI); 50 | 51 | PVOID supMapFile( 52 | _In_ LPWSTR lpFileName, 53 | _Out_ PSIZE_T VirtualSize); 54 | 55 | PBYTE supLdrQueryResourceData( 56 | _In_ ULONG_PTR ResourceId, 57 | _In_ PVOID DllHandle, 58 | _In_ PULONG DataSize); 59 | 60 | BOOL supExtractSymDllsToTemp( 61 | VOID); 62 | 63 | BOOL supPatchFile( 64 | _In_ LPWSTR lpFileName, 65 | _In_ ULONG_PTR *PatchContext, 66 | _In_ ULONG NumberOfPatches); 67 | 68 | BOOL supRunProcessWithParamsAndWait( 69 | _In_ LPWSTR lpszParameters, 70 | _Out_ PDWORD ExitCode); 71 | 72 | BOOL supDisablePeAuthAutoStart( 73 | VOID); 74 | 75 | BOOL supQueryNtBuildNumber( 76 | _Inout_ PULONG BuildNumber 77 | ); 78 | 79 | #define PathFileExists(lpszPath) (GetFileAttributes(lpszPath) != (DWORD)-1) 80 | -------------------------------------------------------------------------------- /src/symdll.rc: -------------------------------------------------------------------------------- 1 | #include "resource.h" 2 | #include "winres.h" 3 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 4 | IDR_DBGHELP RCDATA "symdll\\dbghelp.dll" 5 | IDR_SYMSRV RCDATA "symdll\\symsrv.dll" 6 | -------------------------------------------------------------------------------- /src/symdll/dbghelp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hfiref0x/UPGDSED/86442a3c40cb62b10e24c5978bad9ad74815a765/src/symdll/dbghelp.dll -------------------------------------------------------------------------------- /src/symdll/symsrv.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hfiref0x/UPGDSED/86442a3c40cb62b10e24c5978bad9ad74815a765/src/symdll/symsrv.dll -------------------------------------------------------------------------------- /src/tests/BadRkDemo/Installer/installer.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "installer", "installer.vcxproj", "{756CE193-8FAC-4875-B37B-C169473493D9}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {756CE193-8FAC-4875-B37B-C169473493D9}.Debug|x64.ActiveCfg = Debug|x64 15 | {756CE193-8FAC-4875-B37B-C169473493D9}.Debug|x64.Build.0 = Debug|x64 16 | {756CE193-8FAC-4875-B37B-C169473493D9}.Release|x64.ActiveCfg = Release|x64 17 | {756CE193-8FAC-4875-B37B-C169473493D9}.Release|x64.Build.0 = Release|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /src/tests/BadRkDemo/Installer/installer.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {756CE193-8FAC-4875-B37B-C169473493D9} 23 | Win32Proj 24 | installer 25 | 8.1 26 | 27 | 28 | 29 | Application 30 | true 31 | v140 32 | Unicode 33 | 34 | 35 | Application 36 | false 37 | v140 38 | true 39 | Unicode 40 | 41 | 42 | Application 43 | true 44 | v140 45 | Unicode 46 | 47 | 48 | Application 49 | false 50 | v140 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | true 74 | 75 | 76 | true 77 | .\output\$(Platform)\$(Configuration)\ 78 | .\output\$(Platform)\$(Configuration)\ 79 | 80 | 81 | false 82 | 83 | 84 | false 85 | .\output\$(Platform)\$(Configuration)\ 86 | .\output\$(Platform)\$(Configuration)\ 87 | 88 | 89 | 90 | 91 | 92 | Level3 93 | Disabled 94 | WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) 95 | true 96 | 97 | 98 | Windows 99 | true 100 | 101 | 102 | 103 | 104 | 105 | 106 | Level3 107 | Disabled 108 | _DEBUG;_WINDOWS;%(PreprocessorDefinitions) 109 | true 110 | 111 | 112 | Windows 113 | true 114 | main 115 | AsInvoker 116 | 117 | 118 | 119 | 120 | Level3 121 | 122 | 123 | MaxSpeed 124 | true 125 | true 126 | WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) 127 | true 128 | 129 | 130 | Windows 131 | true 132 | true 133 | true 134 | 135 | 136 | 137 | 138 | Level3 139 | 140 | 141 | MaxSpeed 142 | true 143 | true 144 | NDEBUG;_WINDOWS;%(PreprocessorDefinitions) 145 | true 146 | 147 | 148 | Windows 149 | true 150 | true 151 | false 152 | main 153 | RequireAdministrator 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | -------------------------------------------------------------------------------- /src/tests/BadRkDemo/Installer/installer.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | 47 | 48 | Header Files 49 | 50 | 51 | Header Files 52 | 53 | 54 | Header Files 55 | 56 | 57 | Header Files 58 | 59 | 60 | Header Files 61 | 62 | 63 | -------------------------------------------------------------------------------- /src/tests/BadRkDemo/Installer/installer.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 2 5 | WindowsLocalDebugger 6 | 7 | 8 | 1 9 | WindowsLocalDebugger 10 | 11 | -------------------------------------------------------------------------------- /src/tests/BadRkDemo/Installer/main.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2017 4 | * 5 | * TITLE: MAIN.C 6 | * 7 | * VERSION: 1.10 8 | * 9 | * DATE: 14 May 2017 10 | * 11 | * Installer for BadRkDemo BSOD generator. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | 20 | #if !defined UNICODE 21 | #error ANSI build is not supported 22 | #endif 23 | 24 | #if (_MSC_VER >= 1900) 25 | #ifdef _DEBUG 26 | #pragma comment(lib, "vcruntimed.lib") 27 | #pragma comment(lib, "ucrtd.lib") 28 | #else 29 | #pragma comment(lib, "libvcruntime.lib") 30 | #endif 31 | #endif 32 | 33 | // 34 | // Ignored warnings 35 | // 36 | #pragma warning(disable: 4005) // macro redefinition 37 | #pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union 38 | #pragma warning(disable: 6102) // Using %s from failed function call at line %u 39 | #pragma warning(disable: 6320) // Exception-filter expression is the constant EXCEPTION_EXECUTE_HANDLER 40 | #if (_MSC_VER >= 1900) 41 | #pragma warning(disable: 4091) // 'typedef ': ignored on left of '' when no variable is declared 42 | #pragma warning(disable: 4311) // 'type cast': pointer truncation from %s to %s 43 | #pragma warning(disable: 4312) // 'type cast': conversion from %s to %s of greater size 44 | #endif 45 | 46 | #include 47 | #include "minirtl\minirtl.h" 48 | #include "minirtl\cmdline.h" 49 | #include "ntos.h" 50 | #include 51 | 52 | #define PGDEMOREGDRV L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\PGDemo" 53 | 54 | /* 55 | * NativeAdjustPrivilege 56 | * 57 | * Purpose: 58 | * 59 | * Enable single privilege. 60 | * 61 | */ 62 | NTSTATUS NativeAdjustPrivilege( 63 | _In_ ULONG Privilege 64 | ) 65 | { 66 | NTSTATUS Status; 67 | HANDLE TokenHandle; 68 | 69 | LUID Luid; 70 | TOKEN_PRIVILEGES TokenPrivileges; 71 | 72 | Luid.LowPart = Privilege; 73 | Luid.HighPart = 0; 74 | 75 | TokenPrivileges.PrivilegeCount = 1; 76 | TokenPrivileges.Privileges[0].Luid = Luid; 77 | TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 78 | 79 | Status = NtOpenProcessToken( 80 | NtCurrentProcess(), 81 | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, 82 | &TokenHandle); 83 | 84 | if (NT_SUCCESS(Status)) { 85 | Status = NtAdjustPrivilegesToken( 86 | TokenHandle, 87 | FALSE, 88 | &TokenPrivileges, 89 | sizeof(TOKEN_PRIVILEGES), 90 | (PTOKEN_PRIVILEGES)NULL, 91 | NULL); 92 | 93 | NtClose(TokenHandle); 94 | } 95 | 96 | if (Status == STATUS_NOT_ALL_ASSIGNED) 97 | Status = STATUS_PRIVILEGE_NOT_HELD; 98 | 99 | return Status; 100 | } 101 | 102 | /* 103 | * NativeLoadDriver 104 | * 105 | * Purpose: 106 | * 107 | * Write required registry settings and load driver. 108 | * 109 | */ 110 | NTSTATUS NativeLoadDriver( 111 | _In_ PWSTR DrvFullPath, 112 | _In_ PWSTR KeyName, 113 | _In_opt_ PWSTR DisplayName, 114 | _In_ BOOL ReloadDrv 115 | ) 116 | { 117 | UNICODE_STRING ValueName, drvName; 118 | OBJECT_ATTRIBUTES attr; 119 | 120 | HANDLE hDrvKey; 121 | ULONG data, dataSize = 0; 122 | NTSTATUS ns = STATUS_UNSUCCESSFUL; 123 | hDrvKey = NULL; 124 | 125 | __try 126 | { 127 | if (!ARGUMENT_PRESENT(KeyName)) { 128 | ns = STATUS_OBJECT_NAME_NOT_FOUND; 129 | __leave; 130 | } 131 | 132 | RtlInitUnicodeString(&drvName, KeyName); 133 | InitializeObjectAttributes(&attr, &drvName, OBJ_CASE_INSENSITIVE, 0, NULL); 134 | ns = NtCreateKey(&hDrvKey, KEY_ALL_ACCESS, &attr, 0, NULL, REG_OPTION_NON_VOLATILE, NULL); 135 | if (!NT_SUCCESS(ns)) { 136 | __leave; 137 | } 138 | 139 | if (ARGUMENT_PRESENT(DrvFullPath)) { 140 | RtlInitUnicodeString(&ValueName, L"ImagePath"); 141 | dataSize = (ULONG)(1 + _strlen(DrvFullPath)) * sizeof(WCHAR); 142 | ns = NtSetValueKey(hDrvKey, &ValueName, 0, REG_EXPAND_SZ, (PVOID)DrvFullPath, dataSize); 143 | if (!NT_SUCCESS(ns)) { 144 | __leave; 145 | } 146 | } 147 | 148 | data = 1; 149 | RtlInitUnicodeString(&ValueName, L"Type"); 150 | ns = NtSetValueKey(hDrvKey, &ValueName, 0, REG_DWORD, (PVOID)&data, sizeof(DWORD)); 151 | if (!NT_SUCCESS(ns)) { 152 | __leave; 153 | } 154 | 155 | data = 3; 156 | RtlInitUnicodeString(&ValueName, L"Start"); 157 | ns = NtSetValueKey(hDrvKey, &ValueName, 0, REG_DWORD, (PVOID)&data, sizeof(DWORD)); 158 | if (!NT_SUCCESS(ns)) { 159 | __leave; 160 | } 161 | 162 | data = SERVICE_ERROR_NORMAL; 163 | RtlInitUnicodeString(&ValueName, L"ErrorControl"); 164 | ns = NtSetValueKey(hDrvKey, &ValueName, 0, REG_DWORD, (PVOID)&data, sizeof(DWORD)); 165 | if (!NT_SUCCESS(ns)) { 166 | __leave; 167 | } 168 | 169 | if (ARGUMENT_PRESENT(DisplayName)) { 170 | RtlInitUnicodeString(&ValueName, L"DisplayName"); 171 | dataSize = (ULONG)(1 + _strlen(DisplayName)) * sizeof(WCHAR); 172 | ns = NtSetValueKey(hDrvKey, &ValueName, 0, REG_SZ, DisplayName, dataSize); 173 | if (!NT_SUCCESS(ns)) { 174 | __leave; 175 | } 176 | } 177 | NtClose(hDrvKey); 178 | hDrvKey = NULL; 179 | 180 | ns = NtLoadDriver(&drvName); 181 | if (ns == STATUS_IMAGE_ALREADY_LOADED) { 182 | if (ReloadDrv == TRUE) { 183 | NtUnloadDriver(&drvName); //unload previous driver version 184 | NtYieldExecution(); 185 | ns = NtLoadDriver(&drvName); 186 | } 187 | else { 188 | ns = STATUS_SUCCESS; 189 | } 190 | } 191 | 192 | } 193 | __finally { 194 | if (hDrvKey != NULL) { 195 | NtClose(hDrvKey); 196 | } 197 | } 198 | return ns; 199 | } 200 | 201 | #define PGDEMO_SET_TEST_TYPE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0800, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 202 | 203 | #define TT_DRIVER_LIST 0 204 | #define TT_CR4 1 205 | #define TT_DRIVER_OBJECT 2 206 | #define TT_NOTIFY_CALLOUT 3 207 | 208 | typedef struct _INOUT_PARAM { 209 | ULONG TestType; 210 | } INOUT_PARAM, *PINOUTPARAM; 211 | 212 | 213 | /* 214 | * CallDriver 215 | * 216 | * Purpose: 217 | * 218 | * Send request to the driver. 219 | * 220 | */ 221 | void CallDriver( 222 | ULONG TestType) 223 | { 224 | HANDLE h; 225 | INOUT_PARAM tmp; 226 | DWORD bytesIO; 227 | 228 | h = CreateFile(TEXT("\\\\.\\PGDemo"), GENERIC_READ | GENERIC_WRITE, 229 | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); 230 | if (h != INVALID_HANDLE_VALUE) { 231 | 232 | tmp.TestType = TestType; 233 | 234 | DeviceIoControl(h, PGDEMO_SET_TEST_TYPE, 235 | &tmp, sizeof(tmp), &tmp, 236 | sizeof(tmp), &bytesIO, NULL); 237 | 238 | CloseHandle(h); 239 | } 240 | } 241 | 242 | typedef struct _CPUInfo { 243 | int eax; 244 | int ebx; 245 | int ecx; 246 | int edx; 247 | } CPUInfo, *PCPUInfo; 248 | 249 | /* 250 | * IsSmepSupported 251 | * 252 | * Purpose: 253 | * 254 | * Return TRUE if SMEP supported by current CPU, FALSE otherwise. 255 | * 256 | */ 257 | BOOL IsSmepSupported( 258 | VOID) 259 | { 260 | CPUInfo cpuInfo = { 0, 0, 0, 0 }; 261 | 262 | __cpuid((int*)&cpuInfo, 7); 263 | 264 | if (cpuInfo.ebx & (1 << 7)) { 265 | return TRUE; 266 | } 267 | return FALSE; 268 | } 269 | 270 | /* 271 | * main 272 | * 273 | * Purpose: 274 | * 275 | * Program entry point. 276 | * 277 | */ 278 | void main() 279 | { 280 | NTSTATUS Status; 281 | ULONG l, TestType = 0; 282 | 283 | HANDLE Link = NULL; 284 | 285 | UNICODE_STRING str, drvname; 286 | OBJECT_ATTRIBUTES Obja; 287 | 288 | WCHAR szBuffer[MAX_PATH + 1]; 289 | 290 | l = 0; 291 | RtlSecureZeroMemory(szBuffer, sizeof(szBuffer)); 292 | GetCommandLineParam(GetCommandLine(), 1, (LPWSTR)&szBuffer, MAX_PATH, &l); 293 | if (l > 0) 294 | TestType = strtoul(szBuffer); 295 | 296 | if (TestType == TT_CR4) { 297 | if (!IsSmepSupported()) { 298 | MessageBox(GetDesktopWindow(), TEXT("[PGDemo] SMEP is not supported by this CPU"), NULL, MB_ICONERROR); 299 | return; 300 | } 301 | } 302 | 303 | Status = NativeAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE); 304 | if (!NT_SUCCESS(Status)) { 305 | RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer)); 306 | _strcpy(szBuffer, L"[PGDemo] NativeAdjustPrivilege result = 0x"); 307 | ultohex(Status, _strend(szBuffer)); 308 | MessageBox(GetDesktopWindow(), szBuffer, NULL, MB_ICONERROR); 309 | return; 310 | } 311 | 312 | _strcpy(szBuffer, L"\\??\\"); 313 | _strcat(szBuffer, NtCurrentPeb()->ProcessParameters->CurrentDirectory.DosPath.Buffer); 314 | _strcat(szBuffer, L"pgdemo.sys"); 315 | 316 | RtlInitUnicodeString(&str, L"\\*"); 317 | RtlInitUnicodeString(&drvname, szBuffer); 318 | InitializeObjectAttributes(&Obja, &str, OBJ_CASE_INSENSITIVE, 0, NULL); 319 | 320 | Status = NtCreateSymbolicLinkObject(&Link, SYMBOLIC_LINK_ALL_ACCESS, &Obja, &drvname); 321 | if (!NT_SUCCESS(Status)) { 322 | RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer)); 323 | _strcpy(szBuffer, L"[Test] NtCreateSymbolicLinkObject result = 0x"); 324 | ultohex(Status, _strend(szBuffer)); 325 | MessageBox(GetDesktopWindow(), szBuffer, NULL, MB_ICONERROR); 326 | } 327 | else { 328 | 329 | Status = NativeLoadDriver(L"\\*", PGDEMOREGDRV, NULL, TRUE); 330 | RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer)); 331 | _strcpy(szBuffer, L"[Test] NativeLoadDriver result = 0x"); 332 | ultohex(Status, _strend(szBuffer)); 333 | MessageBox(GetDesktopWindow(), szBuffer, NULL, MB_ICONINFORMATION); 334 | 335 | if (Link) 336 | NtClose(Link); 337 | 338 | if (NT_SUCCESS(Status)) { 339 | CallDriver(TestType); 340 | } 341 | } 342 | } 343 | -------------------------------------------------------------------------------- /src/tests/BadRkDemo/Installer/minirtl/_filename.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "minirtl.h" 3 | 4 | char *_filename_a(const char *f) 5 | { 6 | char *p = (char *)f; 7 | 8 | if (f == 0) 9 | return 0; 10 | 11 | while (*f != (char)0) { 12 | if (*f == '\\') 13 | p = (char *)f + 1; 14 | f++; 15 | } 16 | return p; 17 | } 18 | 19 | wchar_t *_filename_w(const wchar_t *f) 20 | { 21 | wchar_t *p = (wchar_t *)f; 22 | 23 | if (f == 0) 24 | return 0; 25 | 26 | while (*f != (wchar_t)0) { 27 | if (*f == (wchar_t)'\\') 28 | p = (wchar_t *)f + 1; 29 | f++; 30 | } 31 | return p; 32 | } 33 | 34 | char *_fileext_a(const char *f) 35 | { 36 | char *p = 0; 37 | 38 | if (f == 0) 39 | return 0; 40 | 41 | while (*f != (char)0) { 42 | if (*f == '.') 43 | p = (char *)f; 44 | f++; 45 | } 46 | 47 | if (p == 0) 48 | p = (char *)f; 49 | 50 | return p; 51 | } 52 | 53 | wchar_t *_fileext_w(const wchar_t *f) 54 | { 55 | wchar_t *p = 0; 56 | 57 | if (f == 0) 58 | return 0; 59 | 60 | while (*f != (wchar_t)0) { 61 | if (*f == (wchar_t)'.') 62 | p = (wchar_t *)f; 63 | f++; 64 | } 65 | 66 | if (p == 0) 67 | p = (wchar_t *)f; 68 | 69 | return p; 70 | } 71 | 72 | char *_filename_noext_a(char *dest, const char *f) 73 | { 74 | char *p, *l, *dot; 75 | 76 | if ((f == 0) || (dest == 0)) 77 | return 0; 78 | 79 | p = _filename_a(f); 80 | dot = _strend_a(p); 81 | l = p; 82 | 83 | while (*l != (char)0) 84 | { 85 | if (*l == '.') 86 | dot = l; 87 | l++; 88 | } 89 | 90 | while (p 2 | 3 | BOOL GetCommandLineParamW( 4 | IN LPCWSTR CmdLine, 5 | IN ULONG ParamIndex, 6 | OUT LPWSTR Buffer, 7 | IN ULONG BufferSize, 8 | OUT PULONG ParamLen 9 | ) 10 | { 11 | ULONG c, plen = 0; 12 | TCHAR divider; 13 | 14 | if (ParamLen != NULL) 15 | *ParamLen = 0; 16 | 17 | if (CmdLine == NULL) { 18 | if ((Buffer != NULL) && (BufferSize > 0)) 19 | *Buffer = 0; 20 | return FALSE; 21 | } 22 | 23 | for (c = 0; c <= ParamIndex; c++) { 24 | plen = 0; 25 | 26 | while (*CmdLine == ' ') 27 | CmdLine++; 28 | 29 | switch (*CmdLine) { 30 | case 0: 31 | goto zero_term_exit; 32 | 33 | case '"': 34 | CmdLine++; 35 | divider = '"'; 36 | break; 37 | 38 | default: 39 | divider = ' '; 40 | } 41 | 42 | while ((*CmdLine != '"') && (*CmdLine != divider) && (*CmdLine != 0)) { 43 | plen++; 44 | if (c == ParamIndex) 45 | if ((plen < BufferSize) && (Buffer != NULL)) { 46 | *Buffer = *CmdLine; 47 | Buffer++; 48 | } 49 | CmdLine++; 50 | } 51 | 52 | if (*CmdLine != 0) 53 | CmdLine++; 54 | } 55 | 56 | zero_term_exit: 57 | 58 | if ((Buffer != NULL) && (BufferSize > 0)) 59 | *Buffer = 0; 60 | 61 | if (ParamLen != NULL) 62 | *ParamLen = plen; 63 | 64 | if (plen < BufferSize) 65 | return TRUE; 66 | else 67 | return FALSE; 68 | } 69 | 70 | BOOL GetCommandLineParamA( 71 | IN LPCSTR CmdLine, 72 | IN ULONG ParamIndex, 73 | OUT LPSTR Buffer, 74 | IN ULONG BufferSize, 75 | OUT PULONG ParamLen 76 | ) 77 | { 78 | ULONG c, plen = 0; 79 | TCHAR divider; 80 | 81 | if (CmdLine == NULL) 82 | return FALSE; 83 | 84 | if (ParamLen != NULL) 85 | *ParamLen = 0; 86 | 87 | for (c = 0; c <= ParamIndex; c++) { 88 | plen = 0; 89 | 90 | while (*CmdLine == ' ') 91 | CmdLine++; 92 | 93 | switch (*CmdLine) { 94 | case 0: 95 | goto zero_term_exit; 96 | 97 | case '"': 98 | CmdLine++; 99 | divider = '"'; 100 | break; 101 | 102 | default: 103 | divider = ' '; 104 | } 105 | 106 | while ((*CmdLine != '"') && (*CmdLine != divider) && (*CmdLine != 0)) { 107 | plen++; 108 | if (c == ParamIndex) 109 | if ((plen < BufferSize) && (Buffer != NULL)) { 110 | *Buffer = *CmdLine; 111 | Buffer++; 112 | } 113 | CmdLine++; 114 | } 115 | 116 | if (*CmdLine != 0) 117 | CmdLine++; 118 | } 119 | 120 | zero_term_exit: 121 | 122 | if ((Buffer != NULL) && (BufferSize > 0)) 123 | *Buffer = 0; 124 | 125 | if (ParamLen != NULL) 126 | *ParamLen = plen; 127 | 128 | if (plen < BufferSize) 129 | return TRUE; 130 | else 131 | return FALSE; 132 | } 133 | 134 | char *ExtractFilePathA(const char *FileName, char *FilePath) 135 | { 136 | char *p = (char *)FileName, *p0 = (char *)FileName; 137 | 138 | if ((FileName == 0) || (FilePath == 0)) 139 | return 0; 140 | 141 | while (*FileName != 0) { 142 | if (*FileName == '\\') 143 | p = (char *)FileName + 1; 144 | FileName++; 145 | } 146 | 147 | while (p0 < p) { 148 | *FilePath = *p0; 149 | FilePath++; 150 | p0++; 151 | } 152 | 153 | *FilePath = 0; 154 | 155 | return FilePath; 156 | } 157 | 158 | wchar_t *ExtractFilePathW(const wchar_t *FileName, wchar_t *FilePath) 159 | { 160 | wchar_t *p = (wchar_t *)FileName, *p0 = (wchar_t *)FileName; 161 | 162 | if ((FileName == 0) || (FilePath == 0)) 163 | return 0; 164 | 165 | while (*FileName != 0) { 166 | if (*FileName == '\\') 167 | p = (wchar_t *)FileName + 1; 168 | FileName++; 169 | } 170 | 171 | while (p0 < p) { 172 | *FilePath = *p0; 173 | FilePath++; 174 | p0++; 175 | } 176 | 177 | *FilePath = 0; 178 | 179 | return FilePath; 180 | } 181 | -------------------------------------------------------------------------------- /src/tests/BadRkDemo/Installer/minirtl/cmdline.h: -------------------------------------------------------------------------------- 1 | #ifndef _CMDLINEH_ 2 | #define _CMDLINEH_ 3 | 4 | BOOL GetCommandLineParamW( 5 | IN LPCWSTR CmdLine, 6 | IN ULONG ParamIndex, 7 | OUT LPWSTR Buffer, 8 | IN ULONG BufferSize, 9 | OUT PULONG ParamLen 10 | ); 11 | 12 | BOOL GetCommandLineParamA( 13 | IN LPCSTR CmdLine, 14 | IN ULONG ParamIndex, 15 | OUT LPSTR Buffer, 16 | IN ULONG BufferSize, 17 | OUT PULONG ParamLen 18 | ); 19 | 20 | char *ExtractFilePathA(const char *FileName, char *FilePath); 21 | wchar_t *ExtractFilePathW(const wchar_t *FileName, wchar_t *FilePath); 22 | 23 | #ifdef UNICODE 24 | 25 | #define ExtractFilePath ExtractFilePathW 26 | #define GetCommandLineParam GetCommandLineParamW 27 | 28 | #else // ANSI 29 | 30 | #define ExtractFilePath ExtractFilePathA 31 | #define GetCommandLineParam GetCommandLineParamA 32 | 33 | #endif 34 | 35 | #endif /* _CMDLINEH_ */ 36 | -------------------------------------------------------------------------------- /src/tests/BadRkDemo/Installer/minirtl/minirtl.h: -------------------------------------------------------------------------------- 1 | /* 2 | Module name: 3 | minirtl.h 4 | 5 | Description: 6 | header for string handling and conversion routines 7 | 8 | Date: 9 | 1 Mar 2015 10 | */ 11 | 12 | #ifndef _MINIRTL_ 13 | #define _MINIRTL_ 14 | 15 | // string copy/concat/length 16 | 17 | char *_strend_a(const char *s); 18 | wchar_t *_strend_w(const wchar_t *s); 19 | 20 | char *_strcpy_a(char *dest, const char *src); 21 | wchar_t *_strcpy_w(wchar_t *dest, const wchar_t *src); 22 | 23 | char *_strcat_a(char *dest, const char *src); 24 | wchar_t *_strcat_w(wchar_t *dest, const wchar_t *src); 25 | 26 | char *_strncpy_a(char *dest, size_t ccdest, const char *src, size_t ccsrc); 27 | wchar_t *_strncpy_w(wchar_t *dest, size_t ccdest, const wchar_t *src, size_t ccsrc); 28 | 29 | size_t _strlen_a(const char *s); 30 | size_t _strlen_w(const wchar_t *s); 31 | 32 | // comparing 33 | 34 | int _strcmp_a(const char *s1, const char *s2); 35 | int _strcmp_w(const wchar_t *s1, const wchar_t *s2); 36 | 37 | int _strncmp_a(const char *s1, const char *s2, size_t cchars); 38 | int _strncmp_w(const wchar_t *s1, const wchar_t *s2, size_t cchars); 39 | 40 | int _strcmpi_a(const char *s1, const char *s2); 41 | int _strcmpi_w(const wchar_t *s1, const wchar_t *s2); 42 | 43 | int _strncmpi_a(const char *s1, const char *s2, size_t cchars); 44 | int _strncmpi_w(const wchar_t *s1, const wchar_t *s2, size_t cchars); 45 | 46 | char *_strstr_a(const char *s, const char *sub_s); 47 | wchar_t *_strstr_w(const wchar_t *s, const wchar_t *sub_s); 48 | 49 | char *_strstri_a(const char *s, const char *sub_s); 50 | wchar_t *_strstri_w(const wchar_t *s, const wchar_t *sub_s); 51 | 52 | // conversion of integer types to string, returning string length 53 | 54 | size_t ultostr_a(unsigned long x, char *s); 55 | size_t ultostr_w(unsigned long x, wchar_t *s); 56 | 57 | size_t ultohex_a(unsigned long x, char *s); 58 | size_t ultohex_w(unsigned long x, wchar_t *s); 59 | 60 | size_t itostr_a(int x, char *s); 61 | size_t itostr_w(int x, wchar_t *s); 62 | 63 | size_t i64tostr_a(signed long long x, char *s); 64 | size_t i64tostr_w(signed long long x, wchar_t *s); 65 | 66 | size_t u64tostr_a(unsigned long long x, char *s); 67 | size_t u64tostr_w(unsigned long long x, wchar_t *s); 68 | 69 | size_t u64tohex_a(unsigned long long x, char *s); 70 | size_t u64tohex_w(unsigned long long x, wchar_t *s); 71 | 72 | // string to integers conversion 73 | 74 | unsigned long strtoul_a(char *s); 75 | unsigned long strtoul_w(wchar_t *s); 76 | 77 | unsigned long long strtou64_a(char *s); 78 | unsigned long long strtou64_w(wchar_t *s); 79 | 80 | unsigned long hextoul_a(char *s); 81 | unsigned long hextoul_w(wchar_t *s); 82 | 83 | int strtoi_a(char *s); 84 | int strtoi_w(wchar_t *s); 85 | 86 | signed long long strtoi64_a(char *s); 87 | signed long long strtoi64_w(wchar_t *s); 88 | 89 | unsigned long long hextou64_a(char *s); 90 | unsigned long long hextou64_w(wchar_t *s); 91 | 92 | /* =================================== */ 93 | 94 | #ifdef UNICODE 95 | 96 | #define _strend _strend_w 97 | #define _strcpy _strcpy_w 98 | #define _strcat _strcat_w 99 | #define _strlen _strlen_w 100 | #define _strncpy _strncpy_w 101 | 102 | #define _strcmp _strcmp_w 103 | #define _strncmp _strncmp_w 104 | #define _strcmpi _strcmpi_w 105 | #define _strncmpi _strncmpi_w 106 | #define _strstr _strstr_w 107 | #define _strstri _strstri_w 108 | 109 | #define ultostr ultostr_w 110 | #define ultohex ultohex_w 111 | #define itostr itostr_w 112 | #define i64tostr i64tostr_w 113 | #define u64tostr u64tostr_w 114 | #define u64tohex u64tohex_w 115 | 116 | #define strtoul strtoul_w 117 | #define hextoul hextoul_w 118 | #define strtoi strtoi_w 119 | #define strtoi64 strtoi64_w 120 | #define strtou64 strtou64_w 121 | #define hextou64 hextou64_w 122 | 123 | #else // ANSI 124 | 125 | #define _strend _strend_a 126 | #define _strcpy _strcpy_a 127 | #define _strcat _strcat_a 128 | #define _strlen _strlen_a 129 | #define _strncpy _strncpy_a 130 | #define _strcmp _strcmp_a 131 | 132 | #define _strcmp _strcmp_a 133 | #define _strncmp _strncmp_a 134 | #define _strcmpi _strcmpi_a 135 | #define _strncmpi _strncmpi_a 136 | #define _strstr _strstr_a 137 | #define _strstri _strstri_a 138 | 139 | #define ultostr ultostr_a 140 | #define ultohex ultohex_a 141 | #define itostr itostr_a 142 | #define i64tostr i64tostr_a 143 | #define u64tostr u64tostr_a 144 | #define u64tohex u64tohex_a 145 | 146 | #define strtoul strtoul_a 147 | #define hextoul hextoul_a 148 | #define strtoi strtoi_a 149 | #define strtoi64 strtoi64_a 150 | #define strtou64 strtou64_a 151 | #define hextou64 hextou64_a 152 | 153 | #endif 154 | 155 | #endif /* _MINIRTL_ */ 156 | -------------------------------------------------------------------------------- /src/tests/BadRkDemo/Installer/minirtl/rtltypes.h: -------------------------------------------------------------------------------- 1 | #ifndef _WCHAR_T_DEFINED 2 | typedef unsigned short wchar_t; 3 | #define _WCHAR_T_DEFINED 4 | #endif /* _WCHAR_T_DEFINED */ 5 | 6 | #ifndef _SIZE_T_DEFINED 7 | #ifdef _WIN64 8 | typedef unsigned __int64 size_t; 9 | #else /* _WIN64 */ 10 | typedef __w64 unsigned int size_t; 11 | #endif /* _WIN64 */ 12 | #define _SIZE_T_DEFINED 13 | #endif /* _SIZE_T_DEFINED */ 14 | 15 | __forceinline char locase_a(char c) 16 | { 17 | if ((c >= 'A') && (c <= 'Z')) 18 | return c + 0x20; 19 | else 20 | return c; 21 | } 22 | 23 | __forceinline wchar_t locase_w(wchar_t c) 24 | { 25 | if ((c >= 'A') && (c <= 'Z')) 26 | return c + 0x20; 27 | else 28 | return c; 29 | } 30 | 31 | __forceinline char byteabs(char x) { 32 | if (x < 0) 33 | return -x; 34 | return x; 35 | } 36 | 37 | __forceinline int _isdigit_a(char x) { 38 | return ((x >= '0') && (x <= '9')); 39 | } 40 | 41 | __forceinline int _isdigit_w(wchar_t x) { 42 | return ((x >= L'0') && (x <= L'9')); 43 | } 44 | -------------------------------------------------------------------------------- /src/tests/BadRkDemo/Installer/minirtl/strtoul.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | unsigned long strtoul_a(char *s) 4 | { 5 | unsigned long long a = 0; 6 | char c; 7 | 8 | if (s == 0) 9 | return 0; 10 | 11 | while (*s != 0) { 12 | c = *s; 13 | if (_isdigit_a(c)) 14 | a = (a*10)+(c-'0'); 15 | else 16 | break; 17 | 18 | if (a > 0xffffffff) 19 | return 0xffffffff; 20 | 21 | s++; 22 | } 23 | return (unsigned long)a; 24 | } 25 | 26 | unsigned long strtoul_w(wchar_t *s) 27 | { 28 | unsigned long long a = 0; 29 | wchar_t c; 30 | 31 | if (s == 0) 32 | return 0; 33 | 34 | while (*s != 0) { 35 | c = *s; 36 | if (_isdigit_w(c)) 37 | a = (a * 10) + (c - L'0'); 38 | else 39 | break; 40 | 41 | if (a > 0xffffffff) 42 | return 0xffffffff; 43 | 44 | s++; 45 | } 46 | return (unsigned long)a; 47 | } 48 | -------------------------------------------------------------------------------- /src/tests/BadRkDemo/Installer/minirtl/ultohex.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | size_t ultohex_a(unsigned long x, char *s) 4 | { 5 | char p; 6 | size_t c; 7 | 8 | if (s==0) 9 | return 8; 10 | 11 | for (c=0; c<8; c++) { 12 | p = (char)(x & 0xf); 13 | x >>= 4; 14 | 15 | if (p<10) 16 | p += '0'; 17 | else 18 | p = 'A' + (p-10); 19 | 20 | s[7-c] = p; 21 | } 22 | 23 | s[8] = 0; 24 | return 8; 25 | } 26 | 27 | size_t ultohex_w(unsigned long x, wchar_t *s) 28 | { 29 | wchar_t p; 30 | size_t c; 31 | 32 | if (s==0) 33 | return 8; 34 | 35 | for (c=0; c<8; c++) { 36 | p = (wchar_t)(x & 0xf); 37 | x >>= 4; 38 | 39 | if (p<10) 40 | p += L'0'; 41 | else 42 | p = L'A' + (p-10); 43 | 44 | s[7-c] = p; 45 | } 46 | 47 | s[8] = 0; 48 | return 8; 49 | } 50 | -------------------------------------------------------------------------------- /src/tests/BadRkDemo/drv/dummy.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dummy", "dummy\dummy.vcxproj", "{3D8146DE-8064-46C0-9E70-CEEC357B2290}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Release|x64 = Release|x64 11 | ReleaseSigned|x64 = ReleaseSigned|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {3D8146DE-8064-46C0-9E70-CEEC357B2290}.Release|x64.ActiveCfg = Release|x64 15 | {3D8146DE-8064-46C0-9E70-CEEC357B2290}.Release|x64.Build.0 = Release|x64 16 | {3D8146DE-8064-46C0-9E70-CEEC357B2290}.Release|x64.Deploy.0 = Release|x64 17 | {3D8146DE-8064-46C0-9E70-CEEC357B2290}.ReleaseSigned|x64.ActiveCfg = ReleaseSigned|x64 18 | {3D8146DE-8064-46C0-9E70-CEEC357B2290}.ReleaseSigned|x64.Build.0 = ReleaseSigned|x64 19 | {3D8146DE-8064-46C0-9E70-CEEC357B2290}.ReleaseSigned|x64.Deploy.0 = ReleaseSigned|x64 20 | EndGlobalSection 21 | GlobalSection(SolutionProperties) = preSolution 22 | HideSolutionNode = FALSE 23 | EndGlobalSection 24 | EndGlobal 25 | -------------------------------------------------------------------------------- /src/tests/BadRkDemo/drv/dummy/dummy.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | ReleaseSigned 10 | x64 11 | 12 | 13 | Release 14 | x64 15 | 16 | 17 | 18 | {3D8146DE-8064-46C0-9E70-CEEC357B2290} 19 | {1bc93793-694f-48fe-9372-81e2b05556fd} 20 | v4.5 21 | 12.0 22 | Debug 23 | Win32 24 | dummy 25 | 8.1 26 | 27 | 28 | 29 | Windowsv6.3 30 | true 31 | WindowsKernelModeDriver10.0 32 | Driver 33 | KMDF 34 | Universal 35 | 36 | 37 | Windowsv6.3 38 | false 39 | WindowsKernelModeDriver8.1 40 | Driver 41 | KMDF 42 | Universal 43 | true 44 | 45 | 46 | Windowsv6.3 47 | false 48 | WindowsKernelModeDriver8.1 49 | Driver 50 | KMDF 51 | Universal 52 | true 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | DbgengKernelDebugger 64 | AllRules.ruleset 65 | .\output\$(Platform)\$(Configuration)\ 66 | .\output\$(Platform)\$(Configuration)\ 67 | pgdemo 68 | 69 | 70 | DbgengKernelDebugger 71 | AllRules.ruleset 72 | false 73 | .\output\$(Platform)\$(Configuration)\ 74 | .\output\$(Platform)\$(Configuration)\ 75 | pgdemo 76 | 77 | 78 | DbgengKernelDebugger 79 | AllRules.ruleset 80 | false 81 | .\output\$(Platform)\$(Configuration)\ 82 | .\output\$(Platform)\$(Configuration)\ 83 | pgdemo 84 | 85 | 86 | 87 | false 88 | true 89 | Speed 90 | false 91 | true 92 | All 93 | true 94 | CompileAsC 95 | false 96 | false 97 | Disabled 98 | 99 | 100 | false 101 | false 102 | true 103 | true 104 | true 105 | DriverEntry 106 | true 107 | true 108 | false 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | false 118 | true 119 | Speed 120 | false 121 | true 122 | All 123 | true 124 | CompileAsC 125 | false 126 | false 127 | Disabled 128 | 129 | 130 | false 131 | false 132 | true 133 | true 134 | true 135 | DriverEntry 136 | true 137 | true 138 | false 139 | /INTEGRITYCHECK %(AdditionalOptions) 140 | 141 | 142 | \Certs\SignTsugumi64.cmd .\output\$(Platform)\$(Configuration)\pgdemo.sys 143 | 144 | 145 | 146 | 147 | false 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /src/tests/BadRkDemo/drv/dummy/dummy.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Source Files 24 | 25 | 26 | 27 | 28 | Header Files 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/tests/BadRkDemo/drv/dummy/dummy.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Off 5 | 6 | 7 | Off 8 | 9 | -------------------------------------------------------------------------------- /src/tests/BadRkDemo/drv/dummy/main.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2017 4 | * 5 | * TITLE: MAIN.C 6 | * 7 | * VERSION: 1.00 8 | * 9 | * DATE: 14 May 2017 10 | * 11 | * PatchGuard BSOD generator. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | #include 20 | #include 21 | #include "main.h" 22 | 23 | //Disable nonmeaningful warnings. 24 | #pragma warning(disable: 4005) // macro redefinition 25 | #pragma warning(disable: 4054) // 'type cast' : from function pointer %s to data pointer %s 26 | #pragma warning(disable: 4152) // nonstandard extension, function/data pointer conversion in expression 27 | #pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union 28 | 29 | RTL_OSVERSIONINFOW g_osver; 30 | 31 | typedef NTSTATUS(NTAPI * pfnDispatch)( 32 | _In_ struct _DEVICE_OBJECT *DeviceObject, 33 | _Inout_ struct _IRP *Irp); 34 | 35 | pfnDispatch g_NtfsFsdCreateOriginal = NULL; 36 | 37 | /* 38 | * ModifyPsLoadedModuleList 39 | * 40 | * Purpose: 41 | * 42 | * Modify PsLoadedModulesList by removing entry from it. 43 | * 44 | * Expected PG BSOD: Loaded module list modification. 45 | * 46 | */ 47 | NTSTATUS ModifyPsLoadedModuleList( 48 | _In_ DEVICE_OBJECT *DeviceObject) 49 | { 50 | DRIVER_OBJECT *DriverObject = DeviceObject->DriverObject; 51 | KLDR_DATA_TABLE_ENTRY *LoaderSection = (KLDR_DATA_TABLE_ENTRY*)DriverObject->DriverSection; 52 | 53 | // 54 | // Corrupt list. 55 | // 56 | if (RemoveEntryList(&LoaderSection->InLoadOrderLinks)) 57 | return STATUS_SUCCESS; 58 | 59 | return STATUS_UNSUCCESSFUL; 60 | } 61 | 62 | NTSTATUS NtfsFsdCreateHook( 63 | _In_ PDEVICE_OBJECT DeviceObject, 64 | _In_ PIRP Irp) 65 | { 66 | if (KeGetCurrentIrql() == PASSIVE_LEVEL) { 67 | DbgPrint("[PGDemo] NtfsFsdCreate called\n"); 68 | } 69 | return g_NtfsFsdCreateOriginal(DeviceObject, Irp); 70 | } 71 | 72 | /* 73 | * ModifyDriverObject 74 | * 75 | * Purpose: 76 | * 77 | * Modify driver object by replacing IRP handler for NTFS->IRP_MJ_CREATE. 78 | * 79 | * Expected PG BSOD: Driver object corruption. 80 | * 81 | */ 82 | NTSTATUS ModifyDriverObject( 83 | VOID) 84 | { 85 | NTSTATUS Status; 86 | UNICODE_STRING fsdName; 87 | PDRIVER_OBJECT drvNtfs; 88 | 89 | RtlInitUnicodeString(&fsdName, L"\\FileSystem\\NTFS"); 90 | 91 | // 92 | // Modify driver object 93 | // 94 | Status = ObReferenceObjectByName( 95 | &fsdName, 96 | OBJ_CASE_INSENSITIVE, 97 | NULL, 98 | 0, 99 | *IoDriverObjectType, 100 | KernelMode, 101 | NULL, 102 | &drvNtfs); 103 | 104 | if (NT_SUCCESS(Status)) { 105 | 106 | g_NtfsFsdCreateOriginal = InterlockedExchangePointer( 107 | (PVOID*)&drvNtfs->MajorFunction[IRP_MJ_CREATE], 108 | (PVOID)NtfsFsdCreateHook); 109 | 110 | ObfDereferenceObject(drvNtfs); 111 | } 112 | 113 | return Status; 114 | } 115 | 116 | typedef struct _CPUInfo { 117 | int eax; 118 | int ebx; 119 | int ecx; 120 | int edx; 121 | } CPUInfo, *PCPUInfo; 122 | 123 | /* 124 | * ModifyCR4 125 | * 126 | * Purpose: 127 | * 128 | * Modify CR4 by turning off SMEP (if supported). 129 | * 130 | * Expected PG BSOD: A processor control register. 131 | * 132 | */ 133 | NTSTATUS ModifyCR4( 134 | VOID) 135 | { 136 | ULONG_PTR cr4; 137 | 138 | CPUInfo cpuInfo = { 0, 0, 0, 0 }; 139 | 140 | KeSetSystemAffinityThread(0x00000001); 141 | 142 | __cpuid((int*)&cpuInfo, 7); 143 | 144 | if (cpuInfo.ebx & (1 << 7)) { 145 | 146 | // 147 | // Modify CR4, disable SMEP. 148 | // 149 | cr4 = __readcr4(); 150 | DbgPrint("[PGDemo] cr4 value, before = %llx\n", cr4); 151 | 152 | cr4 &= ~(1 << 20); 153 | __writecr4(cr4); 154 | 155 | cr4 = __readcr4(); 156 | DbgPrint("[PGDemo] cr4 value, after = %llx\n", cr4); 157 | 158 | return STATUS_SUCCESS; 159 | } 160 | 161 | return STATUS_NOT_SUPPORTED; 162 | } 163 | 164 | // xor eax, eax 165 | // retn 166 | unsigned char StubRoutine[] = { 0x33, 0xC0, 0xC3 }; 167 | 168 | /* 169 | * SetNotifyFromPool 170 | * 171 | * Purpose: 172 | * 173 | * Allocate nonpaged executable pool and use it as LoadImageNotifyRoutine code. 174 | * 175 | * Expected PG BSOD: Kernel notification callout modification. 176 | * 177 | */ 178 | NTSTATUS SetNotifyFromPool( 179 | VOID) 180 | { 181 | NTSTATUS status = STATUS_UNSUCCESSFUL; 182 | PVOID CodeBuffer; 183 | 184 | CodeBuffer = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, 'edgP'); 185 | if (CodeBuffer) { 186 | RtlSecureZeroMemory(CodeBuffer, PAGE_SIZE); 187 | RtlCopyMemory(CodeBuffer, StubRoutine, sizeof(StubRoutine)); 188 | status = PsSetLoadImageNotifyRoutine((PLOAD_IMAGE_NOTIFY_ROUTINE)CodeBuffer); 189 | DbgPrint("[PGDemo] CodeBuffer=%p, PsSetLoadImageNotifyRoutine=%lx\n", CodeBuffer, status); 190 | } 191 | return status; 192 | } 193 | 194 | /* 195 | * DevioctlDispatch 196 | * 197 | * Purpose: 198 | * 199 | * IRP_MJ_DEVICE_CONTROL dispatch. 200 | * 201 | */ 202 | NTSTATUS DevioctlDispatch( 203 | _In_ struct _DEVICE_OBJECT *DeviceObject, 204 | _Inout_ struct _IRP *Irp 205 | ) 206 | { 207 | NTSTATUS status = STATUS_SUCCESS; 208 | ULONG bytesIO = 0; 209 | PIO_STACK_LOCATION stack; 210 | BOOLEAN condition = FALSE; 211 | PINOUTPARAM rp; 212 | 213 | UNREFERENCED_PARAMETER(DeviceObject); 214 | 215 | DbgPrint("[PGDemo] %s IRP_MJ_DEVICE_CONTROL\n", __FUNCTION__); 216 | 217 | stack = IoGetCurrentIrpStackLocation(Irp); 218 | 219 | do { 220 | 221 | if (stack == NULL) { 222 | status = STATUS_INTERNAL_ERROR; 223 | break; 224 | } 225 | 226 | rp = (PINOUTPARAM)Irp->AssociatedIrp.SystemBuffer; 227 | if (rp == NULL) { 228 | status = STATUS_INVALID_PARAMETER; 229 | break; 230 | } 231 | 232 | switch (stack->Parameters.DeviceIoControl.IoControlCode) { 233 | case PGDEMO_SET_TEST_TYPE: 234 | 235 | DbgPrint("[PGDemo] %s PGDEMO_SET_TEST_TYPE hit\n", __FUNCTION__); 236 | if (stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(INOUT_PARAM)) { 237 | status = STATUS_INVALID_PARAMETER; 238 | break; 239 | } 240 | 241 | switch (rp->TestType) { 242 | 243 | case TT_DRIVER_LIST: 244 | DbgPrint("[PGDemo] Corrupting drivers list\n"); 245 | status = ModifyPsLoadedModuleList(DeviceObject); 246 | break; 247 | 248 | case TT_DRIVER_OBJECT: 249 | DbgPrint("[PGDemo] Corrupting driver object\n"); 250 | status = ModifyDriverObject(); 251 | break; 252 | 253 | case TT_CR4: 254 | DbgPrint("[PGDemo] Corrupting CPU Control Register\n"); 255 | status = ModifyCR4(); 256 | if (status == STATUS_NOT_SUPPORTED) { 257 | DbgPrint("[PGDemo] SMEP not supported\n"); 258 | } 259 | break; 260 | 261 | case TT_NOTIFY_CALLOUT: 262 | DbgPrint("[PGDemo] Corrupting notify callout\n"); 263 | status = SetNotifyFromPool(); 264 | break; 265 | 266 | default: 267 | DbgPrint("[PGDemo] %lx is unknown test type\n", rp->TestType); 268 | break; 269 | } 270 | 271 | status = STATUS_SUCCESS; 272 | bytesIO = sizeof(INOUT_PARAM); 273 | 274 | break; 275 | 276 | default: 277 | DbgPrint("[PGDemo] %s hit with invalid IoControlCode\n", __FUNCTION__); 278 | status = STATUS_INVALID_PARAMETER; 279 | }; 280 | 281 | } while (condition); 282 | 283 | Irp->IoStatus.Status = status; 284 | Irp->IoStatus.Information = bytesIO; 285 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 286 | return status; 287 | } 288 | 289 | /* 290 | * UnsupportedDispatch 291 | * 292 | * Purpose: 293 | * 294 | * Unused IRP_MJ_* dispatch. 295 | * 296 | */ 297 | NTSTATUS UnsupportedDispatch( 298 | _In_ struct _DEVICE_OBJECT *DeviceObject, 299 | _Inout_ struct _IRP *Irp 300 | ) 301 | { 302 | UNREFERENCED_PARAMETER(DeviceObject); 303 | 304 | Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; 305 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 306 | return Irp->IoStatus.Status; 307 | } 308 | 309 | /* 310 | * CreateDispatch 311 | * 312 | * Purpose: 313 | * 314 | * IRP_MJ_CREATE dispatch. 315 | * 316 | */ 317 | NTSTATUS CreateDispatch( 318 | _In_ struct _DEVICE_OBJECT *DeviceObject, 319 | _Inout_ struct _IRP *Irp 320 | ) 321 | { 322 | UNREFERENCED_PARAMETER(DeviceObject); 323 | 324 | DbgPrint("[PGDemo] %s Create\n", __FUNCTION__); 325 | 326 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 327 | return Irp->IoStatus.Status; 328 | } 329 | 330 | /* 331 | * CloseDispatch 332 | * 333 | * Purpose: 334 | * 335 | * IRP_MJ_CLOSE dispatch. 336 | * 337 | */ 338 | NTSTATUS CloseDispatch( 339 | _In_ struct _DEVICE_OBJECT *DeviceObject, 340 | _Inout_ struct _IRP *Irp 341 | ) 342 | { 343 | UNREFERENCED_PARAMETER(DeviceObject); 344 | 345 | DbgPrint("[PGDemo] %s Close\n", __FUNCTION__); 346 | 347 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 348 | return Irp->IoStatus.Status; 349 | } 350 | 351 | /* 352 | * BeaconRoutine 353 | * 354 | * Purpose: 355 | * 356 | * Print alive message in infinite loop with a short delay. 357 | * 358 | */ 359 | VOID BeaconRoutine( 360 | _In_ PVOID StartContext 361 | ) 362 | { 363 | LARGE_INTEGER tm, time; 364 | TIME_FIELDS SystemTime; 365 | 366 | UNREFERENCED_PARAMETER(StartContext); 367 | 368 | tm.QuadPart = -10000000; 369 | 370 | do { 371 | KeDelayExecutionThread(KernelMode, FALSE, &tm); 372 | 373 | KeQuerySystemTime(&time); 374 | RtlTimeToTimeFields(&time, &SystemTime); 375 | 376 | DbgPrint("[PGDemo] Beacon %02hd:%02hd:%02hd:%03hd\n", 377 | SystemTime.Hour, 378 | SystemTime.Minute, 379 | SystemTime.Second, 380 | SystemTime.Milliseconds); 381 | 382 | } while (1); 383 | } 384 | 385 | /* 386 | * DriverEntry 387 | * 388 | * Purpose: 389 | * 390 | * Driver base entry point. 391 | * 392 | */ 393 | NTSTATUS DriverEntry( 394 | _In_ struct _DRIVER_OBJECT *DriverObject, 395 | _In_ PUNICODE_STRING RegistryPath 396 | ) 397 | { 398 | NTSTATUS status; 399 | HANDLE hThread; 400 | UNICODE_STRING SymLink, DevName; 401 | OBJECT_ATTRIBUTES Obja; 402 | PDEVICE_OBJECT devobj; 403 | ULONG t; 404 | 405 | UNREFERENCED_PARAMETER(RegistryPath); 406 | 407 | RtlSecureZeroMemory(&g_osver, sizeof(RTL_OSVERSIONINFOW)); 408 | g_osver.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW); 409 | if (NT_SUCCESS(RtlGetVersion(&g_osver))) { 410 | if (g_osver.dwBuildNumber <= 10240) { 411 | DbgPrint("[PGDemo] This version of Windows is out of interest."); 412 | return STATUS_NOT_SUPPORTED; 413 | } 414 | } 415 | else { 416 | return STATUS_INTERNAL_ERROR; 417 | } 418 | 419 | DbgPrint("[PGDemo] %s", __FUNCTION__); 420 | 421 | RtlInitUnicodeString(&DevName, L"\\Device\\PGDemo"); 422 | status = IoCreateDevice(DriverObject, 0, &DevName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, TRUE, &devobj); 423 | 424 | DbgPrint("[PGDemo] %s IoCreateDevice(%wZ) = %lx\n", __FUNCTION__, DevName, status); 425 | 426 | if (NT_SUCCESS(status)) { 427 | 428 | RtlInitUnicodeString(&SymLink, L"\\DosDevices\\PGDemo"); 429 | status = IoCreateSymbolicLink(&SymLink, &DevName); 430 | 431 | DbgPrint("[PGDemo] %s IoCreateSymbolicLink(%wZ) = %lx\n", __FUNCTION__, SymLink, status); 432 | 433 | devobj->Flags |= DO_BUFFERED_IO; 434 | 435 | for (t = 0; t <= IRP_MJ_MAXIMUM_FUNCTION; t++) 436 | DriverObject->MajorFunction[t] = &UnsupportedDispatch; 437 | 438 | DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = &DevioctlDispatch; 439 | DriverObject->MajorFunction[IRP_MJ_CREATE] = &CreateDispatch; 440 | DriverObject->MajorFunction[IRP_MJ_CLOSE] = &CloseDispatch; 441 | DriverObject->DriverUnload = NULL; 442 | 443 | hThread = NULL; 444 | InitializeObjectAttributes(&Obja, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); 445 | if (NT_SUCCESS(PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS, &Obja, NULL, NULL, 446 | (PKSTART_ROUTINE)BeaconRoutine, NULL))) 447 | { 448 | ZwClose(hThread); 449 | } 450 | } 451 | 452 | return status; 453 | } 454 | -------------------------------------------------------------------------------- /src/tests/BadRkDemo/drv/dummy/main.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2017 4 | * 5 | * TITLE: MAIN.H 6 | * 7 | * VERSION: 1.00 8 | * 9 | * DATE: 14 May 2017 10 | * 11 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 12 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 13 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 14 | * PARTICULAR PURPOSE. 15 | * 16 | *******************************************************************************/ 17 | 18 | #pragma once 19 | 20 | extern POBJECT_TYPE *IoDriverObjectType; 21 | 22 | NTKERNELAPI 23 | NTSTATUS 24 | ObReferenceObjectByName( 25 | __in PUNICODE_STRING ObjectName, 26 | __in ULONG Attributes, 27 | __in_opt PACCESS_STATE AccessState, 28 | __in_opt ACCESS_MASK DesiredAccess, 29 | __in POBJECT_TYPE ObjectType, 30 | __in KPROCESSOR_MODE AccessMode, 31 | __inout_opt PVOID ParseContext, 32 | __out PVOID *Object); 33 | 34 | _Dispatch_type_(IRP_MJ_DEVICE_CONTROL) 35 | DRIVER_DISPATCH DevioctlDispatch; 36 | _Dispatch_type_(IRP_MJ_CREATE) 37 | DRIVER_DISPATCH CreateDispatch; 38 | _Dispatch_type_(IRP_MJ_CLOSE) 39 | DRIVER_DISPATCH CloseDispatch; 40 | 41 | _Dispatch_type_(IRP_MJ_CREATE) 42 | _Dispatch_type_(IRP_MJ_CREATE_NAMED_PIPE) 43 | _Dispatch_type_(IRP_MJ_CLOSE) 44 | _Dispatch_type_(IRP_MJ_READ) 45 | _Dispatch_type_(IRP_MJ_WRITE) 46 | _Dispatch_type_(IRP_MJ_QUERY_INFORMATION) 47 | _Dispatch_type_(IRP_MJ_SET_INFORMATION) 48 | _Dispatch_type_(IRP_MJ_QUERY_EA) 49 | _Dispatch_type_(IRP_MJ_SET_EA) 50 | _Dispatch_type_(IRP_MJ_FLUSH_BUFFERS) 51 | _Dispatch_type_(IRP_MJ_QUERY_VOLUME_INFORMATION) 52 | _Dispatch_type_(IRP_MJ_SET_VOLUME_INFORMATION) 53 | _Dispatch_type_(IRP_MJ_DIRECTORY_CONTROL) 54 | _Dispatch_type_(IRP_MJ_FILE_SYSTEM_CONTROL) 55 | _Dispatch_type_(IRP_MJ_DEVICE_CONTROL) 56 | _Dispatch_type_(IRP_MJ_INTERNAL_DEVICE_CONTROL) 57 | _Dispatch_type_(IRP_MJ_SHUTDOWN) 58 | _Dispatch_type_(IRP_MJ_LOCK_CONTROL) 59 | _Dispatch_type_(IRP_MJ_CLEANUP) 60 | _Dispatch_type_(IRP_MJ_CREATE_MAILSLOT) 61 | _Dispatch_type_(IRP_MJ_QUERY_SECURITY) 62 | _Dispatch_type_(IRP_MJ_SET_SECURITY) 63 | _Dispatch_type_(IRP_MJ_POWER) 64 | _Dispatch_type_(IRP_MJ_SYSTEM_CONTROL) 65 | _Dispatch_type_(IRP_MJ_DEVICE_CHANGE) 66 | _Dispatch_type_(IRP_MJ_QUERY_QUOTA) 67 | _Dispatch_type_(IRP_MJ_SET_QUOTA) 68 | _Dispatch_type_(IRP_MJ_PNP) 69 | DRIVER_DISPATCH UnsupportedDispatch; 70 | 71 | DRIVER_INITIALIZE DriverInitialize; 72 | DRIVER_INITIALIZE DriverEntry; 73 | #pragma alloc_text(INIT, DriverEntry) 74 | 75 | typedef struct _KLDR_DATA_TABLE_ENTRY { 76 | LIST_ENTRY InLoadOrderLinks; 77 | PVOID ExceptionTable; 78 | ULONG ExceptionTableSize; 79 | // ULONG padding on IA64 80 | PVOID GpValue; 81 | PVOID NonPagedDebugInfo; 82 | PVOID DllBase; 83 | PVOID EntryPoint; 84 | ULONG SizeOfImage; 85 | UNICODE_STRING FullDllName; 86 | UNICODE_STRING BaseDllName; 87 | ULONG Flags; 88 | USHORT LoadCount; 89 | USHORT __Unused5; 90 | PVOID SectionPointer; 91 | ULONG CheckSum; 92 | // ULONG padding on IA64 93 | PVOID LoadedImports; 94 | PVOID PatchInformation; 95 | } KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY; 96 | 97 | #define PGDEMO_SET_TEST_TYPE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0800, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 98 | 99 | #define TT_DRIVER_LIST 0 100 | #define TT_CR4 1 101 | #define TT_DRIVER_OBJECT 2 102 | #define TT_NOTIFY_CALLOUT 3 103 | 104 | typedef struct _INOUT_PARAM { 105 | ULONG TestType; 106 | } INOUT_PARAM, *PINOUTPARAM; 107 | --------------------------------------------------------------------------------