Shellcode Execution
REVA
Throughout this course we will deal with assembly language in many contexts: disassembly
from static analysis tools, disassembly in dynamic analysis tools, and source listings to be
assembled into machine code. In many cases you’ll be particularly interested in a small block
of instructions to understand exactly what behavior they are causing the machine to exhibit.
It can be helpful to execute those instructions multiple times to analyze their overall behavior
or step through them with a debugger to note the smaller, incremental changes they cause.
However, it may be challenging to repeatedly execute them when they are nested deep inside
of other logic.
To remedy this, it’s helpful to know the tools and methods that allow you to more easily
accomplish this kind of task.
1 x32dbg
x32dbg is one of the Windows debuggers we’ll be using in this course and it contains a feature
where you can patch the instructions in a binary. For testing purposes this is incredibly helpful
as you can modify the next and subsequent instructions and step through them as if they were
there all along.
1. Open x32dbg.
2. Open any 32-bit executable. (“File”, “Open” and browse to
C:\windows\system32\calc.exe [this is the 32-bit version as WoW64 redirection
takes you to the appropriate spot])
2
3. In the top left you have the CPU window. This shows a disassembled view of the data
surrounding the instruction pointer, which is to say the instructions that will be executed
next. Click on the current instruction (it should be the top instruction, but if not click
anywhere in the CPU window, press CTRL + G then type in eip and click go).
3
4. Press the spacebar to enable editing via assembler.
5. If “Keep Size” is checked, please uncheck it. This prevents unintended behavior when
the length of the new instruction(s) does not exactly match the length of the existing
instruction(s).
6. Type your assembly one line at a time, pressing “OK” after each instruction.
7. When you have completed entering your assembly, click “Cancel” to get out of the assem-
bly entry view.
4
8. In the bottom right you have the Stack window. This shows a view of the data surrounding
the stack pointer, which is to say the “scratch space” for the current execution context.
You may also edit the stack as needed to best suite your task.
(a) Note: The “top of the stack” is shown in the same manner as my diagrams (low
memory address at the top, higher memory addresses towards the bottom)..
(b) Double-click on a location to edit the values. For example, double-click the second
stack location and edit it to be 0x00000001 and then edit the third stack location to
be 0x00000002.
9. Now you can single step through your instructions using the F8 key, or using the “Debug”,
“Step Over” menu item.
5
10. Examine the changes to the register window (top right) and the stack window (bottom
right) to see how your instructions affect the registers and the stack.
11. As an example, the images that follow show several instructions being executed in se-
quence. Consider each instruction and how it will modify the stack and registers - try to
predict what changes will occur before moving on to each subsequent image.
6
7
8
2 gdb/gef
gdb is a debugger most commonly used on Linux and Unix platforms while gef is a set of
helpful commands to improve the gdb experience. While there are multiple ways to accomplish
this functionality with gdb, we will only show one here.
1. Create a file named example_nasm.s and add the following code to it. Where the code
has ; PUT YOUR CODE HERE add your code. The int3 instruction is a breakpoint so
you can easily stop at that location when you run gdb.
section .text ; The linker looks for this global
global _start ; "_start" symbol
; Linux uses interrupt 0x80 to transition
; from usermode to kernel mode to make
; a system call
%define systemcall int 0x80
%define syscallEXIT 0x1
_start:
int3
; PUT YOUR CODE HERE
xor ebx, ebx
mov eax, syscallEXIT
systemcall
section .data
d db 0xcc
2. Assemble this file using the command:
nasm -f elf32 -o example_nasm.o example_nasm.s
3. Link the file to create an ELF executable binary:
ld -m elf_i386 -o example_nasm example_nasm.o
9
4. Run this binary via gdb:
gdb ./example_nasm
5. Enter “r” (or the word “run”) and press Enter.
6. You should be broken at your first instruction. You can use si (step instruction) to execute
your instructions one at a time. The stack is shown in the middle (labeled stack on the
right). As you step through, examine how the stack changes.
Use the following commands to change the stack values accordingly. The context com-
mand refreshes the screen to update the displayed information.
• set *(int*)($esp+4)=2
• set *(int*)($esp+8)=3
• context
10
7. The images that follow show several instructions being executed in sequence. Like before,
see if you can predict the changes that will occur before moving on to each subsequent
image.
11
12