金币830
积分1476
注册时间2019-5-11
最后登录2024-9-29
|
仅适用于1803及以下的Windows版本。
使用的函数是MmMapIoSpace。
用法:
- // cr3 (system) can be: 0x1AA000, 0x1AB000, 0x1AC000, 0x1AD000
- // you will bsod if you enter wrong cr3
-
- // init
- auto bypass = new PhysicalMemory(get_system_eprocess(), 0x1AA000);
-
- if (!bypass->is_initialized())
- {
- bypass->unload();
- delete bypass;
- return;
- }
- if (!bypass->find_eprocess(1337)) //enter pid here
- {
- bypass->unload();
- delete bypass;
- return;
- }
- if (!bypass->find_base_address("1337.exe") //enter module name here
- {
- bypass->unload();
- delete bypass;
- return;
- }
-
- // reading
- uintptr_t buffer;
- if (!bypass->read(0xADDRESS, &buffer))
- {
- error...
- }
-
- // writing
- uintptr_t buffer = 0x1337;
- if (!bypass->write(0xADDRESS, &buffer))
- {
- error...
- }
-
- //get base addr obtained earlier
- uintptr_t base_addr = bypass->get_base_address();
复制代码
源:
- uint64_t get_system_eprocess()
- {
- typedef struct _SYSTEM_HANDLE {
- ULONG ProcessId;
- UCHAR ObjectTypeNumber;
- UCHAR Flags;
- USHORT Handle;
- PVOID Object;
- ACCESS_MASK GrantedAccess;
- } SYSTEM_HANDLE, *PSYSTEM_HANDLE;
- typedef struct _SYSTEM_HANDLE_INFORMATION {
- ULONG HandleCount; // Or NumberOfHandles if you prefer
- SYSTEM_HANDLE Handles[1];
- } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
-
- NTSTATUS status;
- ULONG handleInfoSize = 0x10000;
- auto handleInfo = reinterpret_cast<PSYSTEM_HANDLE_INFORMATION>(malloc(handleInfoSize));
-
- while ((status = NtQuerySystemInformation(static_cast<SYSTEM_INFORMATION_CLASS>(16), handleInfo, handleInfoSize, nullptr)) == (NTSTATUS)0xC0000004L)
- handleInfo = reinterpret_cast<PSYSTEM_HANDLE_INFORMATION>(realloc(handleInfo, handleInfoSize *= 2));
-
- if (!NT_SUCCESS(status)) return 0;
-
- for (auto i = 0; i < handleInfo->HandleCount; i++)
- {
- auto handle = handleInfo->Handles[i];
-
- if (handle.ObjectTypeNumber == 7 && handle.ProcessId == 4)
- return reinterpret_cast<uint64_t>(handle.Object);
- }
- }
-
- namespace dynamic_data
- {
- uint32_t offset_directorytable;
- uint32_t offset_process_id;
- uint32_t offset_process_links;
- uint32_t offset_object_table;
- uint32_t offset_peb;
-
- bool get_dynamic_data()
- {
- //hard coded for 1709 only!!!
- offset_directorytable = 0x28;
- offset_process_id = 0x2E0;
- offset_process_links = 0x2E8;
- offset_object_table = 0x418;
- offset_peb = 0x3F8;
-
- return true;
- }
- }
-
- class CoreTempDriver
- {
- #define CTL_READ_PHYSICAL_ADDRESS 0x9C402618
- #define CTL_WRITE_PHYSICAL_ADDRESS 0x9C40261C
-
- public:
- CoreTempDriver::CoreTempDriver(const std::string& service) : _service_name(service),
- _driver(CreateFileA(service.c_str(), 0xC0000000, 0,
- NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL))
- {
- if (_driver != INVALID_HANDLE_VALUE)
- _initialized = true;
- }
- CoreTempDriver::~CoreTempDriver()
- {
- CloseHandle(_driver);
- }
- bool is_initialized()
- {
- return _initialized;
- }
- bool unload()
- {
- auto hManager = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
- if (!hManager) return false;
-
- auto hService = OpenServiceA(hManager, _service_name.c_str(), SERVICE_ALL_ACCESS);
- if (!hService)
- {
- CloseServiceHandle(hManager);
- return false;
- }
-
- SERVICE_STATUS ss;
- if (!ControlService(hService, SERVICE_CONTROL_STOP, &ss))
- {
- DeleteService(hService);
- CloseServiceHandle(hManager);
- CloseServiceHandle(hService);
- return false;
- }
-
- if (!DeleteService(hService)) return false;
- CloseServiceHandle(hManager);
- CloseServiceHandle(hService);
-
- return true;
- }
-
- template <typename T>
- bool physical_read(uint64_t address_phys, T* buffer, uint32_t size = sizeof(T))
- {
- uint64_t input_buffer[2];
-
- input_buffer[0] = address_phys;
- input_buffer[1] = size;
-
- return DeviceIoControl(hDriver, CTL_READ_PHYSICAL_ADDRESS,
- &input_buffer, sizeof(input_buffer), buffer, size, nullptr, nullptr);
- }
-
- template <typename T>
- bool physical_write(uint64_t address_phys, T* buffer, uint32_t size = sizeof(T))
- {
- //direct heap allocation causes BSOD for whatever reason, so do it via WINAPI
- //15/04/2020: not sure what this is about?? please change this
-
- auto input_buffer = reinterpret_cast<uint64_t>(VirtualAlloc(NULL,
- size + 0xC, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE));
- if (!input_buffer)
- return false;
-
- ZeroMemory((void*)input_buffer, size + 0xC);
- memcpy((void*)input_buffer, &address_phys, sizeof(address_phys));
- memcpy((void*)(input_buffer + 0x8), &size, sizeof(size));
- memcpy((void*)(input_buffer + 0xC), buffer, size);
-
- auto result = DeviceIoControl(_driver, CTL_WRITE_PHYSICAL_ADDRESS,
- (LPVOID)input_buffer, size + 0xC, nullptr, NULL, nullptr, NULL);
- if (!VirtualFree((LPVOID)input_buffer, NULL, MEM_RELEASE))
- return false;
-
- return result;
- }
- private:
- HANDLE _driver = INVALID_HANDLE_VALUE;
- bool _initialized;
- std::string _service_name;
- };
-
- class PhysicalMemory
- {
- public:
- PhysicalMemory(uint64_t eproc, uint64_t cr3) :
- _coretemp(new CoreTempDriver("\\\\.\\ALSysIO")), _system({ eproc, cr3 })
- {
- if (_coretemp->is_initialized() && _system.cr3 && _system.eproc)
- _initialized = true;
- }
- ~PhysicalMemory()
- {
- delete _coretemp;
- }
- bool is_initialized()
- {
- return _initialized;
- }
- bool unload()
- {
- return _coretemp->unload();
- }
-
- bool find_eprocess(uint32_t pid)
- {
- using namespace dynamic_data;
- if (!get_dynamic_data())
- return false;
-
- auto list_head = _system.eproc + offset_process_links; //ActiveProcessLinks
- auto link_current = list_head;
-
- uint64_t link_last = 0;
- if (!system_read(list_head + sizeof(uint64_t), &link_last))
- return false;
-
- if (!link_last)
- return false;
-
- do
- {
- auto entry = link_current - offset_process_links;
-
- uint64_t current_link_process_id = 0;
- if (!system_read(entry + offset_process_id, ¤t_link_process_id))
- return false;
-
- if (current_link_process_id == pid)
- {
- _target_eproc = entry;
- return true;
- }
-
- if (!system_read(link_current, &link_current))
- return false;
- } while (link_current != link_last);
- return false;
- }
- bool find_base_address(std::string module)
- {
- uint64_t peb;
- if (!read(_target_eproc + dynamic_data::offset_peb, &peb))
- return false;
-
- uint64_t ldr;
- if (!read(peb + 0x18, &ldr))
- return false;
-
- uint64_t first_module;
- if (!read(ldr + 0x10, &first_module))
- return false;
-
- uint64_t current_module = first_module;
-
- do
- {
- uint64_t wstring_ptr;
- if (!read(current_module + 0x60, &wstring_ptr))
- return false;
-
- wchar_t wstring[256];
- if (!read(wstring_ptr, wstring, 256))
- return false;
-
- char module_name[256];
- sprintf(module_name, "%ws", wstring);
-
- if (!_stricmp(module_name, module.c_str()))
- {
- uint64_t base;
- if (!read(current_module + 0x30, &base))
- return false;
-
- _target_base = base;
- return !!_target_base;
- }
-
- if (!read(current_module, ¤t_module))
- return false;
-
- } while (first_module != current_module);
-
- return false;
- }
- uint64_t get_base_address()
- {
- return _target_base;
- }
- void set_base_address(uint64_t base)
- {
- _target_base = base;
- }
-
- template <typename T>
- bool read(uint64_t address, T* buffer, uint32_t size = sizeof(T))
- {
- address = virtual_to_physical(address, get_cr3());
- if (!address)
- return false;
-
- return _coretemp->physical_read(address, buffer, size);
- }
- template <typename T>
- bool write(uint64_t address, T* buffer, uint32_t size = sizeof(T))
- {
- address = virtual_to_physical(address, get_cr3());
- if (!address)
- return false;
-
- return coretemp->physical_write(address, buffer, size);
- }
-
- private:
- template <typename T>
- bool system_read(uint64_t address, T* buffer, uint32_t size = sizeof(T))
- {
- address = virtual_to_physical(address);
- if (!address)
- return false;
-
- return coretemp->physical_read(address, buffer, size);
- }
- template <typename T>
- bool system_write(uint64_t address, T* buffer, uint32_t size = sizeof(T))
- {
- address = virtual_to_physical(address);
- if (!address)
- return false;
-
- return coretemp->physical_write(address, buffer, size);
- }
-
- uint64_t get_cr3()
- {
- uint64_t buffer;
- if (!system_read(_target_eproc + dynamic_data::offset_directorytable, &buffer))
- return 0;
-
- buffer -= buffer % 0x10; //this is going to always zero out the last digit e.g. (0x1ab002 -> 0x1ab000)
- return buffer;
- }
- uint64_t virtual_to_physical(uint64_t address, uint64_t cr3 = 0)
- {
- //credits to markhc
- if (!cr3)
- cr3 = _system.cr3;
-
- std::int16_t pml4 = (address >> 39) & 0x1FF;
- std::int16_t directory_pointer = (address >> 30) & 0x1FF;
- std::int16_t directory = (address >> 21) & 0x1FF;
- std::int16_t table = (address >> 12) & 0x1FF;
-
- uint64_t pml4e = 0;
- if (!_coretemp->physical_read(cr3 + pml4 * sizeof(uint64_t), &pml4e))
- return 0;
- if (!pml4e)
- return 0;
-
- uint64_t pdpte = 0;
- if (!_coretemp->physical_read((pml4e & 0xFFFFFFFFFF000) + directory_pointer * sizeof(uint64_t), &pdpte))
- return 0;
- if (!pdpte)
- return 0;
-
- if ((pdpte & (1 << 7)) != 0)
- return (pdpte & 0xFFFFFC0000000) + (address & 0x3FFFFFFF);
-
- uint64_t pde = 0;
- if (!_coretemp->physical_read((pdpte & 0xFFFFFFFFFF000) + directory * sizeof(uint64_t), &pde)) return 0;
- if (!pde)
- return 0;
-
- // check PS bit
- if ((pde & (1 << 7)) != 0)
- return (pde & 0xFFFFFFFE00000) + (address & 0x1FFFFF);
-
- uint64_t pte = 0;
- if (!_coretemp->physical_read((pde & 0xFFFFFFFFFF000) + table * sizeof(uint64_t), &pte)) return 0;
- if (!pte)
- return 0;
-
- return (pte & 0xFFFFFFFFFF000) + (address & 0xFFF);
- }
-
- CoreTempDriver* _coretemp;
- bool _initialized = false;
- uint64_t _target_eproc;
- uint64_t _target_base;
-
- struct System
- {
- uint64_t eproc;
- uint64_t cr3;
- } _system;
- };
复制代码
|
|