Call of Duty Series Console Unlocking on All Platforms

DOGBIT.IN Call of Duty Console

Since Call of Duty 4 was released on PC, I wished that there would be some way or form to enable console for the Xbox 360 and PlayStation 3 platforms. There were findings in the way of removing the RSA Security checks on the executable on both platforms when the appropriate tools were released publicly. Mainly that method was used for cheating, unlocking everything online and changing leaderboard stats. This is not what I wanted to be done. Some cool things did come out of it like a CoDJumper mod and a few other zombie mods but most of the time it was just for “10th Prestige Lobbies” and for cheating.

In early of 2007 Infinity Ward and Activision Released a open public beta of Call of Duty 4 for the masses to play, then pulled the servers after the beta went down. This left a collector that wanted to play the game again unable due to the LIVE servers being taken down and getting signed out of live when they wanted to play.

Due to recent findings in Xbox 360 Hardware and Software exploits (JTAG/RGH) and PlayStation 3 Software (CFW 3.55) this would allow us to make modifications to the game code and still be able to run the game with unsigned code. This is the research for creating your own patches and loading the game.

  1. The Call of Duty Engine, runs off of a slightly modified version of the Quake 3 Engine. I recommend picking up the Q3 Source Code
  2. Xbox 360 and PlayStation 3 modifications require knowledge of PowerPC assembly. You can find documentation from IBM

You can find a way to send your own console commands from the Quake 3 Source Code. This was pulled from qcommon.h and it shows how command execution works. This is how we will “poke” and “peek” commands from the console in Call of Duty by writing a simple codecave or more complex hook.

/*
==============================================================
CMD
Command text buffering and command execution
==============================================================
*/
/*
Any number of commands can be added in a frame, from several different sources.
Most commands come from either keybindings or console line input, but entire text
files can be execed.
*/
void Cbuf_Init (void);
// allocates an initial text buffer that will grow as needed
void Cbuf_AddText( const char *text );
// Adds command text at the end of the buffer, does NOT add a final \n
void Cbuf_ExecuteText( int exec_when, const char *text );
// this can be used in place of either Cbuf_AddText or Cbuf_InsertText
void Cbuf_Execute (void);
// Pulls off \n terminated lines of text from the command buffer and sends
// them through Cmd_ExecuteString.  Stops when the buffer is empty.
// Normally called once per frame, but may be explicitly invoked.
// Do not call inside a command function, or current args will be destroyed.

If you search in a disassembler for “screenshot\n” or just “screenshot” this is a command that gets called whenever Call of Duty wants to take a screenshot. This will give you a basic setup and example of how to use the Cbuf_ExecuteText function.

Here is the x86 Disassembly

.text:005D9AE9                 mov     eax, [ebp+arg_0]
.text:005D9AEC                 push    offset aScreenshot ; "screenshot\n"
.text:005D9AF1                 push    eax
.text:005D9AF2                 call    sub_49B930

As you can see here if you know x86 assembly which works on a stack based system (First In Last Out) that it pushes the string “screenshot\n” then eax, I happen to know that eax is 0 and in some Call of Duty games it is the “delay” before a command gets called. I normally just pass 0 to the function sub_49B930 which by the similar arguments we can say that it is Cbuf_ExecuteText. Using what we know with the current arguments that are pushed on to the stack we can reverse this into a basic prototype for use on the PC.

Cbuf_ExecuteText(int v0, char* v1);

Then from there we can actually write a typedef to call it from inside our own code.

typedef void (__cdecl *lpCbuf_ExecuteText)(int v0, char* v1);
lpCbuf_ExecuteText SendCommandToConsole = (lpCbuf_ExecuteText)(0x49B930);

I got the address of 0x49B930 because that is the address where the function Cbuf_ExecuteText is in memory aka sub_49B930.

In order to use this function we would need some kind of loop. I will supply a basic injectable DLL that you can use with Call of Duty to fire a gun.

#include <Windows.h>
typedef void (__cdecl *lpCbuf_ExecuteText)(int v0, char* v1);
lpCbuf_ExecuteText SendCommandToConsole = (lpCbuf_ExecuteText)(0x49B930);

DWORD WINAPI HackTest(LPVOID)
{
	while (1)
	{
		if(GetAsyncKeyState(VK_F2)&0x8000)
		{
			SendCommandToConsole(0, "+attack\n");
			Sleep(5);
			SendCommandToConsole(0, "-attack\n");
		}
		Sleep(5);
	}
	return 0;
}

BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpvReserved)
{
	if(dwReason == DLL_PROCESS_ATTACH)
	{
		CreateThread(0,0,HackTest,0,0,0);
	}
	return TRUE;
}

This process works for PowerPC in a sort of way. Except for PowerPC arguments get passed through registers up until r10, then everything after that gets pushed to the stack. So instead of having everything pushed to the stack most of our arguments should be r3-r5.

Finding the Cbuf_ExecuteText method is the same on every platform since the console is platform-independant. So search for “screenshot” or “pb_status” or one of the many cross platform items.

.text:822C6434                 lis       r11, ((aScreenshotSile+0x10000)@h) # "screenshot silent\n"
.text:822C6438                 li        r3, 0
.text:822C643C                 addi      r4, r11, -0x7514 # aScreenshotSile
.text:822C6440                 bl        sub_82235858

Looks familar 😀 Thats because its the same basic code. PowerPC loads into r3, 0 (the first argument that is passed) and “screenshot silent\n” as the argument. We can recycle the code from the pc side with a few tweaks.

typedef void (__cdecl *lpCbuf_ExecuteText)(int v0, char* v1);
lpCbuf_ExecuteText SendCommandToConsole = (lpCbuf_ExecuteText)(0x82235858);

That will solve everything. For this you will need some kind of background thread on the Xbox or PS3. You will have to find those tools and tutorials elsewhere because it does not apply to this writeup.

Using the console is easy, it will be able to change so much about the engine. The only thing that is different version to version is that there will be more dvar/cvar checks in the newer revisions of the InfinityWard engine. Call of Duty Black Ops by Treyarch had some checks in place but they are easily removed. You can search for “is cheat-protected” or “is write-protected” and make it skip the checks right to the end of the function and you will be able to modify anything with the console. In older version of the IW engine there are fewer checks because Online Cheating was not a big part back then. (With mods and dedicated servers freely available)

Unlocking the Console.

Unlocking the console is a very simple process for any of the Call of Duty Series Engines. A simple search of “is cheat protected” will land you there almost 90% of the time. (Black Ops and Modern Warfare 3 were a little trickier)

.text:821CEC64                 cmplwi    cr6, r11, 0
.text:821CEC68                 bne       cr6, loc_821CEC88
.text:821CEC6C                 lis       r11, [email protected] # "%s is cheat protected.\n"
.text:821CEC70                 lwz       r5, 0(r31)
.text:821CEC74                 li        r3, 0x10
.text:821CEC78                 addi      r4, r11, [email protected] # "%s is cheat protected.\n"
.text:821CEC7C                 bl        sub_82230A90

You should see something like that in the disassembly. Very easy to spot, If you are using OllyDbg you can trace it back up by selecting the start of the sub function and see where it was going to be called from. This also works in other disassemblers but it may vary. You should be able to find the first instruction in the function then follow it down to the first branching compare. I’m going off of memory but the first one should be a “valid value” check. I would leave that in-tact if you do not have any checking code before you use the console. Either the IW engine will freeze/crash or kick you back to the main menu with some sort of error. It varies (COD4 will Crash, Modern Warfare 2 will return to menu sometimes…) After the “valid value” check I would scroll down to see where it would fail and land you at the above nasty message, check where it would go if everything passed. Take note of that address and you will need to write a patch. The patch code that I am going to send is in PowerPC but with basic knowledge of x86 you can write a similar patch for PC.

#   IW3_BETA PATCHES BY k
.globl _start
_start:
.set PatchLine,        0x821CEB60
.set PatchTo,        0x821CECE8
# ============================================================================
#  Remove all of the checks on dvar setting
# ============================================================================
.long PatchLine
.long (9f - 0f) / 4
0:
8:        bl        PatchTo-((8b-0b)+PatchLine)
9:
# ============================================================================
.long 0xffffffff
.end
# ============================================================================

With the basic patch there it will skip all of the checks and drop down to the last few checks to see if its a multi-var command or whatever. It won’t give you any errors about setting a “write-protected”, “cheat-protected”, or “read-only” dvar.

That about concludes all of the work I have to offer. The rest is up for exploration. You can add your own cvars to call your own code whenever you want. I have added things like “startmw2”, “startcod4” and what that will do when you enter that into the console is, search for a mw2.exe or cod4.exe and then if it finds it it will launch that game from INSIDE of another Call of Duty game! Have fun finding out the rest of the functions that are similar to Quake 3, there are many and you can do things like enable noclip on games that have the console command “noclip” disabled.

Post Notes:

Call of Duty games using the Infinity Ward engine:

  • Call of Duty
  • Call of Duty 2
  • Call of Duty 4
  • Call of Duty 5: World at War
  • Call of Duty: Modern Warfare 2
  • Call of Duty: Black Ops
  • Call of Duty: Modern Warfare 3
  • Call of Duty: Classic

There may be a few others that I cannot think of right now. I don’t think that Big Red One, nor 3 use the IW engine but some proprietary engine that Treyarch made. I hope that this was informational and that someone will be able to finish rewriting the basic part of the console engine for free use.

Thanks To:
TheFallen93
sotg caboose
Xenon.7

3 thoughts on “Call of Duty Series Console Unlocking on All Platforms”

Leave a Reply