Here is the full ~6Mb image that I used as my slide deck within MS Paint in Windows 3.1 for my CactusCon 2016 presentation: Machining, A Love Story. Below the large image are all the images again, slide-by-slide, with brief notes; so there can be some context. All non-screenshot art done by KRT c0c4!N (my lovely girlfriend), it should be noted that I limited her to 16 colors with a specific pallet.
The intro slide:
A slide showing the 2016 CactusCon art in less than 16 colors:
The 'ToC' slide summing up what's to come:
As a teenager, I got my first family computer, a 486DX. Playing games on a SNES or SEGA I felt like I was playing games from the 'gods.' But playing games on a computer made me realize I was using the same platform that could allow me to be one of the gods: I wanted to learn to program.
I tried QBasic, which was fun at first. But I didn't want an interpreted language. I wanted to write software where I could just run the executable standalone; where the program was the machine code meant for the processor, not an interpreter.
I wanted to see what a 'real' program looked like. So I dropped a program into Notepad and inspected. Even though I knew this code was not printable, I still had a feeling that if I could understand these characters, and had the right editor, I would have all I needed to write software (this assumption turns out to be correct, it's just too bad I didn't find the answer until way later in life)
I found the nerdiest friend I new in school and asked him:
So I ask:
Remembering my exploration of a program inspected in notepad:
He still persists, only knowing what he has heard, with no appreciation that there are lower levels handed to us by the false gods of abstraction:
I remember this conversation for eternity. It is the moment I start to hate abstractions, to fundamentally know that if something can't be done at the layer of abstraction we are dealing with, one must only go a level deeper and repeat if needed (even though lower levels of abstraction are more difficult to deal with, they always come with more control and power):
This starts my journey to learning programming, assembly language, and machine code. I remember programming in BASIC for this TI-82. But then I learned you can program in assembly for it (Z80 chip). My first program cleared the screen (as intended). My second experiment cleared the memory (it was meant to be 'Hello World'). I gave up on this for a little while.
Then I formally learned assembly (and even machine code) for the Motorola 68HC11 embedded system. For class, we didn't get a text-book. Instead we had a lab manual and the Motorola reference manual for this chip. The reference manual had every instruction and even the corresponding machine code for each instruction. After doing all of the labs, my personal project was to try to write some code that would replicate itself into memory right after itself. This required an appreciation for machine code.
The next architecture I learned assembly for was the Parallax Propeller chip. I wrote a 4-channel wave table based audio driver in assembly. I put the chip in my 4-string bass with a NES controller as input. It was only until later that I experimented with Propeller machine code, only to find out that this architecture is the closest to 1-to-1 between assembly and machine code that I had ever seen. More on this project: Bass + Computer
I finally learn x86 assembly. I learn it from some SANS GREM (GIAC Reverse Engineering Malware) training that a previous employer sent me to. It was actually a fantastic intro to x86 assembly. It also offered/explained a tool that can be used to convert 'shellcode' into a real executable program under windows. I liked this, but really wanted one for GNU/Linux instead (one did not exist at the time)
I then read more than 10 books on assembly and all 3 volumes (3,500 pages) of the Intel Manual.
I learned that Assembly is too high level. I wont go into too much detail on the next 3 slides; as the deeper explanation of these topics is contained within this same blog (in other posts), and is enough for a dedicated talk...
My rant on responses I see on stackoverflow (not about the platform itself). Remember, I wanted something like shellcode2exe.py, but for GNU/Linux ELF. To see if there was anything like this, I started with a search, and found someone asked this question:
This was the first moronic (and highest upvoted) answer. It is assembly (not machine code, like the question asked for):
In the comment of that first answer was this (correct):
This is probably the best answer, as it fully satisfies the question of having no headers (PE nor ELF). But there was no proof of concept :(
Right above (with the moar shit), someone gives an 'example'. It is moar shit because the example is just more assembly (not machine code):
Then there are these unhelpful tidbits. Being that ELF is not machine code and a.out is not an appropriate alternative to ELF in the context of wanting to do pure machine code.
Finally, I create something for my own needs; writing pure machine code / 'shellcode' and being able to run it, albeit in ELF format. It takes a machine code (ascii hex) source file, and makes an ELF executable of it. I respond with my tool and a proof of concept:
This is the closest thing to a helpful answer. Not only are we back to the DOS .COM format file (pure machine code, no headers), but there is a proof of concept; the fully functional and executable EICAR antivirus test file. But it wouldn't be stackoverflow if the most helpful answer wasn't the most downvoted and has the most ignorant responses. 'compiler' says that it doesn't look like machine code (it is). 'petersaints' states that this isn't machine code, and that it's just the EICAR test string (it is machine code, it also tests AV). For an in-depth debug of EICAR, see http://thestarman.pcministry.com/asm/eicar/eicarcom.html (it's elite). Also, my friend did a write-up on the same topic: http://www.biebermalware.info/2016/05/playing-with-eicar-my-nerdiest-post-ever/
So now starts the section where I give various ways to write raw machine code and execute it. Starting with the Windows platform and shellcode2exe.py. The screenshot itself shows how it is run:
This ImmunityDBG screenshot is the output of the above shellcode2exe.py command. Note that I used assembly and machine code in the examples above about assembly being too high-level; hence a few ??? dissasemblies.
Below is a source file for my m2elf script. I have another blog entry that goes into more depth on these tools: How to Machine
A screenshot showing the running of the script and the executing of the result
NASM directives are another way of inserting literal bytes into otherwise assembly source files. The advantage of this is that it allows for 64-bit code (my m2elf script only supports 32-bit). The thing to be aware of is the memory order model, as things can tend to get reversed if you're not paying attention.
Another method is to write boot sector code. The slide below outlines the features of coding this way. I wrote a PoC that I call TronSolitare, https://github.com/XlogicX/tronsolitare
And to return a way to write raw machine code without headers, a method I could have used as a teenager, if only I had the right knowledge:
Cheatsheet on how to use DEBUG to write machine-code
Commented machine code for Hello World (as used in live demo):
48656c6c6f20576f726c642124 #Hello World!
ba 0001 #mov 0100 to dx
b4 09 #mov 9 to ah
cd 21 #API Call
b4 4c #mov 4c into ah (exit)
cd 21 #API Call
I also wrote a program to interpret commented machine code (like above) and output a .COM file. I demo'd this as well during the talk. Even though this is assembly, I took the machine code from the assembled output and wrote this entire program using debug (in machine code), because I'm a purist...