Inital (stash) commit
This commit is contained in:
commit
f86ed5fda6
20
LICENSE
Normal file
20
LICENSE
Normal 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
17
asm/Makefile
Normal 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
182
asm/fork.s
Normal 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
19
asm/loud.s
Normal 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
170
asm/pt.s
Normal 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
1
hs/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
dist-newstlye
|
19
hs/csrc/pre.c
Normal file
19
hs/csrc/pre.c
Normal 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
52
hs/loud.cabal
Normal 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
23
hs/pre.s
Normal 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
22
hs/src/Loud.hs
Normal 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
6
hs/test/Main.hs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
module Main (main) where
|
||||||
|
|
||||||
|
import Loud ( write )
|
||||||
|
|
||||||
|
main :: IO Int
|
||||||
|
main = write
|
2
rs/.gitignore
vendored
Normal file
2
rs/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/target
|
||||||
|
/Cargo.lock
|
11
rs/Cargo.toml
Normal file
11
rs/Cargo.toml
Normal 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
14
rs/src/lib.rs
Normal 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;
|
Loading…
x
Reference in New Issue
Block a user