Unlocking Brink’s Console on Xbox 360

Xbox 360 Brink Unlocked Console

Brink, one of the newer id Tech games running under the engine idTech4 still keeps to the original roots of the idTech engine. I had a hunch that the console would be easily unlocked with just a keyboard. Well they did better than that to leave a console fully enabled in the game…or did they?

I started to mess around with Brink, reversing the engine and comparing it to the previous idTech games. They are very similar with huge improvements and very good work done by the guys at id software. Just for personal use I wanted to be able to run my console commands just like on the PC version.

The console command that gets pushed through the engine to “show” the console is “com_allowConsole” or “com_allowFullConsole”. With experimenting with this engine, I found out that the button binds are re-loaded from a .cfg file within the files inside of the games archives. I did not to very much research into the game archives, BUT all hope is not lost. If you were to search for the string “com_allowFullConsole” you can find where a cvar list is generated with defaults and pointers to game code to execute similar to Call of Duty (Quake 3 Engine). The engines are similar in the way that they handle cvars.

To find the function where we can enable the console on the start, we need to find the function where all of the default values are loaded. As I stated before the button configurations are re-loaded from file and thus will get overwritten after we leave the initialization console. After we find the string find where it is referenced. As shown here.

.text:82ACCA98                 mflr      r12
.text:82ACCA9C                 stw       r12, -8(r1)
.text:82ACCAA0                 stwu      r1, -0x60(r1)
.text:82ACCAA4                 lis       r10, ((flt_8210B698+0x10000)@h)
.text:82ACCAA8                 lis       r9, [email protected]
.text:82ACCAAC                 lis       r6, [email protected]
.text:82ACCAB0                 lis       r11, [email protected]
.text:82ACCAB4                 lis       r8, [email protected]
.text:82ACCAB8                 lis       r4, ((aCom_allowfullc+0x10000)@h) # "com_allowFullConsole"
.text:82ACCABC                 lfs       f2, [email protected](r10)
.text:82ACCAC0                 lis       r3, ((off_82B6DC24+0x10000)@h)
.text:82ACCAC4                 lfs       f1, [email protected](r9)
.text:82ACCAC8                 addi      r11, r11, [email protected]
.text:82ACCACC                 addi      r5, r6, [email protected]
.text:82ACCAD0                 addi      r7, r8, [email protected]
.text:82ACCAD4                 stw       r11, 0x54(r1)
.text:82ACCAD8                 addi      r4, r4, -0x904 # aCom_allowfullc
.text:82ACCADC                 addi      r3, r3, -0x23DC # off_82B6DC24
.text:82ACCAE0                 li        r10, 0
.text:82ACCAE4                 li        r6, 0x4009
.text:82ACCAE8                 bl        sub_82231058
.text:82ACCAEC                 lis       r11, ((loc_82B29F80+0x10000)@h)
.text:82ACCAF0                 addi      r3, r11, -0x6080 # loc_82B29F80
.text:82ACCAF4                 bl        sub_82AA9228
.text:82ACCAF8                 addi      r1, r1, 0x60
.text:82ACCAFC                 lwz       r12, -8(r1)
.text:82ACCB00                 mtlr      r12
.text:82ACCB04                 blr

This may look like a huge bunch of garbled mess, which to be honest it is. We can look through the disassembly and figure a few things out. If each of the functions start at r3, and moves up until it gets to r10 then pushes everything else to the stack. We can assume that r3 is going to be the start for this “dvar_register” function. Since 32-bit PowerPC loads everything at 16-bits at a time then we load shifted, then and or or it to get the full 32-bit address. The auto-comments say that r3, and r11 get anded to be offset 82B29F80 which is a piece of code that is not attached to any “defined” function. You see this system used in a bunch of Quake-Engine/Doom-Engine variants and Brink is no exception.

Register 4 (r4), has loaded the address of “com_allowFullConsole” which is our dvar command that gets added then linked to the code that was talked about above. r5, which seems to pull a byte from a “unknown offset”. If we see where that offset lands us it has a hex value of 0x30. A hex value of 0x30 is a string of “0”. That means that the default value that gets loaded for “com_allowFullConsole” is “0”. There are a few ways we could go about changing this.

We see that there is a byte value of 0 referenced, I happen to know that to add the function that it pushes a few things then calls the function. To change the default value just either load immediate into the correct register OR you can change where the address of the “Default Value” is pointing. Just find a 1 somewhere in the game code and change the reference address and it will load a 1 instead of a zero. This way it is a little less intrusive on the game and will cause a lot less crashes then changing a bunch of code.

When you change the default value of “com_allowFullConsole” it will load up with a full console right away, the second the game starts! Allowing you to change whatever console commands that you want. I don’t think that this article was the clearest but if you read the Call of Duty Unlocking the Console article it should fill in the gaps.

Leave a Reply