PDA

View Full Version : [MISC] Halo Custom Edition [1.08] Interesting Addresses



Dwood
November 4th, 2009, 05:04 PM
Well I was looking around in Cheat engine lately and I found some crap. I figured I haven't done anything with them yet, and probably won't, for a while, thus, you might make use of some of these addys.



Dev Boolean-

006BD096

01/00 00 60 C8 14 00 02 00 00 00 40 B8 16 00 00 00

Console boolean-

00651E89

01/00 00 00 01 00 00 60 10 00 00 0D FF FF 00 00 00



I was toying with the idea of making those booleans accessible via scripts in Open Sauce :iamafag:

The following I was planning on releasing in Open Sauce (and still am) however I need to find the addy in dedi still.

This was an Idea I had for modifying the jump height/velocity of the player. It turns out that Cheat_Super_Jump multiplies the default velocity (in stock maps, 1.7 mps) by 4.

I forget how jump velocity works in tandem with jump height in the game but hey.



SJ Bool-
00815CA4


SJ Modifier
00612388
-set to 4 by default. Fun to use on Hugeass or Coldsnap.

Timberland as well. :P


Another note, that Super jump MUST be enabled in order for this method of modifying jump height to work.

I'm going to use this as a log to the interesting values that I find in Halo.

Currently on my list to be found are: Maximum Health, Max shields, and Grenades.

With those I expect to find the actual health, shields, and 'nades the player is holding. If you have ideas feel free to let meh know.

Kornman00
November 5th, 2009, 04:56 AM
The only thing that needs to be enabled with OS is the console. OS can override the devmode check for runtime script commands (read: console commands). Also, all you need to have is a lookup function or the actual global index of cheat_super_jump and then just access the value definition using the HSExternalGlobals() function or w/e I had named it in the Script related code files (I think I defined it in the ScriptLibrary component source)

an object's heath/shields and a unit's grenades are already defined in the OS codebase

Dwood
November 5th, 2009, 05:45 AM
an object's heath/shields and a unit's grenades are already defined in the OS codebase

If that's so I think I'll want to be exposing those values so scripters may manipulate them, even though i'm not sure about how to do it 100%.

Yeah, FireScythe showed me the parts of Open Sauce I need to add my custom globals so expect my own build or something like that some time this month maybe.

Kornman00
November 5th, 2009, 05:53 AM
unit_get_heath/unit_get_shield (just make 'set' versions)

however, player_add_equipment can set all three things (including weapons). also, these would need to be functions, not globals.

blind
November 5th, 2009, 12:46 PM
Keep up the good work!

Dwood
November 6th, 2009, 05:55 PM
004D3BDD - mov edi,esi (not exactly sure why this is here)
004D3BEC - mov [esi],eax (esi is a pointer to the player, eax is player ID...)

if you're looking at our Player structure, should be
unsigned short m_ID
^
(when a player joins)

this code is called at...

004D3971 - CALL 004D3BD0
^called by

004DD3FF - call 004E1E60

all values are in hex (0x20, 0x40, etc)
when RUSSIA WINS hosts game | Dwood joins hosted game | USA JOIN
EAX = 007F0001
ECX = 0 (player index??) | 20 | 40
EDX = 0 (player index??mb team??) | 1 (player index) | 2
EBX = 1 (??, successful join mb [like banning?])
EBP = 007FC467 |7FC487 |7FC4A7
ESI = pointer to player name
EDI = 0080DD40 (??)

EBP points to a value

when i host,
00 00 00 00
when you join
00 01 01 00... could be (??) (player #) (team #) (??)

second test (this time, im on team 1)
00 00 00 00 (me)
00 00 01 00 (you)

third test (in order, no team switching, me, RUSSIA, USA)
00 00 00 00
00 01 01 00
00 00 02 00

registers up top remain the same

analysis for pointed structure by EBP:
00 (team) (player #) 00

EAX and EDI point to a bunch of 0s, maybe they are for bitwise operations?

more info on ESI register above

ESI points to this structure
seems to be 32 bytes
24 bytes = player name
last 8 bytes go for me as follows:
01 00 FF FF 00 00 00 00

for you, same structure, except last 8 bytes
02 00 FF FF 01 00 01 01

for me, with Dwood on blue
02 00 FF FF 01 00 00 01.... meaning that the second to last byte = team

for USA WINS joins as third player (joins to red)
02 00 FF FF 02 00 00 02

assuming first byte means 01 for host, 02 for client
(above) 00 FF FF (player index+1) 00 (destination team) (player index+1)



Thanks to IGM.Bitidork for help in finding these addresses.

Kornman00
November 6th, 2009, 06:17 PM
pretty sure you're looking at a s_network_player structure

Rhydgaled
November 8th, 2009, 07:46 AM
unit_get_heath/unit_get_shield (just make 'set' versions)

however, player_add_equipment can set all three things (including weapons). also, these would need to be functions, not globals.
I don't suppose there's a unit_set_equipment that can be used on AI. One would be able to have an elite draw an energy sword when it's shield is low then.

Kornman00
November 8th, 2009, 01:58 PM
I don't suppose there's a unit_set_equipment that can be used on AI. One would be able to have an elite draw an energy sword when it's shield is low then.
ai_actors, then iterate over each unit checking their shield.

also, there are already methods for setting the health/shield properties: unit(s)_set_maximum_vitality & unit(s)_set_current_vitality

Dwood
November 8th, 2009, 02:14 PM
ai_actors, then iterate over each unit checking their shield.

also, there are already methods for setting the health/shield properties: unit(s)_set_maximum_vitality & unit(s)_set_current_vitality

Oh hey I didn't know about that, thanks. :neckbeard:

Dwood
November 11th, 2009, 11:15 AM
[1.09] Devmode addresses:

00651F71 - Inclined to believe that's the console
006BD17E - That is Dev mode.

I will look into making my own Dev mode. Someone teach me how to pattern scan?

IF YOU DON'T want to wait, Get Cheat Engine. Start halo CE 1.09, open Cheat Engine, go to process and find haloce.exe.

Go to 'add address manually'. Add both of the above addresses, double click on the type of each of the addys and change to 'Byte'

The values for each should now be 0. changing those addresses to 1 will turn on and 0 will turn off.

Turn on console before you join a game and then turn on Dev when you are ingame.

Skyline
November 11th, 2009, 02:12 PM
Boredom. (http://www.filefront.com/14908913/DevMode.rar)

Dwood
November 11th, 2009, 02:52 PM
Boredom. (http://www.filefront.com/14907267/DevMode.rar)

Thanks!!!! Too bad it won't detect Halo? :P

Limited
November 11th, 2009, 03:28 PM
Thanks!!!! Too bad it won't detect Halo? :P
Gosh, learn your API's skyline :D



bool FindHaloPlease(){
DWORD pid;
HWND halo_w;

HWND halo_w2;
halo_w = FindWindow(NULL, "Halo");
halo_w2 = FindWindow(NULL, "Halo H4x'd by Limited");
BOOL tog = false;

if(halo_w != NULL && tog == false)
{
SetWindowText(halo_w, "Halo H4x'd by Limited");
tog = true;
}

if(halo_w2 != NULL){
SetWindowText(halo_w2, "Halo H4x'd by Limited");
GetWindowThreadProcessId(halo_w2, &pid);
halo_h = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
if(halo_h == NULL){
return false;
}
return true;
}
return false;
}

Skyline
November 11th, 2009, 03:50 PM
Stop using windows 98 :downs:.

Limited
November 11th, 2009, 04:00 PM
Pfft, legacy ftw.




#include <tchar.h>
#include <windows.h>
#include <stdio.h>

bool FindHaloPlease();


byte buffer;
HANDLE halo_h;

int _tmain(int argc, _TCHAR* argv[])
{
while(true){
printf("Limited always has to fix shit huh?\n");
if(!FindHaloPlease()){

printf("Failed to Locate Halo CE; Sleeping for 5 Seconds...\n");
Sleep(1000);
printf("5\n");
Sleep(1000);
printf("4\n");
Sleep(1000);
printf("3\n");
Sleep(1000);
printf("2\n");
Sleep(1000);
printf("1\n");

}
else{
printf("Working...\n");
//Check if Consoles open...
ReadProcessMemory(halo_h, (LPVOID)0x651F70, &buffer, 1, NULL);
if(buffer == 1){
//Check if it needs to be changed.
ReadProcessMemory(halo_h, (LPVOID)0x6BD17E, &buffer, 1, NULL);
if(buffer == 0){
//Turn on Devmode
buffer = 1;
WriteProcessMemory(halo_h, (LPVOID)0x6BD17E, &buffer, 1, NULL);
}

}
else if(buffer == 0){
//Console isn't open
ReadProcessMemory(halo_h, (LPVOID)0x6BD17E, &buffer, 1, NULL);
if(buffer == 1){
//Turn off Devmode if on.
buffer = 0;
WriteProcessMemory(halo_h, (LPVOID)0x6BD17E, &buffer, 1, NULL);
}
}

Sleep(1500);
}

}
return 0;
}

bool FindHaloPlease(){
DWORD pid;
HWND halo_w;

HWND halo_w2;
halo_w = FindWindow(NULL, "Halo");

BOOL tog = false;

if(halo_w != NULL && tog == false)
{
SetWindowText(halo_w, "Halo H4x'd by Limited");
tog = true;
}
halo_w2 = FindWindow(NULL, "Halo H4x'd by Limited");
if(halo_w2 != NULL){
SetWindowText(halo_w2, "Halo H4x'd by Limited");
GetWindowThreadProcessId(halo_w2, &pid);
halo_h = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
if(halo_h == NULL){
return false;
}
return true;
}
return false;
}

chrisk123999
November 11th, 2009, 07:40 PM
As seen on http://wmclan.net/main/


http://ts.wmclan.net/1tb/devmode/app.png

Download: http://wmclan.net/main/downloads.php?cat_id=1&download_id=14
Virus total: http://www.virustotal.com/analisis/74d2cb01a5dc39edd17db96318cdc3340371c419a84d396b47 409acb7212e6cc-1257907300
DIG: http://digg.com/pc_games/Halo_Custom_Edition_Devmode_1_09
Video: http://digg.com/d319l98

This was posted on Halomaps yesterday. The program seems safe. I used it today and nothing bad happened.

jcap edit: If it comes up as a keylogger, it's probably the same false positive that several apps use to monitor your keyboard for button presses. It's necessary because otherwise pressing "page up" would not do anything. Even the original AllDev for CE by Paulus (right?) dropped what some apps considered a keylogger on your computer.

Dwood
November 12th, 2009, 06:28 PM
After that stint.... I will be grabbing a reference that skarma oh-so-encouragingly sent me, and taking a look at Halo when it loads Map Cache files. If anyone already has stuff on that subject, I'd appreciate it if you'd share.

Dwood
November 19th, 2009, 03:16 PM
Oh hey what's this? A few addresses from Brainz? Have fun.




PLAYER_SIZE = 0x200;
PLAYER_OFFSET_TEAM = 0x1C;
PLAYER_OFFSET_RESPAWN_TIMER = 0x28;
PLAYER_OFFSET_OBJIND = 0x30;
PLAYER_OFFSET_OBJID = 0x32;
PLAYER_OFFSET_NAME = 0x44;
PLAYER_OFFSET_SPEED = 0x68;
PLAYER_OFFSET_KILLS = 0x98;
PLAYER_OFFSET_DEATHS = 0xAA;
PLAYER_OFFSET_CTF = 0xC4;
PLAYER_OFFSET_PING = 0xD8;

ShadowSpartan
November 19th, 2009, 03:31 PM
Oh hey what's this? A few addresses from Brainz? Have fun.




PLAYER_SIZE = 0x200;
PLAYER_OFFSET_TEAM = 0x1C;
PLAYER_OFFSET_RESPAWN_TIMER = 0x28;
PLAYER_OFFSET_OBJIND = 0x30;
PLAYER_OFFSET_OBJID = 0x32;
PLAYER_OFFSET_NAME = 0x44;
PLAYER_OFFSET_SPEED = 0x68;
PLAYER_OFFSET_KILLS = 0x98;
PLAYER_OFFSET_DEATHS = 0xAA;
PLAYER_OFFSET_CTF = 0xC4;
PLAYER_OFFSET_PING = 0xD8;

That doesn't help anybody without any context whatsoever, you might as well not even post them. It looks like the player_datum struct in OS (the only one not in OS is "PLAYER_OFFSET_CTF"), but all of these offsets are 0x4 lower than they should be, why is that?

Dwood
November 19th, 2009, 04:04 PM
That doesn't help anybody without any context whatsoever, you might as well not even post them. It looks like the player_datum struct in OS (the only one not in OS is "PLAYER_OFFSET_CTF"), but all of these offsets are 0x4 lower than they should be, why is that?

Sorry about that:




PLAYER_OFFSET_IS_INGAME = -4;
PLAYER_BASE = 0x402AAFD0;
SLAYERSCORES_BASE = 0x0064C280;
OBJREF_BASE = 0x400506E0;
PLAYER_TABLE_START = 0x007FC44A;
TEAM_RED_SLAYER_SCORE = 0x64C240;
TEAM_BLUE_SLAYER_SCORE = 0x64C244;

PLAYER_CD_HASH_PTR_BASE = 0x010570B0;
GAME_MODE = 0x007FCCAF;
GAME_MAP = 0x400001E8;
GAME_TYPE = 0x007FC36C;

Limited
November 19th, 2009, 04:58 PM
Oh hey what's this? A few addresses from Brainz? Have fun.
Um yeah, these havent changed from 1.08, they are well known and have been documented since (at least) 1.04.

Dwood
February 6th, 2010, 04:29 PM
I found some nice, easy-to-find addresses in sapien_dualcore and since I haven't updated the thread in a while I thought I'd share. I would have used OS_Sapienbeta but Sapienbeta doesn't play well with dual cores. :(

(floats)
camera speed is: @ 00A32EE8
X Value for camera position is: 00DB46DC
Y Value is: 00DB46E0
Z Value is: 00DB46E4

What I envision, for the xy and z values are to, say, put a bar on a value so the camera can't pass that point.

One of the things I would like to get is the object that is selected by the user, then get the rotation of an object, and increment it by, say, 5. E: Angle snapping, basically.

Dwood
February 7th, 2010, 03:42 PM
I have 5 addresses that get the current selected items' index. 00B179B4 seems to be the common factor. Same Sapien As Before.

Dwood
February 7th, 2010, 09:04 PM
Ok two new addys, 00B179B0 00B179D0. one gets the physically selected objects index and the other goes to 0 when an object is selected. Both only change when selected from 3d view.

Dwood
April 20th, 2010, 08:49 PM
[...]The source code is freely available somewhere (I think I posted it on Halomods). I made a few classes for it in C++.


EDIT: Here are the classes. God my C++ skills sucked back in 2004. As CrashTECH pointed out, the locations are liable to change from version to version, but IIRC the locations I chose are never deleted and reallocated. You can be sure they are valid once you've found the correct offset. The offset has likely changed since I wrote this. You should use a memory searching tool (TSearch works very well) to find the initial offset, upon which all others are based.

Sorry for the length.
Player.h:


/*
Player.h

Contains a class that provides functions for reading in and retrieving player information
in Halo.

Copyright 2004 Kybo Ren
*/
#include <windows.h>
#include <string>
#include <algorithm>
#include <cmath>
#include <cstring>

/*
#ifdef _DEBUG
#define CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#endif
//this is a class I have to detect memory leaks for me -- don't worry about it
*/

#define MAX_INSTANCES 12
#define MAX_NAMELENGTH 24

#define PC_DS 1
#define PC_GM 2
#define CE_DS 3
#define CE_GM 4//pc and ce ingame and DS servers

#define PC_DS_CLASS 0x4029CF64
#define PC_DS_SCORE 0x63A090

#define CE_GM_CLASS 0x402AB07A
#define CE_GM_SCORE 0x64C280

#define PC_GM_CLASS 0x0
#define PC_GM_SCORE 0x0//PC ingame is obviously not supported right now.

int my_itoa(const int number, char *data);//base can only be 10, and ASSUMES the data buffer supplied is big enough to hold the number

class Player
{
int player_score;
short player_deaths;
short player_assists;
short player_kills;
short player_betrayals;
short player_suicides;
char player_team;
char player_ingame;
std::string player_name;
std::string player_ipadd;
std::string player_cdkey;
//end of player data
//start of class data
int SIZE;//offset between players
int ASSISTS;//offset of assists from kills
int DEATHS;//offset of deaths from kills (beginning of player info structure)
int SUICIDES;//offset of suicides from kills
int TKS;//offset of TKs for each player from kills
int NAMES;//offset of name from player's kills.
int TEAMS;//IMPORTANT: this is the offset of player teams from player 1 kills! this is an array of characters! ***NOT PART OF THE STRUCTURE***
int PLAYERIN;//IMPORTANT: this is the offset of player teams from player 1 score! this is an array of separate structures! ***NOT PART OF THE PLAYER INFO STRUCTURE**
int PLAYERSZ;//Size of the abovementioned structure
//start of individual class data
unsigned int player_class_location;
unsigned int player_score_location;
unsigned int player_number;

unsigned long process_PID;
HANDLE hProc;//the handle to the process

public:

Player();
Player(const unsigned long &PID, const unsigned int &type, const unsigned int &player_number);
~Player();
int Score();
short Deaths();
short Kills();
short Betrayals();
short Assists();
short Suicides();
char Team();
char In_game();
const char *Name();
int Refresh();
int Refresh_Score();
int Refresh_Kills();
int Refresh_Assists();
int Refresh_Deaths();
int Refresh_Suicides();
int Refresh_Betrayals();
int Refresh_Team();
int Refresh_In_Game();
int Refresh_Name();
//end of player info
//start of class info
void Set_PID(const unsigned long &PID);
void Set_Location(const unsigned long &class_location, const unsigned long &score_location, const unsigned long &ipadd_location);
void Set_Player_Number(const unsigned int &player_num);
void Set_Size(const unsigned long &size);
void Set_Type(const unsigned long &type);
bool Handle_Is_Null();
unsigned int Open_Halo();
};//our player class

Player::Player()
{
SIZE = 0x200;
ASSISTS = 0x8;
DEATHS = 0x12;
SUICIDES= 0x14;
TKS = 0x44;
NAMES = -0x54;
TEAMS = -0x7C;
PLAYERIN= -0x890;
PLAYERSZ= 0x30;

player_score = 0;
player_deaths = 0;
player_kills = 0;
player_betrayals = 0;
player_team = 0;
player_ingame = 0;
player_name = "<NULL>";

player_class_location = 0;
player_score_location = 0;
player_ipadd_location = 0;
player_number = 0;
process_PID = 0;
}

Player::Player(const unsigned long& PID, const unsigned int &type, const unsigned int &player_num)
{
switch(type)
{
case PC_DS:
player_class_location = PC_DS_CLASS;
player_score_location = PC_DS_SCORE;
break;
case CE_GM:
player_class_location = CE_GM_CLASS;
player_score_location = CE_GM_SCORE;
break;
case PC_GM:
player_class_location = PC_GM_CLASS;
player_score_location = PC_GM_SCORE;
break;
default:
break;
}

if( (player_num <= 16) && (player_num >= 1) )//if valid range
{
player_number = player_num;
}

process_PID = PID;//assign PID

SIZE = 0x200;
ASSISTS = 0x8;
DEATHS = 0x12;
SUICIDES= 0x14;
TKS = 0x44;
NAMES = -0x54;
TEAMS = -0x7C;
PLAYERIN= -0x890;
PLAYERSZ= 0x30;

player_score = 0;
player_deaths = 0;
player_kills = 0;
player_team = 0;
player_ingame = 0;
player_name = "<NULL>";

hProc = OpenProcess(PROCESS_VM_READ, FALSE, process_PID);//attempt to open the process
if(hProc == NULL)
{
hProc = NULL;//assign a NULL value
}//we failed. Oh. Noes. We'll try again when refreshing

}

Player::~Player()
{
CloseHandle(hProc);//close our handle
}

int Player::Score()
{
return player_score;
}

short Player::Deaths()
{
return player_deaths;
}

short Player::Suicides()
{
return player_suicides;
}

short Player::Kills()
{
return player_kills;
}

short Player::Betrayals()
{
return player_betrayals;
}

short Player::Assists()
{
return player_assists;
}

char Player::Team()
{
return player_team;
}

char Player::In_game()
{
return player_ingame;
}

const char * Player::Name()
{
return player_name.c_str();
}

int Player::Refresh()
{
int result = 1;// we start with one so we can mutiply
char name[13];//temp buffer for name
ipaddr_union address;//for the IP address

if(hProc == NULL)
{
hProc = OpenProcess(PROCESS_VM_READ, FALSE, process_PID);

if(hProc == NULL)
{
MessageBox(0, "Couldn't open the Halo process for reading. \nIf you are sure Halo is running and you have access, send an email to Kybo Ren at:\nkyboren@gmail.com", "Warning", MB_OK | MB_ICONWARNING);
return 0;//0 is fail
}//we try once more then fail
}

result *= ReadProcessMemory(hProc, reinterpret_cast<void*>((player_score_location) + ((player_number-1)*4) + 0 ), (void*)&player_score , 4, 0);//read scores
result *= ReadProcessMemory(hProc, reinterpret_cast<void*>((player_class_location) + ((player_number-1)*SIZE) + 0 ), (void*)&player_kills , 2, 0);//read kills
result *= ReadProcessMemory(hProc, reinterpret_cast<void*>((player_class_location) + ((player_number-1)*SIZE) + DEATHS ), (void*)&player_deaths , 2, 0);//read deaths
result *= ReadProcessMemory(hProc, reinterpret_cast<void*>((player_class_location) + ((player_number-1)*SIZE) +SUICIDES), (void*)&player_suicides , 2, 0);//read suicides
result *= ReadProcessMemory(hProc, reinterpret_cast<void*>((player_class_location) + ((player_number-1)*SIZE) + ASSISTS), (void*)&player_assists , 2, 0);//read assists
result *= ReadProcessMemory(hProc, reinterpret_cast<void*>((player_class_location) + ((player_number-1)*SIZE) + TKS ), (void*)&player_betrayals, 2, 0);//read TKs
result *= ReadProcessMemory(hProc, reinterpret_cast<void*>((player_score_location) + ((player_number-1)*PLAYERSZ)+ PLAYERIN), (void*)&player_ingame , 1, 0);//read ingame
result *= ReadProcessMemory(hProc, reinterpret_cast<void*>((player_class_location) + ((player_number-1)*SIZE) + TEAMS ), (void*)&player_team , 1, 0);//read team
for(unsigned int name_index = 0; name_index < MAX_NAMELENGTH; name_index += 2)
{
result *= ReadProcessMemory(hProc, reinterpret_cast<void*>((player_class_location) + ((player_number-1)*SIZE) + NAMES + name_index), (void*)&name[(name_index / 2)], 1, 0);//read name
}
name[12] = '\0';//nullify the name
player_name = name;//the name is what we just read

return result;
}

int Player::Refresh_Score()
{
if(hProc == NULL)
{
hProc = OpenProcess(PROCESS_VM_READ, FALSE, process_PID);

if(hProc == NULL)
{
MessageBox(0, "Couldn't open the Halo process for reading. \nIf you are sure Halo is running and you have access, send an email to Kybo Ren at:\nkyboren@gmail.com", "Warning", MB_OK | MB_ICONWARNING);
return 0;//0 is fail
}//we try once more then fail

}//if hProc still is messed
int result = 1;

result *= ReadProcessMemory(hProc, reinterpret_cast<void*>((player_score_location) + ((player_number-1)*4) + 0 ), (void*)&player_score , 4, 0);//read scores

return result;
}

int Player::Refresh_Kills()
{
if(hProc == NULL)
{
hProc = OpenProcess(PROCESS_VM_READ, FALSE, process_PID);

if(hProc == NULL)
{
MessageBox(0, "Couldn't open the Halo process for reading. \nIf you are sure Halo is running and you have access, send an email to Kybo Ren at:\nkyboren@gmail.com", "Warning", MB_OK | MB_ICONWARNING);
return 0;//0 is fail
}//we try once more then fail

}//if hProc still is messed
int result = 1;

result *= ReadProcessMemory(hProc, reinterpret_cast<void*>((player_class_location) + ((player_number-1)*SIZE) + 0 ), (void*)&player_kills , 2, 0);//read kills

return result;
}

int Player::Refresh_Betrayals()
{
if(hProc == NULL)
{
hProc = OpenProcess(PROCESS_VM_READ, FALSE, process_PID);

if(hProc == NULL)
{
MessageBox(0, "Couldn't open the Halo process for reading. \nIf you are sure Halo is running and you have access, send an email to Kybo Ren at:\nkyboren@gmail.com", "Warning", MB_OK | MB_ICONWARNING);
return 0;//0 is fail
}//we try once more then fail
}//if hProc still is messed
int result = 1;

result *= ReadProcessMemory(hProc, reinterpret_cast<void*>((player_class_location) + ((player_number-1)*SIZE) + TKS ), (void*)&player_betrayals, 2, 0);//read TKs

return result;
}

int Player::Refresh_Assists()
{
if(hProc == NULL)
{
hProc = OpenProcess(PROCESS_VM_READ, FALSE, process_PID);

if(hProc == NULL)
{
MessageBox(0, "Couldn't open the Halo process for reading. \nIf you are sure Halo is running and you have access, send an email to Kybo Ren at:\nkyboren@gmail.com", "Warning", MB_OK | MB_ICONWARNING);
return 0;//0 is fail
}//we try once more then fail

}//if hProc still is messed
int result = 1;

result *= ReadProcessMemory(hProc, reinterpret_cast<void*>((player_class_location) + ((player_number-1)*SIZE) + ASSISTS), (void*)&player_assists , 2, 0);//read assists

return result;
}

int Player::Refresh_Deaths()
{
if(hProc == NULL)
{
hProc = OpenProcess(PROCESS_VM_READ, FALSE, process_PID);

if(hProc == NULL)
{
MessageBox(0, "Couldn't open the Halo process for reading. \nIf you are sure Halo is running and you have access, send an email to Kybo Ren at:\nkyboren@gmail.com", "Warning", MB_OK | MB_ICONWARNING);
return 0;//0 is fail
}//we try once more then fail

}//if hProc still is messed
int result = 1;

result *= ReadProcessMemory(hProc, reinterpret_cast<void*>((player_class_location) + ((player_number-1)*SIZE) + DEATHS ), (void*)&player_deaths , 2, 0);//read deaths

return result;
}


int Player::Refresh_Suicides()
{
if(hProc == NULL)
{
hProc = OpenProcess(PROCESS_VM_READ, FALSE, process_PID);

if(hProc == NULL)
{
MessageBox(0, "Couldn't open the Halo process for reading. \nIf you are sure Halo is running and you have access, send an email to Kybo Ren at:\nkyboren@gmail.com", "Warning", MB_OK | MB_ICONWARNING);
return 0;//0 is fail
}//we try once more then fail

}//if hProc still is messed
int result = 1;

result *= ReadProcessMemory(hProc, reinterpret_cast<void*>((player_class_location) + ((player_number-1)*SIZE) +SUICIDES), (void*)&player_suicides , 2, 0);//read suicides
return result;
}


int Player::Refresh_Team()
{
if(hProc == NULL)
{
hProc = OpenProcess(PROCESS_VM_READ, FALSE, process_PID);

if(hProc == NULL)
{
MessageBox(0, "Couldn't open the Halo process for reading. \nIf you are sure Halo is running and you have access, send an email to Kybo Ren at:\nkyboren@gmail.com", "Warning", MB_OK | MB_ICONWARNING);
return 0;//0 is fail
}//we try once more then fail
}//if hProc still is messed
int result = 1;

result *= ReadProcessMemory(hProc, reinterpret_cast<void*>((player_class_location) + ((player_number-1)*SIZE) + TEAMS ), (void*)&player_team , 1, 0);//read team

return result;
}

int Player::Refresh_In_Game()
{
if(hProc == NULL)
{
hProc = OpenProcess(PROCESS_VM_READ, FALSE, process_PID);

if(hProc == NULL)
{
MessageBox(0, "Couldn't open the Halo process for reading. \nIf you are sure Halo is running and you have access, send an email to Kybo Ren at:\nkyboren@gmail.com", "Warning", MB_OK | MB_ICONWARNING);
return 0;//0 is fail
}//we try once more then fail

}//if hProc still is messed
int result = 1;

result *= ReadProcessMemory(hProc, reinterpret_cast<void*>((player_score_location) + ((player_number-1)*PLAYERSZ) + PLAYERIN ), (void*)&player_ingame , 1, 0);//read ingame

return result;
}

int Player::Refresh_Name()
{
if(hProc == NULL)
{
hProc = OpenProcess(PROCESS_VM_READ, FALSE, process_PID);

if(hProc == NULL)
{
MessageBox(0, "Couldn't open the Halo process for reading. \nIf you are sure Halo is running and you have access, send an email to Kybo Ren at:\nkyboren@gmail.com", "Warning", MB_OK | MB_ICONWARNING);
return 0;//0 is fail
}//we try once more then fail
}//if hProc still is messed
int result = 1;
char name[13];

for(unsigned int name_index = 0; name_index < MAX_NAMELENGTH; name_index += 2)
{
result *= ReadProcessMemory(hProc, reinterpret_cast<void*>((player_class_location) + ((player_number-1)*SIZE) + NAMES + name_index), (void*)&name[(name_index / 2)], 1, 0);//read name
}
name[12] = '\0';//nullify the name
player_name = name;//the name is what we just read

return result;
}

void Player::Set_PID(const unsigned long &PID)
{
process_PID=PID;
}

void Player::Set_Location(const unsigned long &class_location, const unsigned long &score_location, const unsigned long &ipadd_location)
{
player_class_location = class_location;
player_score_location = score_location;
player_ipadd_location = ipadd_location;
}

void Player::Set_Player_Number(const unsigned int &player_num)
{
player_number = player_num;
}

void Player::Set_Size(const unsigned long &size)
{
SIZE = size;
}

void Player::Set_Type(const unsigned long &type)
{
switch(type)
{
case PC_DS:
player_class_location = PC_DS_CLASS;
player_score_location = PC_DS_SCORE;
break;
case CE_GM:
player_class_location = CE_GM_CLASS;
player_score_location = CE_GM_SCORE;
break;
case PC_GM:
player_class_location = PC_GM_CLASS;
player_score_location = PC_GM_SCORE;
break;
default:
break;
}
}
bool Player::Handle_Is_Null()
{
return (hProc == NULL);
}

unsigned int Player::Open_Halo()
{
hProc = OpenProcess(PROCESS_VM_READ, FALSE, process_PID);
return (hProc != NULL);//return 1 for success
}

int my_itoa(const int number, char *data)
{
std::string buf;
std::string buffer;
int num = std::abs(number);
const unsigned int numdigits = (log((float)num) / log(10.0f)) + 1;
unsigned int dig_buf;

for(int i = 1; i <= numdigits; ++i)
{
dig_buf = static_cast<int>(std::pow(10.0f, i-1));

buffer = (num % static_cast<int>(std::pow(10.0f, i))) / dig_buf + '0';
buf += buffer;
}

if(number < 0)
{
buf += '-';
}

std::reverse(buf.begin(), buf.end());

std::strcpy(data, buf.c_str());

return (buf.size() > 0);

};


Server.h:


/*
Server.h

Provides a class interface to be used between your application and Halo.

Copyright 2004 Kybo Ren
*/
#include <vector>
#include "Player.h"

#define MAX_PLAYERS 16

#define ERROR 0
#define PC_DS 1
#define PC_GM 2
#define CE_DS 3
#define CE_GM 4//pc and ce ingame and DS servers

#define PC_DS_GAMETYPE 0x6712D8 //1 = CTF, 2 = Slayer, 3 = Oddball, 4 = KOTH, 5 = Race
#define CE_GM_GAMETYPE 0x0
#define PC_GM_GAMETYPE 0x0//obviously these aren't implemented#nwe

const int CTF = 1;
const int SLAYER = 2;
const int ODDBALL = 3;
const int KOTH = 4;
const int RACE = 5;//gametypes
const char gametypes[5][15] = {"CTF","Slayer","Oddball","KOTH","Race"};//gametype strings


class Server
{
unsigned long server_PID;//the PID of the server
unsigned long server_isEnabled;//is it enabled? did the user check off this box?
unsigned long server_Number;//i.e. 1 for "Halo Console (1)", 2 for "Halo Console (2)"
unsigned long server_Type;//type of server, i.e. Halo PC DS, Halo CE game
unsigned long server_Gametype;//gametype on server
unsigned long server_gametype_loc;//location of gametype on server proc
HANDLE hProc;//handle to the process
HANDLE server_thread;//handle to the thread for this process

public:
Server();//default constructor
~Server();//destructor
std::vector<Player*> Players;//vector of POINTERS to Player objects
ConsoleLogger Console;//for logging the console data if it is a DS
const char *Gametype();//returns gametype string of current gametype on server
const unsigned long PID();
HANDLE Thread();//returns a handle to the current thread
const unsigned long isEnabled();
const unsigned long Number();
const unsigned long Type();//echoes the variables above
const int Refresh(void);//refresh all
const int Set_PID(const unsigned long PID);
const int Set_Thread(HANDLE hThread);
const int Set_Enabled(const unsigned long isEnabled);
const int Set_Number(const unsigned long Number);//sets the variables above
const int Set_Type(const unsigned int Type);//set type
const int Set_All(const unsigned long PID, HANDLE hThread, const unsigned long isEnabled, const unsigned long Number, const unsigned long Type);

};

Server::Server()
{
server_PID = 0;
server_thread = 0;
server_isEnabled = 0;
server_Number = 0;
server_Type = 0;
server_thread = 0;//0 the values


for(unsigned int i=0; i < MAX_PLAYERS; ++i)
{
Players.push_back(new Player(server_PID, server_Type, (i+1)));//insert a new player
}

}

const int Server::Set_All(const unsigned long PID, HANDLE hThread, const unsigned long isEnabled, const unsigned long Number, const unsigned long Type)
{
server_PID = PID;
server_thread = hThread;
server_isEnabled = isEnabled;
server_Number = Number;
server_Type = Type;

switch(Type)
{
case PC_DS:
server_gametype_loc = PC_DS_GAMETYPE;
break;
case CE_GM:
server_gametype_loc = CE_GM_GAMETYPE;
break;
case PC_GM:
server_gametype_loc = PC_GM_GAMETYPE;
break;

default:
server_gametype_loc = PC_DS_GAMETYPE;//weird type, assume PC dedicated server
break;
}

return 0;
}

Server::~Server()
{
for(unsigned int i=0; i < MAX_PLAYERS; ++i)
{
delete Players[i];//delete memory
}

CloseHandle(hProc);//close the handle to the proc
CloseHandle(server_thread);//close the thread handle
}

const unsigned long Server::PID()
{
return server_PID;
}

HANDLE Server::Thread()
{
return server_thread;
}

const unsigned long Server::isEnabled()
{
return server_isEnabled;
}

const unsigned long Server::Number()
{
return server_Number;
}

const unsigned long Server::Type()
{
return server_Type;
}

const int Server::Refresh()
{
int result = 1;

if(hProc == NULL)
{
hProc = OpenProcess(PROCESS_VM_READ, FALSE, server_PID);

if(hProc == NULL)
{
MessageBox(0, "Couldn't open the Halo process for reading. \nIf you are sure Halo is running and you have access, send an email to Kybo Ren at:\nkyboren@gmail.com", "Warning", MB_OK | MB_ICONWARNING);
return 0;//0 is fail
}//we try once more, then fail

}//if hProc still is messed

for(unsigned int i = 0; i < MAX_PLAYERS; ++i)
{
if(Players[i]->Handle_Is_Null())//null handle
{
Players[i]->Open_Halo();//try to open the process
}

result *= Players[i]->Refresh();
}
result *= ReadProcessMemory(hProc, reinterpret_cast<void*>(server_gametype_loc), (void*)&server_Gametype, 1, 0);//read gametype

return result;
}


const int Server::Set_PID(const unsigned long PID)
{
server_PID = PID;

for(unsigned int i=0; i < MAX_PLAYERS; ++i)
{
Players[i]->Set_PID(PID);
}

return 0;
}

const int Server::Set_Thread(HANDLE hThread)
{
if(hThread = NULL)
{
return 1;
}

server_thread = hThread;

return 0;
}

const int Server::Set_Enabled(const unsigned long isEnabled)
{
server_isEnabled = isEnabled;

return 0;
}

const int Server::Set_Number(const unsigned long Number)
{
server_Number = Number;

return 0;
}
const int Server::Set_Type(const unsigned int Type)
{
server_Type = Type;


for(unsigned int i = 0; i < MAX_PLAYERS; ++i)
{
Players[i]->Set_Type(Type);
}//set the type

return Type;
}

const char *Server::Gametype()
{
if(hProc == NULL)
{
hProc = OpenProcess(PROCESS_VM_READ, FALSE, server_PID);

if(hProc == NULL)
{
MessageBox(0, "Couldn't open the Halo process for reading. \nIf you are sure Halo is running and you have access, send an email to Kybo Ren at:\nkyboren@gmail.com", "Warning", MB_OK | MB_ICONWARNING);
return 0;//0 is fail
}//we try once more, then fail

}//if hProc still is messed
int result = 1;

result *= ReadProcessMemory(hProc, reinterpret_cast<void*>(server_gametype_loc), (void*)&server_Gametype, 1, 0);//read gametype

return gametypes[server_Gametype];
}


No guarantees on anything, but it did work when I wrote it. [...] this could be a helpful reference. Good luck.

This was given to me 8+ months ago.

Kornman00
April 21st, 2010, 02:58 AM
Damn, Kybo Ren, wonder what ever came of that guy?

On a lighter note, a single call to ReadProcessMemory would probably yield better results. 1) Less overhead and 2) You're reading from a separate process which may actually update (the game state in this case) before you do your next call. So you could very well retain old player information all the while you're getting new information from the multiple Read (or Write) calls. You'd want to treat the other program like a database.

E: Those field offsets will never change unless they want to break all prior game saves. Part of the reason why I never chose to introduce certain game-state upgrades in OS. It would have broken all prior game saves.

Dwood
April 21st, 2010, 05:55 PM
I still talk to kybo ren occasionally duder.

Limited
April 21st, 2010, 06:44 PM
Like Korn said, its alot better to read the 200 bytes in one big whoop, then parse out that info.

Kybo is at university I think.