├── HideMemory.cpp ├── HideMemory.h ├── README.md ├── Virtualization.cpp ├── Virtualization.sln ├── Virtualization.vcxproj ├── Virtualization.vcxproj.filters ├── Virtualization.vcxproj.user ├── globals.cpp └── globals.h /HideMemory.cpp: -------------------------------------------------------------------------------- 1 | #include "globals.h" 2 | #include "HideMemory.h" 3 | 4 | std::vectorPagesOfNoAccessOfData; 5 | 6 | //只想读写的话可以打开这个锁 7 | std::mutex m; 8 | 9 | //DeFault Encrypt/Decrypt 10 | void EncryptData(DWORD64 lpAddress, size_t size) 11 | { 12 | for (int i = 0; i < size; i++) 13 | { 14 | ((char*)lpAddress)[i] = ((char*)lpAddress)[i] ^ 'b'; 15 | } 16 | } 17 | 18 | LONG NTAPI VehExceptionHandler(EXCEPTION_POINTERS* ExceptionInfo) 19 | { 20 | DWORD OldProtect = 0; 21 | if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) 22 | { 23 | for (auto it = PagesOfNoAccessOfData.begin(); it != PagesOfNoAccessOfData.end(); it++) 24 | { 25 | if (ExceptionInfo->ExceptionRecord->ExceptionInformation[1] <= (*it).lpAddress + (*it).dwSize && 26 | ExceptionInfo->ExceptionRecord->ExceptionInformation[1] >= (*it).lpAddress) 27 | { 28 | m.lock(); 29 | //Restore Page Protection and Decrypt 30 | (*it).Protected = FALSE;//Not Protected 31 | VirtualProtect((LPVOID)(*it).lpAddress, (*it).dwSize, PAGE_EXECUTE_READWRITE, &OldProtect); 32 | 33 | if ((*it).Decrypt) 34 | (*it).Decrypt((*it).lpAddress, (*it).dwSize); 35 | else 36 | EncryptData((*it).lpAddress, (*it).dwSize);//Decrypt 37 | 38 | ExceptionInfo->ContextRecord->EFlags |= 0x100;//Do a single step 39 | return EXCEPTION_CONTINUE_EXECUTION; 40 | 41 | } 42 | } 43 | 44 | } 45 | 46 | if (ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP) 47 | { 48 | for (auto it = PagesOfNoAccessOfData.begin(); it != PagesOfNoAccessOfData.end(); it++) 49 | { 50 | if ((*it).Protected == FALSE) 51 | { 52 | if ((*it).Encrypt) 53 | (*it).Encrypt((*it).lpAddress, (*it).dwSize); 54 | else 55 | EncryptData((*it).lpAddress, (*it).dwSize);//加密 56 | 57 | VirtualProtect((LPVOID)(*it).lpAddress, (*it).dwSize, PAGE_NOACCESS, &OldProtect); 58 | m.unlock(); 59 | return EXCEPTION_CONTINUE_EXECUTION; 60 | } 61 | } 62 | } 63 | 64 | return EXCEPTION_CONTINUE_SEARCH; 65 | 66 | } 67 | 68 | BOOL Init() 69 | { 70 | return AddVectoredExceptionHandler(TRUE, VehExceptionHandler) == NULL ? FALSE : TRUE; 71 | } 72 | 73 | DWORD64 AllocateHiddenMemory(LPVOID lpAddress, SIZE_T dwSize,ENCRYPTDATAPROC Encrypt, DECRYPTDATAPROC Decrypt) 74 | { 75 | PVOID allocated = VirtualAlloc(lpAddress, dwSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 76 | if (allocated != NULL) 77 | { 78 | DWORD OldProtect = 0; 79 | dwSize = ((dwSize-1) & 0xfffffffffffff000) + 0x1000;//size是0 就走不到这里 80 | 81 | PROTECTEDMEMORY protected_mem = { 0 }; 82 | protected_mem.lpAddress = (DWORD64)allocated; 83 | protected_mem.dwSize = dwSize; 84 | protected_mem.ExecutingProtection = FALSE; 85 | protected_mem.Protected = TRUE; 86 | protected_mem.Encrypt = Encrypt; 87 | protected_mem.Decrypt = Decrypt; 88 | 89 | 90 | if(!Encrypt) 91 | EncryptData((DWORD64)allocated, dwSize); 92 | else 93 | Encrypt((DWORD64)allocated, dwSize); 94 | 95 | PagesOfNoAccessOfData.push_back(protected_mem); 96 | 97 | VirtualProtect(allocated, dwSize, PAGE_NOACCESS, &OldProtect); 98 | } 99 | 100 | return (DWORD64)allocated; 101 | } 102 | 103 | BOOL FreeHiddenMemory(DWORD64 lpAddress) 104 | { 105 | for (auto it = PagesOfNoAccessOfData.begin(); it != PagesOfNoAccessOfData.end(); it++) 106 | { 107 | if ((*it).lpAddress == lpAddress) 108 | { 109 | PagesOfNoAccessOfData.erase(it); 110 | return VirtualFree((LPVOID)lpAddress, 0, MEM_RELEASE); 111 | } 112 | } 113 | return FALSE; 114 | } 115 | -------------------------------------------------------------------------------- /HideMemory.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1401199262/MemoryVirtualization/1e067e5ed921e63dc6e8b27c241ab696c460f958/HideMemory.h -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MemoryVirtualization 2 | 3 | 利用VEH和PAGE_NOACCESS,在应用层隐藏一块内存 4 | x64 编译通过 5 | -------------------------------------------------------------------------------- /Virtualization.cpp: -------------------------------------------------------------------------------- 1 | #include "globals.h" 2 | #include "HideMemory.h" 3 | 4 | DWORD64 hidemem; 5 | 6 | //如果只想读写的话可以删除这个锁,并打开在VEH处理函数内的锁, 要执行的话可能会在执行时触发双重异常,所以在这里加锁 7 | //std::mutex m; 8 | 9 | typedef NTSTATUS (NTAPI* _NtClose)(IN HANDLE ObjectHandle); 10 | typedef NTSTATUS (NTAPI* _NtReadVirtualMemory)(HANDLE ProcessHandle,PVOID BaseAddress,PVOID Buffer,ULONG NumberOfBytesToRead,PULONG NumberOfBytesReaded); 11 | 12 | #define STATUS_SUCCESS ((NTSTATUS)0x00000000L) 13 | #define STATUS_INVALID_HANDLE ((NTSTATUS)0xC0000008L) 14 | 15 | BOOL CheckSEH() 16 | { 17 | __try 18 | { 19 | std::cout << **(DWORD64**)hidemem << std::endl; 20 | } 21 | __except (1) 22 | { 23 | return TRUE; 24 | } 25 | return FALSE; 26 | } 27 | 28 | //BOOL ExecuteHiddenMemory() 29 | //{ 30 | // //todo test long jump 31 | // 32 | // 33 | // auto ntdll = GetModuleHandle(L"ntdll.dll"); 34 | // //auto NtClose = GetProcAddress(ntdll, "NtClose"); 35 | // auto NtReadVirtualMemory = GetProcAddress(ntdll, "NtReadVirtualMemory"); 36 | // 37 | // auto NtReadVirtualMemory_index = *(LONG*)((DWORD64)NtReadVirtualMemory + 4); 38 | // 39 | // char NtReadShell[0x50] = { 0 }; 40 | // *(UINT*)(NtReadShell) = 0xB8D18B4C; //mov r10,rcx mov eax, 41 | // *(UINT*)(NtReadShell + 4) = NtReadVirtualMemory_index; // index 42 | // *(USHORT*)(NtReadShell + 8) = (USHORT)0x050F; //syscall 43 | // *(UCHAR*)(NtReadShell + 10) = (UCHAR)0xC3; //ret 44 | // memcpy((PVOID)(hidemem + 0x10), NtReadShell, 0x50); 45 | // 46 | // auto hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, GetCurrentProcessId()); 47 | // char Buf[0x27] = { 0 }; 48 | // 49 | // if (((_NtReadVirtualMemory)(hidemem + 0x10))(hProcess, (PVOID)((DWORD64)ntdll + 0x4E), Buf, 0x26, 0) == STATUS_SUCCESS) 50 | // { 51 | // if (strcmp(Buf, "This program cannot be run in DOS mode") == 0)//Should Be this. 52 | // { 53 | // CloseHandle(hProcess); 54 | // return TRUE; 55 | // } 56 | // } 57 | // CloseHandle(hProcess); 58 | // return FALSE; 59 | //} 60 | 61 | BOOL IsMemoryHidden() 62 | { 63 | MEMORY_BASIC_INFORMATION MemInfo = { 0 }; 64 | VirtualQuery((LPVOID)hidemem, &MemInfo, sizeof(MemInfo)); 65 | if (MemInfo.Protect != PAGE_NOACCESS) 66 | { 67 | return FALSE; 68 | } 69 | return TRUE; 70 | } 71 | 72 | void ReadThreadProc2() 73 | { 74 | while (1) 75 | { 76 | ULONGLONG tick = GetTickCount64(); 77 | //m.lock(); 78 | printf("Thread2 ReadTime %llu ms Data:%llx\n", GetTickCount64() - tick, *(DWORD64*)hidemem); 79 | //m.unlock(); 80 | Sleep(100); 81 | } 82 | } 83 | 84 | void ReadThreadProc3() 85 | { 86 | while (1) 87 | { 88 | ULONGLONG tick = GetTickCount64(); 89 | //m.lock(); 90 | printf("Thread3 ReadTime %llu ms Data:%llx\n", GetTickCount64() - tick, *(DWORD64*)hidemem); 91 | //m.unlock(); 92 | Sleep(100); 93 | } 94 | } 95 | 96 | 97 | int main() 98 | { 99 | WCHAR title[64]; 100 | _snwprintf_s(title, sizeof(title), L"PID: %lx", GetCurrentProcessId()); 101 | SetConsoleTitleW(title); 102 | 103 | Init(); 104 | hidemem = AllocateHiddenMemory(NULL, 1, 105 | [](DWORD64 lpAddress, size_t _Size) { 106 | for (int i = 0; i < _Size; i++) 107 | { 108 | ((char*)lpAddress)[i] += (char)6; 109 | ((char*)lpAddress)[i] = ((char*)lpAddress)[i] ^ 'a'; 110 | } 111 | }, 112 | [](DWORD64 lpAddress, size_t _Size) { 113 | for (int i = 0; i < _Size; i++) 114 | { 115 | ((char*)lpAddress)[i] = ((char*)lpAddress)[i] ^ 'a'; 116 | ((char*)lpAddress)[i] -= (char)6; 117 | } 118 | }); 119 | 120 | std::thread ReadThread1(ReadThreadProc2); 121 | std::thread ReadThread2(ReadThreadProc3); 122 | 123 | //BOOL MessageBoxState = TRUE; 124 | 125 | while (1) 126 | { 127 | printf("Allocated %llx\n\n", hidemem); 128 | 129 | ULONGLONG tick = GetTickCount64(); 130 | 131 | //R/W ========================================================================================== 132 | //m.lock(); 133 | *(DWORD64*)hidemem += 1; 134 | printf("ReadWriteTime %llu ms Data:%llx\n", GetTickCount64() - tick, *(DWORD64*)hidemem); 135 | //m.unlock(); 136 | //R/W ========================================================================================== 137 | 138 | //Execute ======================================================================================= 139 | //tick = GetTickCount64(); 请查看当前文件头部的锁 140 | //m.lock(); 141 | //if (ExecuteHiddenMemory()) 142 | // printf("ExecuteTime %llu ms \n", GetTickCount64() - tick); 143 | //else 144 | // printf("Execute Failed\n"); 145 | //m.unlock(); 146 | //Execute ======================================================================================= 147 | 148 | 149 | //SEH =========================================================================================== 150 | tick = GetTickCount64(); 151 | //m.lock(); 152 | if(CheckSEH()) 153 | printf("Support SEH %llu ms\n", GetTickCount64() - tick); 154 | //m.unlock(); 155 | //SEH =========================================================================================== 156 | 157 | Sleep(200); 158 | system("cls"); 159 | } 160 | 161 | END: 162 | //m.lock(); 163 | FreeHiddenMemory(hidemem); 164 | //m.unlock(); 165 | } 166 | 167 | -------------------------------------------------------------------------------- /Virtualization.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31702.278 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Virtualization", "Virtualization.vcxproj", "{A185A0BF-3D9C-4025-8FD1-B120F77A5F36}" 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 | {A185A0BF-3D9C-4025-8FD1-B120F77A5F36}.Debug|x64.ActiveCfg = Debug|x64 17 | {A185A0BF-3D9C-4025-8FD1-B120F77A5F36}.Debug|x64.Build.0 = Debug|x64 18 | {A185A0BF-3D9C-4025-8FD1-B120F77A5F36}.Debug|x86.ActiveCfg = Debug|Win32 19 | {A185A0BF-3D9C-4025-8FD1-B120F77A5F36}.Debug|x86.Build.0 = Debug|Win32 20 | {A185A0BF-3D9C-4025-8FD1-B120F77A5F36}.Release|x64.ActiveCfg = Release|x64 21 | {A185A0BF-3D9C-4025-8FD1-B120F77A5F36}.Release|x64.Build.0 = Release|x64 22 | {A185A0BF-3D9C-4025-8FD1-B120F77A5F36}.Release|x86.ActiveCfg = Release|Win32 23 | {A185A0BF-3D9C-4025-8FD1-B120F77A5F36}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {D1B1D528-F2EC-4748-A787-9EB6B1DAB927} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /Virtualization.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 | {a185a0bf-3d9c-4025-8fd1-b120f77a5f36} 25 | Virtualization 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 | false 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 | true 118 | MultiThreadedDebug 119 | ..\dependencies\zydis-3.2.1\dependencies\zycore\include;..\dependencies\zydis-3.2.1\include;..\dependencies\zydis-3.2.1\msvc;%(AdditionalIncludeDirectories) 120 | stdcpp17 121 | 122 | 123 | Console 124 | true 125 | Zycore.lib;Zydis.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 126 | ..\dependencies\zydis-3.2.1\msvc\bin\DebugX64\ 127 | 128 | 129 | 130 | 131 | Level3 132 | true 133 | true 134 | true 135 | true 136 | MultiThreaded 137 | ..\dependencies\zydis-3.2.1\dependencies\zycore\include;..\dependencies\zydis-3.2.1\include;..\dependencies\zydis-3.2.1\msvc;%(AdditionalIncludeDirectories) 138 | stdcpp17 139 | 140 | 141 | Console 142 | true 143 | true 144 | true 145 | Zycore.lib;Zydis.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 146 | ..\dependencies\zydis-3.2.1\msvc\bin\ReleaseX64;%(AdditionalLibraryDirectories) 147 | /NOVCFEATURE /NOCOFFGRPINFO %(AdditionalOptions) 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /Virtualization.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 | {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 | 源文件 20 | 21 | 22 | 资源文件 23 | 24 | 25 | 源文件 26 | 27 | 28 | 29 | 30 | 资源文件 31 | 32 | 33 | 头文件 34 | 35 | 36 | -------------------------------------------------------------------------------- /Virtualization.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /globals.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1401199262/MemoryVirtualization/1e067e5ed921e63dc6e8b27c241ab696c460f958/globals.cpp -------------------------------------------------------------------------------- /globals.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | std::vector split(const std::string& s, char delim); 20 | std::string extract(std::string& values, int index, char delim ); 21 | 22 | std::wstring to_wide_string(const std::string& input); 23 | std::string to_byte_string(const std::wstring& input); 24 | --------------------------------------------------------------------------------