Hooks - Explain?

Started by Mathew_Wi, September 22, 2010, 06:31:38 AM

Previous topic - Next topic

Mathew_Wi

I've recently compiled an app that can communicate with WiiRd & Gecko dotNET. Aka Memory viewer, search, etc.
I'm going to try the same thing for all homebrew. However, I don't quite understand the hooks very well.
If someone could show some example, that would be excellent.

James0x57

..are you the one that IM'd me on MSN? =P


As far as I know, a "hook" requires a common piece of code found across many games that generally executes every frame.
The handler's code has to create a branch from this common piece of code (the handler can search for it because its form is known) to itself.
The act of "hijacking" this common chunk of game ASM to run itself and ensure it stays able to run is known as "hooking".


dcx2

Set an execute breakpoint on 800018A8 (I think that's the right address).  It should be the entrance to the code handler.

Easy way, but slow: click "Step out" in Gecko.NET.  It will step until it sees a blr.  Just before the blr will probably be the hook.  It will look like a C2 hook; it's a branch that goes somewhere low in memory (800018A8).

Faster, but harder: Scroll through the code handler in the disassembly view and try to find the branch that returns from the hook.  Follow that branch and the instruction before it will be the hook.

James0x57

Quote from: Mathew_Wi on September 22, 2010, 07:00:16 AM
Yes, it was me. You claimed not to know.  ;D
I really wasn't sure about it and in those cases I prefer to know who the person is, plus I was kind of busy working and slaving on AH.. or the DB.. or both possibly. =P


Nuke

#4
When a game is running, it will have a main game update loop which is called every frame. All games will run at 60 or 30 frames per second and within that time all the running game update loop is called.

Now as all Wii games are built on a pre defined set of libraries (The Nintendo Wii SDK or whatever it is called), then you know certain functions in the game update loop with be called. Generic code like Clear the screen or read the Joypad, as you know this code is needed for all games.

Now a Hook is just a piece of code that will insert a jump in this existing routine and call your custom code (Cheat handler in this case). Then it will jump back to the original code.

Some pseudo code to help visualize it.

Update Loop: (Game code which gets called every frame )
{
   Clear_screen(); <----- Say we want to hook into this function
   Update_world();
   Render_world();
   Wait_VBL();
}

Clear_Screen:
   Assembly_code:
   Assembly_code:
   ""
   blr <--- jmp our_routine
   
   
our_routine: (somewhere safe in memory, already preloaded by the loader)
   save_registers; (To avoid crashing, we want to save all the register state as it can be doing anything)
   Assembly_code: <-- This will be the handler, which does all the cheaty stuff
   Assemblt_code:
   restore_registers; (restore everything back)
   blr <--- This then returns back, and then everything is back in the update loop
   
   
To find hooks is knowing the SDK function signatures (bytes which are unique and identify the function). And knowing the function runs in the game loop.

Once you know these bytes and the function runs every frame, you hook this code from your loader (insert your jmp to our_routine) so when the game loads your code gets executed every frame.

The tricky part is that the SDK changes regular, and all games are not equal, so one routine might be able to be hooked for one game and not for another.

I hope that helps some, looking at the gecko source code will probably help, although the code is pretty old and messy.

For Homebrew, its actually much harder as although most homebrew uses libogc, not all homebrew uses the wiipad etc. It is worth a try though.
0xFFFFFFuuuuuuu

Romaap

Gecko.NET reads the Game ID from 0x80000000 (or 0x80001800), but if I remember correctly it could also be zero (like with the system menu when using rebooter function).

QuoteThanks for that! Could someone just explain this?

lis     r4, 0x8000   # 800018A0 hook location (source) (from patchhook.s)
There is probably an ori r4,0x18A0 after that one, then r4 will hold the value 0x800018A0