Sign in to follow this  
blueshogun96

Saving a pointer address in a non-pointer variable

Recommended Posts

Just cast it. E.g.
intptr_t pointer_to_integer(void *ptr) {
return (intptr_t) ptr;
}

Just be sure you're using an appropriately-sized integer for your platform.

Care to explain why you want to do this? There might be a 'better' way.

Share this post


Link to post
Share on other sites
In C++, a cast from a pointer to an integral type of sufficient size is guaranteed to yield a value that can be cast back to a pointer of the original type. (Section 5.2.10 paragraph 5). All bets are off for any other use of that value, however.

Share this post


Link to post
Share on other sites
Quote:
Original post by Hodgman
N.B. that while this often works, I'm pretty sure it's not guaranteed to work in the standard so the code will be non-portable. But if you're already using MS-defined types like DWORD then that's probably not a problem ;)
I wouldn't know about C++ but C certainly allows it. After all why provide the (u)intptr_t types if you cannot use them?
Of course few guarantees are made as to what those integers actually represent, basically that a valid pointer can be cast to an integer and back. Still, it's enough to use as an identifier, print pointer values for debugging, construct XOR-linked lists and so forth.

Share this post


Link to post
Share on other sites
I'm writing an emulator. Right now I'm writing the dynamic binary translator (it's an x86 -> x86 translator/emulator). My implemintation involves creating code blocks in a dymanic array of bytes. So what I do to execute a code block is something like this:


// Create a code block with instructions encoded byte by byte
// unsigned char* code_block = malloc( [insert size here in bytes]+1 );
unsigned char* code_block[] =
{
0x90, // NOP
0xB8, 0x78, 0x56, 0x34, 0x12, // MOV EAX, 0x12345678
0xC3 // RET
};

// Get the address of this code block
unsigned int* code_block_address = (unsigned int*) code_block;

// Execute this code block
__asm call code_block_address;


jmp and call instructions take a different approach as well as memory read/writes and privelaged instructions such as wbinvd, sfence, monitor, bounds, etc.

What I need to do is get the actual address for the variables holding data for the CPU registers. Then when encoding the instructions I need to add the actual address of this variable in little endian order so that the code block will modify the the variable. I figured it would be faster than just saving the state of the host PC's registers and restoring them each time. If you have better ideas, please let me know :) Thanks.

Share this post


Link to post
Share on other sites
Fair enough. In this particular case you could have poked written the address directly as a pointer but in other cases, say to calculate PC-relative addresses for a JMP, you'll have to treat pointers as integers.
As for the technique poking static addresses into assembly snippets sounds like a reasonable thing to do, especially when you're going to be generating code anyway. For instance it's what WTL does to bind object addresses to window procedures, and I did it myself not too long ago in a huffman decoder.

Any particular reason you're opting for emulation rather then virtualization? Having to deal with all the x86 complexities while maintaining reasonable performance seems like a bloody nightmare.

Share this post


Link to post
Share on other sites
Quote:
Original post by blueshogun96
What's the real difference between emulation and virtualization? Would virtualization be better? How would I impliment such a thing?
Virtualization is the technique that products like VMWare and VirtualPC (the x86 version) use, or how DOS executables run under Win9x.

Basically instead of translating the instructions you let the processor execute them as usual but trap IO accesses, privileged instructions and the like to make it for the program as if it's running on an independent machine.
It's a bit like only writing the hardware emulation parts of an emulator. Another example is how your favorite operating system uses virtual memory and swap space on disk to make it seem to an application as if you've got a virtual unlimited amount of memory.

As for the details, that is how to make it work, what kind of hardware and operating system support is needed and so forth you'll have to do some Googling because I don't have a clue. Any way you look at it it's a significant project, but then so is writing a dynamic recompiler.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this