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