#pragma once #include "../Config.h" #include // Architecture-dependent pointer size #define WordSize sizeof(void*) // Rebase address #define MAKE_PTR(T, pRVA, base) (T)((ptr_t)pRVA + (ptr_t)base) #define REBASE(pRVA, baseOld, baseNew) ((ptr_t)pRVA - (ptr_t)baseOld + (ptr_t)baseNew) // Field offset info #define FIELD_OFFSET2(type, field) ((LONG)(LONG_PTR)&(((type)0)->field)) #define GET_FIELD_PTR(entry, field) (uintptr_t)((uint8_t*)entry + FIELD_OFFSET2(decltype(entry), field)) #define CALL_64_86(b, f, ...) (b ? f(__VA_ARGS__) : f(__VA_ARGS__)) #define FIELD_PTR_64_86(b, e, t, f) (b ? fieldPtr( e, &t::f ) : fieldPtr( e, &t::f )) #define LODWORD(l) ((uint32_t)(((uint64_t)(l)) & 0xffffffff)) #define HIDWORD(l) ((uint32_t)((((uint64_t)(l)) >> 32) & 0xffffffff)) // Set or reset particular bit #define SET_BIT(v, b) v |= (1ull << b) #define RESET_BIT(v, b) v &= ~(1ull << b) // Register aliases #ifdef USE64 #define NAX Rax #define NSP Rsp #define NIP Rip #define NDI Rdi #define BitScanForwardT _BitScanForward64 #define BitScanReverseT _BitScanReverse64 #define BitTestAndSetT _bittestandset64 #define BitTestAndResetT _bittestandreset64 #define SET_JUMP(_src,_dst) *(uintptr_t*)(_src) = 0x25FF; *(uintptr_t*)((_src) + 6) = (uintptr_t)_dst; #else #define NAX Eax #define NSP Esp #define NIP Eip #define NDI Edi #define BitScanForwardT _BitScanForward #define BitScanReverseT _BitScanReverse #define BitTestAndSetT _bittestandset #define BitTestAndResetT _bittestandreset #define SET_JUMP(_src,_dst) *(uint8_t*)(_src) = 0xE9; *(uintptr_t*)((_src) + 1) = (uintptr_t)(_dst) - (uintptr_t)(_src) - 5 #endif #define ENUM_OPS(e) \ inline e operator |(e a1, e a2) { \ return static_cast(static_cast(a1) | static_cast(a2)); \ } \ \ inline e operator |= (e& a1, e a2) { \ return a1 = a1 | a2; \ } \ \ inline e operator &(e a1, e a2) { \ return static_cast(static_cast(a1)& static_cast(a2)); \ } \ \ inline e operator &= (e& a1, e a2) { \ return a1 = a1 & a2; \ } \ \ inline e operator ~(e a1) { \ return static_cast(~static_cast(a1)); \ } template struct CompileTimeSizeOf; // offsetof alternative template constexpr size_t offsetOf( U T::*member ) { return reinterpret_cast(&(reinterpret_cast(nullptr)->*member)); } template constexpr uint64_t fieldPtr( uint64_t base, U T::*member ) { return base + offsetOf( member ); } // CONTAINING_RECORD alternative template constexpr uint64_t structBase( uint64_t ptr, U T::*member ) { return ptr - offsetOf( member ); } // Type-unsafe cast. template inline _Tgt brutal_cast( const _Src& src ) { static_assert(sizeof( _Tgt ) == sizeof( _Src ), "Operand size mismatch"); union _u { _Src s; _Tgt t; } u; u.s = src; return u.t; } // Align value inline size_t Align( size_t val, size_t alignment ) { return (val % alignment == 0) ? val : (val / alignment + 1) * alignment; } // Offset of 'LastStatus' field in TEB #define LAST_STATUS_OFS (0x598 + 0x197 * WordSize) using NTSTATUS = long; /// /// Get last NT status /// /// inline NTSTATUS LastNtStatus() { return *(NTSTATUS*)((unsigned char*)NtCurrentTeb() + LAST_STATUS_OFS); } /// /// Set last NT status /// /// The status. /// inline NTSTATUS SetLastNtStatus( NTSTATUS status ) { return *(NTSTATUS*)((unsigned char*)NtCurrentTeb() + LAST_STATUS_OFS) = status; } #define SharedUserData32 ((KUSER_SHARED_DATA* const)0x7FFE0000)