Overview Enable (master) codes are nothing mystical. They simply provide the cheat software with enough information to force the game to execute the main cheat engine frequently. They are not difficult at all, but no cheat can function without an appropriate enable code for its game. How They Work An enable code provides addresses and data that will be used to somehow force the game to execute the cheat engine code. This information varies depending on the type of enable code you are creating, but the results will be one of three things. * A jump and link (JAL) to the main cheat engine will replace an operation in an oft-executed part of the game. This will typically be one of SCE's library functions, most often part of libpad. * The cheat engine will set up as an interrupt handler. * The cheat engine will run as a separate thread. These various methods are all the result of hooking certain kernel code, specifically syscalls that have to do with initializing or spawning new processes. The code injected into these syscalls will use the master code information to force the game to execute the main cheat engine. The exact details of this process are outside the scope of this document. Hook 1: Jump and Link The Jump and Link hook is the most commonly used method of hooking the game. When an enable code creates this type of hook, the operation at the address you provide, and the address that immediately follows will be copied to the last part of the main cheat engine--they still need to be executed after all--and those addresses will then be overwritten with a JAL to the cheat engine, and a NOP, respectively. The one immutable rule with this type of enable code is that the address must reside within a function that is executed frequently. If you choose game-specific code that is only executed when a particular menu is accessed, then the cheat engine will only execute at that time. That would make infinite health not-so-infinite, since the cheat engine cannot overwrite the address constantly, and no cheats all would become active until you accessed that menu for the first time. That is why Sony library code, and specifically the pad read is generally hooked. Those functions execute many times per second, and the pad read has the advantage of being user-interface related. It is not the sort of function that might be bypassed somehow, at a crucial moment. The most commonly used enable code hooks the call (JAL) to memcpy that resides within the scePadRead function. Much of what follows is information established from reviewing the CodeBreaker. It is most likely true of all cheat devices, but there may be some small variations. It is written in FAQ format. I would prefer to just write up the information, but since these will be answers to questions that are likely to arise, I want the question itself to be prominent and explicit, rather than implied. Q: Why does the cheat engine copy and replace the address specified and the next address? A: Any type of branch operation (JAL, BEQ, J, JR, BEQL, etc. see any MIPS assembly reference) executes the operation that immediately follows. This operation is said to be in the branch delay slot. Regardless of what the CodeBreaker is replacing, the operation in the address that immediately follows the one you provide will be in the branch delay slot once the enable codes does its work. The address you specify (hereafter the "hook address") may be a JAL, it may be an ADDU, or it may be a LUI. The cheat device doesn't waste time analyzing that. Let us say the hook address contains, "lui v0, 0x3B". The op that follows is, "ori v0, v0, 0x4668". That would put the value 0x003B4668 on v0. If only the op at the hook address is cached, and is then replaced with the JAL to the cheat engine, then v0 will not contain 0x003B0000 as expected when the branch delay op is executed. The result there would be garbage, but worse, later, when the cheat engine executes the operation it cached, v0 will be overwritten entirely with 0x003B0000. The game will probably crash because v0 does not contain the value it would under normal circumstances, when the cheat engine returns back to the game. The rule here is that the cheat engine must be able to either restore, or recreate everything, so that the game can execute as though it was never interrupted. The next question contains some basic guidelines to follow, that should prevent you from corrupting the game's process. Q: What operations can I hook? A: As stated previously, any operation that is executed sufficiently often will do. However, there are some operations that should not be hooked, as doing so will cause all manner of problems. 1. Never hook any operation that uses, or that is immediately followed by an operation that uses the SP or RA register. In order to ensure that the context of the cached operations is preserved, all the registers used by the cheat engine are preserved, and are restored before the cached operations execute. The only exceptions are that register RA is not restored, and register SP is not restored. See below for an explanation of this. 2. Never hook a conditional branch operation (BEQ, BEQL, BNE, etc.). These operations use strictly relative addresses, and will not branch anywhere useful once the operations have been relocated. 3. Never hook an operation that precedes any branch operation, including unconditional branches like J, JAL, etc. Assume the game has code that looks like this: addu a0, zero, s3 jal 1acb10 addiu a1, zero, 3 If you chose to hook the address of the, "addu a0, zero, s3", operation, the JAL that follows will be cached, but the next op is most likely setting register A1 to a value that is necessary for that subroutine to function properly. Since that op will not be relocated, it will not be executed prior to the branch into the subroutine being taken. In fact, you will in all likelihood execute an op you should not that belongs to the cheat engine. In the case of the CodeBreaker, it would be the restoration of register RA, if I recall correctly. So the return address would be destroyed, and when the CodeBreaker attempts to return to the hooked function, it will be unable to do so. You also still have the problem of relative branches not branching to where the game expects. Q: Why does the cheat engine not restore RA and SP before executing the operations it relocated? A: In the event that the hooked operation is a JAL, RA needs to remain on the stack, and the stack pointer cannot be restored. Otherwise, when the relocated JAL is executed, the contents of RA will be replaced, and the CodeBreaker will be unable to recover the value and return properly to the game. Q: If we are usually replacing the memcpy JAL, why can the cheat engine not just J to it, and let memcpy return normally to the pad read? A: There are too many assumptions there. We may not always have the pad read to abuse, and if the cheat engine was locked into only using JALs in that way, it would be very easy to block them. Also, the cheat engine does not do much analysis of the data you provide it. It needs to be a small amount of code that executes quickly, so it is not designed to be user-friendly. It is designed to be used by people who can determine what the rules are, and follow them. Determining that a replaced operation is a JAL, checking to be sure it is safe to change it to a J, and finally changing it to a J might be possible, but it would be a fair amount of unnecessary code. There are two command types that are used for this type of enable. Conditional enable 9aaaaaaa oooooooo Unconditional enable Faaaaaaa dddddddd (most devices) C4 (OR) aaaaaaa 00030800 (AR MAX) The primary difference between these two types of codes should be obvious from their names. The AR MAX creates conditional enables by putting separate conditional commands in the master code. Other devices encapsulate that functionality in a single command. These codes serve essentially the same purpose, the only difference is that the conditional enable, or in the case of the AR MAX, a master code with conditional commands in it, will write the hook only when the condition is met. You can be a bit more liberal with the AR MAX, but with other devices, the only condition available is that the value (operation) at aaaaaaa must be equal to the value of oooooooo before the hook will be written to aaaaaaa and a NOP to aaaaaaa + 4. The unconditional enable will write the hook and the NOP whenever the the game's process initializes. Note that dddddddd is used as the address of the hook in the unconditional type; aaaaaaa is typically the game's entrypoint. Although it can also be the address of the hook on older devices, even if it is not actually used. The value of dddddddd should be set to the hook address + 3. Hook 2: Interrupt Handler This type of enable adds the cheat engine as the last handler for specific interrupts. The CodeBreaker hooks the V_BLANK_END interrupt (if I am reading the PS2 documentation correctly), other devices do as well, but I am not sure if other interrupts are hooked. V_BLANK_END has to do with the graphical subsystem. This code is setup much like the other enable codes, in that whenever the game's process initializes, part of the cheat software code is executed that will register the interrupt. With this enable type, the cheat engine will be executed whenver this interrupt is generated. You will have used it if you have ever made use of one of the so-called universal enable codes. Beyond that, it is not used frequently, but it is a reliable way to get the cheat engine executed when all else fails. This hook can be created as follows: Faaaaaaa 0000000E (Most devices) C4 (OR) aaaaaaa 00030802 (AR MAX) I hear the AR MAX version is buggy, but it may have been fixed in more recent versions. The value of aaaaaaa is typcially set to the entrypoint or the JAL to main within the game. I am not sure that the address actually matters in this code. Incidentally, V_BLANK_END is interrupt 3. The reason you specify E in the code, at least with CodeBreaker, is that if the low order bit of the value in the F command is checked. If it is 1, then the value of this code is assumed to be the hook address. If it is not set, then it is the interrupt number or other control data. Regardless, the value is right-shifted two, so that the lower two bits are cleared. Hook 3: Running as a Thread This one will not be documented very well. I have never seen it used, and I am not entirely certain that it is implemented at all, or properly in any device. This guide will not even explain how to create enable codes that use this hook. The PS2 does not support preemptive multi-threading. What that means is that the OS kernel will not force processes to suspend so that other processes can execute as in your PC operating system. In order for two or more threads to work in this way on the PS2, they must each contain code to relinquish control to another thread. Basically, this requires that we have a game thread, and the cheat engine thread, both running with the same priority, and each one must issue a syscall known as RotateThreadReadyQueue. This will pass control to the next thread of the same priority in the queue. With only two threads running, that would equate to a swap between the cheat engine and the game. I have not investigated this too closely yet. It seems like it would be an overly complicated way of getting the cheat engine executed, if that is the only way it is used.