added slide examples
This commit is contained in:
parent
58562dc628
commit
227c01cefe
|
@ -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
|
|
@ -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
|
|
@ -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"
|
|
@ -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"
|
|
@ -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"
|
|
@ -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"
|
|
@ -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"
|
|
@ -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"
|
|
@ -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"
|
|
@ -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"
|
|
@ -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"
|
|
@ -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"
|
|
@ -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"
|
|
@ -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"
|
|
@ -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"
|
|
@ -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"
|
|
@ -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"
|
|
@ -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"
|
|
@ -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"
|
|
@ -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"
|
|
@ -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"
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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"
|
|
@ -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
|
|
@ -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
|
|
@ -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"
|
|
@ -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
|
|
@ -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"
|
||||
|
|
@ -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"
|
||||
|
|
@ -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 <instr> (scasb) and repeat if <cond> (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"
|
||||
|
|
@ -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"
|
||||
|
|
@ -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"
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
nop ; add a few nops for synchronization
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
int3 ; set software breakpoint to first instruction
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue