Like a program I wasn't even interested in. Once done, wouldn't even use it.
Years I was 14-15 were spent looking at disassembly listings(I used Win32DASM) getting drowned in patching versions (HexDecChar Editor), changing things. Sometimes not keeping track, wait, what did I change ?
Learning to organize, even on paper. Offsets.
Then writing small programs in Assembly, Pascal and C to do that.
EB, 74, 75, 76, 90 etc.. Had a special meaning to me. Test calls, bogus functions and bloated DLLs getting called from a gazillion places(some of these on purpose).
This has been invaluable to me. When I went to college, some courses have people struggling with debugging a program, but as you said, when you've been so close to the machine and didn't get lost, following an index is fairly easier.
Also undeniably, when we had uP architecture course, I already knew that 5 years before, so it just was a refresher (bear in mind that they didn't even scratch the surface of what I was doing on my own as a kid. The most interrupt they toid with was printing (09h/21h) whilst I played with TSR and some neat things.
It was also very useful with microcontroller class. PIC micros had only 35 instructions (didn't like MikroC).
A lot of what I did as a kid or a bit later, turned to come in handy, always, at a later time..
So it became a sort of rule .. Whenever I'm doing something, I trust my gut instinct that some time, I'll use it. I'm yet to be proven wrong.
Thanks for sharing, man.
Thanks to that, the sequence 180 48 205 33 is now embedded in my memory, as is the number 144, and I've acquired the ability to literally read x86 machine code in ASCII. That's a skill that is probably not much more useful than memorising digits of pi, but it's fun to see the reactions of experienced developers when I open some executable in Notepad and start mentally disassembling it.
I've bypassed a few protections too, but probably have spent more time on tweaking various software to my liking. Correcting spelling errors in messages, adjusting UI elements, removing useless messageboxes ("Operation complete! Click OK to continue."), etc.
There was a presentation I saw where a guy was able to extract a private RSA key from memory of a novell login screen by using typing in machine code using alt key combos in the username or password text field, exploiting a format string vulnerability.
This is the video of that presentation for the interested: http://www.youtube.com/watch?v=jv0adeL4x1U
For example, I once patched the setup of NT 3.1 to work with an Aztech IDE CD driver: http://www.betaarchive.com/forum/viewtopic.php?t=28570
(for those who can't be bothered to click the link, it was a conditional jump to unconditional jump. I always prefer to patch a conditional jump to an unconditional jump, or NOP it out, depending on the code flow, as that way it would work in all cases)
..and in some other related subject, I know a little z80-gb asm too, and I've been playing with that Pokémon arbitrary code execution.. destroying a save file in 23 bytes is fun. But then again, so is beating the game in 12 bytes: something that I ported across to every language and version of Red/Blue/Yellow for the lulz.
It was more than patching things with NOPs(), but correcting checksums and so on.
We never released the programs once without protection. It was fun.
()for people that are not into this, just replacing opcodes alone does not work as the OS checks that the executable has not been modified, and the program could do it too itself in very sophisticated ways.