remote local hook WIP

This commit is contained in:
DarthTon
2015-01-13 13:50:48 +02:00
parent ee7930ea03
commit 2921538719
13 changed files with 371 additions and 227 deletions
+2
View File
@@ -408,6 +408,7 @@
<ClCompile Include="Process\ProcessModules.cpp" />
<ClCompile Include="Process\RPC\RemoteExec.cpp" />
<ClCompile Include="Process\RPC\RemoteHook.cpp" />
<ClCompile Include="Process\RPC\RemoteLocalHook.cpp" />
<ClCompile Include="Process\RPC\RemoteMemory.cpp" />
<ClCompile Include="Process\Threads\Thread.cpp" />
<ClCompile Include="Process\Threads\Threads.cpp" />
@@ -499,6 +500,7 @@
<ClInclude Include="Process\RPC\RemoteExec.h" />
<ClInclude Include="Process\RPC\RemoteFunction.hpp" />
<ClInclude Include="Process\RPC\RemoteHook.h" />
<ClInclude Include="Process\RPC\RemoteLocalHook.h" />
<ClInclude Include="Process\RPC\RemoteMemory.h" />
<ClInclude Include="Process\Threads\Thread.h" />
<ClInclude Include="Process\Threads\Threads.h" />
+17 -11
View File
@@ -25,9 +25,6 @@
<Filter Include="ManualMap\Native">
<UniqueIdentifier>{ed49eaa5-5d59-4422-9da7-4e68f2e82774}</UniqueIdentifier>
</Filter>
<Filter Include="Process\RPC">
<UniqueIdentifier>{f688ae04-991b-40b2-9243-89e38275be42}</UniqueIdentifier>
</Filter>
<Filter Include="AsmJit">
<UniqueIdentifier>{400c27bd-fb7a-4125-abf2-90a4bdb04f09}</UniqueIdentifier>
</Filter>
@@ -46,6 +43,9 @@
<Filter Include="AsmJit\Core">
<UniqueIdentifier>{84644925-22dd-4022-be68-30ddf267b977}</UniqueIdentifier>
</Filter>
<Filter Include="Process\Remote">
<UniqueIdentifier>{f688ae04-991b-40b2-9243-89e38275be42}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Subsystem\NativeSubsystem.cpp">
@@ -82,10 +82,10 @@
<Filter>Process\Threads</Filter>
</ClCompile>
<ClCompile Include="Process\RPC\RemoteExec.cpp">
<Filter>Process\RPC</Filter>
<Filter>Process\Remote</Filter>
</ClCompile>
<ClCompile Include="Process\RPC\RemoteHook.cpp">
<Filter>Process\RPC</Filter>
<Filter>Process\Remote</Filter>
</ClCompile>
<ClCompile Include="PE\ImageNET.cpp">
<Filter>PE</Filter>
@@ -121,7 +121,7 @@
<Filter>DriverControl</Filter>
</ClCompile>
<ClCompile Include="Process\RPC\RemoteMemory.cpp">
<Filter>Process\RPC</Filter>
<Filter>Process\Remote</Filter>
</ClCompile>
<ClCompile Include="Asm\AsmHelper32.cpp">
<Filter>AsmJit\Helpers</Filter>
@@ -189,6 +189,9 @@
<ClCompile Include="..\..\contrib\AsmJit\base\zone.cpp">
<Filter>AsmJit\Core</Filter>
</ClCompile>
<ClCompile Include="Process\RPC\RemoteLocalHook.cpp">
<Filter>Process\Remote</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Config.h" />
@@ -226,16 +229,16 @@
<Filter>Process\Threads</Filter>
</ClInclude>
<ClInclude Include="Process\RPC\RemoteContext.hpp">
<Filter>Process\RPC</Filter>
<Filter>Process\Remote</Filter>
</ClInclude>
<ClInclude Include="Process\RPC\RemoteExec.h">
<Filter>Process\RPC</Filter>
<Filter>Process\Remote</Filter>
</ClInclude>
<ClInclude Include="Process\RPC\RemoteFunction.hpp">
<Filter>Process\RPC</Filter>
<Filter>Process\Remote</Filter>
</ClInclude>
<ClInclude Include="Process\RPC\RemoteHook.h">
<Filter>Process\RPC</Filter>
<Filter>Process\Remote</Filter>
</ClInclude>
<ClInclude Include="PE\ImageNET.h">
<Filter>PE</Filter>
@@ -316,7 +319,7 @@
<Filter>DriverControl</Filter>
</ClInclude>
<ClInclude Include="Process\RPC\RemoteMemory.h">
<Filter>Process\RPC</Filter>
<Filter>Process\Remote</Filter>
</ClInclude>
<ClInclude Include="Asm\AsmHelper64.h">
<Filter>AsmJit\Helpers</Filter>
@@ -426,5 +429,8 @@
<ClInclude Include="..\..\contrib\AsmJit\base\zone.h">
<Filter>AsmJit\Core</Filter>
</ClInclude>
<ClInclude Include="Process\RPC\RemoteLocalHook.h">
<Filter>Process\Remote</Filter>
</ClInclude>
</ItemGroup>
</Project>
+188 -188
View File
@@ -2,209 +2,209 @@
namespace blackbone
{
std::unordered_map<void*, DetourBase*> DetourBase::_breakpoints;
void* DetourBase::_vecHandler = nullptr;
std::unordered_map<void*, DetourBase*> DetourBase::_breakpoints;
void* DetourBase::_vecHandler = nullptr;
DetourBase::DetourBase()
DetourBase::DetourBase()
{
_buf = (uint8_t*)VirtualAlloc( nullptr, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
_origCode = _buf + 0x100;
_newCode = _buf + 0x200;
}
DetourBase::~DetourBase()
{
VirtualFree( _buf, 0, MEM_RELEASE );
}
/// <summary>
/// Temporarily disable hook
/// </summary>
/// <returns>true on success</returns>
bool DetourBase::DisableHook()
{
if (_type == HookType::InternalInline || _type == HookType::Int3)
WriteProcessMemory( GetCurrentProcess(), _original, _origCode, _origSize, NULL );
else if (_type == HookType::HWBP)
ToggleHBP( _hwbpIdx[GetCurrentThreadId()], false );
return true;
}
/// <summary>
/// Enable disabled hook
/// </summary>
/// <returns>true on success</returns>
bool DetourBase::EnableHook()
{
if (_type == HookType::InternalInline || _type == HookType::Int3)
WriteProcessMemory( GetCurrentProcess(), _original, _newCode, _origSize, NULL );
else if (_type == HookType::HWBP)
ToggleHBP( _hwbpIdx[GetCurrentThreadId()], true );
return true;
}
/// <summary>
/// Toggle hardware breakpoint for current thread
/// </summary>
/// <param name="index">Breakpoint index ( 0-4 )</param>
/// <param name="enable">true to enable, false to disable</param>
/// <returns>true on success</returns>
bool DetourBase::ToggleHBP( int index, bool enable )
{
CONTEXT context = { 0 };
context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
if (GetThreadContext( GetCurrentThread(), &context ) != TRUE)
return FALSE;
if (enable)
BitTestAndSetT( (LONG_PTR*)&context.Dr7, 2 * index );
else
BitTestAndResetT( (LONG_PTR*)&context.Dr7, 2 * index );
return (SetThreadContext( GetCurrentThread(), &context ) != FALSE);
}
/// <summary>
/// Copy original function bytes
/// </summary>
/// <param name="Ptr">Origianl function address</param>
void DetourBase::CopyOldCode( uint8_t* ptr )
{
// Store original bytes
uint8_t* src = ptr;
uint8_t* old = (uint8_t*)_origCode;
uint32_t all_len = 0;
ldasm_data ld = { 0 };
do
{
_buf = (uint8_t*)VirtualAlloc( nullptr, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
_origCode = _buf + 0x100;
_newCode = _buf + 0x200;
}
uint32_t len = ldasm( src, &ld, is_x64 );
DetourBase::~DetourBase()
{
VirtualFree( _buf, 0, MEM_RELEASE );
}
/// <summary>
/// Temporarily disable hook
/// </summary>
/// <returns>true on success</returns>
bool DetourBase::DisableHook()
{
if (_type == HookType::InternalInline || _type == HookType::Int3)
WriteProcessMemory( GetCurrentProcess(), _original, _origCode, _origSize, NULL );
else if (_type == HookType::HWBP)
ToggleHBP( _hwbpIdx[GetCurrentThreadId()], false );
return true;
}
/// <summary>
/// Enable disabled hook
/// </summary>
/// <returns>true on success</returns>
bool DetourBase::EnableHook()
{
if (_type == HookType::InternalInline || _type == HookType::Int3)
WriteProcessMemory( GetCurrentProcess(), _original, _newCode, _origSize, NULL );
else if (_type == HookType::HWBP)
ToggleHBP( _hwbpIdx[GetCurrentThreadId()], true );
return true;
}
/// <summary>
/// Toggle hardware breakpoint for current thread
/// </summary>
/// <param name="index">Breakpoint index ( 0-4 )</param>
/// <param name="enable">true to enable, false to disable</param>
/// <returns>true on success</returns>
bool DetourBase::ToggleHBP( int index, bool enable )
{
CONTEXT context = { 0 };
context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
if (GetThreadContext( GetCurrentThread(), &context ) != TRUE)
return FALSE;
if (enable)
BitTestAndSetT( (LONG_PTR*)&context.Dr7, 2 * index );
else
BitTestAndResetT( (LONG_PTR*)&context.Dr7, 2 * index );
return (SetThreadContext( GetCurrentThread(), &context ) != FALSE);
}
/// <summary>
/// Copy original function bytes
/// </summary>
/// <param name="Ptr">Origianl function address</param>
void DetourBase::CopyOldCode( uint8_t* ptr )
{
// Store original bytes
uint8_t* src = ptr;
uint8_t* old = (uint8_t*)_origCode;
uint32_t all_len = 0;
ldasm_data ld = { 0 };
do
// Determine code end
if (ld.flags & F_INVALID
|| (len == 1 && (src[ld.opcd_offset] == 0xCC || src[ld.opcd_offset] == 0xC3))
|| (len == 3 && src[ld.opcd_offset] == 0xC2)
|| len + all_len > 128)
{
uint32_t len = ldasm( src, &ld, is_x64 );
break;
}
// Determine code end
if (ld.flags & F_INVALID
|| (len == 1 && (src[ld.opcd_offset] == 0xCC || src[ld.opcd_offset] == 0xC3))
|| (len == 3 && src[ld.opcd_offset] == 0xC2)
|| len + all_len > 128)
{
// move instruction
memcpy( old, src, len );
// if instruction has relative offset, calculate new offset
if (ld.flags & F_RELATIVE)
{
#ifdef USE64
// exit if jump is greater then 2GB
if (_abs64( (uintptr_t)(src + *((int*)(old + ld.opcd_size))) - (uintptr_t)old ) > INT_MAX)
break;
}
// move instruction
memcpy( old, src, len );
// if instruction has relative offset, calculate new offset
if (ld.flags & F_RELATIVE)
{
#ifdef USE64
// exit if jump is greater then 2GB
if (_abs64( (uintptr_t)(src + *((int*)(old + ld.opcd_size))) - (uintptr_t)old ) > INT_MAX)
break;
else
*(uint32_t*)(old + ld.opcd_size) += (uint32_t)(src - old);
#else
*(uintptr_t*)(old + ld.opcd_size) += src - old;
#endif
}
src += len;
old += len;
all_len += len;
} while (all_len < _origSize);
// Failed to copy old code, use backup plan
if (all_len < _origSize)
{
_type = HookType::InternalInline;
memcpy( _origCode, ptr, _origSize );
}
else
{
SET_JUMP( old, src );
_callOriginal = _origCode;
}
}
/// <summary>
/// Exception handler
/// </summary>
/// <param name="excpt">Exception information</param>
/// <returns>Exception disposition</returns>
LONG NTAPI DetourBase::VectoredHandler( PEXCEPTION_POINTERS excpt )
{
switch (excpt->ExceptionRecord->ExceptionCode)
{
case EXCEPTION_BREAKPOINT:
return Int3Handler( excpt );
case EXCEPTION_ACCESS_VIOLATION:
return AVHandler( excpt );
case EXCEPTION_SINGLE_STEP:
return StepHandler( excpt );
default:
return EXCEPTION_CONTINUE_SEARCH;
}
}
/// <summary>
/// Int3 exception handler
/// </summary>
/// <param name="excpt">Exception information</param>
/// <returns>Exception disposition</returns>
LONG NTAPI DetourBase::Int3Handler( PEXCEPTION_POINTERS excpt )
{
if (_breakpoints.count( excpt->ExceptionRecord->ExceptionAddress ))
{
DetourBase* pInst = _breakpoints[excpt->ExceptionRecord->ExceptionAddress];
((_NT_TIB*)NtCurrentTeb())->ArbitraryUserPointer = (void*)pInst;
excpt->ContextRecord->NIP = (uintptr_t)pInst->_internalHandler;
return EXCEPTION_CONTINUE_EXECUTION;
else
*(uint32_t*)(old + ld.opcd_size) += (uint32_t)(src - old);
#else
*(uintptr_t*)(old + ld.opcd_size) += src - old;
#endif
}
return EXCEPTION_CONTINUE_SEARCH;
}
src += len;
old += len;
all_len += len;
/// <summary>
/// Access violation handler
/// </summary>
/// <param name="excpt">Exception information</param>
/// <returns>Exception disposition</returns>
LONG NTAPI DetourBase::AVHandler( PEXCEPTION_POINTERS /*excpt*/ )
} while (all_len < _origSize);
// Failed to copy old code, use backup plan
if (all_len < _origSize)
{
return EXCEPTION_CONTINUE_SEARCH;
}
/// <summary>
/// Single step exception handler
/// </summary>
/// <param name="excpt">Exception information</param>
/// <returns>Exception disposition</returns>
LONG NTAPI DetourBase::StepHandler( PEXCEPTION_POINTERS excpt )
_type = HookType::InternalInline;
memcpy( _origCode, ptr, _origSize );
}
else
{
DWORD index = 0;
int found = _BitScanForward( &index, static_cast<DWORD>(excpt->ContextRecord->Dr6) );
SET_JUMP( old, src );
_callOriginal = _origCode;
}
}
if (found != 0 && index < 4 && _breakpoints.count( excpt->ExceptionRecord->ExceptionAddress ))
{
DetourBase* pInst = _breakpoints[excpt->ExceptionRecord->ExceptionAddress];
// Disable breakpoint at current index
BitTestAndResetT( (LONG_PTR*)&excpt->ContextRecord->Dr7, 2 * index );
/// <summary>
/// Exception handler
/// </summary>
/// <param name="excpt">Exception information</param>
/// <returns>Exception disposition</returns>
LONG NTAPI DetourBase::VectoredHandler( PEXCEPTION_POINTERS excpt )
{
switch (excpt->ExceptionRecord->ExceptionCode)
{
case EXCEPTION_BREAKPOINT:
return Int3Handler( excpt );
((_NT_TIB*)NtCurrentTeb())->ArbitraryUserPointer = (void*)pInst;
excpt->ContextRecord->NIP = (uintptr_t)pInst->_internalHandler;
case EXCEPTION_ACCESS_VIOLATION:
return AVHandler( excpt );
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
case EXCEPTION_SINGLE_STEP:
return StepHandler( excpt );
default:
return EXCEPTION_CONTINUE_SEARCH;
}
}
/// <summary>
/// Int3 exception handler
/// </summary>
/// <param name="excpt">Exception information</param>
/// <returns>Exception disposition</returns>
LONG NTAPI DetourBase::Int3Handler( PEXCEPTION_POINTERS excpt )
{
if (_breakpoints.count( excpt->ExceptionRecord->ExceptionAddress ))
{
DetourBase* pInst = _breakpoints[excpt->ExceptionRecord->ExceptionAddress];
((_NT_TIB*)NtCurrentTeb())->ArbitraryUserPointer = (void*)pInst;
excpt->ContextRecord->NIP = (uintptr_t)pInst->_internalHandler;
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
/// <summary>
/// Access violation handler
/// </summary>
/// <param name="excpt">Exception information</param>
/// <returns>Exception disposition</returns>
LONG NTAPI DetourBase::AVHandler( PEXCEPTION_POINTERS /*excpt*/ )
{
return EXCEPTION_CONTINUE_SEARCH;
}
/// <summary>
/// Single step exception handler
/// </summary>
/// <param name="excpt">Exception information</param>
/// <returns>Exception disposition</returns>
LONG NTAPI DetourBase::StepHandler( PEXCEPTION_POINTERS excpt )
{
DWORD index = 0;
int found = _BitScanForward( &index, static_cast<DWORD>(excpt->ContextRecord->Dr6) );
if (found != 0 && index < 4 && _breakpoints.count( excpt->ExceptionRecord->ExceptionAddress ))
{
DetourBase* pInst = _breakpoints[excpt->ExceptionRecord->ExceptionAddress];
// Disable breakpoint at current index
BitTestAndResetT( (LONG_PTR*)&excpt->ContextRecord->Dr7, 2 * index );
((_NT_TIB*)NtCurrentTeb())->ArbitraryUserPointer = (void*)pInst;
excpt->ContextRecord->NIP = (uintptr_t)pInst->_internalHandler;
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
}
+5 -5
View File
@@ -16,9 +16,9 @@ namespace CallOrder
{
enum e
{
HookFirst,
HookLast,
NoOriginal,
HookFirst, // Hook called before original function
HookLast, // Hook called after original function
NoOriginal, // Original function doesn't get called
};
}
@@ -40,8 +40,8 @@ namespace ReturnMethod
{
enum e
{
UseNew,
UseOriginal
UseNew, // Return value returned by hook
UseOriginal // Return original function value
};
}
+1
View File
@@ -13,6 +13,7 @@ Process::Process()
, _memory( this )
, _threads( _core )
, _hooks( _memory )
, _localHooks( *this )
, _remote( *this )
, _mmap( *this )
, _nativeLdr( *this )
+20 -16
View File
@@ -6,6 +6,7 @@
#include "Threads/Threads.h"
#include "RPC/RemoteExec.h"
#include "RPC/RemoteHook.h"
#include "RPC/RemoteLocalHook.h"
#include "../ManualMap/Native/NtLoader.h"
#include "../ManualMap/MMap.h"
@@ -141,14 +142,15 @@ public:
//
// Subroutines
//
BLACKBONE_API inline ProcessCore& core() { return _core; } // Core routines and native
BLACKBONE_API inline ProcessMemory& memory() { return _memory; } // Memory manipulations
BLACKBONE_API inline ProcessModules& modules() { return _modules; } // Module management
BLACKBONE_API inline ProcessThreads& threads() { return _threads; } // Threads
BLACKBONE_API inline RemoteHook& hooks() { return _hooks; } // Hooking code remotely
BLACKBONE_API inline RemoteExec& remote() { return _remote; } // Remote code execution
BLACKBONE_API inline MMap& mmap() { return _mmap; } // Manual module mapping
BLACKBONE_API inline NtLdr& nativeLdr() { return _nativeLdr; } // Native loader routines
BLACKBONE_API inline ProcessCore& core() { return _core; } // Core routines and native
BLACKBONE_API inline ProcessMemory& memory() { return _memory; } // Memory manipulations
BLACKBONE_API inline ProcessModules& modules() { return _modules; } // Module management
BLACKBONE_API inline ProcessThreads& threads() { return _threads; } // Threads
BLACKBONE_API inline RemoteHook& hooks() { return _hooks; } // Hooking code remotely
BLACKBONE_API inline RemoteLocalHook& localHooks() { return _localHooks; } // Hooking code remotely
BLACKBONE_API inline RemoteExec& remote() { return _remote; } // Remote code execution
BLACKBONE_API inline MMap& mmap() { return _mmap; } // Manual module mapping
BLACKBONE_API inline NtLdr& nativeLdr() { return _nativeLdr; } // Native loader routines
private:
/// <summary>
@@ -160,15 +162,17 @@ private:
Process(const Process&) = delete;
Process& operator =(const Process&) = delete;
private:
ProcessCore _core; // Core routines and native subsystem
ProcessModules _modules; // Module management
ProcessMemory _memory; // Memory manipulations
ProcessThreads _threads; // Threads
RemoteHook _hooks; // Hooking code remotely
RemoteExec _remote; // Remote code execution
MMap _mmap; // Manual module mapping
NtLdr _nativeLdr; // Native loader routines
ProcessCore _core; // Core routines and native subsystem
ProcessModules _modules; // Module management
ProcessMemory _memory; // Memory manipulations
ProcessThreads _threads; // Threads
RemoteHook _hooks; // Hooking code remotely
RemoteLocalHook _localHooks; // In-process remote hooks
RemoteExec _remote; // Remote code execution
MMap _mmap; // Manual module mapping
NtLdr _nativeLdr; // Native loader routines
};
}
-1
View File
@@ -1,6 +1,5 @@
#pragma once
#include "../Include/Winheaders.h"
#include "../Include/NativeStructures.h"
#include "../Subsystem/Wow64Subsystem.h"
#include "../Subsystem/x86Subsystem.h"
+20 -3
View File
@@ -343,9 +343,11 @@ exportData ProcessModules::GetExport( const ModuleData* hMod, const char* name_o
/// Inject image into target process
/// </summary>
/// <param name="path">Full-qualified image path</param>
/// <param name="pStatus">Injection status code</param>
/// <returns>Module info. nullptr if failed</returns>
const ModuleData* ProcessModules::Inject( const std::wstring& path )
const ModuleData* ProcessModules::Inject( const std::wstring& path, NTSTATUS* pStatus /*= nullptr*/ )
{
NTSTATUS status = STATUS_SUCCESS;
const ModuleData* mod = nullptr;
ptr_t res = 0;
auto& barrier = _core.native()->GetWow64Barrier();
@@ -358,7 +360,12 @@ const ModuleData* ProcessModules::Inject( const std::wstring& path )
// Already loaded
if ((mod = GetModule( path, LdrList, img.mType() )) != nullptr)
{
if (pStatus)
*pStatus = STATUS_IMAGE_ALREADY_LOADED;
return mod;
}
// Image path
UNICODE_STRING ustr = { 0 };
@@ -378,7 +385,7 @@ const ModuleData* ProcessModules::Inject( const std::wstring& path )
// Try to use LoadLibrary if possible
if (pLoadLibrary != 0 && sameArch)
{
_proc.remote().ExecDirect( pLoadLibrary, modName.ptr<ptr_t>() + sizeof(ustr) );
_proc.remote().ExecDirect( pLoadLibrary, modName.ptr() + sizeof( ustr ) );
}
// Can't generate code through WOW64 barrier
else if ((barrier.type != wow_32_64 && img.mType() == mt_mod64) ||
@@ -386,7 +393,12 @@ const ModuleData* ProcessModules::Inject( const std::wstring& path )
{
auto pLdrLoadDll = GetExport( GetModule( L"ntdll.dll", Sections, img.mType() ), "LdrLoadDll" ).procAddress;
if (pLdrLoadDll == 0)
{
if (pStatus)
*pStatus = STATUS_NOT_FOUND;
return nullptr;
}
// Patch LdrFindOrMapDll to enable kernel32.dll loading
#ifdef USE64
@@ -410,9 +422,14 @@ const ModuleData* ProcessModules::Inject( const std::wstring& path )
a.GenCall( (size_t)pLdrLoadDll, { 0, 0, modName.ptr<size_t>(), modName.ptr<size_t>() + 0x800 } );
a->ret();
_proc.remote().ExecInNewThread( a->make(), a->getCodeSize(), res );
status = _proc.remote().ExecInNewThread( a->make(), a->getCodeSize(), res );
if (NT_SUCCESS( status ))
status = static_cast<NTSTATUS>(res);
}
if (pStatus)
*pStatus = status;
if (res == STATUS_SUCCESS)
return GetModule( path, LdrList, img.mType() );
else
+2 -1
View File
@@ -120,8 +120,9 @@ public:
/// Inject image into target process
/// </summary>
/// <param name="path">Full-qualified image path</param>
/// <param name="pStatus">Injection status code</param>
/// <returns>Module info. nullptr if failed</returns>
BLACKBONE_API const ModuleData* Inject( const std::wstring& path );
BLACKBONE_API const ModuleData* Inject( const std::wstring& path, NTSTATUS* pStatus = nullptr );
#ifdef COMPILER_MSVC
/// <summary>
+1 -2
View File
@@ -1,8 +1,7 @@
#pragma once
#include "../../Include/Winheaders.h"
#include "../ProcessMemory.h"
#include "../ProcessCore.h"
#include "../ProcessMemory.h"
#include "../Threads/Thread.h"
#include "../../Include/Macro.h"
@@ -0,0 +1,52 @@
#include "RemoteLocalHook.h"
#include "../Process.h"
#ifdef USE64
#define HOOK_CTX_T(v, ctx) HookCtx64& v = ctx.hook64
#else
#define HOOK_CTX_T(v, ctx) HookCtx32& v = ctx.hook32
#endif
namespace blackbone
{
RemoteLocalHook::RemoteLocalHook( class Process& process )
: _process( process )
{
}
RemoteLocalHook::~RemoteLocalHook()
{
}
NTSTATUS RemoteLocalHook::SetHook( ptr_t address, asmjit::Assembler& /*hook*/ )
{
HookCtx ctx = { 0 };
HOOK_CTX_T( ctx_t, ctx );
UNREFERENCED_PARAMETER( ctx_t );
// Already hooked
if (_hooks.count( address ) != 0)
return STATUS_ADDRESS_ALREADY_EXISTS;
_hooks.emplace( std::make_pair( address, ctx ) );
return STATUS_SUCCESS;
}
NTSTATUS RemoteLocalHook::Restore( ptr_t address )
{
// No such hook
if (_hooks.count( address ) == 0)
return STATUS_NOT_FOUND;
HOOK_CTX_T( ctx_t, _hooks[address] );
_hooks.erase( address );
return STATUS_SUCCESS;
}
}
@@ -0,0 +1,60 @@
#pragma once
#include "../../Config.h"
#include "../../Asm/AsmHelper.h"
#include "../../Include/Types.h"
#include <unordered_map>
namespace blackbone
{
/// <summary>
/// Hook data, sizeof = 0x50 bytes
/// </summary>
struct HookCtx32
{
uint32_t codeSize; // Size of saved code
uint8_t original_code[34]; // Original function code
};
struct HookCtx64
{
uint64_t dst_ptr; // Target address
uint32_t codeSize; // Size of saved code
uint8_t original_code[32]; // Original function code
uint8_t far_jmp[6]; // Far jump code
};
union HookCtx
{
HookCtx32 hook32;
HookCtx64 hook64;
};
/// <summary>
/// In-process remote hook
/// </summary>
class RemoteLocalHook
{
typedef std::unordered_map<ptr_t, HookCtx> mapCtx;
public:
RemoteLocalHook( class Process& process );
~RemoteLocalHook();
NTSTATUS SetHook( ptr_t address, asmjit::Assembler& hook );
NTSTATUS Restore( ptr_t address );
private:
RemoteLocalHook( const RemoteLocalHook& ) = delete;
RemoteLocalHook& operator = (const RemoteLocalHook&) = delete;
private:
class Process& _process;
mapCtx _hooks;
};
}
@@ -357,7 +357,10 @@ ptr_t NativeWow64::getTEB( HANDLE hThread, _TEB64* pteb )
static ptr_t ntQit = _local.GetProcAddress64( _local.getNTDLL64(), "NtQueryInformationThread" );
if (ntQit == 0)
{
LastNtStatus( STATUS_ORDINAL_NOT_FOUND );
return 0;
}
_local.X64Call( ntQit, hThread, 0, &info, sizeof(info), &bytes );