rust-teeny-nostd: compare with asm
This commit is contained in:
@@ -5,4 +5,4 @@ PoC's showing how rust can do stuff people often critiquize it about.
|
|||||||
# Members
|
# Members
|
||||||
|
|
||||||
- `rust-teeny`: A rust std binary only **8.0 KiB** big, achieves so by `abort()`ing instead of having graceful error logging, panics shouldn't have any source information nor should there be `Debug` implementations, no debug symbols and any potential path reference to `$PWD` is renamed. It carries a shellcode payload loaded into memory and executed from memory.
|
- `rust-teeny`: A rust std binary only **8.0 KiB** big, achieves so by `abort()`ing instead of having graceful error logging, panics shouldn't have any source information nor should there be `Debug` implementations, no debug symbols and any potential path reference to `$PWD` is renamed. It carries a shellcode payload loaded into memory and executed from memory.
|
||||||
- `rust-teeny-nostd`: Same as avobe but `no_std`, **4.1 KiB**.
|
- `rust-teeny-nostd`: Same as avobe but `no_std`, **4.1 KiB**. Can't even get raw assembly as small, rust wins by 16 Bytes, `.text` is the same size but rust beats with dynamic table sections and such.
|
||||||
|
|||||||
@@ -2,6 +2,10 @@ alias b := build
|
|||||||
alias s := stat
|
alias s := stat
|
||||||
alias z := stat-size
|
alias z := stat-size
|
||||||
|
|
||||||
|
alias basm := build-asm
|
||||||
|
alias sasm := stat-asm
|
||||||
|
alias zasm := stat-size-asm
|
||||||
|
|
||||||
target := "x86_64-unknown-linux-gnu"
|
target := "x86_64-unknown-linux-gnu"
|
||||||
|
|
||||||
build:
|
build:
|
||||||
@@ -16,7 +20,7 @@ build:
|
|||||||
-Cpanic=immediate-abort --remap-path-prefix=$PWD=[src] \
|
-Cpanic=immediate-abort --remap-path-prefix=$PWD=[src] \
|
||||||
" cargo \
|
" cargo \
|
||||||
\
|
\
|
||||||
-Zbuild-std=core,alloc,std,panic_abort \
|
-Zbuild-std=core,panic_abort \
|
||||||
-Zbuild-std-features="optimize_for_size" \
|
-Zbuild-std-features="optimize_for_size" \
|
||||||
\
|
\
|
||||||
b -r --target {{ target }}
|
b -r --target {{ target }}
|
||||||
@@ -32,8 +36,18 @@ build:
|
|||||||
|
|
||||||
# Not sure why .gnu.version and .gnu.hash don't break if I remove them in my machine, but that's very relative and its related to dynamic loading, but they could reduce size by `0.2 KiB`
|
# Not sure why .gnu.version and .gnu.hash don't break if I remove them in my machine, but that's very relative and its related to dynamic loading, but they could reduce size by `0.2 KiB`
|
||||||
|
|
||||||
|
build-asm:
|
||||||
|
clang -Wl,--gc-sections -Wl,--as-needed -Wl,--strip-all -Wl,--build-id=none -s -fuse-ld=lld -Oz same.S -o target/asm
|
||||||
|
strip --strip-all --strip-unneeded -R .comment -R .note.\* -R .eh_frame\* target/asm
|
||||||
|
|
||||||
stat:
|
stat:
|
||||||
stat target/{{ target }}/release/rust-teeny
|
stat target/{{ target }}/release/rust-teeny
|
||||||
|
|
||||||
|
stat-asm:
|
||||||
|
stat target/asm
|
||||||
|
|
||||||
stat-size:
|
stat-size:
|
||||||
stat target/{{ target }}/release/rust-teeny -c "%s" | numfmt --to=iec-i
|
stat target/{{ target }}/release/rust-teeny -c "%s" | numfmt --to=iec-i
|
||||||
|
|
||||||
|
stat-size-asm:
|
||||||
|
stat target/asm -c "%s" | numfmt --to=iec-i
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
.intel_syntax noprefix
|
||||||
|
.globl main
|
||||||
|
|
||||||
|
.section .rodata
|
||||||
|
SHELLCODE: .ascii "\x31\xC0\xFF\xC0\x89\xC7\x48\x8D\x35\x08\x00\x00\x00\xBA\x0E\x00\x00\x00\x0F\x05\xC3Hello, World!\n"
|
||||||
|
SHELLCODE_end:
|
||||||
|
|
||||||
|
SHELLCODE_len = SHELLCODE_end - SHELLCODE
|
||||||
|
|
||||||
|
#define PROT_READ 0x1
|
||||||
|
#define PROT_WRITE 0x2
|
||||||
|
#define PROT_EXEC 0x4
|
||||||
|
|
||||||
|
#define MAP_PRIVATE 0x2
|
||||||
|
#define MAP_ANONYMOUS 0x20
|
||||||
|
|
||||||
|
#define MAP_FAILED -1
|
||||||
|
|
||||||
|
.section .text
|
||||||
|
main:
|
||||||
|
#define VAR1 [rsp]
|
||||||
|
sub rsp, 8
|
||||||
|
|
||||||
|
// rax = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)
|
||||||
|
xor edi, edi
|
||||||
|
mov rsi, OFFSET SHELLCODE_len
|
||||||
|
mov edx, PROT_READ | PROT_WRITE
|
||||||
|
mov ecx, MAP_PRIVATE | MAP_ANONYMOUS
|
||||||
|
mov r8, -1
|
||||||
|
xor r9d, r9d
|
||||||
|
call QWORD PTR [mmap@GOTPCREL + rip]
|
||||||
|
mov VAR1, rax
|
||||||
|
|
||||||
|
cmp rax, MAP_FAILED
|
||||||
|
je .abort
|
||||||
|
|
||||||
|
// rax = mmove(VAR1, SHELLCODE, SHELLCODE_len)
|
||||||
|
mov rdi, rax
|
||||||
|
lea rsi, [rip+SHELLCODE]
|
||||||
|
mov rdx, OFFSET SHELLCODE_len
|
||||||
|
call QWORD PTR [memmove@GOTPCREL + rip]
|
||||||
|
|
||||||
|
// rax = mprotect(exec_mem, content.len(), PROT_READ | PROT_EXEC)
|
||||||
|
mov rdi, rax
|
||||||
|
mov rsi, OFFSET SHELLCODE_len
|
||||||
|
mov edx, PROT_READ | PROT_EXEC
|
||||||
|
call QWORD PTR [mprotect@GOTPCREL + rip]
|
||||||
|
|
||||||
|
test rax, rax
|
||||||
|
jnz .abort
|
||||||
|
|
||||||
|
mov rax, VAR1
|
||||||
|
call qword ptr VAR1
|
||||||
|
|
||||||
|
// exit(0)
|
||||||
|
xor edi, edi
|
||||||
|
call QWORD PTR [exit@GOTPCREL + rip]
|
||||||
|
|
||||||
|
.abort:
|
||||||
|
call QWORD PTR [abort@GOTPCREL + rip]
|
||||||
Reference in New Issue
Block a user