had to go-go gadget my kernel addresses (make the top most bits set to

high)
master v1.6
_xeroxz 4 years ago
parent b2a6ab5148
commit 3842f39352

@ -200,16 +200,16 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="mapper_ctx\mapper_ctx.cpp" /> <ClCompile Include="mapper_ctx\mapper_ctx.cpp" />
<ClCompile Include="map_driver.cpp" /> <ClCompile Include="map_driver.cpp" />
<ClCompile Include="mem_ctx\mem_ctx.cpp" />
<ClCompile Include="pe_image\pe_image.cpp" /> <ClCompile Include="pe_image\pe_image.cpp" />
<ClCompile Include="ptm_ctx\ptm_ctx.cpp" />
<ClCompile Include="set_mgr\set_mgr.cpp" /> <ClCompile Include="set_mgr\set_mgr.cpp" />
<ClCompile Include="vdm_ctx\vdm_ctx.cpp" /> <ClCompile Include="vdm_ctx\vdm_ctx.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="mapper_ctx\mapper_ctx.hpp" /> <ClInclude Include="mapper_ctx\mapper_ctx.hpp" />
<ClInclude Include="map_driver.hpp" /> <ClInclude Include="map_driver.hpp" />
<ClInclude Include="mem_ctx\mem_ctx.hpp" />
<ClInclude Include="pe_image\pe_image.h" /> <ClInclude Include="pe_image\pe_image.h" />
<ClInclude Include="ptm_ctx\ptm_ctx.hpp" />
<ClInclude Include="set_mgr\set_mgr.hpp" /> <ClInclude Include="set_mgr\set_mgr.hpp" />
<ClInclude Include="util\hook.hpp" /> <ClInclude Include="util\hook.hpp" />
<ClInclude Include="util\loadup.hpp" /> <ClInclude Include="util\loadup.hpp" />

@ -26,15 +26,15 @@
<ClCompile Include="pe_image\pe_image.cpp"> <ClCompile Include="pe_image\pe_image.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="mem_ctx\mem_ctx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="mapper_ctx\mapper_ctx.cpp"> <ClCompile Include="mapper_ctx\mapper_ctx.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="set_mgr\set_mgr.cpp"> <ClCompile Include="set_mgr\set_mgr.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="ptm_ctx\ptm_ctx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="util\hook.hpp"> <ClInclude Include="util\hook.hpp">
@ -52,9 +52,6 @@
<ClInclude Include="util\loadup.hpp"> <ClInclude Include="util\loadup.hpp">
<Filter>Header Files\util</Filter> <Filter>Header Files\util</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="mem_ctx\mem_ctx.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="mapper_ctx\mapper_ctx.hpp"> <ClInclude Include="mapper_ctx\mapper_ctx.hpp">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
@ -73,5 +70,8 @@
<ClInclude Include="vdm_ctx\vdm_ctx.hpp"> <ClInclude Include="vdm_ctx\vdm_ctx.hpp">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="ptm_ctx\ptm_ctx.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>

@ -34,8 +34,8 @@ namespace mapper
}; };
vdm::vdm_ctx v_ctx(_read_phys, _write_phys); vdm::vdm_ctx v_ctx(_read_phys, _write_phys);
nasa::mem_ctx desired_ctx(&v_ctx, GetCurrentProcessId()); ptm::ptm_ctx desired_ctx(&v_ctx, GetCurrentProcessId());
nasa::mem_ctx zombie_ctx(&v_ctx, context_pid); ptm::ptm_ctx zombie_ctx(&v_ctx, context_pid);
nasa::mapper_ctx mapper(&desired_ctx, &zombie_ctx); nasa::mapper_ctx mapper(&desired_ctx, &zombie_ctx);
// disable the working set manager thread // disable the working set manager thread
@ -61,6 +61,10 @@ namespace mapper
if (!drv_base || !drv_entry) if (!drv_base || !drv_entry)
return { mapper_error::init_failed, nullptr }; return { mapper_error::init_failed, nullptr };
std::printf("[+] driver base -> 0x%p\n", drv_base);
std::printf("[+] driver entry -> 0x%p\n", drv_entry);
std::getchar();
mapper.call_entry(drv_entry, entry_data); mapper.call_entry(drv_entry, entry_data);
if (!vdm::unload_drv(drv_handle, drv_key)) if (!vdm::unload_drv(drv_handle, drv_key))
return { mapper_error::unload_error, nullptr }; return { mapper_error::unload_error, nullptr };

@ -4,8 +4,8 @@ namespace nasa
{ {
mapper_ctx::mapper_ctx mapper_ctx::mapper_ctx
( (
nasa::mem_ctx* map_into, ptm::ptm_ctx* map_into,
nasa::mem_ctx* map_from ptm::ptm_ctx* map_from
) )
: :
map_into(map_into), map_into(map_into),
@ -17,7 +17,7 @@ namespace nasa
map_into->set_page(map_into->dirbase)); map_into->set_page(map_into->dirbase));
// look for an empty pml4e... // look for an empty pml4e...
for (auto idx = 100u; idx < 255; ++idx) for (auto idx = 255u; idx < 511; ++idx)
{ {
if (!map_into_pml4[idx].value) if (!map_into_pml4[idx].value)
{ {
@ -33,21 +33,26 @@ namespace nasa
auto [drv_ppml4e, drv_pml4e] = map_from->get_pml4e(drv_alloc); auto [drv_ppml4e, drv_pml4e] = map_from->get_pml4e(drv_alloc);
make_kernel_access(drv_alloc); make_kernel_access(drv_alloc);
while (!map_from->set_pml4e(drv_ppml4e, pml4e{ NULL })) map_from->set_pml4e(drv_ppml4e, pml4e{ NULL });
continue;
drv_pml4e.present = true;
drv_pml4e.nx = false; drv_pml4e.nx = false;
drv_pml4e.user_supervisor = false; drv_pml4e.user_supervisor = false;
drv_pml4e.write = true; drv_pml4e.write = true;
// ensure we insert the pml4e... const auto map_into_pml4 =
while (!map_into->write_phys(
reinterpret_cast<ppml4e>( reinterpret_cast<ppml4e>(
map_into->dirbase) + this->pml4_idx, drv_pml4e)) map_into->set_page(map_into->dirbase));
continue;
map_into_pml4[this->pml4_idx] = drv_pml4e;
virt_addr_t old_addr = { reinterpret_cast<void*>(drv_alloc) };
virt_addr_t new_addr = { reinterpret_cast<void*>(MAXULONG64) };
virt_addr_t new_addr = { reinterpret_cast<void*>(drv_alloc) };
new_addr.pml4_index = this->pml4_idx; new_addr.pml4_index = this->pml4_idx;
new_addr.pdpt_index = old_addr.pdpt_index;
new_addr.pd_index = old_addr.pd_index;
new_addr.pt_index = old_addr.pt_index;
new_addr.offset = old_addr.offset;
return { new_addr.value, drv_entry_addr }; return { new_addr.value, drv_entry_addr };
} }
@ -93,8 +98,15 @@ namespace nasa
if (!drv_alloc_base) if (!drv_alloc_base)
return { {}, {} }; return { {}, {} };
virt_addr_t new_addr = { reinterpret_cast<void*>(drv_alloc_base) }; virt_addr_t old_addr = { reinterpret_cast<void*>(drv_alloc_base) };
virt_addr_t new_addr = { reinterpret_cast<void*>(MAXULONG64) };
new_addr.pml4_index = this->pml4_idx; new_addr.pml4_index = this->pml4_idx;
new_addr.pdpt_index = old_addr.pdpt_index;
new_addr.pd_index = old_addr.pd_index;
new_addr.pt_index = old_addr.pt_index;
new_addr.offset = old_addr.offset;
drv_image.relocate(reinterpret_cast<std::uintptr_t>(new_addr.value)); drv_image.relocate(reinterpret_cast<std::uintptr_t>(new_addr.value));
// dont write nt headers... // dont write nt headers...

@ -1,4 +1,4 @@
#include "../mem_ctx/mem_ctx.hpp" #include "../ptm_ctx/ptm_ctx.hpp"
#include "../pe_image/pe_image.h" #include "../pe_image/pe_image.h"
namespace nasa namespace nasa
@ -6,7 +6,7 @@ namespace nasa
class mapper_ctx class mapper_ctx
{ {
public: public:
explicit mapper_ctx(nasa::mem_ctx* map_into, nasa::mem_ctx* map_from); explicit mapper_ctx(ptm::ptm_ctx* map_into, ptm::ptm_ctx* map_from);
auto map(std::vector<std::uint8_t>& raw_image) -> std::pair<void*, void*>; auto map(std::vector<std::uint8_t>& raw_image) -> std::pair<void*, void*>;
void call_entry(void* drv_entry, void** hook_handler) const; void call_entry(void* drv_entry, void** hook_handler) const;
@ -14,6 +14,6 @@ namespace nasa
std::uint16_t pml4_idx; std::uint16_t pml4_idx;
auto allocate_driver(std::vector<std::uint8_t>& raw_image) -> std::pair<void*, void*>; auto allocate_driver(std::vector<std::uint8_t>& raw_image) -> std::pair<void*, void*>;
void make_kernel_access(void* drv_base); void make_kernel_access(void* drv_base);
nasa::mem_ctx* map_into, *map_from; ptm::ptm_ctx* map_into, *map_from;
}; };
} }

@ -1,8 +1,8 @@
#include "mem_ctx.hpp" #include "ptm_ctx.hpp"
namespace nasa namespace ptm
{ {
mem_ctx::mem_ctx(vdm::vdm_ctx* v_ctx, std::uint32_t pid) ptm_ctx::ptm_ctx(vdm::vdm_ctx* v_ctx, std::uint32_t pid)
: :
v_ctx(v_ctx), v_ctx(v_ctx),
dirbase(get_dirbase(*v_ctx, pid)), dirbase(get_dirbase(*v_ctx, pid)),
@ -89,14 +89,14 @@ namespace nasa
new_pt_entries.pt.second.pfn << 12); new_pt_entries.pt.second.pfn << 12);
} }
mem_ctx::~mem_ctx() ptm_ctx::~ptm_ctx()
{ {
const auto pml4 = const auto pml4 =
reinterpret_cast<ppml4e>( reinterpret_cast<ppml4e>(
set_page(dirbase))[pml4e_index] = pml4e{ NULL }; set_page(dirbase))[pml4e_index] = pml4e{ NULL };
} }
void* mem_ctx::set_page(void* addr) void* ptm_ctx::set_page(void* addr)
{ {
++pte_index; ++pte_index;
if (pte_index > 511) if (pte_index > 511)
@ -146,7 +146,7 @@ namespace nasa
return get_page(); return get_page();
} }
void* mem_ctx::get_page() const void* ptm_ctx::get_page() const
{ {
// builds a new address given the state of all table indexes // builds a new address given the state of all table indexes
virt_addr_t new_addr; virt_addr_t new_addr;
@ -180,7 +180,7 @@ namespace nasa
return new_addr.value; return new_addr.value;
} }
void* mem_ctx::get_dirbase(vdm::vdm_ctx& v_ctx, DWORD pid) void* ptm_ctx::get_dirbase(vdm::vdm_ctx& v_ctx, DWORD pid)
{ {
const auto peproc = const auto peproc =
reinterpret_cast<std::uint64_t>( reinterpret_cast<std::uint64_t>(
@ -190,7 +190,7 @@ namespace nasa
v_ctx.rkm<pte>(peproc + 0x28).pfn << 12); v_ctx.rkm<pte>(peproc + 0x28).pfn << 12);
} }
bool mem_ctx::hyperspace_entries(pt_entries& entries, void* addr) bool ptm_ctx::hyperspace_entries(pt_entries& entries, void* addr)
{ {
if (!addr || !dirbase) if (!addr || !dirbase)
return false; return false;
@ -232,7 +232,7 @@ namespace nasa
return true; return true;
} }
auto mem_ctx::get_pte(void* addr, bool use_hyperspace) -> std::pair<ppte, pte> auto ptm_ctx::get_pte(void* addr, bool use_hyperspace) -> std::pair<ppte, pte>
{ {
if (!dirbase || !addr) if (!dirbase || !addr)
return { {}, {} }; return { {}, {} };
@ -244,7 +244,7 @@ namespace nasa
return { {}, {} }; return { {}, {} };
} }
bool mem_ctx::set_pte(void* addr, const ::pte& pte, bool use_hyperspace) bool ptm_ctx::set_pte(void* addr, const ::pte& pte, bool use_hyperspace)
{ {
if (!dirbase || !addr) if (!dirbase || !addr)
return false; return false;
@ -257,7 +257,7 @@ namespace nasa
return write_phys(addr, pte); return write_phys(addr, pte);
} }
auto mem_ctx::get_pde(void* addr, bool use_hyperspace) -> std::pair<ppde, pde> auto ptm_ctx::get_pde(void* addr, bool use_hyperspace) -> std::pair<ppde, pde>
{ {
if (!dirbase || !addr) if (!dirbase || !addr)
return { {}, {} }; return { {}, {} };
@ -268,7 +268,7 @@ namespace nasa
return { {}, {} }; return { {}, {} };
} }
bool mem_ctx::set_pde(void* addr, const ::pde& pde, bool use_hyperspace) bool ptm_ctx::set_pde(void* addr, const ::pde& pde, bool use_hyperspace)
{ {
if (!dirbase || !addr) if (!dirbase || !addr)
return false; return false;
@ -281,7 +281,7 @@ namespace nasa
return write_phys(addr, pde); return write_phys(addr, pde);
} }
auto mem_ctx::get_pdpte(void* addr, bool use_hyperspace) -> std::pair<ppdpte, pdpte> auto ptm_ctx::get_pdpte(void* addr, bool use_hyperspace) -> std::pair<ppdpte, pdpte>
{ {
if (!dirbase || !addr) if (!dirbase || !addr)
return { {}, {} }; return { {}, {} };
@ -293,7 +293,7 @@ namespace nasa
return { {}, {} }; return { {}, {} };
} }
bool mem_ctx::set_pdpte(void* addr, const ::pdpte& pdpte, bool use_hyperspace) bool ptm_ctx::set_pdpte(void* addr, const ::pdpte& pdpte, bool use_hyperspace)
{ {
if (!dirbase || !addr) if (!dirbase || !addr)
return false; return false;
@ -306,7 +306,7 @@ namespace nasa
return write_phys(addr, pdpte); return write_phys(addr, pdpte);
} }
auto mem_ctx::get_pml4e(void* addr, bool use_hyperspace) -> std::pair<ppml4e, pml4e> auto ptm_ctx::get_pml4e(void* addr, bool use_hyperspace) -> std::pair<ppml4e, pml4e>
{ {
if (!dirbase || !addr) if (!dirbase || !addr)
return { {}, {} }; return { {}, {} };
@ -318,7 +318,7 @@ namespace nasa
return { {}, {} }; return { {}, {} };
} }
bool mem_ctx::set_pml4e(void* addr, const ::pml4e& pml4e, bool use_hyperspace) bool ptm_ctx::set_pml4e(void* addr, const ::pml4e& pml4e, bool use_hyperspace)
{ {
if (!dirbase || !addr) if (!dirbase || !addr)
return false; return false;
@ -331,7 +331,7 @@ namespace nasa
return write_phys(addr, pml4e); return write_phys(addr, pml4e);
} }
auto mem_ctx::read_virtual(void* buffer, void* addr, std::size_t size) -> std::pair<void*, void*> auto ptm_ctx::read_virtual(void* buffer, void* addr, std::size_t size) -> std::pair<void*, void*>
{ {
if (!buffer || !addr || !size || !dirbase) if (!buffer || !addr || !size || !dirbase)
return {}; return {};
@ -373,7 +373,7 @@ namespace nasa
} }
} }
auto mem_ctx::write_virtual(void* buffer, void* addr, std::size_t size) -> std::pair<void*, void*> auto ptm_ctx::write_virtual(void* buffer, void* addr, std::size_t size) -> std::pair<void*, void*>
{ {
if (!buffer || !addr || !size || !dirbase) if (!buffer || !addr || !size || !dirbase)
return {}; return {};
@ -415,7 +415,7 @@ namespace nasa
} }
} }
bool mem_ctx::read_phys(void* buffer, void* addr, std::size_t size) bool ptm_ctx::read_phys(void* buffer, void* addr, std::size_t size)
{ {
if (!buffer || !addr || !size) if (!buffer || !addr || !size)
return false; return false;
@ -432,7 +432,7 @@ namespace nasa
return true; return true;
} }
bool mem_ctx::write_phys(void* buffer, void* addr, std::size_t size) bool ptm_ctx::write_phys(void* buffer, void* addr, std::size_t size)
{ {
if (!buffer || !addr || !size) if (!buffer || !addr || !size)
return false; return false;
@ -449,7 +449,7 @@ namespace nasa
return true; return true;
} }
void* mem_ctx::virt_to_phys(pt_entries& entries, void* addr) void* ptm_ctx::virt_to_phys(pt_entries& entries, void* addr)
{ {
if (!addr || !dirbase) if (!addr || !dirbase)
return {}; return {};

@ -2,13 +2,13 @@
#include "../util/nt.hpp" #include "../util/nt.hpp"
#include "../vdm_ctx/vdm_ctx.hpp" #include "../vdm_ctx/vdm_ctx.hpp"
namespace nasa namespace ptm
{ {
class mem_ctx class ptm_ctx
{ {
public: public:
explicit mem_ctx(vdm::vdm_ctx* v_ctx, std::uint32_t pid = GetCurrentProcessId()); explicit ptm_ctx(vdm::vdm_ctx* v_ctx, std::uint32_t pid = GetCurrentProcessId());
~mem_ctx(); ~ptm_ctx();
auto get_pte(void* addr, bool use_hyperspace = false) -> std::pair<ppte, pte>; auto get_pte(void* addr, bool use_hyperspace = false) -> std::pair<ppte, pte>;
bool set_pte(void* addr, const ::pte& pte, bool use_hyperspace = false); bool set_pte(void* addr, const ::pte& pte, bool use_hyperspace = false);

Binary file not shown.

@ -26,6 +26,6 @@ int __cdecl main(int argc, char** argv)
); );
std::printf("[+] driver mapping result -> 0x%x (0 == mapper_error::error_success)\n", result); std::printf("[+] driver mapping result -> 0x%x (0 == mapper_error::error_success)\n", result);
std::printf("[+] driver base address (usermode) -> 0x%p\n", driver_base); std::printf("[+] driver base address -> 0x%p\n", driver_base);
std::getchar(); std::getchar();
} }
Loading…
Cancel
Save