Assembly is a low level programming language that talks directly with the microprocessor. Keep in mind that type of process you are working with is important for how assembly is written. For the scope of the course I took, we were specifically working with x86 and all disassembly was displayed in Intel format.
Assembly language is just above machine language (binary.) Using the commands of ASM (assembly) we can write instructions for the CPU to perform in Machine language.
The process of assembly is:
- Writing the assembly code
- Using nasm to assemble it
- Using ld to link any files/modules/libraries
The resulting code is our binary.
nasm is the assembler I’ve been using with the course. When it is invoked on a target file, it creates an object file as output. ld is the linker I’ve been using – it is invoked on the object file, which links whatever files are necessary and generates the final output binary executable.
If we had a file called helloworld.nasm and it was composed of assembly language instructions, we can go ahead and compile it like so:
nasm -f elf64 helloworld.nasm -o helloworld.o
The resulting output file would be helloworld.o and it would have been compiled to elf64 bit binary.
Finally, if we do:
ld helloworld.o -o helloworld
At this point the file helloworld will be our executable.
Ok, But why Learn Assembly?
Chances are, most people aren’t picking up assembly language to write an application or driver. It’s usefulness is in the writing of shellcode – that is code that can execute in memory of a target machine. This code will run directly on the system (as long as it is compatible with the processor) and doesn’t require any higher level language to be installed. In other words, it’s great for penetration testing. If a tester could force a scenario where they had access to the memory of a target under test, they could then inject shellcode that would run and execute instructions – all in memory. Such an attack might even escape anti-virus.
Shellcode could be written to open a bind shell (an open port where a user could connect), a reverse shell (returning a callback to the attacker’s machine where he accepts an invite to be logged into the target), or run any system calls that are available (remove files, copy files, etc.)
Aside from shellcode, there’s another great reason to learn assembly – Disassembly. The art of disassembling an application, allows a user to bypass internal security, logic, etc. A user could disassemble a compiled app, and be able to modify values in memory that the app would accept and run with. To know what we’re looking at, we need to know the Assembly language.
Learning assembly also gives us a better understanding of what is occurring under the hood of our high level applications. We gain an appreciation for what is really happening.