#include "x86Subsystem.h" #include "../Misc/DynImport.h" #include "../Include/Macro.h" namespace blackbone { x86Native::x86Native( HANDLE hProcess ) : Native( hProcess, true ) { } x86Native::~x86Native() { } /// /// Query virtual memory /// /// Address to query /// Retrieved memory info /// Status code NTSTATUS x86Native::VirtualQueryExT( ptr_t lpAddress, PMEMORY_BASIC_INFORMATION64 lpBuffer ) { MEMORY_BASIC_INFORMATION tmp = { 0 }; NTSTATUS status = SAFE_NATIVE_CALL( NtQueryVirtualMemory, _hProcess, reinterpret_cast(lpAddress), MemoryBasicInformation, &tmp, sizeof( tmp ), nullptr ); if (status != STATUS_SUCCESS) return status; // Map values lpBuffer->AllocationBase = reinterpret_cast(tmp.AllocationBase); lpBuffer->AllocationProtect = tmp.AllocationProtect; lpBuffer->BaseAddress = reinterpret_cast(tmp.BaseAddress); lpBuffer->Protect = tmp.Protect; lpBuffer->RegionSize = tmp.RegionSize; lpBuffer->State = tmp.State; lpBuffer->Type = tmp.Type; return status; } /// /// Get WOW64 thread context /// /// Thread handle. /// Thread context /// Status code NTSTATUS x86Native::GetThreadContextT( HANDLE hThread, _CONTEXT32& ctx ) { SetLastNtStatus( STATUS_SUCCESS ); GetThreadContext( hThread, reinterpret_cast(&ctx) ); return LastNtStatus(); } /// /// Get native thread context /// /// Thread handle. /// Thread context /// Status code NTSTATUS x86Native::GetThreadContextT( HANDLE /*hThread*/, _CONTEXT64& /*ctx*/ ) { // There is no x64 context under x86 OS return STATUS_NOT_SUPPORTED; } /// /// Set WOW64 thread context /// /// Thread handle. /// Thread context /// Status code NTSTATUS x86Native::SetThreadContextT( HANDLE hThread, _CONTEXT32& ctx ) { SetLastNtStatus( STATUS_SUCCESS ); SetThreadContext( hThread, reinterpret_cast(&ctx) ); return LastNtStatus(); } /// /// Set native thread context /// /// Thread handle. /// Thread context /// Status code NTSTATUS x86Native::SetThreadContextT( HANDLE /*hThread*/, _CONTEXT64& /*ctx*/ ) { // There is no x64 context under x86 OS return STATUS_NOT_SUPPORTED; } /// /// Gets WOW64 PEB /// /// Retrieved PEB /// PEB pointer ptr_t x86Native::getPEB( _PEB32* ppeb ) { PROCESS_BASIC_INFORMATION pbi = { 0 }; ULONG bytes = 0; if (NT_SUCCESS( SAFE_NATIVE_CALL( NtQueryInformationProcess, _hProcess, ProcessBasicInformation, &pbi, (ULONG)sizeof( pbi ), &bytes ) ) && ppeb) ReadProcessMemory( _hProcess, pbi.PebBaseAddress, ppeb, sizeof(_PEB32), NULL ); return reinterpret_cast(pbi.PebBaseAddress); } /// /// Get native PEB /// /// Retrieved PEB /// PEB pointer ptr_t x86Native::getPEB( _PEB64* /*ppeb*/ ) { // There is no x64 PEB under x86 OS SetLastNtStatus( STATUS_NOT_SUPPORTED ); return 0; } /// /// Get WOW64 TEB /// /// Retrieved TEB /// TEB pointer ptr_t x86Native::getTEB( HANDLE hThread, _TEB32* pteb ) { _THREAD_BASIC_INFORMATION_T tbi = { 0 }; ULONG bytes = 0; if (NT_SUCCESS( SAFE_NATIVE_CALL( NtQueryInformationThread, hThread, (THREADINFOCLASS)0, &tbi, (ULONG)sizeof( tbi ), &bytes ) ) && pteb) ReadProcessMemory( _hProcess, (LPCVOID)((uintptr_t)tbi.TebBaseAddress), pteb, sizeof(_TEB32), NULL ); return tbi.TebBaseAddress; } /// /// Get native TEB /// /// Retrieved TEB /// TEB pointer ptr_t x86Native::getTEB( HANDLE /*hThread*/, _TEB64* /*pteb*/ ) { // There is no x64 TEB under x86 OS SetLastNtStatus( STATUS_NOT_SUPPORTED ); return 0; } }