├── NO_ACESS Protect.sln ├── NO_ACESS Protect ├── NO_ACESS Protect.sln ├── NO_ACESS Protect.vcxproj ├── NO_ACESS Protect.vcxproj.filters ├── NO_ACESS Protect.vcxproj.user ├── main.cpp ├── protect.cpp └── protect.h └── README.md /NO_ACESS Protect.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31729.503 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NO_ACESS Protect", "NO_ACESS Protect\NO_ACESS Protect.vcxproj", "{3D446505-97BA-4EFF-ABD1-D51559CAE0BA}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {3D446505-97BA-4EFF-ABD1-D51559CAE0BA}.Debug|x64.ActiveCfg = Debug|x64 17 | {3D446505-97BA-4EFF-ABD1-D51559CAE0BA}.Debug|x64.Build.0 = Debug|x64 18 | {3D446505-97BA-4EFF-ABD1-D51559CAE0BA}.Debug|x86.ActiveCfg = Debug|Win32 19 | {3D446505-97BA-4EFF-ABD1-D51559CAE0BA}.Debug|x86.Build.0 = Debug|Win32 20 | {3D446505-97BA-4EFF-ABD1-D51559CAE0BA}.Release|x64.ActiveCfg = Release|x64 21 | {3D446505-97BA-4EFF-ABD1-D51559CAE0BA}.Release|x64.Build.0 = Release|x64 22 | {3D446505-97BA-4EFF-ABD1-D51559CAE0BA}.Release|x86.ActiveCfg = Release|Win32 23 | {3D446505-97BA-4EFF-ABD1-D51559CAE0BA}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {B6F7060D-B896-4850-912C-32B6C17AFBC1} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /NO_ACESS Protect/NO_ACESS Protect.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31729.503 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NO_ACESS Protect", "NO_ACESS Protect\NO_ACESS Protect.vcxproj", "{3D446505-97BA-4EFF-ABD1-D51559CAE0BA}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {3D446505-97BA-4EFF-ABD1-D51559CAE0BA}.Debug|x64.ActiveCfg = Debug|x64 17 | {3D446505-97BA-4EFF-ABD1-D51559CAE0BA}.Debug|x64.Build.0 = Debug|x64 18 | {3D446505-97BA-4EFF-ABD1-D51559CAE0BA}.Debug|x86.ActiveCfg = Debug|Win32 19 | {3D446505-97BA-4EFF-ABD1-D51559CAE0BA}.Debug|x86.Build.0 = Debug|Win32 20 | {3D446505-97BA-4EFF-ABD1-D51559CAE0BA}.Release|x64.ActiveCfg = Release|x64 21 | {3D446505-97BA-4EFF-ABD1-D51559CAE0BA}.Release|x64.Build.0 = Release|x64 22 | {3D446505-97BA-4EFF-ABD1-D51559CAE0BA}.Release|x86.ActiveCfg = Release|Win32 23 | {3D446505-97BA-4EFF-ABD1-D51559CAE0BA}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {B6F7060D-B896-4850-912C-32B6C17AFBC1} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /NO_ACESS Protect/NO_ACESS Protect.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 | 16.0 23 | Win32Proj 24 | {3d446505-97ba-4eff-abd1-d51559cae0ba} 25 | NOACESSProtect 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | false 78 | 79 | 80 | true 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Level3 88 | true 89 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 90 | true 91 | 92 | 93 | Console 94 | true 95 | 96 | 97 | 98 | 99 | Level3 100 | true 101 | true 102 | true 103 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 104 | true 105 | 106 | 107 | Console 108 | true 109 | true 110 | true 111 | 112 | 113 | 114 | 115 | Level3 116 | true 117 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 118 | true 119 | 120 | 121 | Console 122 | true 123 | 124 | 125 | 126 | 127 | Level3 128 | true 129 | true 130 | true 131 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 132 | true 133 | false 134 | 135 | 136 | Console 137 | true 138 | true 139 | true 140 | /LTCG /OPT:NOREF %(AdditionalOptions) 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /NO_ACESS Protect/NO_ACESS Protect.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {dea67bd7-5c4e-41e4-ad19-f31b54f1d1a4} 14 | 15 | 16 | 17 | 18 | Quelldateien 19 | 20 | 21 | Headerdateien\protect 22 | 23 | 24 | 25 | 26 | Headerdateien\protect 27 | 28 | 29 | -------------------------------------------------------------------------------- /NO_ACESS Protect/NO_ACESS Protect.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /NO_ACESS Protect/main.cpp: -------------------------------------------------------------------------------- 1 | #include "protect.h" 2 | 3 | int main() { 4 | protect::initialize(); 5 | /* 6 | main code 7 | */ 8 | system("pause"); 9 | } -------------------------------------------------------------------------------- /NO_ACESS Protect/protect.cpp: -------------------------------------------------------------------------------- 1 | #include "protect.h" 2 | 3 | 4 | void test_func() { 5 | printf("HELLO FROM .text func!\n"); 6 | } 7 | 8 | #pragma optimize("", off) //Disable it so it doesn't get inlined 9 | #pragma section(".0dev", execute, read, write) //Write so we can erase encryption func 10 | #pragma comment(linker,"/SECTION:.0dev,ERW") 11 | #pragma code_seg(push, ".0dev") 12 | 13 | uint8_t encryption_key; 14 | 15 | PIMAGE_SECTION_HEADER get_section_by_name(const char* name) { 16 | uint64_t modulebase = (uint64_t)GetModuleHandleA(0); 17 | PIMAGE_NT_HEADERS64 nt = (PIMAGE_NT_HEADERS)(modulebase + ((PIMAGE_DOS_HEADER)modulebase)->e_lfanew); 18 | PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(nt); 19 | for (int i = 0; i < nt->FileHeader.NumberOfSections; ++i, ++section) { 20 | if (!_stricmp((char*)section->Name, name)) 21 | return section; 22 | } 23 | return nullptr; 24 | } 25 | 26 | void encrypt_section(PIMAGE_SECTION_HEADER section) { 27 | uint64_t modulebase = (uint64_t)GetModuleHandleA(0); 28 | int valid_page_count = section->Misc.VirtualSize / 0x1000; //If section is smaller than page size skip it 29 | for (int page_idx = 0; page_idx < valid_page_count; page_idx++) 30 | { 31 | uintptr_t address = modulebase + section->VirtualAddress + page_idx * 0x1000; 32 | printf("Encrypted: %p\n", address); 33 | DWORD old; 34 | VirtualProtect((LPVOID)address, 0x1000, PAGE_EXECUTE_READWRITE, &old); 35 | for (int off = 0; off < 0x1000; off += 0x1) { 36 | *(BYTE*)(address + off) = _rotr8((*(BYTE*)(address + off) + 0x10) ^ encryption_key, 69); 37 | } 38 | VirtualProtect((LPVOID)address, 0x1000, PAGE_NOACCESS, &old); 39 | } 40 | } 41 | 42 | bool rip_in_legit_module(uint64_t rip) { 43 | PPEB peb = (PPEB)__readgsqword(0x60); 44 | PPEB_LDR_DATA ldr = peb->Ldr; 45 | PLDR_DATA_TABLE_ENTRY module = NULL; 46 | PLIST_ENTRY list = ldr->InMemoryOrderModuleList.Flink; 47 | while (list != NULL && list != &ldr->InMemoryOrderModuleList) { 48 | module = CONTAINING_RECORD(list, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks); 49 | PIMAGE_NT_HEADERS nt = (PIMAGE_NT_HEADERS)((uint64_t)module->DllBase + ((PIMAGE_DOS_HEADER)module->DllBase)->e_lfanew); 50 | if ((rip >= (uint64_t)module->DllBase) && (rip <= (uint64_t)module->DllBase + nt->OptionalHeader.SizeOfImage)) 51 | { 52 | return true; 53 | } 54 | list = list->Flink; 55 | } 56 | return false; 57 | } 58 | 59 | LONG WINAPI handler(struct _EXCEPTION_POINTERS* ExceptionInfo) { 60 | if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) { 61 | DWORD old; 62 | //ExceptionInformation[1] holds the invalid referenced memory address 63 | uint64_t page_start = (uint64_t)ExceptionInfo->ExceptionRecord->ExceptionInformation[1]; 64 | page_start = page_start - (page_start % 0x1000); 65 | //Before we decrypt our page we want to verify the RIP that caused the violation. If it's not valid someone trys to forcefully decrypt the pages 66 | if (!rip_in_legit_module(ExceptionInfo->ContextRecord->Rip)) 67 | return EXCEPTION_CONTINUE_SEARCH; //Force crash the program 68 | VirtualProtect((LPVOID)page_start, 0x1000, PAGE_READWRITE, &old);//Set write protection to decrypt 69 | for (int off = 0; off < 0x1000; off += 0x1) { 70 | *(BYTE*)(page_start + off) = (_rotl8(*(BYTE*)(page_start + off),69) ^ encryption_key) - 0x10; 71 | } 72 | VirtualProtect((LPVOID)page_start, 0x1000, PAGE_EXECUTE_READ, &old);//Set original protection 73 | printf("Decrypted %p rip %p\n", page_start, ExceptionInfo->ContextRecord->Rip); 74 | return EXCEPTION_CONTINUE_EXECUTION; 75 | } 76 | return EXCEPTION_CONTINUE_SEARCH; 77 | } 78 | 79 | 80 | 81 | 82 | void protect::initialize() { 83 | srand(time(NULL)); 84 | encryption_key = rand() % 255 + 1; //Generate a small decryption key 85 | AddVectoredExceptionHandler(1, handler); //Handler will handle decryption and access rights 86 | encrypt_section(get_section_by_name(".text")); 87 | //We won't use memset since this will unnecessarily decrypt a page 88 | for (int i = 0; i < (uint64_t)rip_in_legit_module - (uint64_t)encrypt_section; i+= 0x1) { 89 | *(uint8_t*)((uint64_t)encrypt_section + i) = 0; 90 | } 91 | //Tests 1: Dereference an address that has NO_ACCESS 92 | printf("%x\n", *(BYTE*)(test_func)); 93 | //Tests 2: Call a func that in a NO_ACCESS region 94 | test_func(); 95 | system("pause"); 96 | } 97 | #pragma code_seg(pop, ".0dev") 98 | #pragma optimize("", on) 99 | -------------------------------------------------------------------------------- /NO_ACESS Protect/protect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | namespace protect { 7 | void initialize(); 8 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NO_ACCESS_Protection 2 | This is a technique that I found while reversing Halos anticheat. They encrypt the text section and set the protection to NO_ACCESS. The pages will be decrypted on first access. If the RIP, that referenced the memory, is outside of a valid module it will fail and will crash the process after some time. 3 | With this they can prevent: 4 | - basic signature scanning (access violation + rip check) 5 | - cheat engine veh debugger 6 | - full process dumping (since you can encrypt the pages again) 7 | --------------------------------------------------------------------------------