@ -1,4 +1,4 @@
# include "pclone_ctx.hpp "
# include " pclone_ctx.hpp "
namespace nasa
{
@ -7,67 +7,67 @@ namespace nasa
clone_target_ctx ( clone_ctx )
{ }
pclone_ctx : : ~ pclone_ctx ( )
{
delete clone_source_ctx ;
}
auto pclone_ctx : : clone ( ) - > std : : pair < std : : uint32_t , HANDLE >
{
const auto runtime_broker_pid =
const auto runtime_broker_pid =
util : : start_runtime_broker ( ) ;
const auto runtime_broker_handle =
const auto runtime_broker_handle =
OpenProcess ( PROCESS_ALL_ACCESS , FALSE , runtime_broker_pid ) ;
const auto v_ctx = clone_target_ctx - > v_ctx ;
clone_source_ctx = new mem_ctx (
* v_ctx , runtime_broker_pid ) ;
if ( ! this - > sync ( ) )
return { { } , { } } ;
// zombie the the process by incrementing an exit counter
// then calling TerminateProcess so the process never closes...
const auto runtime_broker_peproc =
v_ctx - > get_peprocess ( runtime_broker_pid ) ;
const auto runtime_broker_peproc =
reinterpret_cast < std : : uintptr_t > (
v_ctx - > get_peprocess ( runtime_broker_pid ) ) ;
static const auto inc_ref_counter =
static const auto inc_ref_counter =
util : : get_kmodule_export (
" ntoskrnl.exe " ,
" PsAcquireProcessExitSynchronization "
) ;
const auto result =
v_ctx - > syscall < NTSTATUS ( * ) ( PEPROCESS ) > (
const auto result =
v_ctx - > syscall < NTSTATUS ( * ) ( std: : uintptr_t ) > (
inc_ref_counter , runtime_broker_peproc ) ;
TerminateProcess ( runtime_broker_handle , NULL ) ;
return { runtime_broker_pid , runtime_broker_handle } ;
}
if ( result ! = STATUS_SUCCESS )
return { { } , { } } ;
bool pclone_ctx : : sync ( ) const
{
// do not remove...
std : : printf ( " [+] clone target dirbase -> 0x%p \n " , clone_target_ctx - > get_dirbase ( ) ) ;
const auto target_pml4 =
clone_target_ctx - > set_page (
clone_target_ctx - > get_dirbase ( ) ) ;
if ( ! TerminateProcess ( runtime_broker_handle , NULL ) )
return { { } , { } } ;
// change the _KPROCESS.DirectoryTableBase to the
// DirectoryTableBase of the process wanting to be
// cloned...
const auto clone_target_peproc =
reinterpret_cast < std : : uintptr_t > (
v_ctx - > get_peprocess ( clone_target_ctx - > get_pid ( ) ) ) ;
// do not remove...
std : : printf ( " [+] clone source dirbase -> 0x%p \n " , clone_source_ctx - > get_dirbase ( ) ) ;
const auto source_pml4 =
clone_source_ctx - > set_page (
clone_source_ctx - > get_dirbase ( ) ) ;
const auto clone_target_dirbase =
v_ctx - > rkm < pte > ( clone_target_peproc + 0x28 ) ;
__try
{
memcpy ( source_pml4 , target_pml4 , PAGE_4KB ) ;
}
__except ( EXCEPTION_EXECUTE_HANDLER )
{
return false ;
}
return true ;
// change dirbase of runtime broker to the dirbase of the desired process...
v_ctx - > wkm < pte > ( runtime_broker_peproc + 0x28 , clone_target_dirbase ) ;
// get the peb offset inside dirbase...
// .text:00000001403387B0 public PsGetProcessPeb
// .text:00000001403387B0 PsGetProcessPeb proc near;
// .text:00000001403387B0 48 8B 81 50 05 00 00 mov rax, [rcx + 550h] <==== + 3 bytes here...
// .text:00000001403387B7 C3 retn
// .text:00000001403387B7 PsGetProcessPeb endp
const auto eprocess_peb_offset =
* reinterpret_cast < std : : uint32_t * > (
reinterpret_cast < std : : uintptr_t > (
GetProcAddress ( GetModuleHandleA (
" ntoskrnl.exe " ) , " PsGetProcessPeb " ) ) + 0x3 ) ; // <==== + 3 bytes here...
const auto clone_target_peb =
v_ctx - > rkm < std : : uintptr_t > (
clone_target_peproc + eprocess_peb_offset ) ;
v_ctx - > wkm < std : : uintptr_t > ( runtime_broker_peproc + eprocess_peb_offset , clone_target_peb ) ;
return { runtime_broker_pid , runtime_broker_handle } ;
}
}