Different ways to find a pointer

Started by Dude, October 17, 2010, 07:02:37 PM

Previous topic - Next topic

Dude

Hoping I could get some insight into the different ways to locate pointers.

Gecko Dot Net is truly one of the best tools I've used.  The only thing it is lacking is a pointer search, such as is found in Wiird.

I did hear that there are many more different ways to locate a pointer WITHOUT using a pointer search tool...could anyone provide details on this?

I can remember dcx2 saying that you can set a breakpoint on the address that you want to find a pointer for and then browse up at the resulting ASM to find it, or use a C2 codetype to avoid using pointer codes all together.

I would love to know how to find the pointer without a searching tool, as I'm sure would many others.
Examples for this would be perfect, too  :D

Bully@Wiiplaza

#1
bump, great topic, it would be very useful for me awell :P

My thoughts:

- Set a breakpoint read/write on the adress
- When it broke, look for a destination register from the stw/lwz, which is like 8Xyyyyyy or 9Xyyyyyy.
- Set more breakpoints... if it changes all the time, it´s your pointer adress! xD
- If it didn´t, move to another level, if it is still the same, it´s a static adress, where you could try direct ram write, but note that it´s more secure to write in ASM. However, if you do this, you don´t need to find any pointer, it works just right off. :)
My Wii hacking site...
http://bullywiihacks.com/

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

~Bully

dcx2

To use an example from an old guide...this is where the game stores the new star bit value after you shoot one.

[spoiler][/spoiler]

See the "stw r3,64(r31)"?  r31 is your pointer.  Now, it might be derived from another pointer (pointer in pointer) or it might be an offset from some other pointer   In this case it's a little bit of both.

[spoiler][/spoiler]

r13 is a small read/write data anchor.  It's a constant value, in this case 806A4CA0.  Some pointer from that area is put into r5.  Then [r5+12] is put into r3.  Then [r3] is put into r3.  64(r3) is then the star bits.

I think that would look like this

[ [ [0x806A4CA0 (hex) - 14968 (dec)] + 12 ] ] + 64

That would be why everyone has problems using pointer search on Super Mario Galaxy.

Bully@Wiiplaza

could you mark the instructions (second picture) and registers (first picture) with a colour and write 1,2,3 and so on besides them?
Then we can follow your pointer finding method better :-X

Thx...
My Wii hacking site...
http://bullywiihacks.com/

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

~Bully

dcx2

Okay, the SMG example is poor for understanding this technique because it's an example of where Pointer Search will fail because you need to do three pointer in pointer searches.  A better example can be taken from Resident Evil 4.  Sharkbyte has a code for invincibility that he found using pointer search (at least I assume so).

Invincible (leon and ashley) [Sharkbyte]
48000000 8032E274
DE000000 80008180
12000328 00009D9D
E0000000 80008000

He's writing a non-zero value to the invincibility timer.  You can find it like any other timer (using pause/search unknown/next frame/diff by 1/next frame/diff by 1/etc) however I just followed Sharkbyte's code until I found the value.  Once you find the timer address, set a read breakpoint on it.  In this example, you would end up here

[spoiler]
80030168:  88030000   lbz   r0,0(r3)
8003016C:  38800000   li   r4,0
80030170:  2C000000   cmpwi   r0,0
80030174:  40820010   bne-   0x80030184
80030178:  88030001   lbz   r0,1(r3)
8003017C:  2C000000   cmpwi   r0,0
80030180:  41820008   beq-   0x80030188
80030184:  38800001   li   r4,1
80030188:  7C832378   mr   r3,r4
8003018C:  4E800020   blr   
[/spoiler]

Where did r3 come from?  Follow the call stack.

This spoiler ---v will show you the offset, in bold red.  bold blue is the pointer being passed from function to function in this spoiler and the three after it
[spoiler]
80132E80:  9421FFF0   stwu   r1,-16(r1)
80132E84:  7C0802A6   mflr   r0
80132E88:  90010014   stw   r0,20(r1)
80132E8C:  93E1000C   stw   r31,12(r1)
80132E90:  7C7F1B78   mr   r31,r3
80132E94:  38630328   addi   r3,r3,808
80132E98:  4BEFD2D1   bl   0x80030168
[...]
80132F54:  80010014   lwz   r0,20(r1)
80132F58:  83E1000C   lwz   r31,12(r1)
80132F5C:  7C0803A6   mtlr   r0
80132F60:  38210010   addi   r1,r1,16
80132F64:  4E800020   blr   
[/spoiler]

[spoiler]
80072B00:  9421FFD0   stwu   r1,-48(r1)
80072B04:  7C0802A6   mflr   r0
80072B08:  90010034   stw   r0,52(r1)
80072B0C:  93E1002C   stw   r31,44(r1)
80072B10:  93C10028   stw   r30,40(r1)
80072B14:  7C7E1B78   mr   r30,r3
[...]
80072C5C:  7FC3F378   mr   r3,r30
80072C60:  480C0221   bl   0x80132e80
[...]
8007308C:  83E1002C   lwz   r31,44(r1)
80073090:  83C10028   lwz   r30,40(r1)
80073094:  80010034   lwz   r0,52(r1)
80073098:  7C0803A6   mtlr   r0
8007309C:  38210030   addi   r1,r1,48
800730A0:  4E800020   blr   
[/spoiler]

This spoiler --v shows you where the initial pointer came from
[spoiler]
80106B88:  806D9480   lwz   r3,-27520(r13)
80106B8C:  81830008   lwz   r12,8(r3)
80106B90:  818C0018   lwz   r12,24(r12)
80106B94:  7D8903A6   mtctr   r12
80106B98:  4E800421   bctrl   
[/spoiler]

r13 : 80444A20 (this is constant)

27520 dec = 0x6B80 hex

0x80444A20 - 0x6B80 = 0x8043DEA0

So [8043DEA0] has the pointer that we want.  The offset is 0x328.  This gives us [8043DEA0] + 0x328.  Converted to a code type, it would look like this.

Invincible 2 [Sharkbyte-derived]
48000000 8043DEA0
DE000000 80008180
12000328 00009D9D
E0000000 80008000

Dude

Ohhhhhhhhhhh

I'm going to look at this closer later and then try to replicate it using my own copy of RE4.

Thanks so much, dcx2!  I kinda knew you'd be the one to come and explain it all lol  Many many thanks.

I feel that a pointer search tool would still be a great addition to GDN to assist those that don't fully understand these methods, but really do urge others to try and follow along these lines.  Perfect time saver :p

I'll post back here if I find myself having any problems.

Thanks again!

dcx2

By the way, it might not have been immediately obvious, but to do this you should really use the latest Gecko.NET.  On the disassembler tab it has a Call Stack list box that will show you all of the functions that have been called, so you can hop around the various functions without stepping forward.

Also, right-click the disassembly and there's an option, "Go to function start".  That will help you whenever input parameters from r3-10 are cached into non-volatile registers r31-r14 (i.e. in the above, input r3 was cached into non-volatile r30)

Dude

I always use the latest version of Gecko.Net  :D
Seriously, dcx2, keep up the awesome work with that!

That function sure sounds like it would help me.  The additional info is greatly appreciated.
Not had a proper chance to try it out yet, but i'll hop on this once I have need for a pointer again lol I've found an alternate way of doing a code that doesn't require a pointer.

Still itching to give this a whirl.  Got just the game in mind that I've been trying to work on, too.