diff --git a/demo/gdrv/driver/gdrv.sys b/demo/gdrv/driver/gdrv.sys new file mode 100644 index 0000000..2d28866 Binary files /dev/null and b/demo/gdrv/driver/gdrv.sys differ diff --git a/demo/hello-world.sys b/demo/gdrv/hello-world.sys similarity index 100% rename from demo/hello-world.sys rename to demo/gdrv/hello-world.sys diff --git a/demo/gdrv/physmeme.exe b/demo/gdrv/physmeme.exe new file mode 100644 index 0000000..bd9809d Binary files /dev/null and b/demo/gdrv/physmeme.exe differ diff --git a/demo/gdrv/physmeme.hpp b/demo/gdrv/physmeme.hpp new file mode 100644 index 0000000..5fbad1d --- /dev/null +++ b/demo/gdrv/physmeme.hpp @@ -0,0 +1,161 @@ +#pragma once +#include +#include +#include +#include +#include +#include + +#pragma pack ( push, 1 ) +typedef struct _GIOMAP +{ + unsigned long interface_type; + unsigned long bus; + uintptr_t physical_address; + unsigned long io_space; + unsigned long size; +} GIOMAP; +#pragma pack ( pop ) + +static const char* driver_name = "gdrv"; +static const char* driver_path = (std::filesystem::current_path().string() + "\\driver\\gdrv.sys").c_str(); + +namespace physmeme +{ + //--- ranges of physical memory + static std::map pmem_ranges; + + //--- validates the address + static bool is_valid(std::uintptr_t addr) + { + for (auto range : pmem_ranges) + if (addr >= range.first && addr <= range.first + range.second) + return true; + return false; + } + + // Author: Remy Lebeau + // taken from here: https://stackoverflow.com/questions/48485364/read-reg-resource-list-memory-values-incorrect-value + static const auto init_ranges = ([&]() -> bool + { + HKEY h_key; + DWORD type, size; + LPBYTE data; + RegOpenKeyEx(HKEY_LOCAL_MACHINE, "HARDWARE\\RESOURCEMAP\\System Resources\\Physical Memory", 0, KEY_READ, &h_key); + RegQueryValueEx(h_key, ".Translated", NULL, &type, NULL, &size); //get size + data = new BYTE[size]; + RegQueryValueEx(h_key, ".Translated", NULL, &type, data, &size); + DWORD count = *(DWORD*)(data + 16); + auto pmi = data + 24; + for (int dwIndex = 0; dwIndex < count; dwIndex++) + { + pmem_ranges.emplace(*(uint64_t*)(pmi + 0), *(uint64_t*)(pmi + 8)); + pmi += 20; + } + delete[] data; + RegCloseKey(h_key); + return true; + })(); + + /* + please code this function depending on your method of physical read/write. +*/ + static HANDLE load_drv() + { + const SC_HANDLE manager = OpenSCManager(nullptr, nullptr, SC_MANAGER_CREATE_SERVICE); + + if (!manager) + return false; + + SC_HANDLE service_handle = CreateService(manager, + driver_name, + driver_name, + SERVICE_START | SERVICE_STOP | DELETE, SERVICE_KERNEL_DRIVER, + SERVICE_DEMAND_START, + SERVICE_ERROR_IGNORE, + driver_path, nullptr, nullptr, nullptr, nullptr, nullptr); + + if (!service_handle) + service_handle = OpenService(manager, driver_name, SERVICE_START); + + if (!service_handle) + { + CloseServiceHandle(manager); + return false; + } + + bool result = StartService(service_handle, 0, nullptr); + + if (!result) + printf("[-] failed to start service, last_error=%d\n", GetLastError()); + + CloseServiceHandle(service_handle); + CloseServiceHandle(manager); + + auto handle = CreateFile("\\\\.\\GIO", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + std::cout << "[+] service started, handle: " << handle << std::endl; + return handle; + } + + inline HANDLE drv_handle = load_drv(); + + /* + please code this function depending on your method of physical read/write. + */ + static bool unload_drv() + { + const SC_HANDLE manager = OpenSCManager(nullptr, nullptr, SC_MANAGER_CREATE_SERVICE); + + if (!manager) + return false; + + const SC_HANDLE service_handle = OpenService(manager, driver_name, SERVICE_STOP | DELETE); + if (!service_handle) + { + CloseServiceHandle(manager); + return false; + } + + SERVICE_STATUS status = { 0 }; + bool result = ControlService(service_handle, SERVICE_CONTROL_STOP, &status); + + DeleteService(service_handle); + CloseServiceHandle(service_handle); + CloseServiceHandle(manager); + return result; + } + + /* + please code this function depending on your method of physical read/write. + */ + static std::uintptr_t map_phys( + std::uintptr_t addr, + std::size_t size + ) + { + GIOMAP in_buffer = { 0, 0, addr, 0, size }; + uintptr_t out_buffer[2] = { 0 }; + unsigned long returned = 0; + DeviceIoControl(drv_handle, 0xC3502004, reinterpret_cast(&in_buffer), sizeof(in_buffer), + reinterpret_cast(out_buffer), sizeof(out_buffer), &returned, NULL); + return out_buffer[0]; + } + + /* + please code this function depending on your method of physical read/write. + */ + static bool unmap_phys( + std::uintptr_t addr, + std::size_t size + ) + { + uintptr_t in_buffer = addr; + uintptr_t out_buffer[2] = { 0 }; + + unsigned long returned = 0; + DeviceIoControl(drv_handle, 0xC3502008, reinterpret_cast(&in_buffer), sizeof(in_buffer), + reinterpret_cast(out_buffer), sizeof(out_buffer), &returned, NULL); + + return out_buffer[0]; + } +} \ No newline at end of file diff --git a/demo/README.md b/demo/supermicro/README.md similarity index 100% rename from demo/README.md rename to demo/supermicro/README.md diff --git a/demo/supermicro/hello-world.sys b/demo/supermicro/hello-world.sys new file mode 100644 index 0000000..7f2301f Binary files /dev/null and b/demo/supermicro/hello-world.sys differ diff --git a/demo/phymem64.sys b/demo/supermicro/phymem64.sys similarity index 100% rename from demo/phymem64.sys rename to demo/supermicro/phymem64.sys diff --git a/demo/physmeme.exe b/demo/supermicro/physmeme.exe similarity index 100% rename from demo/physmeme.exe rename to demo/supermicro/physmeme.exe diff --git a/demo/pmdll64.dll b/demo/supermicro/pmdll64.dll similarity index 100% rename from demo/pmdll64.dll rename to demo/supermicro/pmdll64.dll