I just wrote this little how-to up for a friend. I sat back and looked at it after I was done, knowing it couldn't be 'wasted' on just 1 person

IMHO, this is a very ghetto way to go about resolving pointers, or shall I say, making your own... But I've resorted to it once or twice because pointer levels were so entirely deep, it wasn't worth my time to keep back-tracking....

Remeber folks, this is 3 different variations on 1 tactic to pointers. I can think of another 6 ways to find pointers, but they are far harder to describe without a straight-up example to go with...

Quote:
Originally Posted by Laen
bla bla bla yackedy-schmackedy..... you have a (or any) link(s?) to any ASM or Pointer value tutorials, ive never been able to get pointers from games lol. if not thanks anyway

That is SUCH a broad topic and difficult to understand at first, that documentation on such things is far and few between, or completely to general. There are literally about a dozen different ways to resolve pointers and it's all really dependant on the game and how it functions as to which way is the best.
I'll quickly describe what I believe is the easiest way to secure pointers, but this is not the cleanest or best way to do it. If you're not way careful, you can wind up crashing the game eventually =) I'll also PM you with a few links.

The method I'm about to describe is what I consider the ghetto way to obtain pointers. With this method, you don't actually 'obtain' pointers at all... You create them your damn self. Finding memory that will *never* be written to is tricky, but you don't need all that much room anyhow. The best place to abuse, is the lower memory areas. Watch them for a good few games/reloads to make sure nothing is ever written, then proceed with the following steps. In 32 bit apps, lower mem would be considered anywhere from 00410000 to about 08FFFFFF, but it can vary depending on the game. (a bigger EXE means more 'lower mem' that doesn't change, usually.)

- Find the value you want to point to.
- Use a debugger to find out what ASM reads/writes/accesses this value. The more, the better, as some ASM is much easier to modify, then others. (due mostly to 'having enough space', at least to insert a jump).
- Launch a disassembler and look over the different ASM that you found. The ideal sitution, is something like this.... (we are assuming [ESI+1c] is the value address)

The int 3's signify 'nothing code'. That is, after it returns (from the ret command) there is usually space after to work with. This is why you want to gather as much ASM that touches it as possible.. because a great many of them will have maybe 2-3 bytes before the next ASM code, and this really isn't enough to work with cleanly.
(as a side note - when you go about finding pointers in other ways, read code usually has the shortest pointer path, as there can be many. Write code can confuse the heck outta you , if it writes to a lot of different values , i.e. health for all things.)
(side note: int 3 is just a common example of nothing code (CC in hex). Just make sure whatever it is you're over-writing isnt actual executable ASM

Lets say you get semi-lucky and find ASM just like this. What you want to do first is pause the game somehow, so you can mess with the live memory, without it blowing up in your face. Of course you don't have to... its just safer.

1 of 3 situations will occur. (none of which I opted for, with B&W2's trainer)

Situation 1: You have enough room to plop in your own ASM , which writes ESI to a 'static and never used address', Again, you can usually find this in the lower areas of memory and even stick it in between other ASM (where int 3's / nothing code is).

Situation 2: You don't have enough room to add your own code, and have to create a horiffic JUMP to your own code-cave, and the code-cave jumps back at the end. Jumps tend to be much much smaller then the code you're trying to write. This is a great deal more dangerous, as you'll likely have to find a good 16-32+ bytes of mem that is never written to.

Situation 3: You have enough room to over-write the code that is writing to the value to begin with (that is, if its write code). Usually, you don't want to even think about nullifying a read, but if you're going to be writing your own value anyhow, it usually doesnt hurt to over-write the original write code.
Below , are examples of all 3...

1. We have enough room, yay!
Original Code.
(ASMcodeASMcodeASMcode)
mov [esi+1c], edx (3 bytes long)
pop esi (1 byte)
pop edx (1 byte)
ret (1 byte)
int 3 (1 byte)
int 3 (1 byte)
int 3 (1 byte)
int 3 (1 byte)
int 3 (1 byte)
int 3 (1 byte)
int 3 (1 byte)
int 3 (1 byte)
int 3 (1 byte)
int 3 (1 byte)
int 3 (1 byte)
( more ASM )
We have 6 bytes that *have* to be a part of the final code, 11 bytes of int 3's, but only 10 real bytes we can use there. Things like MOV's aren't really important, unless the situation calls for it, however if that MOV was a FSTP, you DEFINATELY want to find a way keep this in the new code, else everything collapses. Basically, always try to preserve whats there, and simply add to it, unless you know it'll work without it. Another thing: ALWAYS try to leave AT LEAST 2 bytes (1 byte minimum) between the end of your code, and the begining of the next ASM. If they smash together, it is possible for the other ASM to 'turn into' something completely different, because of your code before it. Having that 1-2 byte buffer stops that from happening.
When writing to live memory, we usually have to do it in chunks of 4... We cant simply start over-writing whats there, because the program/game might wind up executing it as it's being written, at which point *crash* occurs. This is one place that jumps shine, because you can write the pre-code to memory, the overwrite an instruction with a 2-4 byte jump, which RARELY ever causes a crash.
What I would do here, is figure out how many of those bytes im going to be using, then write from the bottom up, like so...
Lets assume that I've been watching offset 00B0802C, which is between other ASM, but never written to from what I can tell. The ASM I would make would be something like this.
mov [00b0802c],esi (6 bytes)
If you wanted to actually get the +1c added to ESI before hand, you can do it with...
add [00b0802c], 1c
or, the more dangers version...
add esi,1c (3 bytes)

The 2nd example there is dangerous, only if ESI is used again in later code. Usually, it's really not important to save the 1c part of the offset, as trainer makers or your own code can add this.

Also , thats 3+ more bytes you'd be using, and you're surely pressed for space. On top of that.. holy [email protected]#$!! our code is 6 bytes! that sounds familiar.. Thats exactly how much code we have to offset anyhow! EASY!
Your program would basically make a copy of the 6 bytes into the int 3's area...

2. "Not enough room" Man, I hate having to do this one... Again, it's very messy, and not respected unless the amount of ASM being inserted is HUGE. I always seem to find a way to get around doing this, although I have had to do it on occasion.

Gee, a whole 1 byte extra to work with... No bother.. We have already located a place in memory (Offset 00800000) which has not been written to in the last 10 restarts of the game and hours of play (seriously, to find a good code cave, this is what it takes. That's ok though... making a trainer takes hours of testing anyhow.)

We have a few options as to how to get there and we must determine this, before writing the code in the new location.
- call 00800000 (5 bytes)
- js 00800000 (ouch, 6 bytes, because its so far.. js = jump short = can be only 2 bytes long, if close enough.)
- jmp 00800000 (5 bytes) - I'm not sure why I feel this way, but I'd rather jump then call. Calls have to 'ret' eventually. Jumps just simply jump (and your code at 00800000 must end in a jmp back to the original code area. Or, a ret, if you used Call)

Ok, now we got a game plan down and know that we're going to need 5 of the 6 bytes to do it. First step, insert our own code at 00800000, then re-code the first 5 bytes we're replacing.

Offset 00800000: mov [00b0802c], esi (3 bytes)
Offset 00800003: add [00b0802c], 1c (7 bytes! But hey, now we have a DIRECT pointer)
Offset 0080000A: mov [esi+1c], edx (3 bytes)
Offset 0080000D: pop esi (1 byte)
Offset 0080000E: pop edx (1 byte)
Offset 0080000F: jmp 0088888D (5 bytes) - This is the jump, back to where we 'left off'. Note, at this point we still havnt touched the target ASM. You want as little interruption in code as possible, and even the milliseconds it takes to write the above to memory can be catastrophic (had you ripped out the original code first).

Now all that's left is to replace the original 5 bytes with your jump...

3. Lastly, the good ol over-write. Lets say it was ammo you were looking to affect, and the above code is what writes to your ammo value. Well we don't need to keep the ASM writing to it, if we're going to do that ourselves via a pointer/value.

Here's the kicker. Almost ALWAYS, the code you want to replace, is 1-3 bytes shorter then the code you want there instead. This is when you start looking up ways to do something in less bytes, but realise its physically (really) impossible. Heres how i'd proceed:

We know this area is going to use 3 of the int 3's , because we're replacing a 3 byte code with a 6 byte one.

Keep in mind that the code has to execute before your pointer will be written. In this case, firing the gun once should do it

I just remembered, that I did use a tactic like this for the B&W2 trainer.

Villager age control! - It went something like this...

Original Code: movss [esi+00000634],xmm0
esi+634 being the current villager whos age was being updated. xmm0 being a calculation before hand.

I simply went above this line and found a good 16 bytes where it was 'figuring out' what xmm0 should be. Great! I then made the slider affect an address in lower memory which wasnt written to evar, then I simply did this...

movss xmm0, [01808080] (or something to that affect).

Jeebus... I hope after this, you feel repaid for giving me a much needed link

- Zhoul

Last edited by Zhoul on Wed Dec 14, 2005 4:01 am; edited 2 times in total

in a few days you should be able to use auto assemble scripts in the ce trainers

and it'll have a pointer scanner that can go any level deep you want. keep in mind that every level exponentially increases time to find it, but if you have a few years you can find anything_________________

Do not ask me about online cheats. I don't know any and wont help finding them.

Last edited by Dark Byte on Fri Nov 25, 2005 8:49 am; edited 2 times in total

in a few days you should be able to use auto assemble scripts in the ce trainers

and it'll have a pointer scanner that can go any level deep you want. keep in mind that every level exponentially increases time to find it, but if you have a few years you can find anything

On this note....

Static pointers are found in ASM, by the use of [Address]

I tried to export all ASM from range 00400000 to 006FFFFF. Now I know that was asking a lot and I really didn't expect it to work, which it didn't, but what I was going for, is the ability to export all the ASM to a text file, then use filters, to find where ASM uses address values to write to registers.

I sware, there are many faster ways to find pointer paths that havn't been found yet, and I'm sure that the ability to do the above is the first step in one such method All it would take after a good filtering, is to match up filtered results with in-game memory and voila, Pointer paths out the arse...

Turtle wrote:

Dynamic pointers are usually the ones with many "levels" (pointer to pointer).

All dynamic pointers start at a base static pointer. Like I said, with most games, they all use the same base pointer, so 'finding' static pointerS doesnt help much

I suppose you could try to branch off, by using "find out what reads from this address" , but wow.. the ammt of results that would be returned would be HUGGGE and confusing.

that's right, and it usually is. But it may be that that pointer isn't always pointing at the structure you want. (e.g perhaps it sometimes points at the enemy)
e.g perhaps it only points to there when the mouse is over a certain object, or when you're in a specific menu, or when you've alt tabed out of the game_________________

Do not ask me about online cheats. I don't know any and wont help finding them.

Last edited by Dark Byte on Fri Nov 25, 2005 9:13 am; edited 1 time in total

that's right, and it usually is. But it may be that that pointer isn't always pointing at the structure you want. (e.g perhaps it sometimes points at the enemy)
e.g perhaps it only points to there when the mouse is over a certain object, or when you're in a specific menu, or when you've alt tabed out of the game

Yes, I have come across a problem like this.

When I selected a different type of character in a game, the values for that type of character were probably in a different structure.

Perhaps in cases like this, there are even deeper static pointers to be found. Like a static pointer that points to the structure where the value for "character type" is.

If you used that deep static pointer to first determine the character type being used, then would you know what structure was going to be used?

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot vote in polls in this forumYou cannot attach files in this forumYou can download files in this forum