Inital (stash) commit

This commit is contained in:
2023-05-12 22:23:58 +02:00
commit f86ed5fda6
14 changed files with 558 additions and 0 deletions

17
asm/Makefile Normal file
View File

@@ -0,0 +1,17 @@
.PHONY: clean
SOOPTS := -shared -nostdlib
OUT := out
test: $(OUT)
$(CC) $(SOOPTS) pt.s -o $(OUT)/pt.so
build: $(OUT)
$(CC) $(SOOPTS) loud.s -o $(OUT)/libloud.so
$(OUT):
mkdir $(OUT)
clean:
$(RM) -r $(OUT)

182
asm/fork.s Normal file
View File

@@ -0,0 +1,182 @@
.intel_syntax noprefix
.file "fork.s"
.text
.data
.section .rodata
child_msg:
.string "Made a child!\n"
child_wait:
.string "Child attach!\n"
fuck:
.string "Fuck you!\n"
.text
.globl main
.type main, @function
main:
# fork
mov rax, 57
syscall
cmp rax, 0
jl no_fork
jg ctrl
child:
# trace me
mov rax, 101
mov rdi, 0
xor rsi, rsi
xor rdx, rdx
xor r10, r10
syscall
# print
mov rax, 1
mov rdi, 1
lea rsi, [rip + child_wait]
mov rdx, 14
syscall
# wait!
mov rax, 110
syscall
mov rdi, rax
mov rax, 61
xor rsi, rsi
xor rdx, rdx
xor r10, r10
syscall
cmp rax, 0
jge print
.rept 42069
nop
.endr
print:
mov rax, 1
mov rdi, 1
lea rsi, [rip + child_msg]
mov rdx, 14
syscall
ret
.data
pid:
.quad 0
regsptr:
.quad 0
.section .rodata
ctrl_msg:
.string "Parent is watching!\n"
.text
ctrl:
# store ptrs
mov [rip + pid], rax
mov rdi, 216
call malloc
mov [rip + regsptr], rax
# wait and set ptrace option
call wait
mov rax, 101
mov rdi, 0x4200
mov rsi, [rip + pid]
xor rdx, rdx
mov r10, 0x100000
syscall
mov rax, 1
mov rdi, 2
lea rsi, [rip + ctrl_msg]
mov rdx, 20
syscall
loop:
# ptrace enter syscall
mov rax, 101
mov rdi, 24
mov rsi, [rip + pid]
xor rdx, rdx
xor r10, r10
syscall
cmp rax, 0
jl ctrl_err
call wait
cmp rax, 0
jl ctrl_err
# fetch child regs
mov rax, 101
mov rdi, 12
mov rsi, [rip + pid]
xor rdx, rdx
lea r10, [rip + regsptr]
syscall
cmp rax, 0
jl ctrl_err
# skip non write syscalls
cmp rax, 1
jne skip
cmp rdi, 2
jg skip
mov rax, 1
mov rdi, 2
lea rsi, [rip + ctrl_err_msg]
mov rdx, 9
syscall
skip:
mov rax, 101
mov rdi, 24
mov rsi, [rip + pid]
xor rdx, rdx
xor r10, r10
syscall
cmp rax, 0
jl ctrl_err
jmp loop
.data
.section .rodata
parent_wait:
.string "Parent waiting!\n"
.text
wait:
mov rax, 1
mov rdi, 2
mov rsi, [rip + parent_wait]
mov rdx, 16
syscall
mov rax, 61
mov rdi, [rip + pid]
xor rsi, rsi
xor rdx, rdx
xor r10, r10
syscall
cmp rax, 0
jl ctrl_err
ret
.data
.section .rodata
ctrl_err_msg:
.string "Fuck you!\n"
.text
ctrl_err:
mov rax, 1
mov rdi, 2
mov rsi, [rip + ctrl_err_msg]
mov rdx, 10
syscall
mov rax, 60
mov rdi, 69
syscall
.data
.section .rodata
no_fork_msg:
.string "Unable to fork!\n"
.text
no_fork:
mov rax, 1
mov rdi, 2
mov rsi, [rip + no_fork_msg]
mov rdx, 15
syscall
mov rax, 60
mov rdi, 420
syscall

19
asm/loud.s Normal file
View File

@@ -0,0 +1,19 @@
.intel_syntax noprefix
.file "lOuD.S"
.text
.section .init_array
.quad pre
.text
.globl pre
.type pre, @function
pre:
# .init_array shit to prevent segv
pushq rbp
movq rbp, rsp
subq rsp, 16
# do fun stuff
leave
ret

170
asm/pt.s Normal file
View File

@@ -0,0 +1,170 @@
.intel_syntax noprefix
.file "pt.s"
.text
# pointers in the .init_array section of shared object files are called by the dynamic linker at load
# before main and even _start of the actual excecutable
.section .init_array
.quad pre
# everything before the next comment is needed for correct linking
# and to run some arbitrary code before an excecutable
.text
.globl pre
.type pre, @function
pre:
pushq rbp
movq rbp, rsp
subq rsp, 16
# fork and setup ptrace
mov rax, 57
syscall
cmp rax, 0 # zero means we're a child
jl err_nofork # negative means we were unable to fork
je leave # leave to the actual executable we're fucking with
jg ctrl # positive indicates we're the parent-/inital-process
# and just in case (this should never run, unless jumed to by address)
jmp err_nofork
# run some actual program this shared object unfortunately got dynamically loaded into
leave:
# ptrace me first
mov rax, 101
xor rdi, rdi
xor rsi, rsi
xor rdx, rdx
xor r10, r10
syscall
# then leave
leave
ret
# hijack and fuck with all write syscalls
ctrl:
# store child pid
mov [rip + pid], rax
# malloc some mem to store captured register values from child
mov rdi, 216 # size of user_regs_struct on x86_64 machines running Linux
call malloc
mov [rip + regsptr], rax
call wait
# ptrace set option exit kill
mov rax, 101
mov rdi, 0x4200
mov rsi, [rip + pid]
mov rdx, 0
mov r10, 0x100000
syscall
ctrl_loop:
# ptrace enter syscall
mov rax, 101
mov rdi, 24
mov rsi, [rip + pid]
mov rdx, 0
mov r10, 0
syscall
cmp rax, -1
jne err_ctrl
call wait
cmp rax, -1
jne err_ctrl
# fetch register values from child about to perform a syscall
mov rax, 101
mov rdi, 12
mov rsi, [rip + pid]
mov rdx, 0
lea r10, [rip + regsptr]
syscall
# don't fuck with non write syscalls
cmp rax, 1
jne skip
# also skip if write destination ain't std-out/-err
cmp rdi, 2
jg skip
# the syscall is a write to std-out/-err
mov rax, 1
mov rdi, 2
lea rsi, [rip + msg]
mov rdx, 10
syscall
skip:
# let the child complete the syscall we captured
mov rax, 101
mov rdi, 24
mov rsi, [rip + pid]
mov rdx, 0
mov r10, 0
syscall
cmp rax, -1
jne err_ctrl
jmp ctrl_loop
# waitid syscall for parent to sync with / wait for child
wait:
mov rax, 247
mov rdi, [rip + pid]
mov rsi, 0
mov rdx, 0
syscall
ret
# ptrace syscall with common args for parent-/ctrl-process
ptrace:
mov rax, 101
mov rsi, [rip + pid]
syscall
ret
# exit syscall
exit:
mov rax, 60
syscall
err_ctrl:
mov rax, 1
mov rdi, 2
lea rsi, [rip + msg]
mov rdx, 10
syscall
mov rax, 60
mov rdi, 42069
syscall
# write no_fork to stderr and return
# hopefully to the start of some executable
err_nofork:
mov rax, 1
mov rdi, 2
lea rsi, [rip + no_fork]
mov rdx, 15
syscall
leave
ret
.section .data
regsptr:
.quad 0
pid: # store child process pid here
.quad 0
# user_regs_struct with labels to the parts we care about
#regs:
# .fill 27 8 0
# .fill 10 8
#_rax:
# .fill 1 8
# .fill 1 8
#_rdx:
# .fill 1 8
#_rsi:
# .fill 1 8
#_rdi:
# .fill 1 8
# .fill 12 8
.section rodata
no_fork:
.string "Unable to fork!\n"
msg:
.string "Fuck you!\n"