Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


How to use a Variable Offset? (Emulators)

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
Kuwaga
Newbie cheater
Reputation: 0

Joined: 21 Apr 2012
Posts: 11

PostPosted: Wed Oct 16, 2013 4:55 am    Post subject: How to use a Variable Offset? (Emulators) Reply with quote

My issue is very simple, I just can't find a way to get Cheat Engine to do what I want it to. Basically, I have a pointer to a larger memory region: Emulator.exe+something (it's a pointer to the start of the emulated console's memory). Then from that pointer, I have with offset y an internal pointer from the game to the player object stored in format 80xxxxx, whereas xxxxx+6c would be - let's say the Z coordinate of the player object - inside the emulated console's memory. So to reach that Z coordinate I would need to look up the internal pointer at [[Emulator.exe+something]+y], then subtract 0x80000000 from it to get my new base offset (offset for the player object inside the game). The value I actually want to reach would then be reached by [[Emulator.exe+something]+(new base offset)+6c]. How do I get Cheat Engine to do this for me?
I have tried putting in [] - expressions as the offset, but it didn't work.


Last edited by Kuwaga on Thu Oct 17, 2013 10:52 am; edited 1 time in total
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

Joined: 09 May 2003
Posts: 25296
Location: The netherlands

PostPosted: Wed Oct 16, 2013 7:50 am    Post subject: Reply with quote

You could use a lua script to fill in the address at runtime

Or try this cheat engine extension I quickly wrote (you can not scan yet, but you should be able to use pointers. Perhaps later today i might add the code to make scans work)

http://cheatengine.org/temp/emurpm.zip

Extract it to the autorun folder in the cheat engine installation dir and restart cheat engine
It will give a new menu item called "emulator memory"
In there is the set base address which you can use to set the address that will be handled as the base.
So if you fill in 80000000 then address 0 becomes 80000000

you can also fill in a pointer that contains the address. E.g : [emulator.exe+something]

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

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
Kuwaga
Newbie cheater
Reputation: 0

Joined: 21 Apr 2012
Posts: 11

PostPosted: Wed Oct 16, 2013 12:48 pm    Post subject: Reply with quote

That's some service! Thanks! Very Happy
possiblepaths[3]=ced.."autorun\emurpm.frm" should be possiblepaths[3]=ced.."autorun\\emurpm.frm" I suppose?
I wonder if it'd be worthwhile to learn how to write such extensions myself. I probably would have gone the route of writing a standalone application in absence of a reply, just because it would have been easier to me.

Yours is a more practical solution than the one I imagined. Though now that the addresses get pretty close to real console game addresses that gameshark codes would use, there is still a little issue. For N64 games in all emulators I have tested, there is a big/little-endian mixup. The form is such that if you replace 0123456789acdef as last digits by 32107654ba98fedc respectively for byte, the addresses will be correct, though for 4 byte/float addresses which typically end in 048c, if they do, no correction is necessary. I take it that the emulators reverse the 4byte big endian values the N64 uses for faster calculations at the cost of having the words and bytes addresses jumbled up in physical memory. (And they can't reverse the whole region because reading backwards all the time is horrible). Words should then also be jumbled up in the same fashion as a result. If I'm right, for words N64 ending 012_456_89a_cde_ should then be translated to 210_654_a98_edc_. Word addresses ending in 3, 7, b and f on N64 require special treatment, as there'd be an overlapping byte into opposite directions.
A N64 word address ending in b overlaps into c. So if we reconstruct it byte by byte, we first reverse into c and b, then apply the rules for byte translations, so that c becomes f and b becomes 8. Likewise, a word address ending in 3 should be built out of bytes 7 and 0, one ending in 7 out of b and 4, and one ending in f out of 3 (with carrie) and c.
Here is an illustration of what I'm claiming:

(I can't post pictures or URLs yet, follow at your own risk) Sad

Then finally, dword addresses would need to be unjambled, so they overlap into the correct numbers as well. By now it becomes easy enough to just visualize what's going on.

So that would hopefully make the addresses displayed by CheatEngine the same as Gameshark codes and as seen by the console itself. It's not unlikely that I screwed up somewhere though.
Now, how to tell if a N64 pointer is a pointer to a byte, word or dword? I think the user would definitely require an option to decide which he thinks it is, even if solid conventions exist, just in case they got broken. Conventionally, though I'm not quite sure, I think word and dword start with 80xxxxxx, and byte ones start with 81xxxxxx, at least that's the convention that gameshark uses.
Sounds like a lot of potentional work.
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

Joined: 09 May 2003
Posts: 25296
Location: The netherlands

PostPosted: Thu Oct 17, 2013 5:27 am    Post subject: Reply with quote

I got a bit distracted yesterday, but here is the version that allows scanning http://cheatengine.org/temp/emurpm.zip (Also fixes the path lookup)

No clue what you're talking about though (I never used gameshark)

An address written/displayed in hexadecimal is the same for both little endian and big endian.
It's just that the order of the bytes stored in memory is reversed

so, address 11223344 in a little endian system is address 11223344 in a big endian system
Just that a pointer to that address on a little endian system would be stored as 44 33 22 11 while a big endian system would store it as 11 22 33 44

So, if the emulator stores memory as little endian as opposed to big endian, that can come in handy for pointers(pointerscan can even be used), else you will have to use scripts to calculate the pointerpath manually

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

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
Kuwaga
Newbie cheater
Reputation: 0

Joined: 21 Apr 2012
Posts: 11

PostPosted: Thu Oct 17, 2013 11:49 am    Post subject: Reply with quote

Well, since the vast majority 4byte big endian values the N64 uses end with 048c (as well as float), I think what the emulators do is reverse all of these, and as I've said no corection here is necessary.

However for byte addresses, it's relatively easy to see why the addresses would have need to be changed from the first picture I posted. If you got a dword 0x12345678 stored at address 0xc200, and you want to read just the 34 byte, it'd be the second byte on original hardware (address 0xc202). However, since in physical memory we have reversed those 4 bytes, if the N64 wants to read 0xc202 or the second byte (34), it's now actually 0xc203 in emulator memory.

I can tell from experience that all byte addresses will be reversed according to this pattern, and it's true for Project64, Mupen64 and Nemu64 (used for its debugging tools), which are the most popular N64 emulators. Like for example with Ocarina of Time the gameshark code for infinite deku sticks is 8011A65C 0009, so that means 0x11a65c would need to be frozen at 9. However, if you search for the deku stick count with Cheat Engine, you'll find that the byte you want to freeze is at the offset 0x11a65f. Makes sense? I'm pretty sure if any game requested 0x11a65c, the emulators would instantly translate it to 0x11a65f and read that byte instead. They can't just reverse dwords for faster calculations without doing these translations for byte addresses as well, or in many cases the wrong byte would be read.

You are correct that a dword address of 0xc203 big endian, if reversed would still be 0xc203 little endian, so it seems no translation would be required. However, I'm fairly certain emulators only reverse dwords which addresses ending in 0, 4, 8 and c (which should be almost all of them in practice).
Let's say we store dwords 0x12345678 and 0x9abcdef0 at 0xc200 and 0xc204 in big endian format. Then the N64 wants to read a dword at 0xc203, also in big endian format. What would it get? The answer seems easy, and it is. It would get 0x789abcde.

But now in actual emulator memory, 0xc200 and 0xc204 have these values stored as little endian 0x12345678 and 0x9abcdef0. What happens if we just try to read 0xc203 as little endian now without applying corrections? It'd be all messed up and we'd get 0xbcdef012 instead, not at all what the real console would get. So to correct that, the transformations I've illustrated in my second diagram would need to be applied, and 0xc203 would have to be manually reconstructed byte by byte.
The console wants to read 0xc203 0xc204 0xc205 0xc206 as a dword. So we'd have to manually construct it by first reversing, then applying byte translations. First byte is 0xc205 (6 becomes 5), second is 0xc206 (5 becomes 6), third is 0xc207 (4 becomes 7), fourth is 0xc200 (3 becomes 0). Let's see if that gives us 0xbcdef012 that the actual console would read.


(This is what my second image was supposed to illustrate)

So that's why I think the translations and transformations I've listed would need to be applied. I hope it makes more sense now? Anyway, I'd be willing to implement these shenanigans myself once I learn how to do it. Not sure when that's gonna be, but I think they are all necessary to replicate browsing a real N64's memory inside an emulator.
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

Joined: 09 May 2003
Posts: 25296
Location: The netherlands

PostPosted: Thu Oct 17, 2013 1:22 pm    Post subject: Reply with quote

I don't have much experience with endianess, but from what you said:
Quote:

Like for example with Ocarina of Time the gameshark code for infinite deku sticks is 8011A65C 0009, so that means 0x11a65c would need to be frozen at 9. However, if you search for the deku stick count with Cheat Engine, you'll find that the byte you want to freeze is at the offset 0x11a65f. Makes sense?

It does make sense, but I don't understand your problem

Assuming that 11a65c is a 4 byte big endian value writing 9 would turn it into 00 00 00 09
The 09 byte would be at byte 11a65f

Which is what cheat engine finds

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

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
Kuwaga
Newbie cheater
Reputation: 0

Joined: 21 Apr 2012
Posts: 11

PostPosted: Thu Oct 17, 2013 1:44 pm    Post subject: Reply with quote

Dark Byte wrote:
It does make sense, but I don't understand your problem

11a65c (on N64 hardware) isn't a 4 byte big endian value though, it's a single byte value for the deku stick count. The other bytes are all used to count other items. 11a65d is the deku nut count, 11a65e is the bomb count and 11a65f is the arrow count. All of which are reversed in emulator memory. There's definitely many instances where this is relevant.

It wasn't a huge problem before and still isn't I guess, you just have to do those calculations yourself. But now that you've written this extension, I feel that the addresses get close enough to real N64 addresses that this extra step should be taken by someone for good measure. So if somebody just takes the addresses from gameshark codes, they're correct, or if there's a pointer to a single byte in the N64's memory, it'd get translated correctly, so that it actually feels like browsing a big endian machine. I was thinking of maybe having custom data types for it.

Thanks for making my image links work, btw.

Edit:
Kuwaga wrote:
Conventionally, though I'm not quite sure, I think word and dword start with 80xxxxxx, and byte ones start with 81xxxxxx, at least that's the convention that gameshark uses.

I guess this was wrong then. I'm sorry. Seems I got confused. For Gameshark, 80xxxxxx sets a single byte and 81xxxxxx sets a word. Google "The Secrets of Professional GameShark(tm) Hacking" for reference. Most N64 internal pointers start with 80, though I'm pretty sure they aren't to byte but to in-game-objects. I know a few people I could probably ask what other prefixes than 80 mean.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine All times are GMT - 6 Hours
Page 1 of 1

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


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites