amd64-linux.elf shlib now fully-SELinux compliant
modified: stub/src/amd64-linux.elf-so_entry.S modified: stub/src/amd64-linux.elf-so_fold.S
This commit is contained in:
parent
be6e77379a
commit
0901ce1b68
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include "arch/amd64/macros.S"
|
#include "arch/amd64/macros.S"
|
||||||
#include "arch/amd64/regs.h"
|
#include "arch/amd64/regs.h"
|
||||||
|
NBPW= 8
|
||||||
|
|
||||||
sz_Ehdr= 64
|
sz_Ehdr= 64
|
||||||
sz_Phdr= 56
|
sz_Phdr= 56
|
||||||
@ -56,8 +57,10 @@ MAP_ANONYMOUS= 0x20
|
|||||||
__NR_mmap= 9 // 64-bit mode only! /usr/include/asm/unistd_64.h
|
__NR_mmap= 9 // 64-bit mode only! /usr/include/asm/unistd_64.h
|
||||||
__NR_mprotect= 10
|
__NR_mprotect= 10
|
||||||
__NR_munmap= 11
|
__NR_munmap= 11
|
||||||
|
__NR_memfd_create= 0x13f // 319
|
||||||
|
|
||||||
__NR_write= 1
|
__NR_write= 1
|
||||||
|
__NR_close= 3
|
||||||
__NR_exit= 60
|
__NR_exit= 60
|
||||||
|
|
||||||
PAGE_SHIFT= 12
|
PAGE_SHIFT= 12
|
||||||
@ -85,8 +88,9 @@ _start:
|
|||||||
push %arg3 // MATCH_07 envp (glibc)
|
push %arg3 // MATCH_07 envp (glibc)
|
||||||
push %arg2 // MATCH_01 argv
|
push %arg2 // MATCH_01 argv
|
||||||
push %arg1 // MATCH_00 argc
|
push %arg1 // MATCH_00 argc
|
||||||
push %rbp // MATCH_02 saved register
|
|
||||||
push %rbx // MATCH_03 saved register
|
push %rbx // MATCH_03 saved register
|
||||||
|
push %rbp // MATCH_02 saved register
|
||||||
|
mov %rsp,%rbp
|
||||||
call L70 // MATCH_08 push $&getbit
|
call L70 // MATCH_08 push $&getbit
|
||||||
/* Working registers */
|
/* Working registers */
|
||||||
#define off %eax /* XXX: 2GB */
|
#define off %eax /* XXX: 2GB */
|
||||||
@ -111,24 +115,16 @@ refill:
|
|||||||
adcl bits,bits // LSB= 1 (CarryIn); CarryOut= next bit
|
adcl bits,bits // LSB= 1 (CarryIn); CarryOut= next bit
|
||||||
ret // infrequent (1/32)
|
ret // infrequent (1/32)
|
||||||
|
|
||||||
L20:
|
L20: // %rdx == &getbit
|
||||||
pop %rbx // MATCH_09 &fold_info
|
pop %rbx // MATCH_09 &fold_info
|
||||||
|
lea _start - 4*4 - getbit(%rdx),%rax // &so_info
|
||||||
|
push %rax // MATCH_14 &so_info
|
||||||
|
|
||||||
// cmpw $M_NRV2B_LE32|(0<<8),b_method(%rbx); je 0f; hlt; 0: // check method and filter bytes
|
// cmpw $M_NRV2B_LE32|(0<<8),b_method(%rbx); je 0f; hlt; 0: // check method and filter bytes
|
||||||
|
|
||||||
// Get pages for unfolded code
|
// De-compress folded code onto the stack
|
||||||
sub %arg6,%arg6 // 0
|
movl /*sz_unc*/(%rbx),%eax; push %rax // MATCH_40 len unfolded code
|
||||||
pop %rdx // MATCH_08 &getbit
|
sub %rax,%rsp; and $-2*NBPW,%rsp
|
||||||
sub %arg5,%arg5 // 0
|
|
||||||
movl /*sz_unc*/(%rbx),%arg2l // dstlen
|
|
||||||
push $MAP_PRIVATE|MAP_ANONYMOUS; pop %sys4
|
|
||||||
push %arg2 // MATCH_10 len for escape hatch
|
|
||||||
push %rdx // MATCH_15 save &getbit over syscall
|
|
||||||
push $PROT_READ|PROT_WRITE; pop %arg3
|
|
||||||
subl %edi,%edi // (%arg1)dst = 0; // kernel chooses
|
|
||||||
push $__NR_mmap; pop %rax; syscall; cmp $-4096,%rax; jb 0f; int3; 0:
|
|
||||||
|
|
||||||
pop %rdx // MATCH_15 &getbit
|
|
||||||
push %rax // MATCH_04 ptr unfolded_code
|
|
||||||
|
|
||||||
// This is nrv2b_d32, inlined and optimized for small space (about 160 bytes).
|
// This is nrv2b_d32, inlined and optimized for small space (about 160 bytes).
|
||||||
// The task is to de-compress the folded pieces for shared library init:
|
// The task is to de-compress the folded pieces for shared library init:
|
||||||
@ -140,7 +136,8 @@ L20:
|
|||||||
// and compressability of C-coded de-compressors for Lzma and Zstd
|
// and compressability of C-coded de-compressors for Lzma and Zstd
|
||||||
// in contrast to the simple and small assembly-coded NRV.
|
// in contrast to the simple and small assembly-coded NRV.
|
||||||
|
|
||||||
push %rax; pop dst // &unfolded_code
|
push %rsp; pop dst // &unfolded_code
|
||||||
|
push %rbp // MATCH_45
|
||||||
movl sz_cpr(%rbx),len // lsrc
|
movl sz_cpr(%rbx),len // lsrc
|
||||||
lea sz_b_info(%rbx),src
|
lea sz_b_info(%rbx),src
|
||||||
decompress: // inlined: (uchar const *src, uint len, uchar *dst /*, u32 &ldst, uint method */)
|
decompress: // inlined: (uchar const *src, uint len, uchar *dst /*, u32 &ldst, uint method */)
|
||||||
@ -150,8 +147,9 @@ decompress: // inlined: (uchar const *src, uint len, uchar *dst /*, u32 &ldst,
|
|||||||
// MATCH_05 &input_eof
|
// MATCH_05 &input_eof
|
||||||
// MATCH_04 ptr unfolded_code
|
// MATCH_04 ptr unfolded_code
|
||||||
// MATCH_10 len unfolded_code
|
// MATCH_10 len unfolded_code
|
||||||
// MATCH_03 saved %rbx
|
//%rbp:
|
||||||
// MATCH_02 saved %rbp
|
// MATCH_02 saved %rbp
|
||||||
|
// MATCH_03 saved %rbx
|
||||||
// MATCH_00 argc
|
// MATCH_00 argc
|
||||||
// MATCH_01 argv
|
// MATCH_01 argv
|
||||||
// MATCH_07 envp
|
// MATCH_07 envp
|
||||||
@ -201,33 +199,57 @@ gotlen_n2b:
|
|||||||
eof_n2b:
|
eof_n2b:
|
||||||
pop %rcx // MATCH_05 &input_eof
|
pop %rcx // MATCH_05 &input_eof
|
||||||
cmp %rcx,%rsi; je 0f; hlt; 0: // test for ending in correct place
|
cmp %rcx,%rsi; je 0f; hlt; 0: // test for ending in correct place
|
||||||
lea _start - 4*4 - getbit(%rdx),%rdx // &so_info
|
|
||||||
|
|
||||||
pop %arg1 // MATCH_11 ptr unfolded code
|
pop %rbp // MATCH_45
|
||||||
pop %arg2 // MATCH_10 len unfolded code
|
|
||||||
push %rdx // MATCH_14 &so_info
|
push $0; pop %arg2
|
||||||
push %arg2 // MATCH_12 len unfolded code
|
call 0f; .asciz "upx"; 0: pop %arg1
|
||||||
push %arg1 // MATCH_13 ptr unfolded code
|
mov $__NR_memfd_create,%rax; call do_sys
|
||||||
push $PROT_EXEC|PROT_READ; pop %arg3
|
|
||||||
push $__NR_mprotect; pop %rax; syscall; cmp $-4096,%rax; jb 0f; int3; 0:
|
push %rax; pop %arg1 // mfd
|
||||||
|
push %rsp; pop %arg2 // buffer
|
||||||
|
push %rax // MATCH_47 save mfd
|
||||||
|
mov -2*NBPW(%rbp),%arg3 // length
|
||||||
|
push $__NR_write; pop %rax; call do_sys // scribbles %rcx !!
|
||||||
|
|
||||||
|
// Map unfolded code the SELinux way
|
||||||
|
pop %arg5 // MATCH_47 mfd
|
||||||
|
lea -2*NBPW(%rbp),%rsp
|
||||||
|
pop %arg2; push %arg2 // MATCH_40 len unfolded code
|
||||||
|
sub %arg6l,%arg6l // 0
|
||||||
|
push $MAP_PRIVATE; pop %sys4
|
||||||
|
push $PROT_READ|PROT_EXEC; pop %arg3
|
||||||
|
subl %edi,%edi // (%arg1)dst = 0; // kernel chooses addr
|
||||||
|
push $__NR_mmap; pop %rax; call do_sys
|
||||||
|
push %rax // MATCH_11 ptr unfolded code
|
||||||
|
|
||||||
|
push %arg5; pop %arg1 // mfd
|
||||||
|
push $__NR_close; pop %rax; call do_sys
|
||||||
|
|
||||||
// %rsp:
|
// %rsp:
|
||||||
// MATCH_13 ptr unfolded_code; for escape hatch
|
// MATCH_11 ptr unfolded_code; for escape hatch
|
||||||
// MATCH_12 len unfolded code; for escape hatch
|
// MATCH_10 len unfolded code; for escape hatch
|
||||||
// MATCH_14 &so_info
|
// MATCH_14 &so_info
|
||||||
// MATCH_03 saved %rbx
|
// %rbp:
|
||||||
// MATCH_02 saved %rbp
|
// MATCH_02 saved %rbp
|
||||||
|
// MATCH_03 saved %rbx
|
||||||
// MATCH_00 argc
|
// MATCH_00 argc
|
||||||
// MATCH_01 argv
|
// MATCH_01 argv
|
||||||
// MATCH_07 envp
|
// MATCH_07 envp
|
||||||
|
|
||||||
pop %rax; push %rax // MATCH_13 ptr unfolded code
|
pop %rax; push %rax // MATCH_11 ptr unfolded code
|
||||||
jmp *%rax // enter C code
|
jmp *%rax // enter C code
|
||||||
|
|
||||||
|
do_sys:
|
||||||
|
syscall
|
||||||
|
cmp $-4096,%rax; jb 0f; int3; 0:
|
||||||
|
ret
|
||||||
|
|
||||||
// IDENTSTR goes here
|
// IDENTSTR goes here
|
||||||
|
|
||||||
section ELFMAINZ
|
section ELFMAINZ
|
||||||
L70:
|
L70:
|
||||||
|
pop %rdx // MATCH_08 &getbit
|
||||||
call L20 // MATCH_09 push $&fold_info
|
call L20 // MATCH_09 push $&fold_info
|
||||||
fold_info:
|
fold_info:
|
||||||
// b_info (sz_unc, sz_cpr, method) of folded code (C-language, etc.)
|
// b_info (sz_unc, sz_cpr, method) of folded code (C-language, etc.)
|
||||||
|
|||||||
@ -8,33 +8,34 @@ NBPW= 8
|
|||||||
#endif //}
|
#endif //}
|
||||||
|
|
||||||
// %rsp:
|
// %rsp:
|
||||||
// MATCH_13 ptr unfolded_code; for escape hatch
|
// MATCH_11 ptr unfolded_code; for escape hatch
|
||||||
// MATCH_12 len unfolded code; for escape hatch
|
// MATCH_10 len unfolded code; for escape hatch
|
||||||
// MATCH_14 &so_info:
|
// MATCH_14 &so_info:
|
||||||
// .long offset(.) // detect relocation
|
// .word offset(.) // detect relocation
|
||||||
// .long offset(user DT_INIT)
|
// .word offset(user DT_INIT)
|
||||||
// .long offset(escape_hatch)
|
// .word offset(escape_hatch)
|
||||||
// .long offset({l_info; p_info; b_info; compressed data})
|
// .word offset({l_info; p_info; b_info; compressed data})
|
||||||
// MATCH_03 saved %rbx
|
// %rbp:
|
||||||
// MATCH_02 saved %rbp
|
// MATCH_02 saved %rbp
|
||||||
|
// MATCH_03 saved %rbx
|
||||||
// MATCH_00 argc
|
// MATCH_00 argc
|
||||||
// MATCH_01 argv
|
// MATCH_01 argv
|
||||||
// MATCH_07 envp
|
// MATCH_07 envp
|
||||||
|
|
||||||
section SO_HEAD
|
section SO_HEAD
|
||||||
fold:
|
fold:
|
||||||
pop %rbx // MATCH_13 ptr unfolded code
|
pop %rbx // MATCH_11 ptr unfolded code
|
||||||
pop %rbp // MATCH_12 len unfolded code
|
pop %rbp // MATCH_10 len unfolded code
|
||||||
pop %arg1 // MATCH_14 &so_info
|
pop %arg1 // MATCH_14 &so_info
|
||||||
lea 2*NBPW(%rsp),%arg2 // skip MATCH_03, MATCH_02; MATCH_00 &{argc, argv, envp}
|
lea 2*NBPW(%rsp),%arg2 // &{argc, argv, envp}
|
||||||
sub $MAX_ELF_HDR_64,%rsp; mov %rsp,%arg3 // space for Elf64_Ehdr and Elf64_Phdrs
|
sub $MAX_ELF_HDR_64,%rsp; mov %rsp,%arg3 // space for Elf64_Ehdr and Elf64_Phdrs
|
||||||
call upx_so_main // (&so_info, &{argc, argv, envp}, elf_tmp); returns &escape_hatch
|
call upx_so_main // (&so_info, &{argc, argv, envp}, elf_tmp); returns &escape_hatch
|
||||||
add $MAX_ELF_HDR_64,%rsp
|
add $MAX_ELF_HDR_64,%rsp
|
||||||
|
|
||||||
push %rbp; pop %arg2 // len unfolded code
|
push %rbp; pop %arg2 // len unfolded code
|
||||||
push %rbx; pop %arg1 // ptr unfolded code
|
push %rbx; pop %arg1 // ptr unfolded code
|
||||||
pop %rbx // MATCH_03 restore
|
|
||||||
pop %rbp // MATCH_02 restore
|
pop %rbp // MATCH_02 restore
|
||||||
|
pop %rbx // MATCH_03 restore
|
||||||
push %rax // MATCH_30 &escape_hatch
|
push %rax // MATCH_30 &escape_hatch
|
||||||
push $__NR_munmap; pop %rax
|
push $__NR_munmap; pop %rax
|
||||||
ret // MATCH_30 ==>escape_hatch:
|
ret // MATCH_30 ==>escape_hatch:
|
||||||
@ -73,7 +74,7 @@ eof: // end of a compressed extent
|
|||||||
// Subroutines and syscalls needed by upx_so_main
|
// Subroutines and syscalls needed by upx_so_main
|
||||||
//
|
//
|
||||||
my_bkpt: .globl my_bkpt
|
my_bkpt: .globl my_bkpt
|
||||||
int3
|
int3 // my_bkpt
|
||||||
ret
|
ret
|
||||||
|
|
||||||
memset: .globl memset // void *memset(void *s, int c, size_t n);
|
memset: .globl memset // void *memset(void *s, int c, size_t n);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user