I've made a DLL which I load into the Sonic Generations game process, which I'm using to learn how to move variables around and whatnot in the form of "cheats" for the game.
Using various debugging tools, I've found base pointers that store Sonic's XYZ location. I wanted to code a save location button, and a restore location button. The issue I'm having is writing it in C++, as far as getting and saving those values.
I know that a base pointer of 0x01E11C60 points to another pointer, which it plus 0x00000010 points to a final location, which that location plus 0x00000070 holds the X value, then 4 bytes later the Y, then 4 bytes later the Z value.
Should I address this like an array? How do I write a statement to save it, and a statement to reference it? Remember this is a DLL inside the process, so I don't need ReadProcessMemory or WriteProcessMemory.
This is what I have so far, which of course doesn't compile:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
int SonicXYZ = (int*)((*(INT*)((*(INT*)((*(INT*)(SonicAddr)) + 0x10))) + 0x70));
if (GetAsyncKeyState(VK_END)) // Save location
SavedLoc = *SonicXYZ;
if (GetAsyncKeyState(VK_HOME)) // Restore location
*SonicXYZ = SavedLoc;
I found the issue. I'm not sure if I'm going to word this correctly.
x = (float*)((int)*p1 + 0x00000070);
An additional dereference operator (*) before the "p1". I'm sorry if my description of the data layout lead to this error.
The code you gave me is AWESOME! Thank you for helping me make my first struct.
P.S. I like how you break it out into seperate lines. I've been bleeding my eyes out with things like the following, which adjusts Sonic's Rings quantity:
*(INT*)((*(INT*)(SonicAddr)) + 0x5b8) = 999;
Since the pointers can change, I need to re-spawn this struct between levels. How do I properly destroy the previous variables? In this case, previous "sonicpos"?
And lastly, I noticed I forgot to initialize the struct I made for saving the current location. The game crashed, with a verbose Visual C++ description of the error. It even knew my variable names. Is this possible because my DLL was compiled in Debug mode? Just curious.
You aren't creating data, just pointers when we create the struct. When the struct goes out of scope, these pointers are automatically deleted. The data will remain, but that's okay, because the data itself isn't yours. You don't want to delete that as it will cause the original program to crash. Therefore you don't need to do any manual cleanup.
If you ever use the "new" keyword, that's when you need to start manually cleaning stuff up. That can be done in the "destructor" like so:
1 2 3 4 5 6 7 8 9 10 11 12 13
i = newint; // the pointer now points to a newly created integer.
~A() // This is automatically called with the object becomes out of scope
delete i; // We have to clean this up or we lose the data.
For your stuff, the struct only contains pointers to the position. If you want to save the position, we'll need to something like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
x = *pos.x;
y = *pos.y;
z = *pos.z;
*pos.x = x;
*pos.y = y;
*pos.z = z;
} SaveSlot; // Creating 10 slots to save the position
Then to save or recall position 0.
1 2 3 4