Inital (stash) commit

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

20
LICENSE Normal file
View File

@ -0,0 +1,20 @@
Copyright (c) 2023 Sivert V. Sæther
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

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"

1
hs/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
dist-newstlye

19
hs/csrc/pre.c Normal file
View File

@ -0,0 +1,19 @@
#include <unistd.h>
#include <string.h>
extern void hs_init(int*, char***);
extern void hs_exit();
extern void setup();
int argc = 0;
char* argv[] = { NULL };
char** pargv = argv;
void __attribute__((constructor)) pre() {
hs_init(&argc, &pargv);
setup();
}
void __attribute__((destructor)) post() {
hs_exit();
}

52
hs/loud.cabal Normal file
View File

@ -0,0 +1,52 @@
cabal-version: 3.4
name: loud
version: 0.1.0
-- synopsis:
-- description:
license: MIT
license-file: LICENSE
author: Sivert V. Sæther
maintainer: gmail@sivert.pw
category: Prank
build-type: Simple
extra-source-files: cbits
common warnings
ghc-options: -Wall
foreign-library loud
type: native-shared
other-extensions: CApiFFI
other-modules: Loud
build-depends:
bytestring ^>= 0.11.4.0,
vector ^>= 0.13.0.0,
base ^>= 4.18.0.0
hs-source-dirs: src
-- asm-sources: pre.s
c-sources: csrc/pre.c
default-language: GHC2021
library
import: warnings
exposed-modules: Loud
other-extensions: CApiFFI
build-depends:
bytestring ^>= 0.11.4.0,
vector ^>= 0.13.0.0,
base ^>= 4.18.0.0,
mmap ^>= 0.5.9
hs-source-dirs: src
asm-sources: pre.s
-- c-sources: csrc/pre.c
default-language: GHC2021
test-suite loud-test
import: warnings
default-language: GHC2021
type: exitcode-stdio-1.0
hs-source-dirs: test
main-is: Main.hs
build-depends:
base ^>=4.18.0.0,
loud

23
hs/pre.s Normal file
View File

@ -0,0 +1,23 @@
.intel_syntax noprefix
.file "pre.s"
.text
.extern hs_init
.extern setup
.section .init_array, "aw"
.quad pre
.text
.global pre
.type pre, @function
pre:
pushq rbp
movq rbp, rsp
subq rsp, 16
call hs_init
call setup
leave
ret

22
hs/src/Loud.hs Normal file
View File

@ -0,0 +1,22 @@
module Loud ( write ) where
import Data.String ( fromString )
import Data.ByteString
import Foreign.Ptr
import Foreign.C
setup :: IO ()
setup = putStrLn "Fuck you!"
write :: IO Int
write = do
let msg = "Hello, Haskell!\n"
useAsCStringLen (fromString msg :: ByteString) sus_write
sus_write :: CStringLen -> IO Int
sus_write (cstr, len) = _syscall 1 1 (minusPtr cstr nullPtr) len 0 0
foreign import ccall "syscall"
_syscall :: Int -> Int -> Int -> Int -> Int -> Int -> IO Int
foreign export ccall setup :: IO ()

6
hs/test/Main.hs Normal file
View File

@ -0,0 +1,6 @@
module Main (main) where
import Loud ( write )
main :: IO Int
main = write

2
rs/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/target
/Cargo.lock

11
rs/Cargo.toml Normal file
View File

@ -0,0 +1,11 @@
[package]
name = "loud"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
[dependencies]
libc = "0.2.144"
ctor = "0.2.0"

14
rs/src/lib.rs Normal file
View File

@ -0,0 +1,14 @@
#[ctor::ctor]
fn pre() {
println!("Fuck you");
}
/*
#[no_mangle]
unsafe extern "C" fn write(fd: libc::c_int, buf: *const libc::c_void, len: libc::size_t) -> libc::ssize_t {
println!("hook'd!");
libc::write(fd, buf, len)
}
*/
#[cfg(test)]
mod test;