microsoft365microsoftmassgravelmassgravewindows-11kms38windows-10kmswindowshwidpowershellactivatorohookoffice365office
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
2.4 KiB
77 lines
2.4 KiB
#pragma once |
|
#include "mem_util.hpp" |
|
#include "mem_iter.hpp" |
|
#include "util_raii.hpp" |
|
|
|
namespace impl |
|
{ |
|
inline bool search_for_signature_helper( const std::uint8_t* data, const std::uint8_t* signature, const char* mask ) |
|
{ |
|
// check if page is correct & readable (this internally checks PTE, PDE, ...) |
|
if ( !MmIsAddressValid( const_cast< std::uint8_t* >( data ) ) ) |
|
return false; |
|
|
|
// iterate through validity of the mask (mask & signature are equal |
|
for ( ; *mask; ++mask, ++data, ++signature ) |
|
if ( *mask == 'x' && *data != *signature ) // if mask is 'x' (a match), and the current byte is not equal to the byte in the signature, then return false. |
|
return false; |
|
|
|
return true; |
|
} |
|
|
|
std::uint8_t* search_for_signature( const nt::rtl_module_info* module, const char* signature, const char* signature_mask ) |
|
{ |
|
if ( !module ) |
|
return nullptr; |
|
|
|
const auto module_start = reinterpret_cast< std::uint8_t* >( module->image_base ); |
|
const auto module_size = module_start + module->image_size; |
|
|
|
/* iterate the entire module */ |
|
for ( auto segment = module_start; segment < module_size; segment++ ) |
|
{ |
|
if ( search_for_signature_helper( segment, reinterpret_cast< std::uint8_t* >( const_cast< char* >( signature ) ), signature_mask ) ) |
|
return segment; |
|
} |
|
|
|
return nullptr; |
|
} |
|
|
|
extern "C" NTSYSAPI PCHAR NTAPI PsGetProcessImageFileName( PEPROCESS ); |
|
|
|
PEPROCESS search_for_process( const char* process_name ) |
|
{ |
|
const auto kernel_module_info = search_for_module( "ntoskrnl.exe" ); |
|
|
|
if ( !kernel_module_info ) |
|
return nullptr; |
|
|
|
/* we are scanning for a conditional jump, that jumps to a call to the unexported function that we want, so we follow the jump, then follow the call to get to the function. */ |
|
const auto conditional_instruction = search_for_signature( kernel_module_info, "\x79\xdc\xe9", "xxx" ); |
|
|
|
if ( !conditional_instruction ) |
|
return nullptr; |
|
|
|
const auto call_instruction = follow_conditional_jump( conditional_instruction ); |
|
|
|
if ( !call_instruction ) |
|
return nullptr; |
|
|
|
const auto PsGetNextProcess = follow_call< PEPROCESS( __stdcall* )( PEPROCESS ) >( call_instruction ); |
|
|
|
if ( !PsGetNextProcess ) |
|
return nullptr; |
|
|
|
PEPROCESS previous_process = PsGetNextProcess( nullptr ); |
|
|
|
while ( previous_process ) |
|
{ |
|
if ( !std::strcmp( PsGetProcessImageFileName( previous_process ), process_name ) ) |
|
return previous_process; |
|
|
|
previous_process = PsGetNextProcess( previous_process ); |
|
} |
|
|
|
return nullptr; |
|
} |
|
}
|
|
|