GP2X Some Questions About Variables And Their Location In The Process Memor


joyrider

Active Member
Joined
Mar 29, 2006
Messages
589
Age
43
Website
www.willemssoft.be
Well since there's no cheat support in emulators yet, i wanted to try to create some trainers (program that patches a certain adress (variable) in memory (for example the nr of lives)

i found a nice example how this is done in linux and the examples work on the gp2x however i would like to know if u take for example the following program :
Code:
#include <stdio.h>

int main()
{
int i = 1;
int counter = 0;
while(i){
printf("Counter Value: %d Address of Counter: %X\n",counter,&counter);
if(getchar()=='X')
i=0;
counter++;
}
return 0;
}

will the pointer adress of the variable counter always be the same ? when i run it on the gp2x it's BFFFFD90 and it seems to stay the same wheiter i run the program while other programs are running or not, when i restart the program and even when i restart my gp2x it's always at BFFFFD90.

so just to be sure will this always be BFFFFD90 on every gp2x on every firmware version etc ?

i don't know anything about linux memory management so i don't know for sure.

if it is the same it would be easy to create a game trainer for an emulator the hard part would be finding the address where the value of the lives for example is stored (since no tools exist to search for this except gdb perhaps)

does someone know this ?

if it does not stay the same, can someone explain to me why it changes is it due something like DMA on windows ?
 
Theres a lot more to it than you think ;)

A program runs in its _own_ address space; ie: each application has its own address space (essentially), so every program can have pointer to address 0x1000 and its pointing to a different actual memory location.

To lok at another processes memory space, you have to do some tricks.

All you're doing above is looping over a print statement to show a variable.

jeff
 
will the pointer adress of the variable counter always be the same ? when i run it on the gp2x it's BFFFFD90 and it seems to stay the same wheiter i run the program while other programs are running or not, when i restart the program and even when i restart my gp2x it's always at BFFFFD90.
The system does not provide any such guarantee. However, it's very likely that it will happen to be at the same address every time, particularly when the call context is so simple. Some of the newer Linux kernels (well, I don't know if it's in the kernel...) specifically make things less deterministic to make things like buffer overflows more difficult to exploit.

Stack and heap addresses are determined at runtime, so there is no easy way to find where things will end up. You just have to search intelligently. Recompiling a special version won't work, because that will change the addresses.
 
Last edited by a moderator:
joyrider: Good luck with your efforts, but before writing a trainer for an emulator, I would urge you to try and run your test program in the background with a constant value whilst you try and alter that value with a second program. If you try and alter the address directly you will get either a segmentation fault (memory fault) because that address isn't allocated in the current program, or the byte will be changed in your current program rather than the program your trying to modify.

This may explain it better: http://www.memorymanagement.org/glossary/v.html

You may also want to try and run two or more copies of your program.
 
Could always try to come up with somethign superior, too..

1) A cheat manager .. ie: a GUI and method of storing cheat info, and a way of notifiying applications

2) Get emu devs to handle the cheat system or when OSS and dev unavailable, modify the emu yourself.

3) Worst case is to try and hijack the memory space of another application and modify it.

jeff
 
If you write a good enough "search and destroy" technique, you could always hammer the physical memory rather than the logical. May take a while to search even 32MB of RAM however, let alone 64MB due to the case that some people may place the rom into the upper 32MB...

and of course, the physical memory will almost definitely change every time, and could even be fragmented.
 
cool thanks for the reply's the above program was just a test i have another program that modifies the counter value using ptrace PTRACE_ATTACH, PTRACE_POKE_DATA etc. and it works but if the adress of the counter value changes or is diffrent on each gp2x that poses a problem, in windows the emulator i already wrote a trainer for doesn't get the adresses changed when it restarts nor when windows reboots. Except if it uses DMA which it didn't, so i just wanted to be sure if it was in the same place each time.

finding the adress of for example the lives isn't really that hard with a mem searcher, problem is there doesn't exist one as far as i know for linux so i'd have to create it myself.

i was thinking of looking at /proc/pid/maps to know where the memory is mapped and i think i only have to look at the maps that have the RWX attributes and search in those memory region's for the value i want.

i'll try to upgrade my firmware (sicne i'm still on 2.0.0 and see if the adress value from the test program is still the same on 2.1.0 or whatever the latstet version is)

if it is it might work :)

i was just fiddling around, i like searching for these codes and if i manage to create a trainer for super mario bros or sonic or sumthing i'm happy :D

If the address does change, it could be there's another piece of memory that always sits near the code and i could incorporate a memsearcher into the trainer that will search for that particular piece of memory once found it will stay the same during the program well in most cases it does in windows don't know about linux , but the way the emulator is written does matter i'll just have to try.

i was also thinking on using GDB to dump the memory of the rwx maps and capture it into a file and then create a windows program to search for the values, i'm still testing things out

this is the code for the 2nd program (not made by me, found it after some googling on a site about gamehacking) this works like a charm.


update:
bleh the adress changed was now BFFFFD80 instead of BFFFFD90 don't know why it changed all of a sudden so the normal windows way of doing it is not goana work, only thing i see that could make it possible is have it search for unique value that lies always near the counter adress ah well i'm not given up

Code:
#define _POSIX_SOURCE
/*The above is required for certain functions to work*/
#include <stdio.h>
/*for puts/scanf/fflush */
#include <sys/types.h>
/* for the args to ptrace */
#include <sys/ptrace.h>
/* for ptrace and perror */
#include <stdlib.h>
/* for exit */
#include <unistd.h>
/* for sleep function */

/* function prototypes */
void menu(pid_t pid);/* menu to get the users input */
void setcounter(pid_t pid);/* function called by menu to write a value */
void inccounter(pid_t pid);/* function called by menu to read and write a value */

int main(int argc, char *argv[])
{
pid_t pid;/* To hold the pid of the game */
/* make sure that the loader passed the pid of the game */
if(argc < 2)
{
puts("Run the loader dammit");
return 0;
}
/* convert it to an integer */
pid = atoi(argv[1]);
menu(pid);
return 0;
}

void menu(pid_t pid)
{
int error;/* to make sure the game is running */
int choice;/* users choice in the menu */
int done=0;/* used to loop so the program doesn't exit instantly */
/* check to see if the game is running, if not report error message */
if((error = ptrace(PTRACE_ATTACH,pid,NULL,NULL)))
{
perror("Attach");
exit(1);
}
printf("Reading Process\n");
/* sleep for 2 seconds than detach from the program so the program doesn't freeze */
sleep(2);
ptrace(PTRACE_DETACH,pid,NULL,NULL);
/* main loop */
while(!done)
{
/* print the menu */
puts("1)Set Counter to 10000");
puts("2)Increase Counter by 100");
puts("3)About");
puts("4)Quit");
/* get the users choice */
scanf("%d",&choice);
fflush(stdin);
/* process their request */
switch(choice)
{
case 1:/* if menu option 1 was chosen */
setcounter(pid);
break;
case 2:/* if menu option 2 was chosen */
inccounter(pid);
break;
case 3:/* if menu option 3 was chosen */
puts("A simple trainer skeleton");
puts("By: EEDOK");
sleep(2);
break;
case 4:/* if menu option 4 was chosen */
done=1;
break;
default:/* if any other option was chosen */
puts("Invalid choice");
break;
}
}
return;

}

void setcounter(pid_t pid)
{
unsigned long address=0xBFFFFD90;/* the address to hack */
ptrace(PTRACE_ATTACH,pid,NULL,NULL);/* attach to process */
sleep(1);/* give the program some time to fully attach */
ptrace(PTRACE_POKEDATA,pid,address,10000);/* write 10000 to the address */
puts("Value written");
sleep(2);
ptrace(PTRACE_DETACH,pid,NULL,NULL);/* detach from process so it doesn't freeze */
return;
}

void inccounter(pid_t pid)
{
long value;
unsigned long address=0xBFFFFD90;/* address to hack */
ptrace(PTRACE_ATTACH,pid,NULL,NULL);/* attach to process */
sleep(1);/* give the program some time to fully attach */
value=ptrace(PTRACE_PEEKDATA,pid,address,NULL);/* Read Value from the address and store it in value */
value+=100;/* increase value by 100 */
ptrace(PTRACE_POKEDATA,pid,address,value);/* Write the new value back to the program */
puts("Value increased");
sleep(2);
ptrace(PTRACE_DETACH,pid,NULL,NULL);/* detach from process so it doesn't freeze */
return;

}
 
I think the best way to do it is to write a program that scans /dev/[k]mem (was it the device?) and when the user tell so (can be a console program ran by telnet) the program scans for useful vars, and once it finds the offsets of the variables just keep rewriting it many times in a second, that would do (afaik) and be completely compatible with any firmware, of course the program will not be able to stop cpu from working so the game must be held in pause or emulator's pause while the search is ongoing... (for FPS' sake)
 
update:
bleh the adress changed was now BFFFFD80 instead of BFFFFD90 don't know why it changed all of a sudden so the normal windows way of doing it is not goana work, only thing i see that could make it possible is have it search for unique value that lies always near the counter adress ah well i'm not given up
Did you recompile it? Is there anything different in the way you are running the program?

You might want to work with something that prints out the contents of its stack instead of just one variable. Maybe something like:

Code:
int main(void)
{
  int i, *p = &i;
  while ( ((int)++p & 0x0000FFFF) != 0 )
	printf("[%08X] = %08X\n", p, *p);
}
Then if the addresses change, you'll have some idea of what changed.
 
Last edited by a moderator:
no i didn't change a thing well not that i can remember. but it's all a bit of a hassle to do it especially when i found out that squidge/pocketsness has everything in the source code that's needed to add cheat support all that's needed is a user interface for it on the gp2x. But i don't understand all of it an i'm certainly not skilled enough to add this myself.

I did write a small (imperfect) memory dumper that can dump the processmemory using ptract & peekdata the only problem is it can't dump memory that's shared and i've looked at the dumps taken everytime when i lost a live in super mario alstars - super mario world but the value isn't there so i think it could be in the shared memory and if i can't peekdata i certainly won't be able to poke it. i'll give it a shot later on again. could also be that the values in memory change places due to the way the emulator is programmed had this happening on windows a few times

However if people really want cheats it's pretty easy to hack up the save states, (already done this with the save state for super mario world, can change the nr of lives ) only problem is there is as far as i know atm no way to see what save state correspondents with which rom file. in other words if i was to write a save state patcher for pocket / squidge snes and people use a diffrent version of the rom it might not work, i couldn't find an id or something to refererd to the rom in question inside the save state, might have to look again. save state hacking is much easier then memory also and takes way less time since the states are much smaller then the dumps so searching for values takes less time.

i just hope that someone adds the user interface for the cheat searcher, memory patcher in squidge/pocket snes that make it a lot easier.

i could have a look at some homebrew games doh, cause the games i made can be hacked this way (i know cause my games don't use shared memory and the adress for the lives or sumething was in the region i could dump), i just didn't try it yet
 
It might be interesting to see how gdb can attach to a running process and "see" it memory. But in the end you would see the "memory" of the emulator and not the memory of the code running in the emulator (although the data in the memory is the "game" code/data the emulator is emulating). So your would have to figure out how the "game" is finding it's data and then go poke that data. The level of indirectness does make it a challenge.
 
telecoda posted on Feb 6 2007 at 04:03 PM said:
Why not approach it from a different angle...

Take a copy of the ROM and update that ;)

yeah but then u have to know / understand the roms code and i've never done that, and i like the way to search for codes using memory searchers or searching in dumps of memory but linux is a whole diffrent beast then windows. I was unable to get it working (never found the adress) at least not in the emulators, it did work with my formula 1 sdl game but i don't think people will want cheats for homebrew and it most probably wouldn't work with other games

but save state hacking can be done. the only thing i don't like is that i can't find a way to to match a save sate to a rom, only the roms filename/location is saved in the save state and that's diffrent on each gp2x and judging on the zip name is a bad way or not implementing any check to see weither it's the correct savestate from the correct rom is not good at all.

for the zinc emulator on windows i made a trainer and i could detect what game, emulator version was running & all much better.

I'm waiting till someone implements cheats support (mem patcher + searcher) in an emulator and then i'll start searching for codes for it, it's not going to happen very soon it seems. And a universal cheat searcher for all applications & stuff like on the psp i don't know if that's even possible with the gp2x running linux and i sure don't know how to do that.
 
Last edited by a moderator:
Why not generate a hash of the unmodified rom? That way you could easily check to make sure it's the correct rom before patching. You can even identify the rom (regardless of it's filename) via the hash value, and say what is possible with it (ie. infinite lives, ammo, etc...)
 
Squidge posted on Feb 8 2007 at 08:40 PM said:
Why not generate a hash of the unmodified rom? That way you could easily check to make sure it's the correct rom before patching. You can even identify the rom (regardless of it's filename) via the hash value, and say what is possible with it (ie. infinite lives, ammo, etc...)

yeah but i was talking about the savestate files in the last part. not the full rom nor the rom in memory and hashing it wouldn't work then would it ? there are to many variables stored in the savestate files that can change, noone elses savestate will have the same hash. Or am i missing something here ?
 
Last edited by a moderator:
Very true if you go the savestate way, but I think it would work well if you went and found the rom in the memory and altered that one (using a hash to identify it, and then modified known memory locations).

Of course, if you wanted to modify the emu's ram, that would be far trickier, and could change with every emu version or even every rom load, depending on how the memory for the rom is allocated.
 
problem is i still haven't been able to find the rom in the memory. using processmemory dumping. However i dumped /proc/kcore and there i could find the rom, but i guess with /proc/kcore the adress will constantly change but then i could look for the hash or part of the rom first to find the adress and then change it. however i don't know if it's possible to write to /proc/kcore perhaps using mmap but i can't get it working. mmapping /dev/kmem did work but there was mostly 0's being read, could be i mapped it wrong doh cause i'm just experimenting and don't know much about it all :)
edit
i did map wrong just don't know how big the map should be and from what adress is should start, but i let it dump about 127 megs and then i found the rom. How big should i map it ? and from what adress ?

pff i'm giving up it's to much of an hassle
 
Back
Top