From 227c01cefe6d2f16516795c80946e9a97d6baaee Mon Sep 17 00:00:00 2001 From: Christian Rossow Date: Thu, 14 Dec 2023 14:12:51 +0100 Subject: [PATCH] added slide examples --- slide-examples/Makefile | 15 +++ slide-examples/README | 24 +++++ slide-examples/ex01.asm | 17 +++ slide-examples/ex02.asm | 33 ++++++ slide-examples/ex03.asm | 24 +++++ slide-examples/ex04.asm | 22 ++++ slide-examples/ex05.asm | 28 +++++ slide-examples/ex06.asm | 16 +++ slide-examples/ex07.asm | 42 ++++++++ slide-examples/ex08.asm | 30 ++++++ slide-examples/ex09.asm | 40 +++++++ slide-examples/ex10.asm | 31 ++++++ slide-examples/ex11.asm | 38 +++++++ slide-examples/ex12.asm | 40 +++++++ slide-examples/ex13.asm | 34 ++++++ slide-examples/ex14.asm | 34 ++++++ slide-examples/ex15.asm | 21 ++++ slide-examples/ex16.asm | 21 ++++ slide-examples/ex17.asm | 26 +++++ slide-examples/ex18.asm | 28 +++++ slide-examples/ex19.asm | 29 ++++++ slide-examples/ex20.asm | 38 +++++++ slide-examples/ex21.asm | 31 ++++++ slide-examples/ex22.asm | 23 ++++ slide-examples/ex23.asm | 185 +++++++++++++++++++++++++++++++++ slide-examples/ex24.asm | 26 +++++ slide-examples/ex25.asm | 41 ++++++++ slide-examples/ex26.asm | 26 +++++ slide-examples/ex27.asm | 37 +++++++ slide-examples/ex28.asm | 34 ++++++ slide-examples/ex29.asm | 24 +++++ slide-examples/ex30.asm | 45 ++++++++ slide-examples/ex32.asm | 26 +++++ slide-examples/ex33.asm | 68 ++++++++++++ slide-examples/header.asm.inc | 9 ++ slide-examples/macros.asm.inc | 17 +++ slide-examples/sysexit.asm.inc | 10 ++ 37 files changed, 1233 insertions(+) create mode 100644 slide-examples/Makefile create mode 100644 slide-examples/README create mode 100644 slide-examples/ex01.asm create mode 100644 slide-examples/ex02.asm create mode 100644 slide-examples/ex03.asm create mode 100644 slide-examples/ex04.asm create mode 100644 slide-examples/ex05.asm create mode 100644 slide-examples/ex06.asm create mode 100644 slide-examples/ex07.asm create mode 100644 slide-examples/ex08.asm create mode 100644 slide-examples/ex09.asm create mode 100644 slide-examples/ex10.asm create mode 100644 slide-examples/ex11.asm create mode 100644 slide-examples/ex12.asm create mode 100644 slide-examples/ex13.asm create mode 100644 slide-examples/ex14.asm create mode 100644 slide-examples/ex15.asm create mode 100644 slide-examples/ex16.asm create mode 100644 slide-examples/ex17.asm create mode 100644 slide-examples/ex18.asm create mode 100644 slide-examples/ex19.asm create mode 100644 slide-examples/ex20.asm create mode 100644 slide-examples/ex21.asm create mode 100644 slide-examples/ex22.asm create mode 100644 slide-examples/ex23.asm create mode 100644 slide-examples/ex24.asm create mode 100644 slide-examples/ex25.asm create mode 100644 slide-examples/ex26.asm create mode 100644 slide-examples/ex27.asm create mode 100644 slide-examples/ex28.asm create mode 100644 slide-examples/ex29.asm create mode 100644 slide-examples/ex30.asm create mode 100644 slide-examples/ex32.asm create mode 100644 slide-examples/ex33.asm create mode 100644 slide-examples/header.asm.inc create mode 100644 slide-examples/macros.asm.inc create mode 100644 slide-examples/sysexit.asm.inc diff --git a/slide-examples/Makefile b/slide-examples/Makefile new file mode 100644 index 0000000..8872961 --- /dev/null +++ b/slide-examples/Makefile @@ -0,0 +1,15 @@ +# Makefile for SFL examples + +SOURCES = $(wildcard *.asm) +OBJS = $(SOURCES:.asm=.o) +EXECS = $(patsubst %.asm,%.runme,$(SOURCES)) +all: $(EXECS) + +%.o: %.asm + nasm -g -f elf64 $< + +%.runme: %.o + ld -s -o $@ $< + +clean: + rm -f *.o *.runme sre_examples diff --git a/slide-examples/README b/slide-examples/README new file mode 100644 index 0000000..dacc0d7 --- /dev/null +++ b/slide-examples/README @@ -0,0 +1,24 @@ +Build these executables typing + make + +All programs have a software breakpoint (int3) at the very beginning. +Then you can debug each of them with: + + gdbtui -ex run ./ex01.runme + +Then single-step typing `si` once and pressing ENTER. Pressing ENTER +yet another time repeats the last command (in this case, step into). +As soon as you encounter 4 consecuvite NOP instructions you have reached +the end of the code (just before calling sys_exit(42)). + +To enjoy gdbtui's beauty, you should create ~/.gdbinit with this config: + + layout asm + layout regs + set disassembly-flavor intel + + winheight REGS -10 + winheight CMD -5 + winheight ASM +15 + + refresh diff --git a/slide-examples/ex01.asm b/slide-examples/ex01.asm new file mode 100644 index 0000000..0c65826 --- /dev/null +++ b/slide-examples/ex01.asm @@ -0,0 +1,17 @@ +bits 64 + + SECTION .data +;empty + + SECTION .text +global _start +_start: + %include "header.asm.inc" + + mov eax, 0x42 + ;mov ebx, 0xFFFFFFFF + ;xchg bx, ax + mov ah, 0x00 + mov al, bl + + %include "sysexit.asm.inc" diff --git a/slide-examples/ex02.asm b/slide-examples/ex02.asm new file mode 100644 index 0000000..5830c24 --- /dev/null +++ b/slide-examples/ex02.asm @@ -0,0 +1,33 @@ +bits 64 + + SECTION .data +; empty + + SECTION .text +global _start +_start: + %include "header.asm.inc" + + mov eax,0x42 ; immediate value is en- + mov eax,0x1234567 ; coded in instruction + mov eax,0xffff0000 ; (little endian) + + mov ebx,0x42 ; every registers has its + mov ecx,0x42 ; own 32b `mov` opcode + mov edx,0x42 ; (opcodes b8-bf) + mov esp,0x42 + mov ebp,0x42 + mov esi,0x42 + mov edi,0x42 + + mov ax,0x42 ; prefix 0x66 changes size + mov bx,0x42 ; of operand (32b to 16b) + mov cx,0x42 + mov dx,0x42 + + mov al,0x42 ; prefix 0x66 changes size + mov bl,0x42 ; of operand (32b to 16b) + mov cl,0x42 + mov dl,0x42 + + %include "sysexit.asm.inc" diff --git a/slide-examples/ex03.asm b/slide-examples/ex03.asm new file mode 100644 index 0000000..81c230b --- /dev/null +++ b/slide-examples/ex03.asm @@ -0,0 +1,24 @@ +bits 64 + + SECTION .data +; empty + + SECTION .text +global _start +_start: + %include "header.asm.inc" + + mov eax,ebx ; store value of ebx in eax + mov eax,ecx ; (again, each combination has an opcode) + mov eax,edx + + mov ebx,eax + mov ebx,ecx + mov ebx,edx + + mov ah,ah + mov ah,bh + mov al,al + mov al,bl + + %include "sysexit.asm.inc" diff --git a/slide-examples/ex04.asm b/slide-examples/ex04.asm new file mode 100644 index 0000000..ba74bc7 --- /dev/null +++ b/slide-examples/ex04.asm @@ -0,0 +1,22 @@ +bits 64 + + SECTION .data +; empty + + SECTION .text +global _start +_start: + %include "header.asm.inc" + + mov eax, 0x11223344 + mov ebx, 0x55667788 + + xchg ebx,eax ; eax gets content of ebx and vice versa + xchg ecx,eax + xchg edx,eax + + xchg bx,ax ; again, 0x66 is opcode size prefix + xchg bh,ah + xchg bl,al + + %include "sysexit.asm.inc" diff --git a/slide-examples/ex05.asm b/slide-examples/ex05.asm new file mode 100644 index 0000000..ad8bada --- /dev/null +++ b/slide-examples/ex05.asm @@ -0,0 +1,28 @@ +bits 64 + + SECTION .data +; empty + + SECTION .text +global _start +_start: + %include "header.asm.inc" + + mov eax, 0x00000001 ; +1 + mov ebx, 0x00000005 ; +5 + add eax, ebx ; eax = eax + ebx + sub eax, ebx ; eax = eax - ebx + add eax, 0x42 ; eax += 42 + + ; integer over-/underflows + mov eax, 0x0 ; eax = 0 + sub eax, 1 ; eax -= 1: eax = 0xFFFFFFFF + + mov eax, 0xFFFFFFFF ; eax = -1 + add eax, 1 ; eax += 1: eax = 0x00000000 + + mov eax, 0x0 + inc eax ; eax++ + dec eax ; eax-- + + %include "sysexit.asm.inc" diff --git a/slide-examples/ex06.asm b/slide-examples/ex06.asm new file mode 100644 index 0000000..b8b495e --- /dev/null +++ b/slide-examples/ex06.asm @@ -0,0 +1,16 @@ +bits 64 + + SECTION .data +; empty + + SECTION .text +global _start +_start: + %include "header.asm.inc" + + mov ax, -1 ; initialize with negative value (-1) + + mov ebx, eax ; ---> ebx = 0x0000ffff, i.e., positive! + movsx ebx, ax ; ---> ebx = 0xffffffff, i.e., negative (-1) + + %include "sysexit.asm.inc" diff --git a/slide-examples/ex07.asm b/slide-examples/ex07.asm new file mode 100644 index 0000000..0f730cd --- /dev/null +++ b/slide-examples/ex07.asm @@ -0,0 +1,42 @@ +bits 64 + + SECTION .data +; empty + + SECTION .text +global _start +_start: + %include "header.asm.inc" + + ; multiplication: 2 * 0xFFFFFFFF + mov eax, 2 ; 2 + mov edx, 0xFFFFFFFF ; (2^32)-1 + mul edx ; edx:eax = eax * edx + ; edx becomes 0x1 (LSB is 1) + ; eax becomes 0xFFFFFFFE (LSB is 0) + + + ; caveat: EDX is cleared even if even multiplaction + ; does not require it + ; e.g., multiply 2 * 4 + mov edx, 0x11223344 ; init with random value + mov eax, 2 ; 2 (first factor, implicit) + mov ebx, 4 ; 4 (second factor, explicit) + mul ebx ; eax = 8, edx = 0 + + + ; multiplication with signed integers + mov bl, -3 ; -3 or 0xFD + + mov al, -2 ; -2 or 0xFE + mul bl ; dl:al = bl * al (unsigned) + + mov al, -2 ; -2 or 0xFE + imul bl ; dl:al = bl * al (signed) + + ; challenge: (2^32)-1 * 2^8 + mov eax, 0xffffffff + mov edx, 0x100 + mul edx + + %include "sysexit.asm.inc" diff --git a/slide-examples/ex08.asm b/slide-examples/ex08.asm new file mode 100644 index 0000000..d42cae6 --- /dev/null +++ b/slide-examples/ex08.asm @@ -0,0 +1,30 @@ +bits 64 + + SECTION .data +; empty + + SECTION .text +global _start +_start: + %include "header.asm.inc" + + mov rax, 0xFFFFFFFFFFFFFFFF ; maxint + + ; moving data into sub-registers + mov al, 0x11 ; rax -> 0xFFFFFFFFFFFFFF11 + mov ah, 0x22 ; rax -> 0xFFFFFFFFFFFF2211 + mov ax, 0x3333 ; rax -> 0xFFFFFFFFFFFF3333 + + ; There is one exception, though: + ; Intel's reference tells us that "32-bit operands generate + ; a 32-bit result, zero-extended to a 64-bit result in the + ; destination general-purpose register.", thus: + mov eax, 0x44444444 ; rax -> 0x0000000044444444 + + ; moving with zero-extension (movzx) + mov rax, 0xFFFFFFFFFFFFFFFF ; maxint + mov bx, 0x55 + mov al, bl ; rax -> 0xFFFFFFFFFFFFFF55 + movzx rax, bx ; rax -> 0x0000000000000055 + + %include "sysexit.asm.inc" diff --git a/slide-examples/ex09.asm b/slide-examples/ex09.asm new file mode 100644 index 0000000..a705997 --- /dev/null +++ b/slide-examples/ex09.asm @@ -0,0 +1,40 @@ +bits 64 + + SECTION .data +; empty + + SECTION .text +global _start +_start: + %include "header.asm.inc" + + ; division: 17 / 4 (in 64-bit) + mov rcx, 4 ; divisor + + mov rax, 17 ; dividend (LSB) + mov rdx, 0 ; dividend (MSB) + div cl ; 8-bit divisor, dividend is in AX + ; ---> al = 4 (quotient), ah = 1 (remainder) + + mov rax, 17 ; dividend (LSB) + mov rdx, 0 ; dividend (MSB) + div cx ; 16-bit divisor, dividend is in DX:AX + ; ---> ax = 4 (quotient), dx = 1 (remainder) + + mov rax, 17 ; dividend (LSB) + mov rdx, 0 ; dividend (MSB) + div ecx ; 32-bit divisor, dividend is in EDX:EAX + ; ---> eax = 4 (quotient), edx = 1 (remainder) + + mov rax, 17 ; dividend (LSB) + mov rdx, 0 ; dividend (MSB) + div rcx ; 64-bit divisor, dividend is in RDX:RAX + ; ---> rax = 4 (quotient), rdx = 1 (remainder) + + ; challenge: 254 % 16 + mov rcx, 16 ; divisor (64-bit) + mov rax, 0xfe ; dividend (LSB) + mov rdx, 0 ; dividend (MSB) + div rcx ; ---> rax = 15 (quotient), rdx = 14 (remainder) + + %include "sysexit.asm.inc" diff --git a/slide-examples/ex10.asm b/slide-examples/ex10.asm new file mode 100644 index 0000000..70149b5 --- /dev/null +++ b/slide-examples/ex10.asm @@ -0,0 +1,31 @@ +bits 64 + + SECTION .data +; empty + + SECTION .text +global _start +_start: + %include "header.asm.inc" + + ; init constants eax/ebx; ecx will be our playground + mov eax, 0x00FF00FF + mov ebx, 0xFF000000 + + ; bit-wise OR + mov ecx, 0x00000000 + or ecx, eax ; ---> ecx = 0x00FF00FF + or ecx, ebx ; ---> ecx = 0xFFFF00FF + or ecx, 0xFF00 ; ---> ecx = 0xFFFFFFFF + + ; bit-wise AND + and ecx, 0x00FFFFFF ; ---> ecx = 0x00FFFFFF + and ecx, eax ; ---> ecx = 0x00FF00FF + and ecx, 0 ; ---> ecx = 0x00000000 + + ; bit-wise exclusive-OR (XOR) + xor ecx, 0xdeadbeef ; ---> ecx = 0xdeadbeef + xor ecx, 0xd0a0b0e0 ; ---> ecx = 0x0e0d0e0f + xor ecx, ecx ; ---> ecx = 0 + + %include "sysexit.asm.inc" diff --git a/slide-examples/ex11.asm b/slide-examples/ex11.asm new file mode 100644 index 0000000..86008c3 --- /dev/null +++ b/slide-examples/ex11.asm @@ -0,0 +1,38 @@ +bits 64 + + SECTION .data +; empty + + SECTION .text +global _start +_start: + %include "header.asm.inc" + + ; negate: reverse two's complement + mov eax, -1 ; ---> eax = 0xFFFFFFFF + neg eax ; ---> eax = 0x00000001 + + mov eax, 3 ; ---> eax = 0x00000003 + neg eax ; ---> eax = 0xFFFFFFFD + + ; not: flip all bits + mov eax, -1 ; ---> eax = 0xFFFFFFFF + not eax ; ---> eax = 0x00000000 + + mov eax, 3 ; ---> eax = 0x00000003 + not eax ; ---> eax = 0xFFFFFFFC + + ; challenge + mov eax, 0 ; ---> eax = 0x00000000 + not eax + neg eax + not eax + neg eax + not eax + neg eax + not eax + neg eax + not eax + neg eax + + %include "sysexit.asm.inc" diff --git a/slide-examples/ex12.asm b/slide-examples/ex12.asm new file mode 100644 index 0000000..34cead1 --- /dev/null +++ b/slide-examples/ex12.asm @@ -0,0 +1,40 @@ +bits 64 + + SECTION .data +; empty + + SECTION .text +global _start +_start: + %include "header.asm.inc" + + ; indirect jump example #1 + mov eax, 10 + cmp eax, 10 + jge a1 + jmp a2 +a1: + mov ebx, 1 +a2: + nop + + ; indirect jump example 2 + mov rax, -1 + mov rcx, 1 + shl rcx, 63 + test rax, rcx + jz b1 + mov rbx, 1 +b1: + nop + + ; indirect jump example 3 + ; simplified version from above + mov rax, -1 + test rax, rax + js b2 + mov rbx, 1 +b2: + nop + + %include "sysexit.asm.inc" diff --git a/slide-examples/ex13.asm b/slide-examples/ex13.asm new file mode 100644 index 0000000..1843a08 --- /dev/null +++ b/slide-examples/ex13.asm @@ -0,0 +1,34 @@ +bits 64 + + SECTION .data +; empty + + SECTION .text +global _start +_start: + %include "header.asm.inc" + + ; switch example + mov eax, 1234; + + cmp eax, 1 ; a == 1? + je c1 + cmp eax, 2 ; a == 2? + je c2 + cmp eax, 3 ; a == 3? + je c3 + +def: mov ebx, 0 ; default case + jmp fin +c1: mov ebx, 1 ; case 1 + jmp fin +c2: mov ebx, 2 ; case 2 + jmp fin +c3: mov ebx, 3 ; case 3 + jmp fin + + ; end of switch +fin: nop + + + %include "sysexit.asm.inc" diff --git a/slide-examples/ex14.asm b/slide-examples/ex14.asm new file mode 100644 index 0000000..d6b3a58 --- /dev/null +++ b/slide-examples/ex14.asm @@ -0,0 +1,34 @@ +bits 64 + + SECTION .data +; holds 64-bit addresses of all jump target +jumptable: dq switch.c1, switch.c2, switch.c3 + + SECTION .text +global _start +_start: + %include "header.asm.inc" + + ; switch example + mov rax, 1 +switch: + cmp rax, 3 + jg .def + + jmp [jumptable + rax*8] + +.def: mov rbx, 0 ; default case + jmp fin + +.c1: mov rbx, 1 ; case 1 + jmp fin +.c2: mov rbx, 2 ; case 2 + jmp fin +.c3: mov rbx, 3 ; case 3 + jmp fin + + ; end of switch +fin: nop + + + %include "sysexit.asm.inc" diff --git a/slide-examples/ex15.asm b/slide-examples/ex15.asm new file mode 100644 index 0000000..cef68f1 --- /dev/null +++ b/slide-examples/ex15.asm @@ -0,0 +1,21 @@ +bits 64 + + SECTION .data +; empty + + SECTION .text +global _start +_start: + %include "header.asm.inc" + + xor rax, rax + xor rbx, rbx +chk: + cmp rax, 10 + jge fin + inc rax + add rbx, rax + jmp chk +fin: + + %include "sysexit.asm.inc" diff --git a/slide-examples/ex16.asm b/slide-examples/ex16.asm new file mode 100644 index 0000000..b512ab2 --- /dev/null +++ b/slide-examples/ex16.asm @@ -0,0 +1,21 @@ +bits 64 + + SECTION .data +; empty + + SECTION .text +global _start +_start: + %include "header.asm.inc" + + xor rbx, rbx + mov rax, 10 +a1: + inc rbx + dec rax + jz a2 + jmp a1 +a2: + add rbx, rax + + %include "sysexit.asm.inc" diff --git a/slide-examples/ex17.asm b/slide-examples/ex17.asm new file mode 100644 index 0000000..31374e2 --- /dev/null +++ b/slide-examples/ex17.asm @@ -0,0 +1,26 @@ +bits 64 + + SECTION .data +var1: dd 0x00112233 +var2: dd 0x55667788 + + SECTION .text +global _start +_start: + %include "header.asm.inc" + + ; interactions between memory and registers + mov eax, [var1] ; store content at address `var1` in eax + mov eax, var1 ; store address `var1` in eax + mov [var1], eax ; store eax at address `var1` + ;mov var1, eax ; invalid! + + ; many more instructions allow to work on operands + add eax, [var1] ; add value at address `var1` to eax + add [var1], dword 0x42 ; store immediate value at address `var1` + + ; some combinations are invalid, e.g., two memory operands in arithmetic ops + ; (but many others, too!) +; add [var1], [var2] ; invalid! + + %include "sysexit.asm.inc" diff --git a/slide-examples/ex18.asm b/slide-examples/ex18.asm new file mode 100644 index 0000000..8d02c42 --- /dev/null +++ b/slide-examples/ex18.asm @@ -0,0 +1,28 @@ +;; LEA examples +bits 64 + + SECTION .data +;; array of 5 elements, each 2B wide (stored in little-endian) +arr1: dw 0x5501, 0x1102, 0x2203, 0x6604, 0x7705 +arr2: db 0x01, 0x02, 0x03, 0x04, 0x05 + + SECTION .text +global _start +_start: + %include "header.asm.inc" + + mov rdx, 3 ; element offset (offset 3 --> 4th element) + + ;mov rax, arr1 + rdx*2 + 1 ; compute pointer (invalid!) + ;mov rax, [arr1 + rdx*2 + 1] ; valid, but *deferences* (we don't want this) + lea rax, [arr1] + lea rax, [rax + rdx*2 + 1] ; compute pointer + + mov r9b, byte [rax] ; ---> r9b = 0x55 + mov r9b, byte [arr1 + 3*2 + 1] ; (as above, but direct assignment) + + lea rax, [arr2] + lea rax, [rax + 1*2 + 2] ; compute pointer + mov r9b, byte [rax] ; ---> r9b = 0x05 + + %include "sysexit.asm.inc" diff --git a/slide-examples/ex19.asm b/slide-examples/ex19.asm new file mode 100644 index 0000000..1d9d780 --- /dev/null +++ b/slide-examples/ex19.asm @@ -0,0 +1,29 @@ +; string examples +bits 64 + +%include "macros.asm.inc" + + SECTION .data +str1: db 'hello world!',13,10,0 +str1len: equ $-str1 +strlen: dq 0 + + SECTION .text +global _start +_start: + %include "header.asm.inc" + + mov rax, str1 + mov rbx, str1len + + sys_write 1, str1, str1len + nop + + sys_read 0, str1, str1len + nop + + mov [strlen], rax + mov [str1+rax], byte 0 + sys_write 1, str1, [strlen] + + %include "sysexit.asm.inc" diff --git a/slide-examples/ex20.asm b/slide-examples/ex20.asm new file mode 100644 index 0000000..f7ff619 --- /dev/null +++ b/slide-examples/ex20.asm @@ -0,0 +1,38 @@ +; CFG example +bits 64 + + SECTION .data +; empty + + SECTION .text + +add_two_numbers: + push rbp + mov rbp, rsp + mov rax, rdi + add rax, rsi + leave + ret + +global _start +_start: + mov rdi, 20 ; first parameter + mov rsi, 30 ; second parameter + + test rdi, rdi + js negative + + test rsi, rsi + js negative + + call add_two_numbers + jmp return + +negative: + mov rax, -1 + +return: + ; sys_exit(42) + mov rax,60 ; system call number (sys_exit) + mov rdi,42 ; system call return value + syscall diff --git a/slide-examples/ex21.asm b/slide-examples/ex21.asm new file mode 100644 index 0000000..fc69f6c --- /dev/null +++ b/slide-examples/ex21.asm @@ -0,0 +1,31 @@ +; CFG example +bits 64 + + SECTION .data +; empty + + SECTION .text +global _start +_start: + mov rbx, 3 ; a + mov rcx, 2 ; b + + cmp rbx, rcx ; a-b + je equal + ja greater + jb smaller + +equal: + mov rax, 0 + jmp return +greater: + mov rax, 1 + jmp return +smaller: + mov rax, -1 + +return: + ; sys_exit(42) + mov rdi,rax ; system call return value + mov rax,60 ; system call number (sys_exit) + syscall diff --git a/slide-examples/ex22.asm b/slide-examples/ex22.asm new file mode 100644 index 0000000..c50f7a6 --- /dev/null +++ b/slide-examples/ex22.asm @@ -0,0 +1,23 @@ +; CFG example +bits 64 + + SECTION .data +; empty + + SECTION .text +global _start +_start: + + mov rbx, 0 + test rbx, rbx + jz newBB1 + mov rbx, 0 +newBB1: + jmp return + mov rax, 0xdeadc0de + +return: + ; sys_exit(42) + mov rdi,rax ; system call return value + mov rax,60 ; system call number (sys_exit) + syscall diff --git a/slide-examples/ex23.asm b/slide-examples/ex23.asm new file mode 100644 index 0000000..a97e88e --- /dev/null +++ b/slide-examples/ex23.asm @@ -0,0 +1,185 @@ +; code optimizations +bits 64 + + SECTION .data +var_a: dq 0 + + SECTION .text +global _start +_start: + %include "header.asm.inc" + + mov rbx, 3 + mov rcx, 2 + jmp unswitched + + ; conditional moves (non-optimized) + cmp rbx, rcx + jae ge2 + mov rax, 0 + jmp end2 +ge2: + mov rax, 1 +end2: + ; conditional moves (optimized) + mov rax, 0 + mov rdx, 1 + cmp rbx, rcx + cmovae rax, rdx + + ; tertiary operator (exercise) + ; rax = (rbx >= rcx) ? 37 : 13; + xor rax, rax + cmp rbx, rcx + sbb rax, rax + and rax, -24 + add rax, 37 + + ; tertiary operator (non-optimized) + ; rax = (rbx >= rcx) ? 1 : 0; + cmp rbx, rcx + jae ge1 + mov rax, 0 + jmp end +ge1: + mov rax, 1 +end: + ; tertiary operator (optimized) + cmp rbx, rcx + sbb rax, rax + inc rax + + ; constant folding (non-optimized) + mov rax, 4 + add rax, 1 + ; constant folding (optimized) + mov rax, 5 + + ; common subexpression elimination (non-optimized) + xor rcx, rcx + mov rbx, 8 + ; first multiplication + mov rax, 4 + mul rbx + add rcx, rax + ; second multiplication + mov rax, 4 + mul rbx + add rcx, rax + ; third multiplication + mov rax, 4 + mul rbx + add rcx, rax + ; common subexpression elimination (optimized) + xor rcx, rcx + mov rbx, 8 + mov rax, 4 + mul rbx + add rcx, rax + add rcx, rax + add rcx, rax + + ; register uses (non-optimized) + mov rax, 0 + mov [var_a], rax + mov rax, 1 + mov [var_a], rax + mov rax, 2 + cmp [var_a], rax + je set_a_1 + jmp dont_set_a_1 +set_a_1: + mov rax, 1 + mov [var_a], rax +dont_set_a_1: + ; register uses (optimized) + mov rax, 0 + mov rax, 1 + cmp rax, 2 + je set_a_2 + jmp dont_set_a_2 +set_a_2: + mov rax, 1 +dont_set_a_2: + + ; faster assembly equivalents (non-optimized) + mov rax, 0 + mov rbx, 8 + mul rbx + mov rbx, 3 + mul rbx + ; faster assembly equivalents (optimized) + xor rax, rax ; = 0 + shl rax, 3 ; *= 8 + add rax, rax ; += a + add rax, rax ; += a (a *= 3) + + ; loop inversion (non-optimized) + xor rax, rax +repeat1: + cmp rax, 1000 + jae endloop1 + ; do something + inc rax + jmp repeat1 +endloop1: + ; loop inversion (optimized) + xor rax, rax + cmp rax, 1000 + jae endloop2 +repeat2: + inc rax + ; do something + cmp rax, 1000 + jb repeat2 +endloop2: + + ; loop unswitching +unswitch: + xor rax, rax + xor rdx, rdx + mov rcx, 3 + mov rbx, 1 +iter3: + cmp rax, rcx + jae endl3 + test rbx, rbx ; if + jnz do_else + add rdx, 1 ; b==0 + inc rax + jmp finif +do_else: + add rdx, 2 ; b!=1 + inc rax +finif: + jmp iter3 +endl3: + + nop + nop + nop + nop + + ; unswitched loop +unswitched: + xor rax, rax + xor rdx, rdx + mov rcx, 3 + mov rbx, 0 + test rbx, rbx + jnz iterB +iterA: + cmp rax, rcx + jae finuns + add rdx, 1 + inc rax + jmp iterA +iterB: + cmp rax, rcx + jae finuns + add rdx, 2 + inc rax + jmp iterB +finuns: + + %include "sysexit.asm.inc" diff --git a/slide-examples/ex24.asm b/slide-examples/ex24.asm new file mode 100644 index 0000000..4dfe8be --- /dev/null +++ b/slide-examples/ex24.asm @@ -0,0 +1,26 @@ +; assembly obfuscation +bits 64 + + SECTION .data +; empty + + SECTION .text +global _start +_start: + int3 + jmp s0 ; ---------| + dd 0x841f0f66 ; | prefix for a 9-byte-wide NOP + ; | --> will consume the next 5B +s0: xor eax, eax ; <--+ + jmp s1 ; ---------| + dd 0x841f0f66 ; | again, consumes a few bytes +s1: xor rbx, rbx ; <--+ + inc rbx + jmp s2 ; ---------| + dd 0x841f0f66 ; | again, consumes a few bytes +s2: mov rcx, 2 ; <----| + + nop + nop + nop + nop diff --git a/slide-examples/ex25.asm b/slide-examples/ex25.asm new file mode 100644 index 0000000..000f524 --- /dev/null +++ b/slide-examples/ex25.asm @@ -0,0 +1,41 @@ +; opaque predicates +bits 64 + + SECTION .data +; empty + + SECTION .text +extern steal_data; +extern google_me; + +global _start +_start: + + mov rbx, 0 + mov rcx, 2 + cmp rbx, rcx + je obf1 + + mov rax, 42 + mul rcx + cmp rax, rcx + je obf2 + jmp fin + +obf1: + xchg rax, rbx + mov rbx, 7 + div rbx + ; NOTE: call removed, otherwise ld fails to build + ;call steal_data + jmp obf2 + +obf2: + add rax, 13 + xor rax, rcx + ; NOTE: call removed, otherwise ld fails to build + ;call steal_data + ;call google_me + +fin: + nop diff --git a/slide-examples/ex26.asm b/slide-examples/ex26.asm new file mode 100644 index 0000000..3ed1bf8 --- /dev/null +++ b/slide-examples/ex26.asm @@ -0,0 +1,26 @@ +; variable splits/merges +bits 64 + + SECTION .data +; empty + + SECTION .text + +global _start +_start: + %include "header.asm.inc" + + ; original value + mov eax, 0x11223344 + + ; variable splitting + mov eax, 0x11000000 + add eax, 0x00220000 + add eax, 0x00003300 + add eax, 0x00000044 + + ; XOR obfuscation + mov eax, 0x22765B03 + xor eax, 0x33546847 + + %include "sysexit.asm.inc" diff --git a/slide-examples/ex27.asm b/slide-examples/ex27.asm new file mode 100644 index 0000000..40a229c --- /dev/null +++ b/slide-examples/ex27.asm @@ -0,0 +1,37 @@ +; obfuscation via unaligned instructions +bits 64 + +%idefine rip rel $ + + SECTION .data +; empty + + SECTION .text + +global _start +_start: + %include "header.asm.inc" + + xor rax, rax + + ; stores address of subsequent instruction to rax + call getpc + add rax, 8 + jmp rax + +;; this is the original assembly we'd like to include here +; 400081: 48 31 c0 xor rax,rax +; 400084: b9 0a 00 00 00 mov ecx,0xa +; 400089: 48 01 c8 add rax,rcx +; 40008c: e2 fb loop 0x400089 +; finish all unused bytes with NOPs (0x90). +; note, though, that the NOPs are never entered + mov rax, 0x90909005ebc03148 + mov rbx, 0x9003eb0000000ab9 + mov rcx, 0x909090fbe2c80148 + + %include "sysexit.asm.inc" + +getpc: + mov rax, [rsp] + ret diff --git a/slide-examples/ex28.asm b/slide-examples/ex28.asm new file mode 100644 index 0000000..57b46ed --- /dev/null +++ b/slide-examples/ex28.asm @@ -0,0 +1,34 @@ +; NOPs +bits 64 + +%idefine rip rel $ + + SECTION .data +; empty + + SECTION .text + +global _start +_start: + %include "header.asm.inc" + + ; normal NOP operation + nop + + ; 2-byte NOP operation + xchg al, al + xchg ebx, ebx + + ; 3-byte NOP operation + mov rax, rax + lea eax, [eax] + + ; 4-byte NOP operation + lea eax,[byte eax] + + ; 7-byte NOP operation + lea eax,[dword eax] + + + %include "sysexit.asm.inc" + diff --git a/slide-examples/ex29.asm b/slide-examples/ex29.asm new file mode 100644 index 0000000..c0b3ab3 --- /dev/null +++ b/slide-examples/ex29.asm @@ -0,0 +1,24 @@ +; division too large +bits 64 + + SECTION .data +; empty + + SECTION .text + +global _start +_start: + %include "header.asm.inc" + + ; maximum dividend + xor rax, rax + dec rax + xor rdx, rdx + dec rdx + + ; minimal divisor + mov rbx, 1 + div rbx + + %include "sysexit.asm.inc" + diff --git a/slide-examples/ex30.asm b/slide-examples/ex30.asm new file mode 100644 index 0000000..7a608ad --- /dev/null +++ b/slide-examples/ex30.asm @@ -0,0 +1,45 @@ +; strlen +bits 64 + + SECTION .data +mystr: db 't','e','s','t',0 + + SECTION .text + +global _start +_start: + %include "header.asm.inc" + + mov rcx, 0 + xor rbx, rbx + repnz sub rbx, 1 + + ; get reference to string + mov rdi, mystr + + ; move MAXINT to rcx + xor rcx, rcx + not rcx + + ; zero al + xor al, al + + cld ; clear direction flag --> + ; increment addresses during string search + + ; repne: perform (scasb) and repeat if (ne) is met + ; decrements rcx and aborts if rcx == 0 + ; scasb: compare byte at rdi with al and set flags; increment rdi + repne scasb + + ; option 1: current string index minus string start minus one + mov rax, rdi + sub rax, mystr + dec rax + + ; option 2: look at counter modified by repne (rcx) + not rcx + dec rcx + + %include "sysexit.asm.inc" + diff --git a/slide-examples/ex32.asm b/slide-examples/ex32.asm new file mode 100644 index 0000000..e2bebe2 --- /dev/null +++ b/slide-examples/ex32.asm @@ -0,0 +1,26 @@ +; strlen +bits 64 + + SECTION .data +myarr: times 2000 dd 0 + + SECTION .text + +global _start +_start: + ;%include "header.asm.inc" + + mov rcx, 100000000 ; loop counter + mov rbx, 3 ; alignment offset + xor r8, r8 ; i'th element in array + +lp: lea rax, [myarr+r8*4+rbx] + mov rdx, [rax] ; memory access + add r8, 1 + cmp r8, 1999 ; 2000-1, as we have offset + jb pl ; r8 still small enough, skip reset + xor r8, r8 ; reset array index to 0 +pl: loop lp + + %include "sysexit.asm.inc" + diff --git a/slide-examples/ex33.asm b/slide-examples/ex33.asm new file mode 100644 index 0000000..51c2580 --- /dev/null +++ b/slide-examples/ex33.asm @@ -0,0 +1,68 @@ +; strlen +bits 64 + +; program being used for Pin exercise + + SECTION .data +mystr1: db 'string1',0 +mystr2: db 'string2',0 +mystr3: db 'string3',0 + + SECTION .text + +myfun1: + push rbp + mov rbp, rsp + xor rax, rax + lea rax, [rax] + leave + ret + +myfun2: + push rbp + mov rbp, rsp + mov rcx, rsi ; second param, len in bytes + test rcx, rcx + jz .done +.encrypt: + xor byte [rdi], 0x42 ; first param, pointer to byte array that needs en- or decryption + inc rdi + loop .encrypt +.done: + leave + ret + +myfun3: + push rbp + mov rbp, rsp + xor rax, rax + add rax, rdi ; first param + add rax, rsi ; second param + leave + ret + +global _start +_start: + %include "macros.asm.inc" + ;%include "header.asm.inc" + + mov rdi, 5 + mov rsi, 10 + call myfun3 + + call myfun1 + call myfun1 + call myfun1 + call myfun1 + call myfun1 + + ; encrypt + mov rdi, mystr1 + mov rsi, 7 + call myfun2 + + ; write mystr1 to stdout + sys_write 1, mystr1, 7 + + %include "sysexit.asm.inc" + diff --git a/slide-examples/header.asm.inc b/slide-examples/header.asm.inc new file mode 100644 index 0000000..46ebbc0 --- /dev/null +++ b/slide-examples/header.asm.inc @@ -0,0 +1,9 @@ + nop ; add a few nops for synchronization + nop + nop + nop + nop + nop + nop + + int3 ; set software breakpoint to first instruction diff --git a/slide-examples/macros.asm.inc b/slide-examples/macros.asm.inc new file mode 100644 index 0000000..1e3b26e --- /dev/null +++ b/slide-examples/macros.asm.inc @@ -0,0 +1,17 @@ +; sys_write(fd, buf, buflen) +%macro sys_write 3 + mov rax,1 ; system call number + mov rdi,%1 ; arg1: fd + mov rsi,%2 ; arg2: buffer + mov rdx,%3 ; arg3: buflen + syscall +%endmacro + +; sys_read(fd, buf, buflen) +%macro sys_read 3 + mov rax,0 ; system call number + mov rdi,%1 ; arg1: fd + mov rsi,%2 ; arg2: buffer + mov rdx,%3 ; arg3: buflen + syscall +%endmacro diff --git a/slide-examples/sysexit.asm.inc b/slide-examples/sysexit.asm.inc new file mode 100644 index 0000000..65aa1ca --- /dev/null +++ b/slide-examples/sysexit.asm.inc @@ -0,0 +1,10 @@ + ; use this to show that actual code has ended + nop + nop + nop + nop + + ; sys_exit(42) + mov rax,60 ; system call number (sys_exit) + mov rdi,42 ; system call return value + syscall