mirror of https://gitlab.com/PoroCYon/vondehi
Also make the formatting a bit nicer, remove obsolete comments, and add a link to autovndh.py in the README
This commit is contained in:
parent
1e8dd70a46
commit
13f7ed75d8
2
LICENSE
2
LICENSE
|
@ -1,4 +1,4 @@
|
|||
Copyright 2018 PoroCYon.
|
||||
Copyright 2018-2019 PoroCYon and contributors.
|
||||
|
||||
This software is provided "as is", without any express or implied warranties,
|
||||
including but not limited to the implied warranties of merchantability and
|
||||
|
|
9
Makefile
9
Makefile
|
@ -1,8 +1,8 @@
|
|||
|
||||
default: test
|
||||
|
||||
testbin: test.c
|
||||
$(CC) -static -nostdlib -nostartfiles -O3 -s -o "$@" "$<"
|
||||
testbin: hello.c #test.c
|
||||
$(CC) -O3 -s -o "$@" "$<" #-static -nostdlib -nostartfiles
|
||||
|
||||
%.gz: %
|
||||
< "$<" gzip -cnk9 > "$@"
|
||||
|
@ -10,11 +10,12 @@ testbin: test.c
|
|||
< "$<" lzma --format=lzma -9 --extreme --lzma1=preset=9,lc=1,lp=0,pb=0 --keep --stdout > "$@"
|
||||
|
||||
vondehi: vondehi.asm
|
||||
nasm -fbin -o"$@" "$<"
|
||||
nasm -fbin -DNO_CHEATING -o"$@" "$<"
|
||||
chmod +x "$@"
|
||||
|
||||
test: vondehi testbin.lzma
|
||||
cat $^ > test && chmod +x test && strace -f ./test; echo $?
|
||||
-cat $^ > test && chmod +x test && strace -f ./test
|
||||
wc -c "$<"
|
||||
|
||||
.PHONY: default test
|
||||
|
||||
|
|
39
README.md
39
README.md
|
@ -10,18 +10,20 @@ but even smaller. It doesn't have a 64-bit version, though.**
|
|||
|
||||
## Comparison
|
||||
|
||||
| mode etc. | vondehi | trident | Fishypack | sh-based unpacker |
|
||||
|:------------ | -------:| -------:| ---------:| -----------------:|
|
||||
| gzip, 32-bit | 161 | 172 | 179? (198?) | 48 to 72 |
|
||||
| xz, 32-bit | 164 (168*) | 179 | 186 | 48 to 72 |
|
||||
| gzip, 64-bit | N/A | 208 | 208? | 48 to 72 |
|
||||
| xz, 64-bit | N/A | 217 | 217 | 48 to 72 |
|
||||
| Preserves args | Y | N | tries to | can, but often not |
|
||||
| Min. platform | Linux 3.19 | Linux 2.27 | Linux 2.27 | Most Unices |
|
||||
| Touches filesystem | N | N | N | Y |
|
||||
| mode etc. | vondehi | trident | Fishypack | sh-based unpacker |
|
||||
|:------------------ | ----------:| ----------:| -----------:| ------------------:|
|
||||
| gzip, 32-bit | 161 | 172 | 179? (198?) | 48 to 72 |
|
||||
| xz, 32-bit | 164 (168*) | 179 | 186 | 48 to 72 |
|
||||
| gzip, 64-bit | N/A | 208 | 208? | 48 to 72 |
|
||||
| xz, 64-bit | N/A | 217 | 217 | 48 to 72 |
|
||||
| Preserve arg & env | Y/N | N | tries to | can, but often not |
|
||||
| Min. platform | Linux 3.19 | Linux 2.27 | Linux 2.27 | Most Unices |
|
||||
| Touches filesystem | N | N | N | Y |
|
||||
|
||||
\*: with `NO_UBUNTU_COMPAT` **dis**abled.
|
||||
|
||||
All values are with `NO_CHEATING` **dis**abled. If this is enabled, add 5 bytes.
|
||||
|
||||
The exact size of a shell-based unpacker depends on the exact impmelentation,
|
||||
many variations exist. 'xz' means the usage of `xzcat` instead of `zcat`,
|
||||
the former supports both `xz`- and `lzma`-compressed data.
|
||||
|
@ -36,22 +38,31 @@ kernel is 64-bit and supports the 32-bit emulation layer.
|
|||
|
||||
```
|
||||
nasm -fbin -o$out vondehi.asm [-DUSE_GZIP] [-DTAG="j0!"] [-DNO_UBUNTU_COMPAT] \
|
||||
[-DUSE_VFORK]
|
||||
[-DUSE_VFORK] [-DNO_CHEATING]
|
||||
cat $out $intro_compressed > $final
|
||||
```
|
||||
|
||||
See also [autovndh.py](https://pcy.be/tmp/src/autovndh.py), a script that
|
||||
brute-forces all compression parameters to find the optimal binary.
|
||||
|
||||
### Settings
|
||||
|
||||
* `USE_GZIP` (default off): use `gzip` (`/bin/zcat`) instead of `xz`
|
||||
(`/usr/bin/xzcat`).
|
||||
* `NO_UBUNTU_COMPAT` (default off): assume `/bin` is the same as `/usr/bin`.
|
||||
Originally named like this because on my machine, `/bin` is linked t
|
||||
Originally named like this because on my machine, `/bin` is linked to
|
||||
`/usr/bin`, but on the Revision compomachine (which runs Ubuntu), it isn't.
|
||||
* `NO_FILE_MANAGER_COMPAT` (default off): save two bytes by putting instructions in the EI_CLASS and EI_DATA fields of the ELF header. Causes executables packed with vondehi to not be recognized as executable in file managers.
|
||||
* `NO_FILE_MANAGER_COMPAT` (default off): save two bytes by putting
|
||||
instructions in the EI_CLASS and EI_DATA fields of the ELF header. Causes
|
||||
executables packed with vondehi to not be recognized as executable in file
|
||||
managers.
|
||||
* `USE_VFORK` (default off): use `vfork(2)` instead of `fork(2)`. I hope you
|
||||
know what you're doing when you enable this.
|
||||
* `TAG` (default empty): add a vanity tag right before the compressed data.
|
||||
Only use this when you have bytes to spare, of course.
|
||||
* `NO_CHEATING` (default off): don't assume file descriptor numbers and
|
||||
properly pass arguments and environment variable to the payload. You need
|
||||
this if you're running on Wayland. Costs 5 bytes.
|
||||
|
||||
## How to debug it if it doesn't work
|
||||
|
||||
|
@ -71,6 +82,10 @@ cat $out $intro_compressed > $final
|
|||
* Faemiyah, yx, etc., for small sh-based unpackers (yx: nice trick with
|
||||
the script partially embedded in the gzip file!)
|
||||
|
||||
### Extra thanks to:
|
||||
|
||||
* blackle, greg, and others for contributions
|
||||
|
||||
## License
|
||||
|
||||
[SAL](LICENSE).
|
||||
|
|
218
vondehi.asm
218
vondehi.asm
|
@ -1,7 +1,5 @@
|
|||
|
||||
; vim: set ft=nasm noet:
|
||||
|
||||
;%define USE_GZIP
|
||||
; vim: set ft=nasm noet ts=4:
|
||||
|
||||
%define STDIN_FILENO 0
|
||||
%define STDOUT_FILENO 1
|
||||
|
@ -26,159 +24,143 @@ bits 32
|
|||
|
||||
org 0xEBDB0000
|
||||
|
||||
ehdr: ;~e_ident
|
||||
; jg short 0x47 (inc ebp) ; dec esp ; inc esi
|
||||
db 0x7F,"ELF" ;!E_MAGIC
|
||||
ehdr: ;~e_ident
|
||||
; jg short 0x47 (inc ebp) ; dec esp ; inc esi
|
||||
db 0x7F,"ELF" ;!EI_MAGIC
|
||||
%ifndef NO_FILE_MANAGER_COMPAT
|
||||
db 0x01 ;E_CLASS
|
||||
db 0x01 ;E_DATA
|
||||
db 0x01 ;!EI_CLASS
|
||||
db 0x01 ;!EI_DATA
|
||||
%endif
|
||||
_parent.0:
|
||||
%ifdef NO_FILE_MANAGER_COMPAT
|
||||
xor ebx, ebx
|
||||
xor ebx, ebx ; EI_CLASS, EI_DATA
|
||||
%endif
|
||||
xchg eax, edi ;edi is zero now and will be overwritten eventually
|
||||
mov al, SYS_waitpid
|
||||
int 0x80
|
||||
lea esi, [esp+0x08]
|
||||
xchg eax, esi ; esi is zero now ; EI_VERSION
|
||||
mov al, SYS_waitpid ; EI_OSABI, EI_ABIVERSION
|
||||
int 0x80 ; EI_PAD1, EI_PAD2
|
||||
|
||||
db 0x3D ; cmp eax, ...
|
||||
dw 2 ;!e_type
|
||||
dw 3 ;!e_machine
|
||||
%ifdef NO_CHEATING
|
||||
pop eax ; EI_PAD3
|
||||
sub esp, 0x18 ; FIXME: HACK (see below) ; EI_PAD4..6
|
||||
%else
|
||||
lea esi, [esp + 0x08] ; EI_PAD3..6
|
||||
%endif
|
||||
|
||||
db 0x3D ; cmp eax, ... ; EI_PAD7
|
||||
dw 2 ;!e_type
|
||||
dw 3 ;!e_machine
|
||||
_parent.1:
|
||||
mov edx, esp
|
||||
lea ecx, [ebp+__strempty-__self+EBP_bias]
|
||||
add bl, bl
|
||||
db 0xEB ; jmp short _parent.2
|
||||
;dd _start ;!e_entry
|
||||
dd phdr-ehdr ;!e_phoff ; 0x33
|
||||
%ifdef NO_CHEATING
|
||||
push edi ; subs 4 from esp, so we need to take this into account in the
|
||||
; HACK lines as well ; e_version0
|
||||
lea esi, [esp+4*eax+0x20] ; FIXME: HACK ; e_version1..3, !e_entry0
|
||||
; the last byte here^^^^ needs to be 0x20 to have a correct entrypoint
|
||||
; if you want to optimize this, you probably want to move the entrypt
|
||||
; somewhere else, but that means you have to change everything else
|
||||
; with it as well, so good luck.
|
||||
%else
|
||||
mov edx, esp ; e_version0..1
|
||||
lea ecx, [ebp+__strempty-__self+EBP_bias] ; e_version2..3, !e_entry0
|
||||
%endif
|
||||
add bl, bl ;!e_entry1..2
|
||||
db 0xEB ; jmp short _parent.2 ;!e_entry3
|
||||
dd phdr-ehdr ; 0x33 ;!e_phoff
|
||||
_start:
|
||||
mov ax, SYS_memfd_create
|
||||
mov ebx, esp
|
||||
jmp short _start.1
|
||||
;dd 0 ; e_shoff
|
||||
;dd 0 ; e_flags
|
||||
dw ehdr.end-ehdr;!e_ehdrsize ; 0x34 0x00
|
||||
dw phdr.end-phdr;!e_phentsize ; 0x20 0x00
|
||||
|
||||
dw 1 ;!e_phnum
|
||||
mov ax, SYS_memfd_create ; e_shoff
|
||||
mov ebx, esp ; e_flags0..1
|
||||
jmp short _start.1 ; e_flags2..3
|
||||
dw ehdr.end-ehdr ; 0x34 0x00 ;!e_ehdrsize
|
||||
dw phdr.end-phdr ; 0x20 0x00 ;!e_phentsize
|
||||
dw 1 ;!e_phnum
|
||||
_start.1:
|
||||
int 0x80
|
||||
pop eax
|
||||
jmp short _start.2
|
||||
;dw 0 ; e_shentsize
|
||||
;dw 0 ; e_shnum
|
||||
;dw 0 ; e_shstrndx
|
||||
int 0x80 ; e_shentsize
|
||||
%ifdef NO_CHEATING
|
||||
xchg edi, eax ; e_shnum0
|
||||
%else
|
||||
pop eax ; e_shnum0
|
||||
%endif
|
||||
jmp short _start.2 ; e_shnum1, e_shstrndx0
|
||||
phdr:
|
||||
db 1 ;!p_type
|
||||
db 1 ;! p_type0 ; e_shstrndx1
|
||||
ehdr.end:
|
||||
times 3 db 0
|
||||
dd 0 ;!p_offset
|
||||
dd ehdr ;!p_vaddr
|
||||
times 3 db 0 ;! p_type1
|
||||
dd 0 ;!p_offset
|
||||
dd ehdr ;!p_vaddr
|
||||
_start.2:
|
||||
mov ebp, __self-EBP_bias
|
||||
;dd ehdr ; p_paddr
|
||||
jmp short _start.3
|
||||
db 0,0xEB
|
||||
;dd filesize ;~p_filesz
|
||||
jmp short _start.3+4
|
||||
db 0
|
||||
;dd filesize ;~p_memsz
|
||||
db 5 ;~p_flags
|
||||
mov ebp, __self-EBP_bias;!p_paddr, p_filesz0
|
||||
jmp short _start.3 ;~p_filesz1..2
|
||||
db 0 ;~p_filesz3
|
||||
db 0xEB ;~p_memsz0
|
||||
jmp short _start.3+4 ;~p_memsz1..2
|
||||
db 0 ;~p_memsz3
|
||||
db 5 ;~p_flags0
|
||||
_start.3:
|
||||
%ifdef USE_VFORK
|
||||
mov al, SYS_vfork
|
||||
mov al, SYS_vfork ;~p_flags1..2
|
||||
%else
|
||||
mov al, SYS_fork
|
||||
mov al, SYS_fork ;~p_flags1..2
|
||||
%endif
|
||||
jmp short _start.4
|
||||
jmp short _start.4 ;~p_flags3, p_align0
|
||||
|
||||
;dd 5 ;~p_flags
|
||||
;db 0 ; p_align
|
||||
_parent.2:
|
||||
mov bl, 3
|
||||
%ifdef NO_CHEATING
|
||||
pop ebx ; p_align1
|
||||
phdr.endm2:
|
||||
phdr.end equ phdr.endm2 + 2
|
||||
lea ecx, [ebp+__strempty-__self+EBP_bias] ; p_align2..3, ...
|
||||
xchg edx, esp
|
||||
%else
|
||||
mov bl, 3 ; p_align1..2
|
||||
phdr.endm1:
|
||||
phdr.end equ phdr.endm1 + 1
|
||||
|
||||
;_parent.3:
|
||||
mov ax, SYS_execveat
|
||||
mov di, AT_EMPTY_PATH
|
||||
%endif
|
||||
mov ax, SYS_execveat ; p_align3, ...
|
||||
mov di, AT_EMPTY_PATH
|
||||
;int 0x80 ;; fallthru to _start.4
|
||||
|
||||
;_start:
|
||||
; mov ax, SYS_memfd_create
|
||||
; mov ebx, esp
|
||||
; int 0x80
|
||||
|
||||
; pop eax
|
||||
; mov ebp, __self-EBP_bias
|
||||
; mov al, SYS_fork
|
||||
|
||||
_start.4:
|
||||
int 0x80
|
||||
int 0x80
|
||||
|
||||
%ifndef NO_FILE_MANAGER_COMPAT
|
||||
xor ebx, ebx
|
||||
xor ebx, ebx
|
||||
%endif
|
||||
test eax, eax
|
||||
jnz short _parent.0
|
||||
;jz short _child
|
||||
|
||||
;_parent:
|
||||
; xor ebx, ebx
|
||||
; mov ax, SYS_waitid
|
||||
; lea esi, [ebx+P_ALL] ; smaller than mov si, P_ALL
|
||||
; int 0x80
|
||||
|
||||
; mov edx, esp ; use our args in args ; edx == argv
|
||||
; lea ecx, [ebp+__strempty-__self] ; doesn't like a NULL
|
||||
; mov bl, 3 ; __memfd
|
||||
; lea esi, [esp+24]
|
||||
; mov ax, SYS_execveat
|
||||
; mov di, AT_EMPTY_PATH ; can be smaller, reg sucks
|
||||
; int 0x80
|
||||
jnz short _parent.0
|
||||
|
||||
_child:
|
||||
;mov cl, 0 ; fix argc
|
||||
;mov dl, 0
|
||||
; dup stdout->demo
|
||||
mov al, SYS_dup2
|
||||
xchg ebx, edi
|
||||
mov cl, STDOUT_FILENO
|
||||
int 0x80
|
||||
|
||||
lea ebx, [ebp+EBP_bias]
|
||||
;mov ebx, ebp
|
||||
mov al, SYS_open
|
||||
int 0x80
|
||||
; open self for payload reading
|
||||
lea ebx, [ebp+EBP_bias]
|
||||
mov al, SYS_open
|
||||
dec cl
|
||||
int 0x80
|
||||
|
||||
; fd1
|
||||
push eax
|
||||
; seek
|
||||
mov ebx, eax
|
||||
mov al, SYS_lseek
|
||||
mov cl, payload - ehdr
|
||||
int 0x80
|
||||
|
||||
; seek
|
||||
mov al, SYS_lseek
|
||||
pop ebx
|
||||
push ebx
|
||||
mov cl, payload - ehdr
|
||||
int 0x80
|
||||
; dup2 self->stdin
|
||||
mov al, SYS_dup2
|
||||
mov cl, STDIN_FILENO
|
||||
int 0x80
|
||||
|
||||
; dup2 demo->stdout
|
||||
dec ebx
|
||||
mov al, SYS_dup2
|
||||
mov cl, STDOUT_FILENO
|
||||
int 0x80
|
||||
; execve
|
||||
mov al, SYS_execve
|
||||
|
||||
; dup2 self->stdin
|
||||
mov al, SYS_dup2
|
||||
pop ebx
|
||||
dec ecx ; zero it out -> STDIN_FILENO
|
||||
int 0x80
|
||||
|
||||
; execve
|
||||
mov al, SYS_execve
|
||||
|
||||
lea ebx, [ebp+__zip-__self+EBP_bias]
|
||||
lea ebx, [ebp+__zip-__self+EBP_bias]
|
||||
%ifndef USE_GZIP
|
||||
push ecx
|
||||
push ebx
|
||||
%endif
|
||||
mov ecx, esp
|
||||
int 0x80
|
||||
xchg ecx, esp
|
||||
int 0x80
|
||||
|
||||
__self:
|
||||
db '/proc/self/exe'
|
||||
|
|
Loading…
Reference in New Issue