parent
3b4605b22d
commit
bf0912d462
@ -1,190 +0,0 @@
|
|||||||
/*
|
|
||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2020 xerox
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include <Windows.h>
|
|
||||||
#include <map>
|
|
||||||
#include <atomic>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#if _M_IX86
|
|
||||||
#define OFFSET_TO_ADDRESS 0x1
|
|
||||||
#elif _M_X64
|
|
||||||
#define OFFSET_TO_ADDRESS 0x2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace hook
|
|
||||||
{
|
|
||||||
static void write_to_readonly(void* addr, void* data, int size)
|
|
||||||
{
|
|
||||||
DWORD old_flags;
|
|
||||||
VirtualProtect((LPVOID)addr, size, PAGE_EXECUTE_READWRITE, &old_flags);
|
|
||||||
memcpy((void*)addr, data, size);
|
|
||||||
VirtualProtect((LPVOID)addr, size, old_flags, &old_flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
class detour
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
detour(void* addr_to_hook, void* jmp_to, bool enable = true)
|
|
||||||
: hook_addr(addr_to_hook), detour_addr(jmp_to), hook_installed(false)
|
|
||||||
{
|
|
||||||
//setup hook
|
|
||||||
memcpy(
|
|
||||||
jmp_code + OFFSET_TO_ADDRESS,
|
|
||||||
&jmp_to,
|
|
||||||
sizeof(jmp_to)
|
|
||||||
);
|
|
||||||
|
|
||||||
//save bytes
|
|
||||||
memcpy(
|
|
||||||
org_bytes,
|
|
||||||
hook_addr,
|
|
||||||
sizeof(org_bytes)
|
|
||||||
);
|
|
||||||
if(enable)
|
|
||||||
install();
|
|
||||||
}
|
|
||||||
|
|
||||||
void install()
|
|
||||||
{
|
|
||||||
if (hook_installed.load())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// mapped page is already read/write
|
|
||||||
memcpy(hook_addr, jmp_code, sizeof(jmp_code));
|
|
||||||
hook_installed.exchange(true);
|
|
||||||
}
|
|
||||||
void uninstall()
|
|
||||||
{
|
|
||||||
if (!hook_installed.load())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// mapped page is already read/write
|
|
||||||
memcpy(hook_addr, org_bytes, sizeof(org_bytes));
|
|
||||||
hook_installed.exchange(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
~detour() { uninstall(); }
|
|
||||||
bool installed() { return hook_installed; }
|
|
||||||
void* hook_address() { return hook_addr; }
|
|
||||||
void* detour_address() { return detour_addr; }
|
|
||||||
private:
|
|
||||||
std::atomic<bool> hook_installed;
|
|
||||||
void *hook_addr, *detour_addr;
|
|
||||||
|
|
||||||
#if _M_IX86
|
|
||||||
/*
|
|
||||||
0: b8 ff ff ff ff mov eax, 0xffffffff
|
|
||||||
5: ff e0 jmp eax
|
|
||||||
*/
|
|
||||||
unsigned char jmp_code[7] = {
|
|
||||||
0xb8, 0x0, 0x0, 0x0, 0x0,
|
|
||||||
0xFF, 0xE0
|
|
||||||
};
|
|
||||||
#elif _M_X64
|
|
||||||
/*
|
|
||||||
0: 48 b8 ff ff ff ff ff ff ff ff movabs rax,0xffffffffffffffff
|
|
||||||
7: ff e0 jmp rax
|
|
||||||
*/
|
|
||||||
unsigned char jmp_code[12] = {
|
|
||||||
0x48, 0xb8,
|
|
||||||
0x0,
|
|
||||||
0x0,
|
|
||||||
0x0,
|
|
||||||
0x0,
|
|
||||||
0x0,
|
|
||||||
0x0,
|
|
||||||
0x0,
|
|
||||||
0x0,
|
|
||||||
0xff, 0xe0
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
std::uint8_t org_bytes[sizeof(jmp_code)];
|
|
||||||
};
|
|
||||||
|
|
||||||
static std::map<void*, std::unique_ptr<detour>> hooks{};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Author: xerox
|
|
||||||
Date: 12/19/2019
|
|
||||||
|
|
||||||
Create Hook without needing to deal with objects
|
|
||||||
*/
|
|
||||||
static void make_hook(void* addr_to_hook, void* jmp_to_addr, bool enable = true)
|
|
||||||
{
|
|
||||||
if (!addr_to_hook)
|
|
||||||
return;
|
|
||||||
|
|
||||||
hooks.insert({
|
|
||||||
addr_to_hook,
|
|
||||||
std::make_unique<detour>(
|
|
||||||
addr_to_hook,
|
|
||||||
jmp_to_addr,
|
|
||||||
enable
|
|
||||||
)}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Author: xerox
|
|
||||||
Date: 12/19/2019
|
|
||||||
|
|
||||||
Enable hook given the address to hook
|
|
||||||
*/
|
|
||||||
static void enable(void* addr)
|
|
||||||
{
|
|
||||||
if (!addr)
|
|
||||||
return;
|
|
||||||
hooks.at(addr)->install();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Author: xerox
|
|
||||||
Date: 12/19/2019
|
|
||||||
|
|
||||||
Disable hook givent the address of the hook
|
|
||||||
*/
|
|
||||||
static void disable(void* addr)
|
|
||||||
{
|
|
||||||
if (!addr)
|
|
||||||
return;
|
|
||||||
hooks.at(addr)->uninstall();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Author: xerox
|
|
||||||
Date: 12/19/2019
|
|
||||||
|
|
||||||
Remove hook completely from vector
|
|
||||||
*/
|
|
||||||
static void remove(void* addr)
|
|
||||||
{
|
|
||||||
if (!addr)
|
|
||||||
return;
|
|
||||||
hooks.at(addr)->~detour();
|
|
||||||
hooks.erase(addr);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,95 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <Windows.h>
|
|
||||||
#include <winternl.h>
|
|
||||||
#pragma comment(lib, "ntdll.lib")
|
|
||||||
|
|
||||||
constexpr bool physmeme_debugging = true;
|
|
||||||
constexpr auto ntoskrnl_path = "C:\\Windows\\System32\\ntoskrnl.exe";
|
|
||||||
constexpr auto page_size = 0x1000;
|
|
||||||
|
|
||||||
constexpr auto SystemModuleInformation = 11;
|
|
||||||
constexpr auto SystemHandleInformation = 16;
|
|
||||||
constexpr auto SystemExtendedHandleInformation = 64;
|
|
||||||
|
|
||||||
#define MM_COPY_MEMORY_PHYSICAL 0x1
|
|
||||||
#define MM_COPY_MEMORY_VIRTUAL 0x2
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct _SYSTEM_HANDLE
|
|
||||||
{
|
|
||||||
PVOID Object;
|
|
||||||
HANDLE UniqueProcessId;
|
|
||||||
HANDLE HandleValue;
|
|
||||||
ULONG GrantedAccess;
|
|
||||||
USHORT CreatorBackTraceIndex;
|
|
||||||
USHORT ObjectTypeIndex;
|
|
||||||
ULONG HandleAttributes;
|
|
||||||
ULONG Reserved;
|
|
||||||
} SYSTEM_HANDLE, * PSYSTEM_HANDLE;
|
|
||||||
|
|
||||||
typedef struct _SYSTEM_HANDLE_INFORMATION_EX
|
|
||||||
{
|
|
||||||
ULONG_PTR HandleCount;
|
|
||||||
ULONG_PTR Reserved;
|
|
||||||
SYSTEM_HANDLE Handles[1];
|
|
||||||
} SYSTEM_HANDLE_INFORMATION_EX, * PSYSTEM_HANDLE_INFORMATION_EX;
|
|
||||||
|
|
||||||
typedef enum _POOL_TYPE {
|
|
||||||
NonPagedPool,
|
|
||||||
NonPagedPoolExecute,
|
|
||||||
PagedPool,
|
|
||||||
NonPagedPoolMustSucceed,
|
|
||||||
DontUseThisType,
|
|
||||||
NonPagedPoolCacheAligned,
|
|
||||||
PagedPoolCacheAligned,
|
|
||||||
NonPagedPoolCacheAlignedMustS,
|
|
||||||
MaxPoolType,
|
|
||||||
NonPagedPoolBase,
|
|
||||||
NonPagedPoolBaseMustSucceed,
|
|
||||||
NonPagedPoolBaseCacheAligned,
|
|
||||||
NonPagedPoolBaseCacheAlignedMustS,
|
|
||||||
NonPagedPoolSession,
|
|
||||||
PagedPoolSession,
|
|
||||||
NonPagedPoolMustSucceedSession,
|
|
||||||
DontUseThisTypeSession,
|
|
||||||
NonPagedPoolCacheAlignedSession,
|
|
||||||
PagedPoolCacheAlignedSession,
|
|
||||||
NonPagedPoolCacheAlignedMustSSession,
|
|
||||||
NonPagedPoolNx,
|
|
||||||
NonPagedPoolNxCacheAligned,
|
|
||||||
NonPagedPoolSessionNx
|
|
||||||
} POOL_TYPE;
|
|
||||||
|
|
||||||
typedef struct _RTL_PROCESS_MODULE_INFORMATION
|
|
||||||
{
|
|
||||||
HANDLE Section;
|
|
||||||
PVOID MappedBase;
|
|
||||||
PVOID ImageBase;
|
|
||||||
ULONG ImageSize;
|
|
||||||
ULONG Flags;
|
|
||||||
USHORT LoadOrderIndex;
|
|
||||||
USHORT InitOrderIndex;
|
|
||||||
USHORT LoadCount;
|
|
||||||
USHORT OffsetToFileName;
|
|
||||||
UCHAR FullPathName[256];
|
|
||||||
} RTL_PROCESS_MODULE_INFORMATION, * PRTL_PROCESS_MODULE_INFORMATION;
|
|
||||||
|
|
||||||
typedef struct _RTL_PROCESS_MODULES
|
|
||||||
{
|
|
||||||
ULONG NumberOfModules;
|
|
||||||
RTL_PROCESS_MODULE_INFORMATION Modules[1];
|
|
||||||
} RTL_PROCESS_MODULES, * PRTL_PROCESS_MODULES;
|
|
||||||
|
|
||||||
typedef LARGE_INTEGER PHYSICAL_ADDRESS, * PPHYSICAL_ADDRESS;
|
|
||||||
|
|
||||||
typedef struct _MM_COPY_ADDRESS {
|
|
||||||
union {
|
|
||||||
PVOID VirtualAddress;
|
|
||||||
PHYSICAL_ADDRESS PhysicalAddress;
|
|
||||||
};
|
|
||||||
} MM_COPY_ADDRESS, * PMMCOPY_ADDRESS;
|
|
||||||
|
|
||||||
using ExAllocatePool = PVOID(__stdcall*) (POOL_TYPE, SIZE_T);
|
|
||||||
using ExAllocatePoolWithTag = PVOID(__stdcall*)(POOL_TYPE, SIZE_T, ULONG);
|
|
||||||
using MmCopyMemory = NTSTATUS (__stdcall*)(PVOID, MM_COPY_ADDRESS,SIZE_T,ULONG,PSIZE_T);
|
|
||||||
using DRIVER_INITIALIZE = NTSTATUS(__stdcall*)(std::uintptr_t, std::size_t);
|
|
@ -1,192 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <Windows.h>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <string_view>
|
|
||||||
#include <iterator>
|
|
||||||
#include <fstream>
|
|
||||||
#include <string>
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
#include <ntstatus.h>
|
|
||||||
#include <winternl.h>
|
|
||||||
|
|
||||||
#include "nt.hpp"
|
|
||||||
|
|
||||||
namespace util
|
|
||||||
{
|
|
||||||
//--- ranges of physical memory
|
|
||||||
static std::map<std::uintptr_t, std::size_t> 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;
|
|
||||||
})();
|
|
||||||
|
|
||||||
// this was taken from wlan's drvmapper:
|
|
||||||
// https://github.com/not-wlan/drvmap/blob/98d93cc7b5ec17875f815a9cb94e6d137b4047ee/drvmap/util.cpp#L7
|
|
||||||
static void open_binary_file(const std::string& file, std::vector<uint8_t>& data)
|
|
||||||
{
|
|
||||||
std::ifstream fstr(file, std::ios::binary);
|
|
||||||
fstr.unsetf(std::ios::skipws);
|
|
||||||
fstr.seekg(0, std::ios::end);
|
|
||||||
|
|
||||||
const auto file_size = fstr.tellg();
|
|
||||||
|
|
||||||
fstr.seekg(NULL, std::ios::beg);
|
|
||||||
data.reserve(static_cast<uint32_t>(file_size));
|
|
||||||
data.insert(data.begin(), std::istream_iterator<uint8_t>(fstr), std::istream_iterator<uint8_t>());
|
|
||||||
}
|
|
||||||
|
|
||||||
// get base address of kernel module
|
|
||||||
//
|
|
||||||
// taken from: https://github.com/z175/kdmapper/blob/master/kdmapper/utils.cpp#L30
|
|
||||||
static std::uintptr_t get_module_base(const char* module_name)
|
|
||||||
{
|
|
||||||
void* buffer = nullptr;
|
|
||||||
DWORD buffer_size = NULL;
|
|
||||||
|
|
||||||
NTSTATUS status = NtQuerySystemInformation(static_cast<SYSTEM_INFORMATION_CLASS>(SystemModuleInformation), buffer, buffer_size, &buffer_size);
|
|
||||||
|
|
||||||
while (status == STATUS_INFO_LENGTH_MISMATCH)
|
|
||||||
{
|
|
||||||
VirtualFree(buffer, NULL, MEM_RELEASE);
|
|
||||||
buffer = VirtualAlloc(nullptr, buffer_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
|
||||||
status = NtQuerySystemInformation(static_cast<SYSTEM_INFORMATION_CLASS>(SystemModuleInformation), buffer, buffer_size, &buffer_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(status))
|
|
||||||
{
|
|
||||||
VirtualFree(buffer, NULL, MEM_RELEASE);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto modules = static_cast<PRTL_PROCESS_MODULES>(buffer);
|
|
||||||
for (auto idx = 0u; idx < modules->NumberOfModules; ++idx)
|
|
||||||
{
|
|
||||||
const std::string current_module_name = std::string(reinterpret_cast<char*>(modules->Modules[idx].FullPathName) + modules->Modules[idx].OffsetToFileName);
|
|
||||||
if (!_stricmp(current_module_name.c_str(), module_name))
|
|
||||||
{
|
|
||||||
const uint64_t result = reinterpret_cast<uint64_t>(modules->Modules[idx].ImageBase);
|
|
||||||
VirtualFree(buffer, NULL, MEM_RELEASE);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VirtualFree(buffer, NULL, MEM_RELEASE);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get base address of kernel module
|
|
||||||
//
|
|
||||||
// taken from: https://github.com/z175/kdmapper/blob/master/kdmapper/utils.cpp#L30
|
|
||||||
static void* get_module_export(const char* module_name, const char* export_name, bool rva = false)
|
|
||||||
{
|
|
||||||
void* buffer = nullptr;
|
|
||||||
DWORD buffer_size = 0;
|
|
||||||
|
|
||||||
NTSTATUS status = NtQuerySystemInformation(static_cast<SYSTEM_INFORMATION_CLASS>(SystemModuleInformation), buffer, buffer_size, &buffer_size);
|
|
||||||
|
|
||||||
while (status == STATUS_INFO_LENGTH_MISMATCH)
|
|
||||||
{
|
|
||||||
VirtualFree(buffer, 0, MEM_RELEASE);
|
|
||||||
buffer = VirtualAlloc(nullptr, buffer_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
|
||||||
status = NtQuerySystemInformation(static_cast<SYSTEM_INFORMATION_CLASS>(SystemModuleInformation), buffer, buffer_size, &buffer_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(status))
|
|
||||||
{
|
|
||||||
VirtualFree(buffer, 0, MEM_RELEASE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto modules = static_cast<PRTL_PROCESS_MODULES>(buffer);
|
|
||||||
for (auto idx = 0u; idx < modules->NumberOfModules; ++idx)
|
|
||||||
{
|
|
||||||
// find module and then load library it
|
|
||||||
const std::string current_module_name = std::string(reinterpret_cast<char*>(modules->Modules[idx].FullPathName) + modules->Modules[idx].OffsetToFileName);
|
|
||||||
if (!_stricmp(current_module_name.c_str(), module_name))
|
|
||||||
{
|
|
||||||
// had to shoot the tires off of "\\SystemRoot\\"
|
|
||||||
std::string full_path = reinterpret_cast<char*>(modules->Modules[idx].FullPathName);
|
|
||||||
full_path.replace(
|
|
||||||
full_path.find("\\SystemRoot\\"),
|
|
||||||
sizeof("\\SystemRoot\\") - 1,
|
|
||||||
std::string(getenv("SYSTEMROOT")).append("\\")
|
|
||||||
);
|
|
||||||
|
|
||||||
auto module_base = LoadLibraryA(full_path.c_str());
|
|
||||||
PIMAGE_DOS_HEADER p_idh;
|
|
||||||
PIMAGE_NT_HEADERS p_inh;
|
|
||||||
PIMAGE_EXPORT_DIRECTORY p_ied;
|
|
||||||
|
|
||||||
PDWORD addr, name;
|
|
||||||
PWORD ordinal;
|
|
||||||
|
|
||||||
p_idh = (PIMAGE_DOS_HEADER)module_base;
|
|
||||||
if (p_idh->e_magic != IMAGE_DOS_SIGNATURE)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
p_inh = (PIMAGE_NT_HEADERS)((LPBYTE)module_base + p_idh->e_lfanew);
|
|
||||||
if (p_inh->Signature != IMAGE_NT_SIGNATURE)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (p_inh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress == 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
p_ied = (PIMAGE_EXPORT_DIRECTORY)((LPBYTE)module_base +
|
|
||||||
p_inh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
|
|
||||||
|
|
||||||
addr = (PDWORD)((LPBYTE)module_base + p_ied->AddressOfFunctions);
|
|
||||||
name = (PDWORD)((LPBYTE)module_base + p_ied->AddressOfNames);
|
|
||||||
ordinal = (PWORD)((LPBYTE)module_base + p_ied->AddressOfNameOrdinals);
|
|
||||||
|
|
||||||
// find exported function
|
|
||||||
for (auto i = 0; i < p_ied->AddressOfFunctions; i++)
|
|
||||||
if (!strcmp(export_name, (char*)module_base + name[i]))
|
|
||||||
{
|
|
||||||
if (!rva)
|
|
||||||
{
|
|
||||||
auto result = (void*)((std::uintptr_t)modules->Modules[idx].ImageBase + addr[ordinal[i]]);
|
|
||||||
VirtualFree(buffer, NULL, MEM_RELEASE);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto result = (void*)addr[ordinal[i]];
|
|
||||||
VirtualFree(buffer, NULL, MEM_RELEASE);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
VirtualFree(buffer, NULL, MEM_RELEASE);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,92 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <windows.h>
|
||||||
|
#include <mutex>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "../util/util.hpp"
|
||||||
|
#include "../loadup.hpp"
|
||||||
|
#include "../raw_driver.hpp"
|
||||||
|
|
||||||
|
#pragma pack ( push, 1 )
|
||||||
|
typedef struct _GIOMAP
|
||||||
|
{
|
||||||
|
unsigned long interface_type;
|
||||||
|
unsigned long bus;
|
||||||
|
std::uintptr_t physical_address;
|
||||||
|
unsigned long io_space;
|
||||||
|
unsigned long size;
|
||||||
|
} GIOMAP;
|
||||||
|
#pragma pack ( pop )
|
||||||
|
|
||||||
|
namespace physmeme
|
||||||
|
{
|
||||||
|
inline std::string drv_key;
|
||||||
|
|
||||||
|
//
|
||||||
|
// please code this function depending on your method of physical read/write.
|
||||||
|
//
|
||||||
|
inline HANDLE load_drv()
|
||||||
|
{
|
||||||
|
const auto [result, key] = driver::load(raw_driver, sizeof(raw_driver));
|
||||||
|
drv_key = key;
|
||||||
|
|
||||||
|
return CreateFile(
|
||||||
|
"\\\\.\\GIO",
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// please code this function depending on your method of physical read/write.
|
||||||
|
//
|
||||||
|
inline bool unload_drv()
|
||||||
|
{
|
||||||
|
return driver::unload(drv_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline HANDLE drv_handle = load_drv();
|
||||||
|
|
||||||
|
//
|
||||||
|
// please code this function depending on your method of physical read/write.
|
||||||
|
//
|
||||||
|
inline std::uintptr_t map_phys(
|
||||||
|
std::uintptr_t addr,
|
||||||
|
std::size_t size
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//--- ensure the validity of the address we are going to try and map
|
||||||
|
if (!util::is_valid(addr))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
GIOMAP in_buffer = { 0, 0, addr, 0, size };
|
||||||
|
uintptr_t out_buffer[2] = { 0 };
|
||||||
|
unsigned long returned = 0;
|
||||||
|
DeviceIoControl(drv_handle, 0xC3502004, reinterpret_cast<LPVOID>(&in_buffer), sizeof(in_buffer),
|
||||||
|
reinterpret_cast<LPVOID>(out_buffer), sizeof(out_buffer), &returned, NULL);
|
||||||
|
return out_buffer[0];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// please code this function depending on your method of physical read/write.
|
||||||
|
//
|
||||||
|
inline bool unmap_phys(
|
||||||
|
std::uintptr_t addr,
|
||||||
|
std::size_t size
|
||||||
|
)
|
||||||
|
{
|
||||||
|
uintptr_t in_buffer = addr;
|
||||||
|
uintptr_t out_buffer[2] = {sizeof(out_buffer)};
|
||||||
|
|
||||||
|
unsigned long returned = NULL;
|
||||||
|
DeviceIoControl(drv_handle, 0xC3502008, reinterpret_cast<LPVOID>(&in_buffer), sizeof(in_buffer),
|
||||||
|
reinterpret_cast<LPVOID>(out_buffer), sizeof(out_buffer), &returned, NULL);
|
||||||
|
return out_buffer[0];
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue