本文整理汇总了C++中AsmJitHelper类的典型用法代码示例。如果您正苦于以下问题:C++ AsmJitHelper类的具体用法?C++ AsmJitHelper怎么用?C++ AsmJitHelper使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了AsmJitHelper类的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: BLACBONE_TRACE
NTSTATUS MMap::DisableExceptions(ImageContext* pImage) {
BLACBONE_TRACE(L"ManualMap: Disabling exception support for image '%ls'", pImage->FileName.c_str());
#ifdef USE64
if(pImage->pExpTableAddr) {
AsmJitHelper a;
size_t result = 0;
auto pRemoveTable = _process.Modules().GetExport(
_process.Modules().GetModule(L"ntdll.dll", LdrList, pImage->peImage.ImageType()),
"RtlDeleteFunctionTable"
);
a.GenPrologue();
// RtlDeleteFunctionTable(pExpTable);
a.GenCall(static_cast<size_t>(pRemoveTable.procAddress), {pImage->pExpTableAddr});
_process.Remote().AddReturnWithEvent(a);
a.GenEpilogue();
auto status = _process.Remote().ExecInWorkerThread(a->make(), a->getCodeSize(), result);
if(!NT_SUCCESS(status))
return status;
return MExcept::RemoveVEH((pImage->flags & CreateLdrRef) != 0);
} else
return STATUS_NOT_FOUND;
#else
return MExcept::RemoveVEH((pImage->flags & PartialExcept) != 0);
#endif
}
示例2: Call
NTSTATUS Call( T& result, std::vector<AsmVariant>& args, Thread* contextThread = nullptr )
{
uint64_t result2 = 0;
AsmJitHelper a;
// Ensure RPC environment exists
if (_process.remote().CreateRPCEnvironment() != STATUS_SUCCESS)
return LastNtStatus();
// FPU check
bool isFloat = std::is_same<T, float>::value;
bool isDouble = std::is_same<T, double>::value || std::is_same<T, long double>::value;
// Deduce return type
eReturnType retType = rt_int32;
if (isFloat)
retType = rt_float;
else if (isDouble)
retType = rt_double;
else if (sizeof(T) == sizeof(uint64_t))
retType = rt_int64;
else if (!std::is_reference<T>::value && sizeof(T) > sizeof(uint64_t))
retType = rt_struct;
auto pfnNew = brutal_cast<const void*>(_pfn);
_process.remote().PrepareCallAssembly( a, pfnNew, args, _callConv, retType );
// Choose execution thread
if (contextThread == nullptr)
_process.remote().ExecInNewThread( a->make(), a->getCodeSize(), result2 );
else if (*contextThread == _process.remote()._hWorkThd)
_process.remote().ExecInWorkerThread( a->make(), a->getCodeSize(), result2 );
else
_process.remote().ExecInAnyThread( a->make(), a->getCodeSize(), result2, *contextThread );
// Get function return value
_process.remote().GetCallResult<T>( result );
return STATUS_SUCCESS;
}
示例3: RemoveVEH
/// <summary>
/// Removes VEH from target process
/// </summary>
/// <returns></returns>
NTSTATUS MExcept::RemoveVEH()
{
AsmJitHelper a;
uint64_t result = 0;
a.GenPrologue();
// RemoveVectoredExceptionHandler(pHandler);
a.GenCall( reinterpret_cast<void*>(&RemoveVectoredExceptionHandler), { _hVEH } );
_proc.remote().AddReturnWithEvent( a );
a.GenEpilogue();
_proc.remote().ExecInWorkerThread( a->make(), a->getCodeSize(), result );
_pVEHCode.Free();
return STATUS_SUCCESS;
}
示例4: RemoveVEH
NTSTATUS MExcept::RemoveVEH(bool partial) {
AsmJitHelper a;
uint64_t result = 0;
auto& mods = _proc.Modules();
auto pRemoveHandler = mods.GetExport(mods.GetModule(L"ntdll.dll"), "RtlRemoveVectoredExceptionHandler").procAddress;
if(pRemoveHandler == 0)
return STATUS_NOT_FOUND;
a.GenPrologue();
// RemoveVectoredExceptionHandler(pHandler);
a.GenCall(static_cast<size_t>(pRemoveHandler), {_hVEH});
_proc.Remote().AddReturnWithEvent(a);
a.GenEpilogue();
// Destroy table and handler
if(!partial) {
_proc.Remote().ExecInWorkerThread(a->make(), a->getCodeSize(), result);
_pVEHCode.Free();
_hVEH = 0;
_pModTable.Free();
}
return STATUS_SUCCESS;
}
示例5: CreateAPCEvent
/// <summary>
/// Create event to synchronize APC procedures
/// </summary>
/// <param name="threadID">The thread identifier.</param>
/// <returns>true on success</returns>
bool RemoteExec::CreateAPCEvent( DWORD threadID )
{
if(_hWaitEvent == NULL)
{
AsmJitHelper a;
wchar_t pEventName[128] = { 0 };
uint64_t dwResult = NULL;
size_t len = sizeof(pEventName);
OBJECT_ATTRIBUTES obAttr = { 0 };
UNICODE_STRING ustr = { 0 };
// Detect ntdll type
eModType mt = mt_default;
if (_memory.core().native()->GetWow64Barrier().type == wow_64_32)
mt = mt_mod64;
// Event name
swprintf_s( pEventName, ARRAYSIZE( pEventName ), L"\\BaseNamedObjects\\_MMapEvent_0x%x_0x%x", threadID, GetTickCount() );
// Prepare Arguments
ustr.Length = static_cast<USHORT>(wcslen( pEventName ) * sizeof(wchar_t));
ustr.MaximumLength = static_cast<USHORT>(sizeof(pEventName));
ustr.Buffer = reinterpret_cast<PWSTR>(_userData.ptr<size_t>() + ARGS_OFFSET + sizeof(obAttr) + sizeof(ustr));
obAttr.ObjectName = reinterpret_cast<PUNICODE_STRING>(_userData.ptr<size_t>() + ARGS_OFFSET + sizeof(obAttr));
obAttr.Length = sizeof(obAttr);
auto pCreateEvent = _mods.GetExport( _mods.GetModule( L"ntdll.dll", Sections, mt ), "NtCreateEvent" ).procAddress;
if (pCreateEvent == 0)
return false;
a.GenCall( static_cast<size_t>(pCreateEvent), {
_userData.ptr<size_t>( ) + EVENT_OFFSET, EVENT_ALL_ACCESS,
_userData.ptr<size_t>() + ARGS_OFFSET, 0, FALSE } );
// Save status
a->mov( asmjit::host::zdx, _userData.ptr<size_t>() + ERR_OFFSET );
a->mov( asmjit::host::dword_ptr( asmjit::host::zdx ), asmjit::host::eax );
a->ret();
NTSTATUS status = _userData.Write( ARGS_OFFSET, obAttr );
status |= _userData.Write( ARGS_OFFSET + sizeof(obAttr), ustr );
status |= _userData.Write( ARGS_OFFSET + sizeof(obAttr) + sizeof(ustr), len, pEventName );
if (status != STATUS_SUCCESS)
return false;
ExecInNewThread( a->make(), a->getCodeSize(), dwResult );
status = _userData.Read<NTSTATUS>( ERR_OFFSET, -1 );
if (status != STATUS_SUCCESS)
return false;
ustr.Buffer = pEventName;
obAttr.ObjectName = &ustr;
// Open created event
status = GET_IMPORT( NtOpenEvent )( &_hWaitEvent, SYNCHRONIZE | EVENT_MODIFY_STATE, &obAttr );
if (status != STATUS_SUCCESS)
return false;
}
return true;
}
示例6: ExecInNewThread
/// <summary>
/// Create new thread and execute code in it. Wait until execution ends
/// </summary>
/// <param name="pCode">Code to execute</param>
/// <param name="size">Code size</param>
/// <param name="callResult">Code return value</param>
/// <returns>Status</returns>
NTSTATUS RemoteExec::ExecInNewThread( PVOID pCode, size_t size, uint64_t& callResult )
{
AsmJitHelper a;
NTSTATUS dwResult = STATUS_SUCCESS;
// Write code
dwResult = CopyCode( pCode, size );
if (dwResult != STATUS_SUCCESS)
return dwResult;
bool switchMode = (_proc.core().native()->GetWow64Barrier().type == wow_64_32);
auto pExitThread = _mods.GetExport( _mods.GetModule( L"ntdll.dll", LdrList, switchMode ? mt_mod64 : mt_default ), "NtTerminateThread" ).procAddress;
if (pExitThread == 0)
return LastNtStatus( STATUS_NOT_FOUND );
a.GenPrologue( switchMode );
// Prepare thread to run in x64 mode
if(switchMode)
{
// Allocate new x64 activation stack
auto createActStack = _mods.GetExport( _mods.GetModule( L"ntdll.dll", LdrList, mt_mod64 ),
"RtlAllocateActivationContextStack" ).procAddress;
if (createActStack)
{
a.GenCall( static_cast<size_t>(createActStack), { _userData.ptr<size_t>() + 0x3100 } );
a->mov( asmjit::host::zax, _userData.ptr<size_t>( ) + 0x3100 );
a->mov( asmjit::host::zax, asmjit::host::intptr_ptr( asmjit::host::zax ) );
a.SetTebPtr();
a->mov( asmjit::host::intptr_ptr( asmjit::host::zdx, 0x2c8 ), asmjit::host::zax );
}
}
a.GenCall( _userCode.ptr<size_t>(), { } );
a.ExitThreadWithStatus( (size_t)pExitThread, _userData.ptr<size_t>() + INTRET_OFFSET );
// Execute code in newly created thread
if (_userCode.Write( size, a->getCodeSize(), a->make() ) == STATUS_SUCCESS)
{
auto thread = _threads.CreateNew( _userCode.ptr<ptr_t>() + size, _userData.ptr<ptr_t>() );
dwResult = thread.Join();
callResult = _userData.Read<uint64_t>( INTRET_OFFSET, 0 );
}
else
dwResult = LastNtStatus();
return dwResult;
}
示例7: CreateWorkerThread
/// <summary>
/// Create worker RPC thread
/// </summary>
/// <returns>Thread ID</returns>
DWORD RemoteExec::CreateWorkerThread()
{
AsmJitHelper a;
asmjit::Label l_loop = a->newLabel();
//
// Create execution thread
//
if(!_hWorkThd.valid())
{
eModType mt = mt_default;
if (_memory.core().native()->GetWow64Barrier().type == wow_64_32)
{
mt = mt_mod64;
a.SwitchTo64();
// Align stack on 16 byte boundary
a->and_( asmjit::host::zsp, -16 );
// Allocate new x64 activation stack
auto createActStack = _mods.GetExport( _mods.GetModule( L"ntdll.dll", LdrList, mt ),
"RtlAllocateActivationContextStack" ).procAddress;
if(createActStack)
{
a.GenCall( static_cast<size_t>(createActStack), { _userData.ptr<size_t>() + 0x3000 } );
a->mov( asmjit::host::zax, _userData.ptr<size_t>() + 0x3000 );
a->mov( asmjit::host::zax, asmjit::host::intptr_ptr( asmjit::host::zax ) );
a.SetTebPtr();
a->mov( asmjit::host::intptr_ptr( asmjit::host::zdx, 0x2c8 ), asmjit::host::zax );
}
}
auto ntdll = _mods.GetModule( L"ntdll.dll", Sections, mt );
auto proc = _mods.GetExport( ntdll, "NtDelayExecution" ).procAddress;
auto pExitThread = _mods.GetExport( ntdll, "NtTerminateThread" ).procAddress;
if (proc == 0 || pExitThread == 0)
return 0;
/*
for(;;)
SleepEx(5, TRUE);
ExitThread(SetEvent(m_hWaitEvent));
*/
a->bind( l_loop );
a.GenCall( static_cast<size_t>(proc), { TRUE, _workerCode.ptr<size_t>() } );
a->jmp( l_loop );
a.ExitThreadWithStatus( (size_t)pExitThread, _userData.ptr<size_t>() );
// Write code into process
LARGE_INTEGER liDelay = { 0 };
liDelay.QuadPart = -10 * 1000 * 5;
_workerCode.Write( 0, liDelay );
_workerCode.Write( sizeof(LARGE_INTEGER), a->getCodeSize(), a->make() );
_hWorkThd = _threads.CreateNew( _workerCode.ptr<size_t>() + sizeof(LARGE_INTEGER), _userData.ptr<size_t>() );
}
return _hWorkThd.id();
}
示例8: CreateRPCEnvironment
/// <summary>
/// Execute code in context of any existing thread
/// </summary>
/// <param name="pCode">Cde to execute</param>
/// <param name="size">Code size.</param>
/// <param name="callResult">Execution result</param>
/// <param name="thd">Target thread</param>
/// <returns>Status</returns>
NTSTATUS RemoteExec::ExecInAnyThread( PVOID pCode, size_t size, uint64_t& callResult, Thread& thd )
{
NTSTATUS dwResult = STATUS_SUCCESS;
CONTEXT_T ctx;
// Prepare for remote exec
CreateRPCEnvironment( true );
// Write code
dwResult = CopyCode( pCode, size );
if (dwResult != STATUS_SUCCESS)
return dwResult;
if (_hWaitEvent)
ResetEvent( _hWaitEvent );
if (!thd.Suspend())
return LastNtStatus();
if (thd.GetContext( ctx, CONTEXT_ALL, true ))
{
AsmJitHelper a;
#ifdef USE64
const int count = 15;
asmjit::host::GpReg regs[] = { asmjit::host::rax, asmjit::host::rbx, asmjit::host::rcx, asmjit::host::rdx, asmjit::host::rsi,
asmjit::host::rdi, asmjit::host::r8, asmjit::host::r9, asmjit::host::r10, asmjit::host::r11,
asmjit::host::r12, asmjit::host::r13, asmjit::host::r14, asmjit::host::r15, asmjit::host::rbp };
//
// Preserve thread context
// I don't care about FPU, XMM and anything else
//
a->sub( asmjit::host::rsp, count * WordSize ); // Stack must be aligned on 16 bytes
a->pushf(); //
// Save registers
for (int i = 0; i < count; i++)
a->mov( asmjit::host::Mem( asmjit::host::rsp, i * WordSize ), regs[i] );
a.GenCall( _userCode.ptr<size_t>(), { _userData.ptr<size_t>() } );
AddReturnWithEvent( a, mt_default, rt_int32, INTRET_OFFSET );
// Restore registers
for (int i = 0; i < count; i++)
a->mov( regs[i], asmjit::host::Mem( asmjit::host::rsp, i * WordSize ) );
a->popf();
a->add( asmjit::host::rsp, count * WordSize );
a->jmp( asmjit::Imm( ctx.Rip ) );
#else
a->pusha();
a->pushf();
a.GenCall( _userCode.ptr<size_t>(), { _userData.ptr<size_t>() } );
AddReturnWithEvent( a, mt_default, rt_int32, INTRET_OFFSET );
a->popf();
a->popa();
a->push( (size_t)ctx.NIP );
a->ret();
#endif
if (_userCode.Write( size, a->getCodeSize(), a->make() ) == STATUS_SUCCESS)
{
ctx.NIP = _userCode.ptr<size_t>() + size;
if (!thd.SetContext( ctx, true ))
dwResult = LastNtStatus();
}
else
dwResult = LastNtStatus();
}
else
dwResult = LastNtStatus();
thd.Resume();
if (dwResult == STATUS_SUCCESS)
{
WaitForSingleObject( _hWaitEvent, INFINITE );
callResult = _userData.Read<size_t>( INTRET_OFFSET, 0 );
}
return dwResult;
}
示例9: Hook
/// <summary>
/// Hook function in vtable
/// </summary>
/// <param name="ppVtable">Pointer to vtable pointer</param>
/// <param name="index">Function index</param>
/// <param name="hkPtr">Hook function address</param>
/// <param name="copyVtable">if true, vtable will be copied and edited, otherwise existing vtable will be edited</param>
/// <param name="vtableLen">Optional. Valid only when copyVtable is true. Number of function in vtable.
/// Used to determine number of function to copy</param>
/// <returns>true on success</returns>
bool Hook( void** ppVtable, int index, hktype hkPtr, bool copyVtable = false, int vtableLen = 0 )
{
AsmJitHelper jmpToHook;
//_order = CallOrder::HookFirst;
//_retType = ReturnMethod::UseOriginal;
this->_type = HookType::VTable;
this->_callOriginal = this->_original = (*(void***)ppVtable)[index];
this->_callback = hkPtr;
this->_internalHandler = &HookHandler<Fn, C>::Handler;
this->_ppVtable = ppVtable;
this->_pVtable = *ppVtable;
this->_vtIndex = index;
this->_vtCopied = copyVtable;
// Construct jump to hook handler
#ifdef USE64
// mov gs:[0x28], this
jmpToHook->mov( asmjit::host::rax, (uint64_t)this );
jmpToHook->mov( asmjit::host::qword_ptr_abs( 0x28 ).setSegment( asmjit::host::gs ), asmjit::host::rax );
#else
// mov fs:[0x14], this
jmpToHook->mov( asmjit::host::dword_ptr_abs( 0x14 ).setSegment( asmjit::host::fs ), (uint32_t)this );
#endif // USE64
jmpToHook->jmp( (asmjit::Ptr)this->_internalHandler );
jmpToHook->relocCode( this->_buf );
// Modify VTable copy
if (copyVtable)
{
uintptr_t ccpad;
memset( &ccpad, 0xCC, sizeof(ccpad) );
// Copy VTable
if (vtableLen != 0)
{
memcpy( this->_buf + 0x300, *ppVtable, vtableLen * sizeof( void* ) );
}
else for (;; vtableLen++)
{
if ((*(void***)ppVtable)[vtableLen] == nullptr ||
(*(void***)ppVtable)[vtableLen] == (void**)ccpad)
{
memcpy( this->_buf + 0x300, *ppVtable, vtableLen * sizeof( void* ) );
break;
}
}
// Replace pointer to VTable
((void**)this->_buf + 0x300 / sizeof( uintptr_t ))[index] = this->_buf;
*ppVtable = this->_buf + 0x300;
}
// Modify pointer in-place
else
{
DWORD flOld = 0;
VirtualProtect( *(uintptr_t**)ppVtable + index, sizeof(void*), PAGE_EXECUTE_READWRITE, &flOld );
(*(void***)ppVtable)[index] = this->_buf;
VirtualProtect( *(uintptr_t**)ppVtable + index, sizeof(void*), flOld, &flOld );
}
return (this->_hooked = true);
}
示例10: CreateActx
bool MMap::CreateActx(const std::wstring& path, int id /*= 2 */, bool asImage /*= true*/) {
AsmJitHelper a;
uint64_t result = 0;
ACTCTXW act = {0};
_pAContext = _process.Memory().Allocate(512, PAGE_READWRITE);
act.cbSize = sizeof(act);
act.lpSource = reinterpret_cast<LPCWSTR>(_pAContext.Ptr<size_t>() + sizeof(HANDLE) + sizeof(act));
// Ignore some fields for pure manifest file
if(asImage) {
act.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID;
act.lpResourceName = MAKEINTRESOURCEW(id);
}
bool switchMode = (_process.Core().GetNative()->GetWow64Barrier().type == wow_64_32);
auto pCreateActx = _process.Modules().GetExport(_process.Modules().GetModule(L"kernel32.dll"), "CreateActCtxW");
if(pCreateActx.procAddress == 0) {
BLACBONE_TRACE(L"ManualMap: Failed to create activation context for image '%ls'. 'CreateActCtxW' is absent", path.c_str());
return false;
}
// CreateActCtx(&act)
// Emulate Wow64
if(switchMode) {
_ACTCTXW_T<DWORD> act32 = {0};
act32.cbSize = sizeof(act32);
act32.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID;
act32.lpSource = _pAContext.Ptr<uint32_t>() + sizeof(HANDLE) + sizeof(act32);
act32.lpResourceName = id;
a->push(_pAContext.Ptr<uint32_t>() + static_cast<uint32_t>(sizeof(HANDLE)));
a->mov(asmjit::host::eax, static_cast<uint32_t>(pCreateActx.procAddress));
a->call(a->zax);
a->mov(asmjit::host::edx, _pAContext.Ptr<uint32_t>());
//a->mov( asmjit::host::dword_ptr( asmjit::host::edx ), asmjit::host::eax );
a->dw('\x01\x02');
auto pTermThd = _process.Modules().GetExport(_process.Modules().GetModule(L"ntdll.dll"), "NtTerminateThread");
a->push(a->zax);
a->push(uint32_t(0));
a->mov(asmjit::host::eax, static_cast<uint32_t>(pTermThd.procAddress));
a->call(a->zax);
a->ret(4);
// Write path to file
_pAContext.Write(sizeof(HANDLE), act32);
_pAContext.Write(sizeof(HANDLE) + sizeof(act32), (path.length() + 1) * sizeof(wchar_t), path.c_str());
auto pCode = _process.Memory().Allocate(0x1000);
pCode.Write(0, a->getCodeSize(), a->make());
result = _process.Remote().ExecDirect(pCode.Ptr<ptr_t>(), _pAContext.Ptr<size_t>() + sizeof(HANDLE));
}
// Native way
else {
a.GenPrologue();
a.GenCall(static_cast<size_t>(pCreateActx.procAddress), {_pAContext.Ptr<size_t>() + sizeof(HANDLE)});
a->mov(a->zdx, _pAContext.Ptr<size_t>());
a->mov(a->intptr_ptr(a->zdx), a->zax);
_process.Remote().AddReturnWithEvent(a);
a.GenEpilogue();
// Write path to file
_pAContext.Write(sizeof(HANDLE), act);
_pAContext.Write(sizeof(HANDLE) + sizeof(act), (path.length() + 1) * sizeof(wchar_t), path.c_str());
_process.Remote().ExecInWorkerThread(a->make(), a->getCodeSize(), result);
}
if(reinterpret_cast<HANDLE>(result) == INVALID_HANDLE_VALUE) {
_pAContext.Free();
// SetLastError( err::mapping::CantCreateActx );
BLACBONE_TRACE(L"ManualMap: Failed to create activation context for image '%ls'. Status: 0x%x",
path.c_str(), _process.Remote().GetLastStatus());
return false;
}
return true;
}
示例11: RunModuleInitializers
bool MMap::RunModuleInitializers(ImageContext* pImage, DWORD dwReason) {
AsmJitHelper a;
uint64_t result = 0;
auto hNtdll = _process.Modules().GetModule(L"ntdll.dll", LdrList, pImage->peImage.ImageType());
auto pActivateActx = _process.Modules().GetExport(hNtdll, "RtlActivateActivationContext");
auto pDeactivateeActx = _process.Modules().GetExport(hNtdll, "RtlDeactivateActivationContext");
a.GenPrologue();
// ActivateActCtx
if(_pAContext.Valid() && pActivateActx.procAddress) {
a->mov(a->zax, _pAContext.Ptr<size_t>());
a->mov(a->zax, asmjit::host::dword_ptr(a->zax));
a.GenCall(static_cast<size_t>(pActivateActx.procAddress), {0, a->zax, _pAContext.Ptr<size_t>() + sizeof(HANDLE)});
}
// Function order
// TLS first, entry point last
if(dwReason == DLL_PROCESS_ATTACH || dwReason == DLL_THREAD_ATTACH) {
// PTLS_CALLBACK_FUNCTION(pImage->ImageBase, dwReason, NULL);
if(!(pImage->flags & NoTLS))
for(auto& pCallback : pImage->tlsCallbacks) {
BLACBONE_TRACE(L"ManualMap: Calling TLS callback at 0x%p for '%ls', Reason: %d",
static_cast<size_t>(pCallback), pImage->FileName.c_str(), dwReason);
a.GenCall(static_cast<size_t>(pCallback), {pImage->imgMem.Ptr<size_t>(), dwReason, NULL});
}
// DllMain
if(pImage->EntryPoint != 0) {
BLACBONE_TRACE(L"ManualMap: Calling entry point for '%ls', Reason: %d", pImage->FileName.c_str(), dwReason);
a.GenCall(static_cast<size_t>(pImage->EntryPoint), {pImage->imgMem.Ptr<size_t>(), dwReason, NULL});
}
}
// Entry point first, TLS last
else {
// DllMain
if(pImage->EntryPoint != 0) {
BLACBONE_TRACE(L"ManualMap: Calling entry point for '%ls', Reason: %d", pImage->FileName.c_str(), dwReason);
a.GenCall(static_cast<size_t>(pImage->EntryPoint), {pImage->imgMem.Ptr<size_t>(), dwReason, NULL});
}
// PTLS_CALLBACK_FUNCTION(pImage->ImageBase, dwReason, NULL);
if(!(pImage->flags & NoTLS))
for(auto& pCallback : pImage->tlsCallbacks) {
BLACBONE_TRACE(L"ManualMap: Calling TLS callback at 0x%p for '%ls', Reason: %d",
static_cast<size_t>(pCallback), pImage->FileName.c_str(), dwReason);
a.GenCall(static_cast<size_t>(pCallback), {pImage->imgMem.Ptr<size_t>(), dwReason, NULL});
}
}
// DeactivateActCtx
if(_pAContext.Valid() && pDeactivateeActx.procAddress) {
a->mov(a->zax, _pAContext.Ptr<size_t>() + sizeof(HANDLE));
a->mov(a->zax, asmjit::host::dword_ptr(a->zax));
a.GenCall(static_cast<size_t>(pDeactivateeActx.procAddress), {0, a->zax});
}
_process.Remote().AddReturnWithEvent(a, pImage->peImage.ImageType());
a.GenEpilogue();
_process.Remote().ExecInWorkerThread(a->make(), a->getCodeSize(), result);
return true;
}
示例12: CreateVEH
NTSTATUS MExcept::CreateVEH(size_t pTargetBase, size_t imageSize, eModType mt, bool partial) {
AsmJitHelper a;
uint64_t result = 0;
auto& mods = _proc.Modules();
#ifdef USE64
// Add module to module table
if(!_pModTable.Valid()) {
_pModTable = _proc.Memory().Allocate(0x1000);
_pModTable.Release();
if(!_pModTable.Valid())
return LastNtStatus();
}
ModuleTable table;
_pModTable.Read(0, table);
// Add new entry to the table
table.entry[table.count].base = pTargetBase;
table.entry[table.count].size = imageSize;
table.count++;
_pModTable.Write(0, table);
// No handler required
if(partial)
return STATUS_SUCCESS;
// VEH codecave
_pVEHCode = _proc.Memory().Allocate(0x2000);
_pVEHCode.Release();
if(!_pVEHCode.Valid())
return LastNtStatus();
BLACBONE_TRACE("ManualMap: Vectored hander: 0x%p\n", _pVEHCode.Ptr());
asmjit::Label lExit = a->newLabel();
asmjit::Label lLoop1 = a->newLabel();
asmjit::Label skip1 = a->newLabel();
asmjit::Label found1 = a->newLabel();
//
// Assembly code for VectoredHandler64
// 0x10 - EXCEPTION_RECORD.ExceptionAddress
// 0x20 - EXCEPTION_RECORD.ExceptionInformation[0]
// 0x30 - EXCEPTION_RECORD.ExceptionInformation[2]
// 0x38 - EXCEPTION_RECORD.ExceptionInformation[3]
//
a->mov(asmjit::host::rax, asmjit::host::qword_ptr(asmjit::host::rcx));
a->cmp(asmjit::host::dword_ptr(asmjit::host::rax), EH_EXCEPTION_NUMBER); // Exception code
a->jne(lExit);
a->cmp(asmjit::host::qword_ptr(asmjit::host::rax, 0x20), EH_PURE_MAGIC_NUMBER1); // Sub code
a->jne(lExit);
a->cmp(asmjit::host::qword_ptr(asmjit::host::rax, 0x38), 0); // Image base
a->jne(lExit);
a->mov(asmjit::host::r9, _pModTable.Ptr());
a->mov(asmjit::host::rdx, asmjit::host::qword_ptr(asmjit::host::r9)); // Record count
a->add(asmjit::host::r9, sizeof(table.count));
a->xor_(asmjit::host::r10, asmjit::host::r10);
a->bind(lLoop1);
a->mov(asmjit::host::r8, asmjit::host::qword_ptr(asmjit::host::rax, 0x30));
a->mov(asmjit::host::r11, asmjit::host::qword_ptr(asmjit::host::r9));
a->cmp(asmjit::host::r8, asmjit::host::r11);
a->jl(skip1);
a->add(asmjit::host::r11, asmjit::host::qword_ptr(asmjit::host::r9, sizeof(table.entry[0].base))); // Size
a->cmp(asmjit::host::r8, asmjit::host::r11);
a->jg(skip1);
a->jmp(found1);
a->bind(skip1);
a->add(asmjit::host::r9, sizeof(ExceptionModule));
a->add(asmjit::host::r10, 1);
a->cmp(asmjit::host::r10, asmjit::host::rdx);
a->jne(lLoop1);
a->jmp(lExit);
a->bind(found1);
a->mov(asmjit::host::qword_ptr(asmjit::host::rax, 0x20), EH_MAGIC_NUMBER1);
a->mov(asmjit::host::rcx, asmjit::host::qword_ptr(asmjit::host::rcx));
a->mov(asmjit::host::rdx, asmjit::host::qword_ptr(asmjit::host::r9));
a->mov(asmjit::host::qword_ptr(asmjit::host::rax, 0x38), asmjit::host::rdx);
a->bind(lExit);
a->xor_(asmjit::host::rax, asmjit::host::rax);
a->ret();
a->db(0xCC);
a->db(0xCC);
a->db(0xCC);
if(_pVEHCode.Write(0, a->getCodeSize(), a->make()) != STATUS_SUCCESS) {
_pVEHCode.Free();
return LastNtStatus();
}
#else
UNREFERENCED_PARAMETER(pTargetBase);
UNREFERENCED_PARAMETER(imageSize);
// No handler required
if(partial)
return STATUS_SUCCESS;
// VEH codecave
_pVEHCode = _proc.Memory().Allocate(0x2000);
_pVEHCode.Release();
if(!_pVEHCode.Valid())
return LastNtStatus();
// Resolve compiler incremental table address, if any
void *pFunc = ResolveJmp(&VectoredHandler);
size_t fnSize = static_cast<size_t>(SizeOfProc(pFunc));
size_t dataOfs = 0, code_ofs = 0, code_ofs2 = 0;;
// Find and replace magic values
for(uint8_t *pData = reinterpret_cast<uint8_t*>(pFunc);
pData < reinterpret_cast<uint8_t*>(pFunc) + fnSize - 4;
pData++) {
// LdrpInvertedFunctionTable
//.........这里部分代码省略.........
示例13: CreateVEH
/// <summary>
/// Inject VEH wrapper into process
/// Used to enable execution of SEH handlers out of image
/// </summary>
/// <param name="pTargetBase">Target image base address</param>
/// <param name="imageSize">Size of the image</param>
/// <returns>Error code</returns>
NTSTATUS MExcept::CreateVEH( size_t pTargetBase, size_t imageSize )
{
AsmJitHelper ea;
uint64_t result = 0;
// VEH codecave
_pVEHCode = _proc.memory().Allocate( 0x2000 );
_pVEHCode.Release();
if (!_pVEHCode.valid())
return LastNtStatus();
#ifdef USE64
asmjit::Label lExit = ea->newLabel();
//
// Assembly code for VectoredHandler64
// 0x10 - EXCEPTION_RECORD.ExceptionAddress
// 0x20 - EXCEPTION_RECORD.ExceptionInformation[0]
// 0x30 - EXCEPTION_RECORD.ExceptionInformation[2]
// 0x38 - EXCEPTION_RECORD.ExceptionInformation[3]
//
ea->mov( asmjit::host::rax, qword_ptr( asmjit::host::rcx ) );
ea->cmp( asmjit::host::dword_ptr( asmjit::host::rax ), EH_EXCEPTION_NUMBER );
ea->jne( lExit );
ea->mov( asmjit::host::rdx, pTargetBase );
ea->mov( asmjit::host::r8, asmjit::host::qword_ptr( asmjit::host::rax, 0x30 ) );
ea->cmp( asmjit::host::r8, asmjit::host::rdx );;
ea->jl( lExit );
ea->add( asmjit::host::rdx, imageSize );
ea->cmp( asmjit::host::r8, asmjit::host::rdx );;
ea->jg( lExit );
ea->cmp( asmjit::host::qword_ptr( asmjit::host::rax, 0x20 ), EH_PURE_MAGIC_NUMBER1 );;
ea->jne( lExit );
ea->cmp( asmjit::host::qword_ptr( asmjit::host::rax, 0x38 ), 0 );
ea->jne( lExit );
ea->mov( asmjit::host::qword_ptr( asmjit::host::rax, 0x20 ), EH_MAGIC_NUMBER1 );
ea->mov( asmjit::host::rcx, qword_ptr( asmjit::host::rcx ) );
ea->mov( asmjit::host::rdx, pTargetBase );
ea->mov( asmjit::host::qword_ptr( asmjit::host::rax, 0x38 ), asmjit::host::rdx );
ea->bind( lExit );
ea->xor_( asmjit::host::rax, asmjit::host::rax );
ea->ret();
ea->emit( 0xCC );
ea->emit( 0xCC );
ea->emit( 0xCC );
if (_pVEHCode.Write( 0, ea->getCodeSize(), ea->make() ) != STATUS_SUCCESS)
{
_pVEHCode.Free();
return LastNtStatus();
}
#else
UNREFERENCED_PARAMETER( pTargetBase );
UNREFERENCED_PARAMETER( imageSize );
// Resolve compiler incremental table address if any
void *pFunc = ResolveJmp( &VectoredHandler );
size_t fnSize = static_cast<size_t>(SizeOfProc( pFunc ));
size_t dataOfs = 0, code_ofs = 0;
// Find and replace magic values
for (uint8_t *pData = reinterpret_cast<uint8_t*>(pFunc);
pData < reinterpret_cast<uint8_t*>(pFunc) + fnSize - 4;
pData++)
{
// LdrpInvertedFunctionTable
if(*(size_t*)pData == 0xDEADDA7A)
{
dataOfs = pData - reinterpret_cast<uint8_t*>(pFunc);
continue;
}
// DecodeSystemPointer address
if(*(size_t*)pData == 0xDEADC0DE)
{
code_ofs = pData - reinterpret_cast<uint8_t*>(pFunc);
break;
}
}
// Write handler data into target process
if (_pVEHCode.Write( 0, fnSize, pFunc ) != STATUS_SUCCESS ||
_pVEHCode.Write( dataOfs, _proc.nativeLdr().LdrpInvertedFunctionTable() ) != STATUS_SUCCESS ||
_pVEHCode.Write( code_ofs, &DecodeSystemPointer ) != STATUS_SUCCESS)
{
_pVEHCode.Free();
return LastNtStatus();
}
#endif
ea.GenPrologue();
//.........这里部分代码省略.........