| |||
Views: 86,391,890![]() |
![]() ![]() ![]() ![]() |
03-29-23 06:58 PM![]() |
|
Guest: Register | Login |
0 users currently in ROM Hacking Archives | 1 guest |
Main - ROM Hacking Archives - Introduction to Hex (Repost) | New thread | New reply |
Tweaker |
| ||||
![]() ![]() Red Koopa Level: 28 Posts: 6/139 EXP: 125690 Next: 5648 Since: 02-19-07 From: Rochester, NY Last post: 5401 days Last view: 5307 days |
NOTE: It's very possible this is out of date, due to being, well... a repost. =P So feel free to correct me in instances where I may be wrong. Anywho, here we go!
------------------------------ Hey there, Tweaker here. Decided now that I decided to frequent here more, I should contribute a tad bit more. ![]() Anyway, first off, you must realize that Hex stands for Hexadecimal, which is a base 16 number system. This is similar to decimal, which is a base 10 number system. So let's learn the numbers, shall we? Decimal: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ------Hex: 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 As you can see, counting to 16 in decimal is equivalent to counting to 10 in hex. Hex is pretty much decimal with six extra values tacked on to it. Now, how do we hack Super Mario World with hex? Well, as you may or may not know (hopefully may), everything on a computer is represented by binary code (AKA 001010101110, etc). Of course, editing and viewing ROMs -- or ANYTHING -- in binary alone is extremely impractical (unless you're dealing with bit-based compression algorithms and opcodes...). So as us humans oh-so-hate things being complicated when they don't have to be, we found a way to simplify binary; Using hexadecimal. Hex is dealt with by the byte in most operations. In case you don't know your terminology, let's fix that right now: Nybble - Half a byte, or a single digit. "A" would be a good example. Byte - Full hexadecimal value, equal to 8 bits, and two digits. Something like "01" or "1C". Word - Two bytes, or 16 bits. Need I really explain this more? "010A" or "1550" would be good examples. Long(word) - Two words, or 4 bytes, or 32 bits. "00012345' would be a good example. FYI, byte types are advanced in powers of 1,024. 1,024 bytes makes a kilobyte, 1,024 kilobytes makes a megabyte... etc etc down the whole damn chain. Now that you know your basics, we can start editing and move on to pointers and such. So first off, what is a pointer? Well, a pointer is pretty much what it's called -- a pointer. It's a hexadecimal string that lists an offset in ROM in which to locate data. (BTW, an offset is just the current byte in ROM that you're at. $012345 [out of $200000, though that bit's redundant] would be an offset.) Since the SNES' main processor is Little Endian, you need to read pointer backwards by the byte to get the offset to be located. For example, if my pointer read 56341200, first I'd split that into bytes. 56 34 12 00. Now I take the byte order and reverse it. This becomes 00 12 34 56, which I compress back into a longword - 00123456. So this pointer wants to locate data at offset 00123456 ($123456). Let's make a practical example. Let's say you wanted to edit Mario's art to add more frames to some animations (which you should edit mappings for later, but ![]() We'll say (it isn't really) that the location for Mario's art is at offset $55439. However, we don't know where the pointer to his art is! So guess what? We're gonna find it. Remember how I said pointers are offsets byteswapped in ROM? Well, take the offset of Mario's art and byteswap it. Originally, 00055439, it becomes 39540500. Run a search for this in the ROM and you should get at least one result. We found our pointer! Now we'll say the end of the ROM s offset $02000000. byteswap this and replace our pointer with 00000020. This is telling the game to look for Mario's art at $2000000, rather than $55439. Now put Mario's art there and run the game -- It should work! You can even delete the old art and Mario will still be as good as new. Hope this helps some people understand how to use a hex editor better. I may add more examples if requested, but this should be enough to get you going on your own as a better hacker overall. ![]() ____________________
|
Kles |
| ||
![]() Level: 74 Posts: 33/1301 EXP: 3598948 Next: 54596 Since: 02-19-07 From: Canada |
To add to that, Tweaker didn't really explain the "little endian" thing, so I shall.
Some processors work "little endian" which means that the code will be read right to left, in bytes. So, if something read "05F21C63" the processor would read it as "63 1C F2 05". Big endian is the opposite: left to right, in bytes: "05F21C63" would be read as "05 F2 1C 63". He pointed out what you would need to do, but not why. ![]() (I think this is correct) |
Tweaker |
| ||||
![]() ![]() Red Koopa Level: 28 Posts: 20/139 EXP: 125690 Next: 5648 Since: 02-19-07 From: Rochester, NY Last post: 5401 days Last view: 5307 days |
This is for beginners, though. =P I just wasn't trying to overcomplicate things. Besides, I wrote this like a year ago, so yeah. ![]() ____________________
|
Raccoon Sam |
| ||
![]() ![]() Cobrat Level: 56 Posts: 37/672 EXP: 1336042 Next: 62134 Since: 02-19-07 From: Hi Last post: 3074 days Last view: 2305 days |
Posted by Kles That's confusing. If "Big Endian" is 01 02 03, and "Little Endian" is 03 02 01, then what is it if it's set to have "no endianness"? ____________________ |
Lordlazer |
| ||
![]() ![]() Paragoomba Level: 22 Posts: 11/77 EXP: 51724 Next: 6626 Since: 03-13-07 Last post: 5733 days Last view: 4455 days |
I'm working on actually messing with hex now (instead of simply knowing how to count in hex, heh), so I can't answer your question...but I might be able to point (pun intended ![]() As far as "Big Endian" and "Little Endian" goes, I'm sure there is a default, so if it isn't specified (which is what I think you meant to say when you said "no endianness") I'm sure it would default. Now to what it defaults to I'm not sure, my guess would be that it defaults to "Little Endian" considering that Tweaker found that he didn't "need" to mention this in further detail. Anyways, my question now is how do you detect if you're dealing with hex that is "Big Endian" or "Little Endian"? |
Kawa |
| ||
![]() ![]() CHIKKN NI A BAAZZKIT!!! 80's Cheerilee is best pony Level: 136 Posts: 129/5344 EXP: 29958398 Next: 138517 Since: 02-20-07 From: The Netherlands Last post: 4104 days Last view: 2240 days |
Posted by LordlazerMagic numbers. For example, Unicode text files start with a byte order mark, an unprintable character U+FFFE... but it might also be read as U+FEFF, which is used to detect endianness. ____________________ Wife make lunch - Shampoo Opera - give it a spin Spare some of your free time? <GreyMaria> I walked around the Lake so many goddamn times that my sex drive was brutally murdered Kawa rocks ![]() |
Lordlazer |
| ||
![]() ![]() Paragoomba Level: 22 Posts: 19/77 EXP: 51724 Next: 6626 Since: 03-13-07 Last post: 5733 days Last view: 4455 days |
Alright, new question. I've checked a few so called "tutorials" about how to use an hex editor on SMW, but they don't teach HOW. For instance, I understand (more or less) how to count in hex and how to use the reference the data (er, ROM Map), the problem for me is coming up with an understanding on what to do, besides randomly entering numbers.
To be more exact, the tutorial by KPhoenix taught me how to use said ROM Map's addresses to get to the appropriate section, however, I'm still confused with how to figure things out. For instance, how do I read said numbers to know (more or less) what to change them to? How did they figure out what the addresses did without spending an insane amount of time randomly changing things? How do I know what to change something to after going to where the address told me to (the descriptions are pretty vague, they don't say what numbers do what)? Thanks for the help! <3 Edit: I was reading some more stuff on Hex here and correct me if I'm wrong, but I guess it simply requires luck to figure what things do (or if I were to be politically correct, one must do reverse engineering). Edit #2: Nevermind, I went on IRC and got my answer. For those curious, it pretty much is luck. *shrugs* |
Trax |
| ||
![]() ![]() Yellow Stalfos Level: 70 Posts: 10/1145 EXP: 2936855 Next: 78956 Since: 07-06-07 From: Québec Last post: 3233 days Last view: 2485 days |
I'd say it's one part luck, and one part "feeling". When you get accustomed to how data is stored in a ROM, you can more or less "see" patterns in data, and mangle the numbers accordingly. For example, as long as you know how many bytes long a pointer is, you can quite easily detect a pointer table...
But yes, there's a big part of luck, as ROM corruption is mostly random by nature... |
Tweaker |
| ||||
![]() ![]() Red Koopa Level: 28 Posts: 114/139 EXP: 125690 Next: 5648 Since: 02-19-07 From: Rochester, NY Last post: 5401 days Last view: 5307 days |
Posted by Trax This is absolutely true. Learning and understanding patterns is key to becoming a good reverse engineer. For example, I can find everything relating to music in a Genesis game using the SMPS sound engine based on just two bytes. Two bytes! I think that's pretty damn good if you ask me. =P It's always good to find what's consistent in a type of data, and look for that. Chances are, you'll be able to find any kind of that same data in any other game you need to from that point on. It's pretty trippy. ____________________
|
Lid |
|
Verminlamer2-JD |
|
Main - ROM Hacking Archives - Introduction to Hex (Repost) | New thread | New reply |
© 2005-2023 Acmlm, blackhole89, Xkeeper et al. |
MySQL - queries: 69, rows: 88/89, time: 0.033 seconds. |