PassMe2 also works by modifying the header of the game as it passes through.

Both start addresses have to be in RAM, so what do we change them to?

The ARM9 start address is set to point at a "bx lr" instruction in the ARM9 binary. This instruction tells the CPU to jump to the address in the "lr" register. The firmware uses a "bx lr" instruction to get the ARM9 to the ARM9 start address, so the "lr" register already contains the ARM9 start address. So this is a single instruction infinite loop.

The ARM7 start address is set to point at an "swi" instruction in one of the binaries. The "swi" instruction is used to jump into the ARM7 BIOS, execute a function and return. The ARM7 BIOS uses a table of pointers to functions. The argument to the "swi" instruction says which function in the table to use. The argument to the "swi" instruction that PassMe2 uses is larger than the size of the table.

By some fluke, some of the values in the ARM7 BIOS after the "swi" table are valid instructions that cause the CPU to jump to the SRAM area of the GBA slot.

So we need some code in the SRAM of a GBA flash cart. Executing from SRAM is difficult as it is an 8bit bus, so 16bit reads return the same 8bits twice. This limits the available assembly instructions and arguments.

Loopy somehow wrote some code with these limited instructions that moves the ARM9 into the normal PassMe infinite loop and transfers the ARM7 to 0x080000C0.

Homebrew in the GBA slot then runs in exactly the same way as PassMe1.

The locations of the "bx lr" and "swi" instructions are different for each game, so the PassMe2 has to be programmed for the game that will be used. As the SRAM also needs the address of the "bx lr" instruction, the SRAM also has to be programmed for the game that will be used. Not all games contain one of the exploitable "swi" instructions, so they are not PassMe2 compatible.

Nintendo has not tried to stop PassMe2 from working.

See Also

HowPassMe2Works (last edited 2008-01-22 14:02:38 by localhost)