Merge branch 'master' of ssh://git.cs.tu-dortmund.de:2222/christian.rossow/sfl-examples

This commit is contained in:
crossow 2023-12-20 13:37:33 +01:00
commit 1204c70c2d
37 changed files with 1233 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -0,0 +1,9 @@
nop ; add a few nops for synchronization
nop
nop
nop
nop
nop
nop
int3 ; set software breakpoint to first instruction

View File

@ -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

View File

@ -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