You locate the pointer to that address, by determining what piece of code writes to it. From there you backtrack and figure out how the base address is calculated. Then all you need to do is grab/calculate the pointer and add whatever index the value is from it.
Example 1: Say you want to edit a value at address 0x1234 but it changes next time you play. Set a break on write for 0x1234. Your debugger spits out the bottom couple lines. You notice that your offset is based off of the value in register ebx. Find out how ebx gets initialized, then you can always just add the index 4 to get your actual address;)
Code: Select all
mov ebx, dword ptr ds:[PointerLocation] ;<---grabs pointer from static address
xor eax, eax ;useless, dont pay attention to ANYTHING inbetween, just what modifies your base address (ebx).
mov dword ptr ds:[ebx + 4], Value ;<---writes to your value
Example 2: Array-based pointers and stuff, same concepts as above.
Code: Select all
lea ebx, [eax + ecx * 4 + 8] ;<---pointer calculated
mov [ebx + 8], Value ;<---writes to your value
Example 3: Same as above, except this is more common, and unfortunately a whole lot harder to recreate since values are usually retrieved from the stack (get passed as arguments). This means you need to hook into the code and retrieve the other stuff :X
Code: Select all
mov ebx, [esp + 0Ch] ;<---grab argument off stack
mov [ebx + 2], Value ;<---modifies the value at your address
These are just a few examples, but if you would like a more in-depth explanation, paste a few lines of code that modify your address, before and after the break, and I'll see if I can help.