Sega Master System / Mark III / Game Gear|
SG-1000 / SC-3000 / SF-7000 / OMV
Home - Forums - Games - Scans - Maps - Cheats - Credits
Music - Videos - Development - Hacks - Translations - Homebrew
Cheatfinder - how to use it?Posted: Tue May 14, 2013 2:53 pm
|I'm not sure how to use the new cheatfinder in Meka. I want to search for lives, energy and equipment in various games in order to make trainer-patches for personal use. But I cannot find documentation or examples on how to use it? Currently I'm working on Shinobi. Can the cheatfinder be used to locate stuff like lives, energy, melee and ranged weapons and ninja magic? How?|
||Posted: Tue May 14, 2013 11:21 pm|
The cheat finder allows you to narrow down among all possible location of memory which one may be the one containing the value you are looking for.
I think the button called "Reduce" should be renamed to say "Narrow" that would be more clear !
Shinobi - Life
Start the game.
At this point any of the 8192 bytes in RAM may be the location for life.
Select ==, Old Value, and click Reduce
You can click Reduce many times. It will start to narrow down the set from all the variable that haven't changed in memory (== old value). The narrowing won't be very efficient at this point. I got about ~8100 matches.
Lose a life and let the level restart. At this point the game has decrement the number of life.
Select <, Old Value, and click Reduce ONCE.
The cheat finder is narrowing down the result to locations whose value has been decreased since the previous step. Because you are in the same level location, etc, it is likely that only few values have changed at all. Clicking Reduce narrows it down to.. ~44 matches! That was pretty fast.
Lose another life and let the level restart.
Select <, Old Value, and click Reduce ONCE.
Tada, it got narrowed to 1 match!
That would be the RAM location storing the number of lives.
You can click the small button next to the RAM location and it will bring up the Memory Editor at that location. Try changing the value to a big number - I changed it to 9 - and lose another life.
||Posted: Tue May 14, 2013 11:24 pm|
One thing to understand about how old games function is that because they can't spare any CPU cycles for superfluous computation, most of the time the display are only updated when strictly necessary.
When you change a number of life or score in memory, the new value won't usually show up on the screen immediately. You want to put the game in a situation where it would need to change the value itself to update the display accordingly. Or perhaps put the game in a situation where it needs to refresh the display (by going in a menu screen, changing room in a game, etc.)
||Posted: Tue May 14, 2013 11:30 pm|
You can apply the same technique to find the amount of energy.
Weapon and magic may be a little more tricky, but only because it takes more time to get the game to change the state of them. If you have save-states of the game running with different weapons it would help.
I am guessing that the game use 1 byte to store which type of weapon the player is carrying (1 for melee, 1 for range weapon).
Shinobi - Weapon
a/ So you get the game in a situation where you are holding the gun.
== (equal), Old Value, Reduce many times
You can click reduce as long as you hold the gun. If you keep playing the game and click reduce more while still holding the gun the number of matches is more likely to reduce.
b/ Get the game in a situation where you are NOT holding the gun
!= (different), Old Value, Reduce ONCE
== (equal), Old Value, Reduce many times
c/ Get the game in a situation where you are holding the gun
!= (different), Old Value, Reduce ONCE
== (equal), Old Value, Reduce many times
Rinse and repeat.
Would works for both melee and range weapons.
Shinobi - Magic
Here there's two scenarios:
- Maybe the game store a single value to say "player has magic", and the type of the magic depends on the level.
- Maybe the game store a single value encoding which type of magic the player is carrying (with, for example, 0 being no magic)
I would imagine the second scenario is more likely.
You can use a similar technique as the weapon.
In both cases, you can make a reasonable guess that the initial value for "first weapon" and "no magic" is a 0 value. Then you can use the "Constant" mode and type in 0 to perform comparison. Any time you can guess the value being used it makes narrowing much faster.
For lives for examples, you could use
== Constant 2, reduce
== Constant 1, reduce
And narrow to the correct memory location in two steps. Because you know that the number of lives at the start the game is 3 or 2 (depending of if you consider that the first life has been "consumed" by starting to play).
Both weapon/magic cases may be a little tedious to get and you may make a mistake if you are not familiar with the tool. I suggest getting yourself familiar with finding values in other games that are easier to manipulate (such as number of lives, coins, etc.)
||Posted: Tue May 14, 2013 11:55 pm|
Shinobi - Score
Interesting case here.
Score is likely to be a big value.
You can select the size of variables to look for, 8-bits (0 to 255), 16-bits (0 to 65535), 24-bits (0 to 4 billions), or even press ANY which works as well.
Start the game, score is 0
== Constant 0, Reduce. ~73000 matches (don't panic, that's because there's lots of 1-bit values!)
Click one guy, score becomes 100.
== Constant 100, Reduce. ~3 matches!
And the three matches are actually the same location interpreted as a 8-bit, 16-bit of 24-bits value.
At this point I think I have the location of score, so I write 999999 to test and kill a guy. I notice that my variables gets overwritten with something different and the score reaches 200. Hmm.... We got on a wrong path.
What is happening? Recall my sentence above about old games which "can't spare any CPU cycles for superfluous computation".
When you kill the simplest enemy you get 100 points.
If that is the minimum step for points, my guess is that the game doesn't bother storing 100 and only store 1. The 00 are just display, only to make the score looks more impressive!
It allows the game to use less bytes to store the value (which means easier manipulation for the game code). That is a common trick.
So let's start again.
Start the game, score is 0
== Constant 0, Reduce. ~73000 matches
Kill one guy, score is 100
== Constant 1, Reduce a few times. ~786 matches.
Kill another guy, score is now 200
== Constant 2, Reduce. Zero matches :(
Start the game, score is 0.
== Old Value, Reduce. ~89000 matches.
Kill one guy, score is 100
> Old Value, Reduce ~1602 matches.
== Old Value, Reduce a few times ~1450 matches.
Rinse and repeat..
I could narrow it to 6 locations. Looking at the values at said location you can see which one matches the score. ($C040)
As you can see, my guess about not storing the 00 was wrong! (but some games definitively do that, for example Wonder Boy in Monster Land).
So why did the first attempt failed? It failed because I made a newbie error. The error I made is that I forgot that games often uses a special BCD representation of number to store numbers that are meant to be displayed (which is the case of the score). BCD works by storing each *decimal* digit into an hexadecimal 4-bit nibble in a way so that the number 100 is stored as hexadecimal 100 (=256).
So when I input the score as 100 I should have typed $100 (the $ prefix in MEKA let you input a value in hexadecimal), and when I input 200 I should have input $200. Of course all games are a bit different. In the case of big values it is often easier to not input any constant because you can't be sure of how they are stored. Instead just use the "Compare to Old Value" thing to narrow the results based on how the value changed, without ever inputting a reference value.
||Posted: Wed May 15, 2013 12:06 am|
Looking at all this made me realize that the Cheat Finder interface is a bit complicated to use.
Instead of having the 6 comparer buttons and 1 reduce/narrow button, I would like to change it to 6 reduce/narrow buttons each with their specified comparer. So you can use a different comparison function in one click instead of two which is more error prone.
||Posted: Wed May 15, 2013 5:46 pm|
Bock - I don't know what to say.... Thank you so much for all this comprehensive help directly on my project. It is simply unbelievable!! I will try your guide tonight when the kids are asleep. I think me and the cheat finder will become the best of friends in the weeks to come. I will update this post with my humble progress :)
Edit: Yeah - creating the invincible ninja...
How I found the energy:
0) Use SMSchecker to clean dump - mine had headers/footers (thank you Maxim)
Use cheatfinder. Walk to gun man in first stage. The one who is standing on some crates. From here I can jump up into his bullet if I want.
1) Compare old value a couple of times.
2) Jump up into his bullet
3) Compare < , then reduce. 4 RAM locations are possible.
4) I do it again. Then there is only one: $C06C ($02) (2). Succes! I have found the energy RAM location.
5) Use debugger. Watch and break on writes to the location $C06C. This soon leads me to ROM location:
05F1: 32 6c c0 LD (C06Ch), A
I do some dissassembling around this address, and it kind of looks like an initialization routine ending in a RET:
05D0: FB EI
05D1: 3E 08 LD A, 08h
05D3: 32 06 C0 LD (C006h), A
05D6: 3E 02 LD A, 02h ;this is amount of lives, - thank you Bock!
05D8: 32 7A C0 LD (C07Ah), A
05DB: 3E 01 LD A, 01h
05DD: 32 44 C0 LD (C044h), A
05E0: 3E 00 LD A, 00h ; this is melee weapon - 03h is the chain
05E2: 32 A6 C0 LD (C0A6h), A
05E5: 3E 00 LD A, 00h ; ranged weapon - 03h = bomb, 04h = gun
05E7: 32 A7 C0 LD (C0A7h), A
05EA: 3E 01 LD A, 01h ; set to 02h for speed fire (like shuriken power up)
05EC: 32 A8 C0 LD (C0A8h), A
05EF: 3E 06 LD A, 06h
05F1: 32 6C C0 LD (C06Ch), A ; energy, found via cheat finder.
05F4: 32 6D C0 LD (C06Dh), A ; ohh, this is max. energy
05F7: C9 RET
- I have added the results of some further experimentation as comments in the code (weapons, max. energy)
Now I'm going to patch the ROM in Frhed. Before he went to sleep, my boy - for whom I'm making these things (alright, admitted - also for myself :) - wished for loads of lives and energy, and the gun and the chain right from stage 1 in Shinobi. So this will be the first round of patching Shinobi. Then I will explore the magic system. I want to be able to enable say flying squirrel magic always - and make it always available to the player, multiple times on a level, right from the start.
Thanks again, Bock.
Edit2: Unlimited energy:
1) use debugger to watch and break on writes to C06Ch
this catches an LD instruction at b333: 77 LD (HL), A
2) in Frhed, locate b333 and overwrite the 77 with 00.
Edit3: No, I don't want swords or nunchakus
I know where Shinobi stores the type of melee weapon (C0A6h).
I set up a break/watchpoint in the debugger:
b w c0a6 (break on writes to melee weapon location).
It writes to this address at init. No surprise. When I rescue a sword-hostage at level 1, a load instruction at 50EF is trapped.
Disassembling around that location reveal a kind of routine that seems to handle some of the rewards from the hostages.
We have a write here: 50EF: 32 A6 C0 LD (C0A6h), A
- where A was set to 01h (sword) the line before
Nearby we have:
50E9: 3E 02 LD a, 02h (nunchaku)
then jump to the load instruction that writes the nunchaku to RAM.
In Frhed I locate the instruction above and change 3E 02 to 3E 03.
Even though it still says sword and nunchaku when I rescue the poor kids, I can still keep my chain.
Cheat finder on Ghouls and GhostsPosted: Fri May 17, 2013 7:36 pm
How to hack for unlimited energy (hearts):
0) Check dump with smschecker. Mine had headers. Fix it.
1) Boot up in Meka and enable cheat finder.
2) Quickly press compare to Old Value and click Reduce - before the skeleton walks into you.
3) Skeleton walks into you - you loose a heart. Press < then Reduce to narrow you search to variables that just got decremented.
4) Skeleton walks into you again. You die. When you respawn, quickly click > then Reduce (you respawn with two hearts, so the varibale you are searching for have just been incremented). When the skeleton comes again, and hits you, click < then Reduce a final time, and there you have it: RAM: $C04C. This is the place in memory where the game keeps the amount of hearts for Arthur.
5) Poke RAM to check. Bring up MEKA's memory editor and write 0A (10) to C04C. Instant effect. You can max. see 6 hearts, but you can have a lot more energy. The hearts doesn't graphically decrement if you have more than 6 and is hit by enemies, but the counter decrements behind the scenes.
6) In MEKA's debugger, add a breakpoint that breaks on writes to RAM location C04C: b w C04C.Now go touch a skeleton...
7) It breaks at location 15F2. There is no need to disassemble, since the debugger already displays the heart related instructions that we need to overwrite, in the code portion shown in the window at break point:
15EF: 21 4C C0 LD HL, C04Ch
15F2: 35 DEC (HL) (overwrite with 00)
15F6: 32 4C C0 LD (Co4Ch), A (overwrite with 00 00 00)
8) how to overwrite: Load the ROM into Frhed. Locate position 15F6 and replace the 32 4C C0 with 00 00 00. Also overwrite the 35 at position 15F2 with 00.
9) Save and play the patched ROM. You have infinite hearts.Every time you get hit, you are reduced to underwear for a second, then you are instantly back to full armour.
This cheatfinder works great. I have also used it on My Hero.
Edit: the project evolves:
hack for infinite lives:
0) this is harder to check with the above infinite hearts hack enabled...
1) enable cheat finder and compare to constant 2, click Reduce (=2 lives to start with)
2) die once, compare to constant 1, click reduce
3) die again, compare to constant 0, click reduce.
4) we can now see where the lives are stored: at location C033.
5) set up breakpont when somethung is written here "b w c033"
6) we catch a DEC (HL) at location BB5B, with HL containing the location of lives (C033).
7) in Frhed, locate position BB5B, and overwrite 35 with 00. Oh, it is not there?!. Hmm, don't panic. This could have to do with paging or something? Instead search for the code using Frhed search tool. I searched for <bh:c3><bh:c8> as C3 C8 is part of a JP instruction right below the decrement. Hey, I found it. I can also see the 35. I'll overwrite it with 00. This was successful.
8) save and play. Note: You will need these infinite lives as well as infinite hearts, as the antlion will kill you instantly - regardless of hearts - if you get trapped in it's pit.
hack for equipment:
I guess it is 0 for no equipment and 1 for first upgrade, 2 for second etc.
Play until a shop appears. Go into the shop.
Cheat finder. Compare to constant 0. Choose item (I choose helmet). When outside, compare to constant 1. 4 matches. Compare to old value, we are down to two matches.
C042: 01 (this looks good, as it is close to hearts. Indicating a structure for keeping info on the player status (lives, hearts, equipment, etc.).
yeah - after poking around in the memory editor, I can see that I'm on the right track here: C043 clearly holds the armour. It changes colors as I write values to this location. I cannot find a scan of the manual anywhere, so I do actually not know what difference these items make?? Oh, I can see that the shoes make me run faster. Nice! Anyway - I do know I shiny gold armour when I see one, though. So I will stick with this golden outfit. Now I want to mess around with the nearby bytes to see if I can get to choose some of the nice weapons.
c041 seem to control the trajectory of your weapon. 00 for straight forward like the initial lances. 01 for lances thrown backwards? 02 for a kind of spinning lance flying upward (like the axes do).
bonus info (from random poking around):
c03f: state of Arthur. 00 = knight. 02 = duck
checking with a savestate right before I walk into the shop, so that I can go back and choose different items while overwatching the memory editor.
I played further into the game. A shop appears. This time I can choose daggers. F5 save. In cheat finder: reset search. Then compare to constant 0 (and click Reduce). Choose dagger. Then compare to constant 1 (click Reduce). Then compare to Old Value a bit, and walk around while reducing 2 times. 5 matches are left:
c041 (the trajectory byte from above - oh, so 01 is for the special wave-like path of the knives).
Poking the RAM in memory editor I discover:
df32 speed (allows for multiple knives in the air at once. I'm not sure, 05 seems to allow three fast knives)
df3c - or maybe this is in fact the speed...?? Both these speed locations are reset when using your magic..??
I think that c041 is actually the weapon. But the correct graphics and other settings are not loaded when just poking around at this location. I must capture a write to this weapon location and see what else happens here...
OK - this is not so straight forward, so I will give that a rest and maybe pick up on it later.
But I want to hardpatch the golden armour and the golden shoes so that the player gets these from the start. Must then catch the init routine writing 00 to these locations.
1) Set up breakpoint: b w c043.
This catches the init routine allright, but I can see how the helmet, shoes, armour etc. is being initialized quickly one by one with register a containing 00 (it is not set directly to 00, but is or'ed and xor'ed). So there is not an easy way to set up golden armour as standard equipment. Well, I will also get back to this.
So the evening ended with a patch that has infinite lives and armour, and some insights into where the game stores equipment.
I'm writing this to contribute to documenting the MEKA cheat finder in action.
||Posted: Sat May 18, 2013 1:05 am|
When paging happens, use the command
to find the rom address.
To alter block zero initialisation, you have to write some code in an unused area and patch a call to it over the initialisation code. That's getting pretty advanced, I wouldn't do it in a hex editor.
||Posted: Sat May 18, 2013 8:05 pm|
nice tip with the rmap pc command. I did not know it. I will use it from now on when encountering paging!
Would you prefer to disassemble the game to alter the block initializations, Maxim? I was actually thinking about using Frhed to find an unused area with 00's and then hex code simple stuff directly into this (mostly load a value into A, then write to certain places in RAM), then overwrite some of the original initialization code to call this custom initialization. I looked in the z80 instruction manual and got a feeling that it might be within my reach - but of course I'm interested if there is a better/simpler way :)
||Posted: Sat May 18, 2013 8:40 pm|
I'd use an assembler to make the opcodes. Here's an example of patching a rom - for mapping, but it's very similar for your case.
||Posted: Sat May 18, 2013 10:10 pm|
Advanced stuff (relative to my current skill level)
Preparing to bypass block initialization.
Remember to take paging into account! Got to find unused space nearby the original block init code.
I looked up the opcodes for the instructions I need:
CD yy xx : CALL address xx yy (remember paging and little endian)
C9 : RET
3E xx : LD A, xx
I use debugger to locate the block init routine. It is around $277C1
Copy 3 bytes from $277C1 (which are hex 32 42 C0 - load a into RAM C042). This will be overwritten with a call instruction in a moment.
Paste these bytes to location 27102. It looks unused 00's, but not intirely. So I could be screwing some important data up here. Must test. Add a RET after this LD instruction. We now have:
27102: 32 34 C0 C9, which is
LD (C034), A
now go back to 277C1. Replace the LD instruction with a CALL to our custom function at 27102.
MEKA RMAP tells me that 2770C is B70C
How long from this address to custom routine? 2770C-27102 = 60A
calculate address of custom routine: b70c - 60a = b102
So I can now goto 277C1 and overwrite the LD instruction 32 34 C0 with a call to my custom function: CD 02 b1 (remember little endian)
I test it... OMG, it works! This is pushing my own limits!! I disassemble in MEKA, debug etc., and realize that the game still seems to work, the program flow integrates the new routine as intended, ... oh, I'll go have a beer now...
Next thing is to copy all the LD's from the block initialization into the new handler. Here I can tweak them according to my needs. Then go back and overwrite them with 00's at the old place.
It works!!!! I have successfully bypassed the block initialization. I let the program do as it would have done anyway - except that when it wants to write 00 to shoes (c044) and armour (c043) addresses - I throw in my own 3E 03 (LD A, 03h) just before. 03h is the value for golden armour and golden shoes. I set register A back to its original 00 (3E 00) before returning (C9) to the old block init routine, where the program now runs over a short sequence of 00's (NOP) before reaching the rest of the original routine.
Yeah - come on you not-so-scary skeletons. Taste my infinite lives, infinite hearts, golden armour and golden shoes :)
Oh - did not realize that you had already posted something, Maxim. Will look into your link and example. But first I will rest a little on my hex-hacking laurels :) For a guy that never made it past Visual Basic and Flash back in the 90's, opcodes and hex-editing is like... totally the Matrix. :) Thank you for all your support.
||Posted: Sat May 18, 2013 11:06 pm|
|I'd avoid areas of 00 in the middle of a bank as they probably mean something - maybe some graphics you didn't see yet. I'd prefer to use ffs at the end of the bank (assuming that's what you find there).|
||Posted: Sun May 19, 2013 6:56 pm|
OK - there's also some blocks of ff's in the vicinity. I will play through the patched game soon and check that everything is okay. If I encounter faulty graphics etc., I will move my code to the ff's. Thanks for the tip!
Edit: Just finished the game and got the princess. Everything seemed to be working fine. The only weird thing is that the game kind of halts in the final screen. I could do nothing but reset/power off to move on from the final screen with text congratulating me. I don't know if this is also the case on the original, unpatched ROM. It works quite well - maybe even better than just the expected jump back to the intro screen.
||Posted: Mon Jul 22, 2013 10:07 pm|
I have posted a new version of MEKA with a better interface for the Cheat Finder.
There's now no "reduce" button, clicking comparer buttons perform a reduction with the clicked comparer. I think it makes it really easier/faster to converge toward a result. Let me know what you think!
||Posted: Tue Jul 23, 2013 2:52 pm|
|Thank you Bock. I will look forward to trying out the new cheatfinder. I'm still in the ROM-hacking business :)|