Skip to content

Commit 8a6c3f7

Browse files
Add files via upload
0 parents  commit 8a6c3f7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+8626
-0
lines changed

address.h

+187
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
#pragma once
2+
3+
// class size is only 4 bytes on x86-32 and 8 bytes on x86-64.
4+
class Address {
5+
protected:
6+
uintptr_t m_addr;
7+
8+
public:
9+
// default ctor/dtor.
10+
__forceinline Address( ) : m_addr{} {};
11+
__forceinline ~Address( ) {};
12+
13+
// ctors.
14+
__forceinline Address( uintptr_t a ) : m_addr{ a } {}
15+
__forceinline Address( const void* a ) : m_addr{ ( uintptr_t )a } {}
16+
17+
// arithmetic operators for native types.
18+
__forceinline operator uintptr_t( ) { return m_addr; }
19+
__forceinline operator void*( ) { return ( void* )m_addr; }
20+
__forceinline operator const void*( ) { return ( const void* )m_addr; }
21+
22+
// is-equals-operator.
23+
__forceinline bool operator==( Address a ) const {
24+
return as< uintptr_t >( ) == a.as< uintptr_t >( );
25+
}
26+
__forceinline bool operator!=( Address a ) const {
27+
return as< uintptr_t >( ) != a.as< uintptr_t >( );
28+
}
29+
30+
// cast / add offset and cast.
31+
template< typename t = Address >
32+
__forceinline t as( ) const {
33+
return ( m_addr ) ? ( t )m_addr : t{};
34+
}
35+
36+
template< typename t = Address >
37+
__forceinline t as( size_t offset ) const {
38+
return ( m_addr ) ? ( t )( m_addr + offset ) : t{};
39+
}
40+
41+
template< typename t = Address >
42+
__forceinline t as( ptrdiff_t offset ) const {
43+
return ( m_addr ) ? ( t )( m_addr + offset ) : t{};
44+
}
45+
46+
// add offset and dereference.
47+
template< typename t = Address >
48+
__forceinline t at( size_t offset ) const {
49+
return ( m_addr ) ? *( t * )( m_addr + offset ) : t{};
50+
}
51+
52+
template< typename t = Address >
53+
__forceinline t at( ptrdiff_t offset ) const {
54+
return ( m_addr ) ? *( t * )( m_addr + offset ) : t{};
55+
}
56+
57+
// add offset.
58+
template< typename t = Address >
59+
__forceinline t add( size_t offset ) const {
60+
return ( m_addr ) ? ( t )( m_addr + offset ) : t{};
61+
}
62+
63+
template< typename t = Address >
64+
__forceinline t add( ptrdiff_t offset ) const {
65+
return ( m_addr ) ? ( t )( m_addr + offset ) : t{};
66+
}
67+
68+
// subtract offset.
69+
template< typename t = Address >
70+
__forceinline t sub( size_t offset ) const {
71+
return ( m_addr ) ? ( t )( m_addr - offset ) : t{};
72+
}
73+
74+
template< typename t = Address >
75+
__forceinline t sub( ptrdiff_t offset ) const {
76+
return ( m_addr ) ? ( t )( m_addr - offset ) : t{};
77+
}
78+
79+
// dereference.
80+
template< typename t = Address >
81+
__forceinline t to( ) const {
82+
return *( t * )m_addr;
83+
}
84+
85+
// verify adddress and dereference n times.
86+
template< typename t = Address >
87+
__forceinline t get( size_t n = 1 ) {
88+
uintptr_t out;
89+
90+
if( !m_addr )
91+
return t{};
92+
93+
out = m_addr;
94+
95+
for( size_t i{ n }; i > 0; --i ) {
96+
// can't dereference, return null.
97+
if( !valid( out ) )
98+
return t{};
99+
100+
out = *( uintptr_t * )out;
101+
}
102+
103+
return ( t )out;
104+
}
105+
106+
// follow relative8 and relative16/32 offsets.
107+
template< typename t = Address >
108+
__forceinline t rel8( size_t offset ) {
109+
uintptr_t out;
110+
uint8_t r;
111+
112+
if( !m_addr )
113+
return t{};
114+
115+
out = m_addr + offset;
116+
117+
// get relative offset.
118+
r = *( uint8_t * )out;
119+
if( !r )
120+
return t{};
121+
122+
// relative to address of next instruction.
123+
// short jumps can go forward and backward depending on the size of the second byte.
124+
// if the second byte is below 128, the jmp goes forwards.
125+
// if the second byte is above 128, the jmp goes backwards ( subtract two's complement of the relative offset from the address of the next instruction ).
126+
if( r < 128 )
127+
out = ( out + 1 ) + r;
128+
else
129+
out = ( out + 1 ) - ( uint8_t )( ~r + 1 );
130+
131+
return ( t )out;
132+
}
133+
134+
template< typename t = Address >
135+
__forceinline t rel32( size_t offset ) {
136+
uintptr_t out;
137+
uint32_t r;
138+
139+
if( !m_addr )
140+
return t{};
141+
142+
out = m_addr + offset;
143+
144+
// get rel32 offset.
145+
r = *( uint32_t * )out;
146+
if( !r )
147+
return t{};
148+
149+
// relative to address of next instruction.
150+
out = ( out + 4 ) + r;
151+
152+
return ( t )out;
153+
}
154+
155+
// set.
156+
template< typename t = uintptr_t > __forceinline void set( const t &value ) {
157+
if( !m_addr )
158+
return;
159+
160+
*(t *)m_addr = value;
161+
}
162+
163+
// checks if address is not null and has correct page protection.
164+
static __forceinline bool valid( uintptr_t addr ) {
165+
MEMORY_BASIC_INFORMATION mbi;
166+
167+
// check for invalid address.
168+
if( !addr )
169+
return false;
170+
171+
// check for invalid page protection.
172+
if( !g_winapi.VirtualQuery( ( const void * )addr, &mbi, sizeof( mbi ) ) )
173+
return false;
174+
175+
// todo - dex; fix this, its wrong... check for rwe or something too
176+
if( /*!( mbi.State & MEM_COMMIT ) ||*/ ( mbi.Protect & PAGE_NOACCESS ) || ( mbi.Protect & PAGE_GUARD ) )
177+
return false;
178+
179+
return true;
180+
}
181+
182+
// relative virtual address.
183+
template< typename t = Address >
184+
static __forceinline t RVA( Address base, size_t offset ) {
185+
return base.as< t >( offset );
186+
}
187+
};

0 commit comments

Comments
 (0)