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
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. :)
To use an example from an old guide...this is where the game stores the new star bit value after you shoot one.
[spoiler](http://i45.photobucket.com/albums/f60/deadcatx2/WiiRd/03firstbreakpoint.png)[/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](http://i45.photobucket.com/albums/f60/deadcatx2/WiiRd/11preamble.png)[/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.
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...
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
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!
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)
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.