07/09/10 __ ` `. / | | ` . _ `. . ........--- .` `. ..-` `..._ | | ( | ` ` . | ) / | | | .-`w` | < --.. / | ` MMML. | \ / / | . MMML . ` / / ._.. MMM``.--.. .-` / ` MMI`-```--` ( . . \. __ \ ` ---```` L.................... U B E R L E E T H A C K E R F O R C E Hey everyone!! SigFLUP here. This actually is our first text-file!! I'm sitting here on my lappy with a nice fan blowing in my face. Hot as fuck right now, holy shit! So I was staying over at one of my friend's place and we're playing super metroid-- or more specifically she was playing super metriod and I was watching. So she tells me how if you beat the game in less then an hour you get to see metriod in a bikini at the end. I'm like really? I'm sure I had that twinkle in my eye, I was totally thinking AHA!! A challenge! So this is how it went down. She is wicked crazy at that game so she's would be the player. She'd play for a bit inside an emulator and save her game. That's when I would come in with my trusty hex-editor and figure out how to change the time of the save-game. It actually turned out to be pretty simple, it did have a check-sum however. This is how the saved-games work: When you save a game under an emulator it's just an binary-dump of the save ram. This is a 16bit system (SNES) and a lot of the numbers in that dump are going to be words. If you change anything in the safe-file you have to fix the checksum. The checksum algorithm adds each word to an accumulator word, wraping when over 0xffff of course. Once you're done you take the complement of it. That's your checksum. The weird thing about super metroid is that it stores the checksum in two different region near the bottom of ram. One is just the straight word and the other is the inverse of the word. The straight sum is is at 0x1ff8 + 0x1ff9 (each byte addresses) of the ram. The inversed sum is at 0x1ff0 + 0x1ff1 Now we can change anything if the file. I only know where the time for save-slot one (there are three save-slots that appear to be the same format saves sequentially in the ram). Address 0x4c saves the minute and 0x4e saves the hour. That's it- nothing more to the ram. So here's proof of the hack: http://hobones.dogsoft.net/met/after.png here's a small program to do it all automatically: #include #include FILE *fp; unsigned char *rom; int summer(uint8_t *buf, int len) { unsigned int ret, i; unsigned short word; ret = 0; for(i=0;i \n"); exit(0); } if(sscanf(argv[1], "%02d:%02d", &hour, &min)!=2) { printf("invalid time parameter, try hh:mm\n"); exit(0); } if(min >= 60) { printf("invalid time parameter\n"); exit(0); } if((fp = fopen(argv[2], "rb"))<=0) { perror(argv[2]); exit(0); } fstat(fileno(fp), &qstat); if(qstat.st_size < 0xfff) { printf("size not right for sram dump :(\n"); exit(0); } rom = (unsigned char *)malloc( qstat.st_size); fread(rom, 1, qstat.st_size, fp); rom[0x4c] = min; rom[0x4e] = hour&0xff; sum = summer( &rom[0x10], 0x65c); fclose(fp); rom[0x1ff8] = sum&0xff; rom[0x1ff9] = (sum>>8) &0xff; rom[0x1ff0] = (0xffff^sum)&0xff; rom[0x1ff1] = ((0xffff^sum)>>8) &0xff; if((fp = fopen(argv[2], "w"))<=0) { perror(argv[2]); exit(0); } fwrite(rom, 1, qstat.st_size, fp); fclose(fp); printf("set to %d:%02d\n", hour, min); }