I can't find some variables, can you help me?

Started by Fighter19, November 30, 2013, 10:12:34 AM

Previous topic - Next topic

Fighter19

I have a problem regarding finding codes. For example in Wii Play, I want to get the Tanks Coordinates (and later write an ASM code which uses the Cursors coordinates to calculate where the tank can be ported to, using the wiimote). But If I try to get them, I receive some strange behaving variables, which increase and decrease with their X AND Y coordinate on top of that, freezing them does not freeze the Tank itself. Can you suggest me something, (I already tried to set a bp on that variable but I couldn't find anything useful)
Greets,
Fighter19
EDIT:I already tried searching different memory sections.

dcx2

If you look at the address in Memory Viewer with auto-update on, you should see that the numbers "react" properly.

There's a chance the coordinates may be floats.  So you could set Gecko.NET to use Single display mode if you don't naturally have a feel for what 32-bit float hex patterns look like.

Poking may not work like you expect.  There may be several copies of the coordinates in memory that are being passed along from one to the next.  The key is finding where one of these transitions happens and overwriting the source, not the destination.  If you overwrite the destination, chances are the source will be used next frame and your frozen value will be over-written.

Fighter19

Thank you for answering in first place, so If i understand properly those are mirrors I found, since they are changing according to the position. I'll take a look at it asap, but somehow I couldn't find the source. I tried freezing all addresses I found (around 12, afaik) but no one worked. But shouldn't setting a write breakpoint to the mirrors bring me to the source, anyway? (e.g it outputs mov eax,ecx ... then I look at ecx and this should be the source eventually this happens more often)

dcx2

Hmm, so you know some x86.  Not sure what else you already know.

It's not always as easy as just following registers.  You have to know the calling convention, in case it's an argument, so you can follow it back to the caller.  Check out these tutorials.

http://wiird.l0nk.org/forum/index.php/topic,5080 - Function calls, arguments, and walking the stack

http://wiird.l0nk.org/forum/index.php/topic,5249.0.html - introduction to CPU architecture and ASM

http://wiird.l0nk.org/forum/index.php/topic,6555.0.html - On the safety of registers

Proper application of write breakpoints can help you follow the chain, but there's not necessarily a "source" this way.  You can follow it back over and over and eventually land at the same place as your first breakpoint.

Fighter19

#4
Thank you! This looks very useful, seems that it can help me understanding how this with push and pop works on an applied example (e.g I tried figuring out how to deactivate a menu item, at some point a register got incremented by one, when you move the cursor, but disabling this function would lead into not moving it at all, I wasn't able to find a solution to tell the program that he should just skip THIS item and go to the next)

dcx2

If you're on the Gecko.NET disassembly tab for your breakpoint, you can try right-clicking and then "Copy Function" into a spoiler here (use the spoiler tag in case it's huge, so that it doesn't distort the thread), and I will read it and try to explain what's going on.  Sounds like you might want to use a C2 code to optionally avoid execution.

Also, one thing to watch out for is whether the instruction you find with a write breakpoint also writes to other addresses.  You can set an execute breakpoint once you find the write instruction's address.  If the execute breakpoint hits exactly once per frame, it only writes to that address.  If it doesn't hit every frame, that's probably still okay, but check the address.  If it writes more than once per frame, it's probably writing to different addresses.

Fighter19

#6
Well, thank you for your help. I wouldn't have been able to search for it without your help since I didn't know how float would act like. I managed to build the code I wanted using gRNs so there was no need to overwrite any functions. It probably will not work on other systems since it seems that the address is changing due to some other factors (probably any private data that will push the values), since the Teleporter code available on the Geckocodes page wasn't working (Tanks: Multi Teleporter by Bully@Wiiplaza)

2837A640 EFFF1000 //If "-" Button is pressed
82200001 8037A548 //Store the X-position of the cursor into gr0
86A00001 43E6A000 //Multiply the value by 461.25 to get an equivalent Tank position
84200001 91D30624 //Write that new position
82200001 8037A54C //Same for Y-position
86A00001 442FF000 //Just with other value
84200001 91D3062C
E0000000 80008000

Now the tank can be set wherever my cursor points to, yay!  :cool:
Well the only problem is the pointer, I have no clue how to begin to search for it.

Bully@Wiiplaza

#7
It's not working because there are different versions of Wii Play! how it seems.
ASM or F6 is needed then. :)

In fact, your code won't work for me now since I could never get other people's codes to work on this game either. :P

Lol, awesome code. It must be lots of fun to use!
My Wii hacking site...
http://bullywiihacks.com/

My youtube account with a lot of hacking videos...
http://www.youtube.com/user/BullyWiiPlaza

~Bully

Fighter19

Hmm I'll probably try to take a look at F6 codes then, though I need to get my hands (the one or the other way) on another version of Wii Play.
So meanwhile using assembler would be a good option. Do I have to break the function which writes to it directly and insert an ASM (of course with Branching etc.)? Well this will take way more time... How to create an ASM code? I mean I can't simply create it using the debugger, is there some sort of mini-linker which parses for example nop -> 60 (I think it is this byte in PPC assembly) ?
I think I used one, but I don't know the name anymore. So lets assume the value is being stored in r3, I have to copy that function, then I have to do that whole stuff again using assembler and on top If all registers are in use I have to write one down somewhere in memory so I can restore him later, after the operation is done?

Bully@Wiiplaza

#9
You either do a breakpoint read or write to get a good hook address to inject your assembly code. Use ASMWiiRd to convert from source to gecko code and vice versa. You only need to type what your code should do, like loading values into a register and storing them again using the destination given by the default instruction for example. Unfortunately your teleporting code is quite advanced to code already :/ but you should be able to get the hang of it quickly. Two breaks may be needed since I wouldn't say relying on 8037A548 to be correct for all regions is a good idea.

Idea:
An assembly hook to retrieve the value from 8037A548 and store it at some free memory location
Another assembly hook to access coordinates, load value retrieved from 1st code, do stuff like multiplying and writing to the coordinates (conditionally?)

You can see examples where it says C2 at the beginning or even better F6 for this game also.
My Wii hacking site...
http://bullywiihacks.com/

My youtube account with a lot of hacking videos...
http://www.youtube.com/user/BullyWiiPlaza

~Bully

Fighter19

#10
So I overwrite the function that writes to 8037A548 and let it write to a new memory location AND at the original, then use the new address in the other injected code (that overwrites writing to the position address)? Then I have to paste the original code in again, since we don't want to disable moving completely adding a cmp (probably another function in PPC) and check whether the button is "-" (put it simply, probably there it's needed to modify this and copy it to a free location as well) then the rest of the code gets executed (storing it in registers, multiplying, writing it back),  Well this sounds a little dirty but should work fine, shouldn't it?

EDIT: Wow that I need so many words in extra, than you to describe the same thing...
So yeah, I'll try this tomorrow, sounds quite fun and ambitious :) . Thank you for providing me that idea.
EDIT2: There is no EASY way to dynamically allocate free space, is there?

Bully@Wiiplaza

Yes, that's how it would work.

I think there's no easy way to allocate free space dynamically but go check around 80001500 somewhere, it's unused for every game.
My Wii hacking site...
http://bullywiihacks.com/

My youtube account with a lot of hacking videos...
http://www.youtube.com/user/BullyWiiPlaza

~Bully

Fighter19

#12
Man, I tried around replacing this function but somehow it freezes.


stfs f3,4(r3) //Sets position
lis r27,0x8000 //HiByte
addi r27,r27,0x159C //LoByte for free memory
stfs f3,0(r27) //Store f3 (position) to address of r27
lis r22,0x8037 //HiByte
addi r22,r22,0x7FFF //
addi r22,r22,0x2641 //Add together to achieve 8037A640
lhz r23,0(r22) //Load value from 8037A640 (Pressed button) (address of r22) to r23
cmpi 3,0,r23,0x1000  //Is r23 = 0x1000 (So is the "-" Button pressed), using CR3
beq 3,SET //If value in CR3 return true, jump to SET
lis r27,0
lis r23,0
lis r22,0 //If not clean everything up
b END //Jump to a location after SET so it doesn't get executed


SET:
addi r27,r27,0x0020  //Increment by 0x0020
stw r23,0(r27)       //Store the value from r23 (In this case it HAS to be 0x1000) to address of r27
lis r27,0    
lis r23,0
lis r22,0     //clean everything up


END:
nop

(now using the disassembler you can see it now returns to the normal function)

In ASMWIIRD ; doesn't work as comment anyway...

EDIT:Insertion address is 8024239C
EDTI2:Ok, appearantly it DOES work, maybe some bug in geckodotnet.

Fighter19

#13
Pfeeeew, finished coding that now, hopefully it works on other PAL versions now aswell:

C22423A4 00000012
D003000C 7E2802A6
3E408024 3A5243FC
7E119000 40920070
3F608000 3B7B159C
3EC08037 3AD67FFF
3AD62641 A2F60000
2D971000 418E0024
3B7B0020 3AC00000
92DB0000 3F600000
3EE00000 3EC00000
3E200000 48000030
823B0000 92230004
3B7B0004 823B0000
9223000C 3B7B0020
B2FBFFFC 3F600000
3EE00000 3EC00000
3E200000 60000000
60000000 00000000
C20A4280 00000004
D05E0020 3F608000
3B7B15AC D05B0000
3B7B0004 D01B0000
3F600000 00000000
280015BC EFFF1000
82200001 800015AC
86A00001 43E6A000
84200001 8000159C
82200001 800015B0
86A00001 442FF000
84200001 800015A0
E0000000 80008000


I hope double posting is allowed.

Bully@Wiiplaza

#14
Wow, fantastic work man. It should be perfectly fine!

Tips:
To load a 32 bit value you should use lis and ori to get rid of ugly double addi's.
"Brainlessly" overwrite register 12 and work your way down, restoring them again is not needed.
Comments work like this: #This is a comment, it has an opening and closing tag# Be aware not to make it line-wrap in ASMWiiRd!

Gecko.Net may have bugs but codes do the right thing.
My Wii hacking site...
http://bullywiihacks.com/

My youtube account with a lot of hacking videos...
http://www.youtube.com/user/BullyWiiPlaza

~Bully