made the project more stable by scanning for an empty pml4e slot instead

of using 70 constantly.
merge-requests/5/head
xerox 4 years ago
parent 8e3878583e
commit f37470d2f8

@ -1,91 +0,0 @@
#pragma once
#include <windows.h>
#include <cstdint>
#include <cstddef>
extern "C" NTSTATUS __protect_virtual_memory(
HANDLE p_handle,
void** base_addr,
std::size_t* bytes_to_protect,
std::uint32_t new_protect,
std::uint32_t* old_protect
);
extern "C" NTSTATUS __write_virtual_memory(
HANDLE p_handle,
void* base_addr,
void* buffer,
std::size_t size,
std::size_t* bytes_written
);
extern "C" NTSTATUS __read_virtual_memory(
HANDLE p_handle,
void* base_addr,
void* buffer,
std::size_t size,
std::size_t* bytes_written
);
extern "C" NTSTATUS __alloc_virtual_memory(
HANDLE p_handle,
void** base_addr,
std::uint32_t zero_bits,
std::size_t* size,
std::uint32_t alloc_type,
std::uint32_t protect
);
namespace direct
{
__forceinline bool protect_virtual_memory(
HANDLE p_handle,
void* base_addr,
std::size_t size,
std::uint32_t protect,
std::uint32_t* old_protect
)
{
return ERROR_SUCCESS == ::__protect_virtual_memory(p_handle, &base_addr, &size, protect, old_protect);
}
__forceinline bool write_virtual_memory(
HANDLE p_handle,
void* base_addr,
void* buffer,
std::size_t size
)
{
std::size_t bytes_written;
return ERROR_SUCCESS == __write_virtual_memory(p_handle, base_addr, buffer, size, &bytes_written);
}
__forceinline bool read_virtual_memory(
HANDLE p_handle,
void* addr,
void* buffer,
std::size_t size
)
{
std::size_t bytes_written;
return ERROR_SUCCESS == ::__read_virtual_memory(p_handle, addr, buffer, size, &bytes_written);
}
__forceinline void* alloc_virtual_memory(
HANDLE p_handle,
std::size_t size,
std::uint32_t protect
)
{
void* base_addr = NULL;
::__alloc_virtual_memory(
p_handle,
&base_addr,
NULL,
&size,
MEM_COMMIT | MEM_RESERVE,
protect
);
return base_addr;
}
}

Binary file not shown.

@ -1,4 +1,5 @@
#pragma once
#include <thread>
#include "../util/util.hpp"
#include "../physmeme/physmeme.hpp"
#include "../util/hook.hpp"

@ -9,38 +9,32 @@ namespace physmeme
)
:
map_into(map_into),
map_from(map_from)
{}
map_from(map_from),
pml4_idx(0)
{
// find an empty pml4e location...
for (auto idx = 256u; idx > 0u; --idx)
if (!map_into.k_ctx->rkm<pml4e>(map_into.k_ctx->get_virtual(
(reinterpret_cast<::ppml4e>(map_into.get_dirbase()) + idx))).present)
this->pml4_idx = idx;
}
std::pair<void*, void*> mapper_ctx::map(std::vector<std::uint8_t>& raw_image)
{
const auto [drv_alloc, drv_entry_addr] = allocate_driver(raw_image);
auto [drv_ppml4e, drv_pml4e] = map_from.get_pml4e(drv_alloc);
//
// make the pde & pte's containing the driver user supervisor = false...
//
make_kernel_access(drv_alloc);
//
// removes the kernel memory from runtimebroker.exe
//
map_from.set_pml4e(drv_ppml4e, pml4e{ NULL });
//
// set new pml4e into specific process.
//
drv_pml4e.nx = false;
drv_pml4e.user_supervisor = false;
map_into.write_phys
(
reinterpret_cast<ppml4e*>(map_into.get_dirbase()) + PML4_MAP_INDEX,
drv_pml4e
);
map_into.write_phys(reinterpret_cast<ppml4e*>(
map_into.get_dirbase()) + this->pml4_idx, drv_pml4e);
virt_addr_t new_addr = { reinterpret_cast<void*>(drv_alloc) };
new_addr.pml4_index = PML4_MAP_INDEX;
new_addr.pml4_index = this->pml4_idx;
return { new_addr.value, drv_entry_addr };
}
@ -78,9 +72,11 @@ namespace physmeme
const auto drv_alloc_base =
reinterpret_cast<std::uintptr_t>(
direct::alloc_virtual_memory(
VirtualAllocEx(
process_handle,
nullptr,
drv_image.size(),
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE
));
@ -88,18 +84,18 @@ namespace physmeme
return {};
virt_addr_t new_addr = { reinterpret_cast<void*>(drv_alloc_base) };
new_addr.pml4_index = PML4_MAP_INDEX;
new_addr.pml4_index = this->pml4_idx;
drv_image.relocate(reinterpret_cast<std::uintptr_t>(new_addr.value));
//
// dont write nt headers...
//
const bool result = direct::write_virtual_memory
SIZE_T bytes_written = 0;
const bool result = WriteProcessMemory
(
process_handle,
reinterpret_cast<void*>((std::uint64_t)drv_alloc_base + drv_image.header_size()),
reinterpret_cast<void*>((std::uint64_t)drv_image.data() + drv_image.header_size()),
drv_image.size() - drv_image.header_size()
drv_image.size() - drv_image.header_size(),
&bytes_written
);
if (!CloseHandle(process_handle))

@ -1,8 +1,6 @@
#include "../mem_ctx/mem_ctx.hpp"
#include "../pe_image/pe_image.h"
#include "../direct.h"
#define PML4_MAP_INDEX 70
namespace physmeme
{
class mapper_ctx
@ -16,6 +14,7 @@ namespace physmeme
std::pair<void*, void*> map(std::vector<std::uint8_t>& raw_image);
bool call_entry(void* drv_entry, void** hook_handler) const;
private:
std::uint16_t pml4_idx;
std::pair<void*, void*> allocate_driver(std::vector<std::uint8_t>& raw_image);
void make_kernel_access(void* drv_base);
physmeme::mem_ctx map_into;

@ -22,8 +22,8 @@ namespace physmeme
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE
));
PAGE_IN(this->new_pdpt.second, PAGE_SIZE);
PAGE_IN(this->new_pdpt.second, PAGE_SIZE);
// get page table entries for new pdpt
pt_entries new_pdpt_entries;
hyperspace_entries(new_pdpt_entries, new_pdpt.second);

@ -65,7 +65,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<PlatformToolset>v142</PlatformToolset>
<ConfigurationType>Application</ConfigurationType>
<ConfigurationType>StaticLibrary</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<SpectreMitigation>false</SpectreMitigation>
@ -186,7 +186,8 @@
</EntryPointSymbol>
</Link>
<Lib>
<AdditionalDependencies>direct.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>
</AdditionalDependencies>
<LinkTimeCodeGeneration>false</LinkTimeCodeGeneration>
</Lib>
<ProjectReference>
@ -204,7 +205,6 @@
<ClCompile Include="pe_image\pe_image.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="direct.h" />
<ClInclude Include="kernel_ctx\kernel_ctx.h" />
<ClInclude Include="loadup.hpp" />
<ClInclude Include="mapper_ctx\mapper_ctx.hpp" />

@ -88,9 +88,6 @@
<ClInclude Include="raw_driver.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="direct.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="map_driver.hpp">
<Filter>Header Files</Filter>
</ClInclude>

@ -1,13 +1,14 @@
#pragma once
#include <windows.h>
#include <mutex>
#include <cstdint>
#include <map>
#include "../util/util.hpp"
#include "../loadup.hpp"
#include "../raw_driver.hpp"
#define MAP_PHYSICAL 0xC3502004
#define UNMAP_PHYSICAL 0xC3502008
#pragma pack ( push, 1 )
typedef struct _GIOMAP
{
@ -50,10 +51,7 @@ namespace physmeme
return CloseHandle(drv_handle) && driver::unload(drv_key);
}
inline std::uintptr_t map_phys(
std::uintptr_t addr,
std::size_t size
)
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))
@ -62,23 +60,35 @@ namespace physmeme
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];
if (!DeviceIoControl(
drv_handle,
MAP_PHYSICAL,
reinterpret_cast<LPVOID>(&in_buffer),
sizeof(in_buffer),
reinterpret_cast<LPVOID>(out_buffer),
sizeof(out_buffer),
&returned, NULL
))
return NULL;
return out_buffer[0];
}
inline bool unmap_phys(
std::uintptr_t addr,
std::size_t size
)
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];
return DeviceIoControl(
drv_handle,
UNMAP_PHYSICAL,
reinterpret_cast<LPVOID>(&in_buffer),
sizeof(in_buffer),
reinterpret_cast<LPVOID>(out_buffer),
sizeof(out_buffer),
&returned, NULL
);
}
}

Binary file not shown.
Loading…
Cancel
Save