Alright so a few notes about this source…
1. I’ve gotta give credits to [c0z] for stealing portions of the DashLaunch source code and integrating it in here for certain hooking abilities and etc.
2. Natelx helped out a bit with fixing a few things when it came to hacking Alan Wake oh so long ago.
3. Xorloser just because he’s a chill guy :p and me and him always discuss 360 related things.
Now onto the actual discussion of the source:
VOID __declspec(naked) CheckDamage(VOID)
{
DWORD Ptr;
__asm
{
mr Ptr,r24
}
if( InfHealth == TRUE && Ptr != 0x00)
{
//printf("Player Shouldn't have been damaged here\r\n");
float pValue = 900.0f;
__asm{
lfs fr13,0x5C(r29)
fsubs fr12,fr0,fr31
stfs pValue,0x3C(r29)
stfs pValue,0x60(r29)
}
}else{
if( Ptr != 0x00 )
{
//printf("Player Should be damaged here Ptr != 0x00\r\n");
__asm{
lfs fr13,0x5C(r29)
fsubs fr12,fr0,fr31
stfs fr12,0x3C(r29)
stfs fr13,0x60(r29)
}
}
}
if( OneHitKo == TRUE && Ptr == 0x00 )
{
float nValue = 0.0f;
__asm{
lfs fr13,0x5C(r29)
fsubs fr12,fr0,fr31
stfs nValue,0x3C(r29)
stfs nValue,0x60(r29)
}
}else{
if( Ptr == 0x00 )
{
__asm{
lfs fr13,0x5C(r29)
fsubs fr12,fr0,fr31
stfs fr12,0x3C(r29)
stfs fr13,0x60(r29)
}
}
}
__asm{
/* return back to the game */
/* 82B480E0 */
lis r11,0x82B4
ori r11,r11,0x80E4
mtctr r11
bctr
}
}
Code like this above is considered a code cave,
the way it works is you basically insert your code right in-between the games code which allows you to manipulate values while functions of objects are being called.
The reason it was being done in a good majority of the games I hacked is that the damage functions generally affect more then just the current player, most of the time they’ll affect the AI as well as the player which means you have to come up with methods to detect whether the damage function is currently damaging a player or an AI.
I’ll explain a bit about this more in depth when I write a tutorial on trainer making for the team but for now that should be a good enough explanation of why you see it in every one of my trainers source.
Now lets go onto the difference between these two functions
memcpy
DmSetMemory
The ability to simply do memcpy on a DEVKIT build doesn’t work (This includes those with converted devkit kernels) there are memory restrictions to it.
So if you’re testing your trainer code on a devkit (Which is something I recommend is using a devkit kernel if you’re making trainers which we’ll get into later).
You need to use DmSetMemory instead of memcpy otherwise you’ll wind up with access violations and your game/360 crashing at a kernel level.
An example of the two should be provided in the source as I usually just comment out one and write the other back and fourth before release and during updates of my trainers.
VOID ProcessButtonPress( MESSAGEBOX_RESULT g_mb_result )
{
This function has to exist in every new game you train and you just pass the parameters from main.cpp into the header file for the game it makes things easier and makes the trainer engine a bit more universal with the whole UI setup.
VOID ShowTrainerMain()
{
Prompt = XShowMessageBoxUI(0, L"Team XPG - DeadlyData", L"Body Count Trainer V0.1\r\nView Codes: DPAD-DOWN(x4)", ARRAYSIZE(g_strButtons), g_strButtons, 0, XMB_PASSCODEMODE, &g_mb_result, &g_xol);
}
The above code must also exist in every game you train as when the main.cpp gets the START+BACK it calls on this and this spawns the box where it allows you to enter a code in order to view codes, or etc etc etc.
I had to do a bit of hachary to this code in order to make it not have users “Verify their passcode”
Exhibit A.
Flag Definition XMB_NOICON
Does not display an icon. XMB_ERRORICON
Displays an error icon. XMB_WARNINGICON
Displays a warning icon. XMB_ALERTICON
Displays an alert icon. XMB_PASSCODEMODE
Prompts for and returns a passcode. XMB_VERIFYPASSCODEMODE
Prompts to verify a passcode.
In Exhibit A you’ll notice tat the code I used was a prompt for a passcode,
Well shortly after that it’ll request that user re-enter the same passcode in order to verify that it’s the correct one.
The xbox it’s self creates another message box with the “XMB_VERIFYPASSCODEMODE” attribute set the way that you get around this is by clearing the passcode before returning to the xbox/ending your function.
if( g_mb_result.rgwPasscode[0] == Y_BUTTON && g_mb_result.rgwPasscode[1] == Y_BUTTON && g_mb_result.rgwPasscode[2] == Y_BUTTON && g_mb_result.rgwPasscode[3] == Y_BUTTON )
{
Sleep(500);
if( OneHitKo == true )
{
XShowMessageBoxUI(0, L"Cheat Disabled Successfully", L"One Hit Kills - Disabled\r\n", ARRAYSIZE(g_strButtons), g_strButtons, 0, XMB_NOICON, &g_mb_result, &g_xol);
OneHitKo = false;
}else{
XShowMessageBoxUI(0, L"Cheat Enabled Successfully", L"One Hit Kills - Enabled\r\nDescription: Any monster/enemy you hit will die within the first hit.\r\n", ARRAYSIZE(g_strButtons), g_strButtons, 0, XMB_NOICON, &g_mb_result, &g_xol);
OneHitKo = true;
}
memset( &g_mb_result.rgwPasscode[0], 0x00, 0x02 );
memset( &g_mb_result.rgwPasscode[1], 0x00, 0x02 );
memset( &g_mb_result.rgwPasscode[2], 0x00, 0x02 );
memset( &g_mb_result.rgwPasscode[3], 0x00, 0x02 );
Prompt = 0x9999;
}
The above code is an example of that,
Basically what you do is use memset to clear the passcode that was entered previously then clear the Prompt variable via entering a unique value.
Also note the “Sleep(500);” the xbox has some issues with making multiple message boxes…
So we delay the spawning of new ones by 500 milliseconds, then we can display our “Cheat Enabled” or “Cheat Disabled” message boxes notifying the user the action has been done.
Now note the Y_BUTTON attribute in there,
I actually made this part really simple as the SDK didn’t originally have properly set values for the definitions of each button I made a header with each one predefined in it and it’s automatically included in my projects.
#define X_BUTTON 0x00005802
#define Y_BUTTON 0x00005803
#define RIGHT_BUMPER 0x00005804
#define LEFT_BUMPER 0x00005805
#define LEFT_TRIGGER 0x00005806
#define RIGHT_TRIGGER 0x00005807
#define DPAD_UP 0x00005810
#define DPAD_DOWN 0x00005811
#define DPAD_LEFT 0x00005812
#define DPAD_RIGHT 0x00005813
So that way instead of having to declare each hex value in order to check what button is being pressed you can simply use X_BUTTON, Y_BUTTON, etc.
Now,
Back to hooks and then you’ll find a download link for this source code.
DWORD Stuff[4];
patchInJump( (PDWORD)Stuff, (DWORD)CheckDamage, FALSE );
//DmSetMemory( (PDWORD)0x82B480D4, 4, &Stuff[0], NULL );
//DmSetMemory( (PDWORD)0x82B480D8, 4, &Stuff[1], NULL );
//DmSetMemory( (PDWORD)0x82B480DC, 4, &Stuff[2], NULL );
//DmSetMemory( (PDWORD)0x82B480E0, 4, &Stuff[3], NULL );
memcpy( (PDWORD)0x82B480D4, &Stuff[0], 4 );
memcpy( (PDWORD)0x82B480D8, &Stuff[1], 4 );
memcpy( (PDWORD)0x82B480DC, &Stuff[2], 4 );
memcpy( (PDWORD)0x82B480E0, &Stuff[3], 4 );
If you look through the DashLaunch source code you’ll notice that the “patchInJump” function exists,
However this is actually a modified version of it from [c0z]‘s originally implementation the reason being it’s not really quite possible to simply set things the way he was when you’re dealing with memory regions in games.
Nor is it possible on a devkit so what I’ve done is split it into an array of 4, with 4 bytes contained with in each array considering all instructions on PPC come out to be 4 bytes.
What this code does is overwrites the code at the location you specify with a branch into your code so that your code is executed instead of the original as soon as it’s hit.
What this means is that you’ve also got to document and replace the original code which you overwrote as well if you overwrite things that are important to the game and you don’t actually replace the code you’ve overwritten end result will be a crash most likely because you screw up the games entire operation.
Now keep in mind that you have to use the & because it’s an pointer what this is doing is forcing the function to grab the pointer to each object of the array rather then passing the array it’s self.
Anyways, Hopefully that’s explanatory enough to make this code useful to you guys and without further adue here’s a download link.
Requirements:
Xbox360 SDK
Visual Studio 2010
Recommendations for Visual Studio 2010
Get a hold of a copy of Visual Assist X.
It’s a great utility to have while programming in Visual Studio no matter the language.
Download:
https://rapidshare.com/files/3091477282/Trainer_Engine.rar
Password: teamxpg_deadlydata