Memory Hacking question...

Everything about HD, MD, and their mods.

Moderator: Halo Moderators

Post Reply
dummy

Memory Hacking question...

Post by dummy » Fri Jun 18, 2010 8:04 pm

What is the memory address for the XYZ coordinates AND rotation for Player 1 (the host) and Player 2 in multiplayer game. If it's different for computers or instances of running Halo Demo, could someone tell me how these address can be retrieved?

Sparky
Delta Force
Posts: 4194
Joined: Wed Mar 31, 2004 8:59 pm
Location: New Jersey, USA
Contact:

Re: Memory Hacking question...

Post by Sparky » Sun Jun 20, 2010 8:00 am

Use The Cheat to search for unknown memory values by searching for increases or decreases in those values.

Samuco can answer your question, as he likely used Nil's memory modding concepts to create his update to SwordEdit.
Either you are groping for answers, or you are asking God and listening to Jesus.

002
Ranger
Posts: 944
Joined: Wed Aug 16, 2006 5:48 pm
Location: ::1

Re: Memory Hacking question...

Post by 002 » Sun Jun 20, 2010 4:17 pm

I have problems with finding these values, too. They never work when I changed them in the cheat. I think they are floats.

nil
Halo Moderator
Halo Moderator
Posts: 1090
Joined: Sat Jul 05, 2008 8:38 am
Location: null zone

Re: Memory Hacking question...

Post by nil » Sun Jun 20, 2010 7:23 pm

I'll answer this question, though it may be a bit confusing, so bear with me. Also, The Cheat will not really be that practical to use as you can't easily tell it, "give me the value of the variable at this address." Lastly, this is a newbie's warning, but you need to be the host if you want to change player's locations :mrgreen:

I'm going to be referencing this page a bit in my post:
http://www.modacity.net/forums/showthre ... Structures

Also, I'm going to make this post in such a way that it's helpful if you know how to use my memory modding tool or that it's helpful if you want to learn how to use it (as The Cheat will probably not be sufficient enough [as I've already mentioned] for doing this anyway).

Halo has two structures for players. One is a static structure and the other is a dynamic structure. The static structure has some stuff like the player's name and what team he is on. The dynamic structure has stuff like player location, heath, rotation. The static structure is always static [constant] in memory. The dynamic structure is destroyed and re-created, say, every time the player dies (or a new game begins). So, if you happen to grab the player's location values in The Cheat in a particular instance, it'll only apply if the structure is not re-created, unless if you know how to re-calculate the location addresses which is what I'll get into.

The static player structure looks something like this:

Code: Select all

struct Static_Player
{
 unsigned short PlayerID;            // Stats at 0x70EC
 unsigned short PlayerID2;            // ???
 wchar_t PlayerName0[12];           // Unicode / Max - 11 Chars + EOS (12 total)
 long Unknown0;                     // Always -1 / 0xFFFFFFFF
 unsigned long Team;                // 0 = Red / 1 = Blue
 unsigned long SwapID;              // ObjectID
 unsigned short SwapType;           // 8 = Vehicle / 6 = Weapon
 short SwapSeat;                    // Warthog - Driver = 0 / Passenger = 1 / Gunner = 2 / Weapon = -1
 unsigned long RespawnTimer;        // ?????? Counts down when dead, Alive = 0
 unsigned long Unknown1;            // Always 0
 unsigned short ObjectIndexNum;
 unsigned short ObjectID;           // Matches against object table
 unsigned long Unknown3;            // Some sort of ID
 unsigned long LocationID;          // This is very, very interesting. BG is split into 25 location ID's. 1 -19
 long Unknown4;                     // Always -1 / 0xFFFFFFFF
 unsigned long BulletCount;         // Something to do with bullets increases - weird.
 wchar_t PlayerName1[12];           // Unicode / Max - 11 Chars + EOS (12 total)
 unsigned long Unknown5;      // 02 00 FF FF
 unsigned long PlayerIndex;
};
[By the way: short is 2 bytes, long is 4 bytes, wchar_t is 2 bytes [thus playerName is 12 * 2 bytes], unsigned denotes value >= 0].

I'm now going to define the address of the first static player structure, which is indeed the host.
(ALL_CAPS_VARIABLES are constants/definitions for my use)

Code: Select all

FIRST_STATIC_PLAYER_ADDRESS = 0x4BD7AFD0
I'm also going to define the size of a static player structure.

Code: Select all

STATIC_PLAYER_SIZE = 0x200
Now assuming playerIndex exists, I can find the static player structure address of any player I want. If playerIndex is 0, it corresponds to the first player [the host], if playerIndex is 1 it corresponds to the second player, and etc up until and including 15.

Code: Select all

staticPlayerAddress = FIRST_STATIC_PLAYER_ADDRESS + STATIC_PLAYER_SIZE * playerIndex
We will want the object id address in the static player structure because it'll help us determine the dynamic structure's address (more on that later).

Code: Select all

#this is the offset from the top of the static player structure to the object ID
STATIC_PLAYER_OBJECT_ID_OFFSET = 0x32
playerObjectIDAddress = staticPlayerAddress + STATIC_PLAYER_OBJECT_ID_OFFSET
Then get the object ID of the player:

Code: Select all

playerObjectID = readUInt16(playerObjectIDAddress)
Now, in Halo, there exists an object table structure which looks like this:

Code: Select all

struct Object_Table_Array
{
 unsigned short ObjectID;           // Matches up to Object ID in static player table ( for players )
 unsigned short Unknown0;
 unsigned short Unknown1;
 unsigned short Size;                 // Structure size
 unsigned long Offset;                // Pointer to the object data structure
};
Each object table structure corresponds to a certain halo object; the kind of halo object we are interested in are the dynamic player structures. If we can figure out where the object table structure is, we can figure out where the actual object is. In Halo, there's a consecutive array of these object table structures in memory.

I've just so happened to figure out the first object table structure address in the demo, and of course, the size of every structure.

Code: Select all

FIRST_TABLE_OBJECT_ADDRESS = 0x4BB206EC
OBJECT_TABLE_SIZE = 12
The offset field in the object table structure is the address to the actual halo structure (dynamic player structure in our case). We need to figure out the offset to this field from the object table structure (fairly easy to do; size of short [2] * 4 shorts = 8 bytes)

Code: Select all

OFFSET_TO_HALO_OBJECT_POINTER = 0x8
Before we can get the address to the object table that corresponds to the dynamic player structure, we need to make sure the object ID we calculated earlier is valid. In this particular case, this means things like making sure the player is in the game and the player is still alive.

Code: Select all

INVALID_OBJECT_ID = 0xFFFF #(assuming unsigned, otherwise -1 signed)

#Sanity check
if playerObjectID != 0 and playerObjectID != INVALID_OBJECT_ID:
Then we calculate the address to the halo object pointer [pointer aka variable that holds a memory address] inside the object table structure we want by using the object ID.

Code: Select all

dynamicPlayerPointer = (FIRST_TABLE_OBJECT_ADDRESS + playerObjectID * OBJECT_TABLE_SIZE) + OFFSET_TO_HALO_OBJECT_POINTER
Yup, that's the point of the object ID: accessing the object table array so that we can then access the actual object.

Then we can get the dynamic player address:

Code: Select all

dynamicPlayerAddress = readUInt32(dynamicPlayerPointer)
The dynamic player structure looks something like this:

Code: Select all

struct Dynamic_Player
{
 unsigned short MetaIndex;
 unsigned short MetaID; // matches against the map's meta table
 unsigned char Unknown0[88];
 float x; // world coordinate
 float y; // world coordinate
 float z; // world coordinate
 float x2; //movement vector
 float y2; //movement vector
 float z2; //movement vector
 float LegsPitch;
 float LegsYaw;
 float LegsRoll;
 float ScaleX;
 float ScaleY;
 float ScaleZ;
 unsigned char Unknown1[84];
 float Health;
 float Shield;
 unsigned char Unknown2[48];
 unsigned short WeaponIndex;
 unsigned short WeaponID;
 unsigned short VehicleIndex;
 unsigned short VehicleID;
 unsigned char Unknown3[228];
 unsigned long IsInvisible; // normal = 0x41 invis = 0x51 (bitfield?)
 unsigned char IsCrouching;      // crouch = 1, jump = 2
};
Now we can determine (by hand under assumption again) the offset to the x, y, and z player locations from the dynamic player structure.

Code: Select all

OFFSET_TO_PLAYER_X_COORDINATE = 0x5C
OFFSET_TO_PLAYER_Y_COORDINATE = OFFSET_TO_PLAYER_X_COORDINATE + 0x4
OFFSET_TO_PLAYER_Z_COORDINATE = OFFSET_TO_PLAYER_X_COORDINATE + 0x4 * 2
The x, y, z variables are all floats (4 bytes long). You can grab them like this.

Code: Select all

playerX = readFloat(dynamicPlayerAddress + OFFSET_TO_PLAYER_X_COORDINATE)
playerY = readFloat(dynamicPlayerAddress + OFFSET_TO_PLAYER_Y_COORDINATE)
playerZ = readFloat(dynamicPlayerAddress + OFFSET_TO_PLAYER_Z_COORDINATE)
[Notice that "dynamicPlayerAddress + OFFSET_TO_PLAYER_X_COORDINATE" is equivalent to saying playerXAddress; I just didn't feel like making and storing such variables].

I suppose rotation here might be legsPitch/Yaw/and Roll in the dynamic player structure. The offsets from the dynamic player structure are simply:

Code: Select all

OFFSET_TO_LEGS_PITCH = OFFSET_TO_PLAYER_Z_COORDINATE + 0x4 * 4
OFFSET_TO_LEGS_YAW = OFFSET_TO_LEGS_PITCH + 0x4
OFFSET_TO_LEGS_ROLL = OFFSET_TO_LEGS_PITCH + 0x4 * 2
Grabbing them would be just the same:

Code: Select all

playerLegsPitch = readFloat(dynamicPlayerAddress + OFFSET_TO_LEGS_PITCH)
playerLegsYaw = readFloat(dynamicPlayerAddress + OFFSET_TO_YAW_PITCH)
playerLegsRoll = readFloat(dynamicPlayerAddress + OFFSET_TO_LEGS_ROLL)
[edit]: Fixed & added some bit of information about obtaining dynamicPlayerAddress.
I am no longer active to Halo or MGM, and don't guarantee a response on the forums or through email. I will however linger around the discord room for general chatting. It's been fun!

Sparky
Delta Force
Posts: 4194
Joined: Wed Mar 31, 2004 8:59 pm
Location: New Jersey, USA
Contact:

Re: Memory Hacking question...

Post by Sparky » Sun Jun 20, 2010 11:33 pm

LocationID may be referring to the lightmapped regions or the portal regions.
Either you are groping for answers, or you are asking God and listening to Jesus.

nil
Halo Moderator
Halo Moderator
Posts: 1090
Joined: Sat Jul 05, 2008 8:38 am
Location: null zone

Re: Memory Hacking question...

Post by nil » Mon Jun 21, 2010 6:16 am

And it also has no revelance to answering the question raised in this thread?
I am no longer active to Halo or MGM, and don't guarantee a response on the forums or through email. I will however linger around the discord room for general chatting. It's been fun!

nil
Halo Moderator
Halo Moderator
Posts: 1090
Joined: Sat Jul 05, 2008 8:38 am
Location: null zone

Re: Memory Hacking question...

Post by nil » Mon Jun 21, 2010 11:26 am

There is a simple way that I began with for finding the player coordinates with The Cheat, though it only applies in a certain case (that is, if the player does not become destroyed and re-created).

Look at the dynamic player structure and search for something in it that is simple to find. The IsInvisible field is pretty easy. It's a 32-bit integer and it's 0x41 when normal and 0x51 when invisible (may need to convert those to decimal, though The Cheat might be able to handle searching in hex notation). So find the address of that variable with The Cheat. Then find the distance from that address to the x coordinate field.

If I did my math right, the distance would be:

Code: Select all

distance = 228 * 1 + 2 * 4 + 48 * 1 + 4 * 2 + 84 * 1 + 12 * 4
distance = 424
Then you can subtract the address you found to the IsInvisible field with that distance to get the player's x location.

Code: Select all

playerXAddress = IsInvisibleAddress - distance
And playerYAddress is just 0x4 + the playerXAddress, and playerZAddress is just 0x4 + playerYAddress because floats are 4 bytes long. From there, it shouldn't be difficult to calculate the legs pitch, yaw, and roll addresses.
I am no longer active to Halo or MGM, and don't guarantee a response on the forums or through email. I will however linger around the discord room for general chatting. It's been fun!

Samucos

Re: Memory Hacking question...

Post by Samucos » Wed Jun 30, 2010 8:32 pm

Just googling some stuff to see if I can make scenery css... and I found this thread :)
Here's some relevant bits of starlight:

Locations

Code: Select all

const int offsetToPlayerXCoordinate = 0x5C;
const int offsetToPlayerYCoordinate = 0x5C + 0x4;
const int offsetToPlayerZCoordinate = 0x5C + 0x4 + 0x4;
And reading the stuff

Code: Select all

VMReadBytes(haloProcessID, haloObjectPointer + offsetToPlayerXCoordinate, &newHostXValue, &size);
VMReadBytes(haloProcessID, haloObjectPointer + offsetToPlayerYCoordinate, &newHostYValue, &size);
VMReadBytes(haloProcessID, haloObjectPointer + offsetToPlayerZCoordinate, &newHostZValue, &size);
All of the code you're looking for can be found in RenderView.m line 230ish
Rotations a bit stuffed, cause I only just learnt what a radian was :lol:

nil
Halo Moderator
Halo Moderator
Posts: 1090
Joined: Sat Jul 05, 2008 8:38 am
Location: null zone

Re: Memory Hacking question...

Post by nil » Thu Jul 01, 2010 5:56 am

Samucos wrote:Just googling some stuff to see if I can make scenery css... and I found this thread :)
Here's some relevant bits of starlight:

Locations

Code: Select all

const int offsetToPlayerXCoordinate = 0x5C;
const int offsetToPlayerYCoordinate = 0x5C + 0x4;
const int offsetToPlayerZCoordinate = 0x5C + 0x4 + 0x4;
And reading the stuff

Code: Select all

VMReadBytes(haloProcessID, haloObjectPointer + offsetToPlayerXCoordinate, &newHostXValue, &size);
VMReadBytes(haloProcessID, haloObjectPointer + offsetToPlayerYCoordinate, &newHostYValue, &size);
VMReadBytes(haloProcessID, haloObjectPointer + offsetToPlayerZCoordinate, &newHostZValue, &size);
All of the code you're looking for can be found in RenderView.m line 230ish
Rotations a bit stuffed, cause I only just learnt what a radian was :lol:
Yup, those are the same offsets I've said in the thread. Just finding the haloObjectPointer is the hard part, I suppose.
I am no longer active to Halo or MGM, and don't guarantee a response on the forums or through email. I will however linger around the discord room for general chatting. It's been fun!

Post Reply

Who is online

Users browsing this forum: No registered users and 6 guests