« C++: The Fastest foreach loop? (Hacking references again)A way of loading Lua scripts »

C++: Reseating references and getting address of them

As you probably already know, in C++, it's impossible to modify reference variables once they are initialized. Also you can't even get address of reference variable, so it's not possible to cast them to pointers of pointers.


Well, everything is possible when you try enough. Now I'll show you a code I wrote for doing such hacks. It's written to work with VS and X86 architecture, but it can be easily ported to other compilers and cpu architectures.



Here's the promised code (release under GPL v3)
#define GetReferenceAddress(Reference, Output) \
do { \
	__asm \
	{ \
		LEA_OFFSET: \
		__asm lea edx, Reference /* doesn't do anything, but required */ \
		__asm lea eax, LEA_OFFSET /* get address of previous instruction */ \
		__asm movzx edx, [eax + 2] /* get last byte from lea instruction, it's offset to stack */ \
		__asm lea eax, [ebp + edx + (-256)] /* calculate absolute reference address on the stack */ \
		__asm mov Output, eax /* copy address to Output */ \
	} \
} while (0)

#define OverrideReference(Reference, NewAddress) \
do { \
	__asm \
	{ \
		__asm mov eax, NewAddress \
		__asm mov Reference, eax \
	} \
} while (0)


Example usage:

	bool abc = true;
	bool& abc_ref = abc; // reference to abc
	bool* abc_ptr = &abc; // pointer to abc
	bool** abc_ptr2 = NULL; // pointer to pointer to bool

	GetReferenceAddress(abc_ref, abc_ptr2); // get address of abc_ref variable

	// abc_ptr2 now points to abc_ref

	**abc_ptr2 = false; // change abc to false
	*abc_ptr2 = NULL; // abc_ref now points to null object
	// abc_ref = true; // will raise access violation

	OverrideReference(abc_ref, abc_ptr); // set abc_ref to point to abc again

Enjoy!


Categories: Programming, Snippets

No feedback yet