convert i386-bsd.elf-entry.asm
This commit is contained in:
parent
b76118802a
commit
1897148abc
@ -335,9 +335,11 @@ tc.i386-bsd.elf.objdump = $(call tc,m-objdump)
|
||||
tc.i386-bsd.elf.objstrip = $(call tc,objcopy) -R .comment -R .note
|
||||
|
||||
i386-bsd.elf-entry.h : $(srcdir)/src/$$T.asm
|
||||
$(call tc,pp-nasm) $< -o tmp/$T.tmp1
|
||||
$(call tc,app-nasm) tmp/$T.tmp1 tmp/$T.tmp2
|
||||
$(call tc,nasm) -f bin -l tmp/$T.bin.lst tmp/$T.tmp2 -o tmp/$T.bin
|
||||
$(call tc,gcc) -c -x assembler-with-cpp $< -o tmp/$T.bin
|
||||
$(call tc,m-objcopy) --strip-unneeded tmp/$T.bin
|
||||
$(call tc,m-objcopy) -R .text -R .data -R .bss tmp/$T.bin
|
||||
$(call tc,m-objcopy) -R .note -R .comment tmp/$T.bin
|
||||
$(call tc,m-objdump) -trwh tmp/$T.bin >> tmp/$T.bin
|
||||
$(call tc,bin2h) --ident=bsd_i386elf_loader tmp/$T.bin $@
|
||||
|
||||
i386-bsd.elf-fold.h : tmp/$$T.o tmp/i386-bsd.elf-main.o $(srcdir)/src/$$T.lds
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,4 @@
|
||||
/*
|
||||
; i386-BSD.elf-entry.asm -- BSD program entry point & decompressor (Elf binary)
|
||||
;
|
||||
; This file is part of the UPX executable compressor.
|
||||
@ -28,24 +29,22 @@
|
||||
; John F. Reiser
|
||||
; <jreiser@users.sourceforge.net>
|
||||
;
|
||||
*/
|
||||
|
||||
// CPU 386
|
||||
|
||||
#include "arch/i386/macros2.ash"
|
||||
|
||||
|
||||
BITS 32
|
||||
SECTION .text
|
||||
CPU 386
|
||||
/*************************************************************************
|
||||
// program entry point
|
||||
// see glibc/sysdeps/i386/elf/start.S
|
||||
**************************************************************************/
|
||||
|
||||
%define jmps jmp short
|
||||
%define jmpn jmp near
|
||||
|
||||
; /*************************************************************************
|
||||
; // program entry point
|
||||
; // see glibc/sysdeps/i386/elf/start.S
|
||||
; **************************************************************************/
|
||||
|
||||
GLOBAL _start
|
||||
;__LEXEC000__
|
||||
_start:
|
||||
;;;; int3
|
||||
section LEXEC000
|
||||
_start: .globl _start
|
||||
//// int3
|
||||
/*
|
||||
;; How to debug this code: Uncomment the 'int3' breakpoint instruction above.
|
||||
;; Build the stubs and upx. Compress a testcase, such as a copy of /bin/date.
|
||||
;; Invoke gdb, and give a 'run' command. Define a single-step macro such as
|
||||
@ -62,7 +61,8 @@ _start:
|
||||
;; end
|
||||
;; Step through the code; remember that <Enter> repeats the previous command.
|
||||
;;
|
||||
call main ; push address of decompress subroutine
|
||||
*/
|
||||
call main // push address of decompress subroutine
|
||||
decompress:
|
||||
|
||||
; /*************************************************************************
|
||||
@ -70,43 +70,42 @@ decompress:
|
||||
; **************************************************************************/
|
||||
|
||||
; /* Offsets to parameters, allowing for {push + pusha + call} */
|
||||
%define O_INP (4+ 8*4 +1*4)
|
||||
%define O_INS (4+ 8*4 +2*4)
|
||||
%define O_OUTP (4+ 8*4 +3*4)
|
||||
%define O_OUTS (4+ 8*4 +4*4)
|
||||
%define O_PARAM (4+ 8*4 +5*4)
|
||||
#define O_INP (4+ 8*4 +1*4)
|
||||
#define O_INS (4+ 8*4 +2*4)
|
||||
#define O_OUTP (4+ 8*4 +3*4)
|
||||
#define O_OUTS (4+ 8*4 +4*4)
|
||||
#define O_PARAM (4+ 8*4 +5*4)
|
||||
|
||||
%define INP dword [esp+O_INP]
|
||||
%define INS dword [esp+O_INS]
|
||||
%define OUTP dword [esp+O_OUTP]
|
||||
%define OUTS dword [esp+O_OUTS]
|
||||
%define PARM dword [esp+O_PARAM]
|
||||
#define INP dword [esp+O_INP]
|
||||
#define INS dword [esp+O_INS]
|
||||
#define OUTP dword [esp+O_OUTP]
|
||||
#define OUTS dword [esp+O_OUTS]
|
||||
#define PARM dword [esp+O_PARAM]
|
||||
|
||||
;__LEXEC009__
|
||||
;; empty section for commonality with l_lx_exec86.asm
|
||||
;__LEXEC010__
|
||||
section LEXEC009
|
||||
// empty section for commonality with l_lx_exec86.asm
|
||||
section LEXEC010
|
||||
pusha
|
||||
push byte '?' ; cto8 (sign extension does not matter)
|
||||
; cld
|
||||
push '?' // cto8 (sign extension does not matter)
|
||||
// cld
|
||||
|
||||
mov esi, INP
|
||||
mov edi, OUTP
|
||||
|
||||
or ebp, byte -1
|
||||
;;; align 8
|
||||
or ebp, -1
|
||||
//// align 8
|
||||
|
||||
%include "arch/i386/nrv2b_d32.ash"
|
||||
%include "arch/i386/nrv2d_d32.ash"
|
||||
%include "arch/i386/nrv2e_d32.ash"
|
||||
%include "arch/i386/lzma_d.ash"
|
||||
%include "arch/i386/macros.ash"
|
||||
#include "arch/i386/nrv2b_d32_2.ash"
|
||||
#include "arch/i386/nrv2d_d32_2.ash"
|
||||
#include "arch/i386/nrv2e_d32_2.ash"
|
||||
//#include "arch/i386/lzma_d.ash" // FIXME
|
||||
cjt32 0
|
||||
|
||||
;__LEXEC015__
|
||||
; eax is 0 from decompressor code
|
||||
;xor eax, eax ; return code
|
||||
section LEXEC015
|
||||
// eax is 0 from decompressor code
|
||||
//xor eax, eax ; return code
|
||||
|
||||
; check compressed size
|
||||
// check compressed size
|
||||
mov edx, INP
|
||||
add edx, INS
|
||||
cmp esi, edx
|
||||
@ -114,12 +113,12 @@ decompress:
|
||||
dec eax
|
||||
.ok:
|
||||
|
||||
; write back the uncompressed size
|
||||
// write back the uncompressed size
|
||||
sub edi, OUTP
|
||||
mov edx, OUTS
|
||||
mov [edx], edi
|
||||
|
||||
pop edx ; cto8
|
||||
pop edx // cto8
|
||||
|
||||
mov [7*4 + esp], eax
|
||||
popa
|
||||
@ -127,109 +126,105 @@ decompress:
|
||||
|
||||
ctojr32
|
||||
ckt32 edi, dl
|
||||
;__LEXEC017__
|
||||
section LEXEC017
|
||||
popa
|
||||
ret
|
||||
|
||||
;__LEXEC020__
|
||||
section LEXEC020
|
||||
|
||||
%define PAGE_SIZE ( 1<<12)
|
||||
#define PAGE_SIZE ( 1<<12)
|
||||
|
||||
%define MAP_FIXED 0x10
|
||||
%define MAP_PRIVATE 0x02
|
||||
%define MAP_ANONYMOUS 0x1000
|
||||
%define PROT_READ 1
|
||||
%define PROT_WRITE 2
|
||||
%define PROT_EXEC 4
|
||||
%define __NR_mmap 197
|
||||
%define __NR_syscall 198
|
||||
%define szElf32_Ehdr 0x34
|
||||
%define p_memsz 5*4
|
||||
#define MAP_FIXED 0x10
|
||||
#define MAP_PRIVATE 0x02
|
||||
#define MAP_ANONYMOUS 0x1000
|
||||
#define PROT_READ 1
|
||||
#define PROT_WRITE 2
|
||||
#define PROT_EXEC 4
|
||||
#define __NR_mmap 197
|
||||
#define __NR_syscall 198
|
||||
#define szElf32_Ehdr 0x34
|
||||
#define p_memsz 5*4
|
||||
|
||||
%define __NR_write 4
|
||||
%define __NR_exit 1
|
||||
#define __NR_write 4
|
||||
#define __NR_exit 1
|
||||
|
||||
fail_mmap:
|
||||
push byte L71 - L70
|
||||
push L71 - L70
|
||||
call L71
|
||||
L70:
|
||||
db "PROT_EXEC|PROT_WRITE failed.",10
|
||||
.ascii "PROT_EXEC|PROT_WRITE failed\n"
|
||||
L71:
|
||||
push byte 2 ; fd stderr
|
||||
push eax ; fake ret.addr
|
||||
push byte __NR_write
|
||||
push 2 // fd stderr
|
||||
push eax // fake ret.addr
|
||||
push __NR_write
|
||||
pop eax
|
||||
int 0x80
|
||||
die:
|
||||
push byte 127 ; only low 7 bits matter!
|
||||
push eax ; fake ret.addr
|
||||
push byte __NR_exit
|
||||
pop eax ; write to stderr could fail, leaving eax as -EBADF etc.
|
||||
push 127 // only low 7 bits matter!
|
||||
push eax // fake ret.addr
|
||||
push __NR_exit
|
||||
pop eax // write to stderr could fail, leaving eax as -EBADF etc.
|
||||
int 0x80
|
||||
|
||||
; Decompress the rest of this loader, and jump to it
|
||||
// Decompress the rest of this loader, and jump to it
|
||||
unfold:
|
||||
pop esi ; &{ b_info:{sz_unc, sz_cpr, 4{byte}}, compressed_data...}
|
||||
pop esi // &{ b_info:{sz_unc, sz_cpr, 4{byte}}, compressed_data...}
|
||||
|
||||
lea eax, [ebp - (4+ decompress - _start)] ; 4: sizeof(int)
|
||||
sub eax, [eax] ; %eax= &Elf32_Ehdr of this program
|
||||
mov edx, eax ; %edx= &Elf32_Ehdr of this program
|
||||
lea eax, [ebp - (4+ decompress - _start)] // 4: sizeof(int)
|
||||
sub eax, [eax] // %eax= &Elf32_Ehdr of this program
|
||||
mov edx, eax // %edx= &Elf32_Ehdr of this program
|
||||
|
||||
; Linux requires PF_W in order to create .bss (implied by .p_filesz!=.p_memsz),
|
||||
; but strict SELinux (or PaX, grSecurity) forbids PF_W with PF_X.
|
||||
; So first PT_LOAD must be PF_R|PF_X only, and .p_memsz==.p_filesz.
|
||||
; So we must round up here, instead of pre-rounding .p_memsz.
|
||||
add eax, [p_memsz + szElf32_Ehdr + eax] ; address after .text
|
||||
// Linux requires PF_W in order to create .bss (implied by .p_filesz!=.p_memsz),
|
||||
// but strict SELinux (or PaX, grSecurity) forbids PF_W with PF_X.
|
||||
// So first PT_LOAD must be PF_R|PF_X only, and .p_memsz==.p_filesz.
|
||||
// So we must round up here, instead of pre-rounding .p_memsz.
|
||||
add eax, [p_memsz + szElf32_Ehdr + eax] // address after .text
|
||||
add eax, PAGE_SIZE -1
|
||||
and eax, -PAGE_SIZE
|
||||
and eax, 0-PAGE_SIZE
|
||||
|
||||
push eax ; destination for 'ret'
|
||||
push eax // destination for 'ret'
|
||||
|
||||
; mmap a page to hold the decompressed fold_elf86
|
||||
xor ecx, ecx ; %ecx= 0
|
||||
; MAP_ANONYMOUS ==>offset is ignored, so do not push!
|
||||
push ecx ; pad (must be zero?)
|
||||
push byte -1 ; *BSD demands -1==fd for mmap(,,,MAP_ANON,,)
|
||||
push dword MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS
|
||||
mov ch, PAGE_SIZE >> 8 ; %ecx= PAGE_SIZE
|
||||
push byte PROT_READ | PROT_WRITE | PROT_EXEC
|
||||
push ecx ; length
|
||||
push eax ; destination
|
||||
xor eax,eax ; 0
|
||||
push eax ; current thread
|
||||
// mmap a page to hold the decompressed fold_elf86
|
||||
xor ecx, ecx // %ecx= 0
|
||||
// MAP_ANONYMOUS ==>offset is ignored, so do not push!
|
||||
push ecx // pad (must be zero?)
|
||||
push -1 // *BSD demands -1==fd for mmap(,,,MAP_ANON,,)
|
||||
push MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS
|
||||
mov ch, PAGE_SIZE >> 8 // %ecx= PAGE_SIZE
|
||||
push PROT_READ | PROT_WRITE | PROT_EXEC
|
||||
push ecx // length
|
||||
push eax // destination
|
||||
xor eax,eax // 0
|
||||
push eax // current thread
|
||||
mov al, __NR_mmap
|
||||
push eax ; __NR_mmap
|
||||
push eax ; fake return address
|
||||
push eax // __NR_mmap
|
||||
push eax // fake return address
|
||||
mov al, __NR_syscall
|
||||
int 0x80 ; changes only %eax; %edx is live
|
||||
int 0x80 // changes only %eax; %edx is live
|
||||
jb fail_mmap
|
||||
xchg eax, edx ; %edx= page after .text; %eax= &Elf32_Ehdr of this program
|
||||
xchg eax, ebx ; %ebx= &Elf32_Ehdr of this program
|
||||
xchg eax, edx // %edx= page after .text; %eax= &Elf32_Ehdr of this program
|
||||
xchg eax, ebx // %ebx= &Elf32_Ehdr of this program
|
||||
|
||||
cld
|
||||
lodsd
|
||||
push eax ; sz_uncompressed (maximum dstlen for lzma)
|
||||
mov ecx,esp ; save &dstlen
|
||||
push eax ; space for 5th param
|
||||
push ecx ; &dstlen
|
||||
push edx ; &dst
|
||||
push eax // sz_uncompressed (maximum dstlen for lzma)
|
||||
mov ecx,esp // save &dstlen
|
||||
push eax // space for 5th param
|
||||
push ecx // &dstlen
|
||||
push edx // &dst
|
||||
lodsd
|
||||
push eax ; sz_compressed (srclen)
|
||||
lodsd ; last 4 bytes of b_info
|
||||
push eax // sz_compressed (srclen)
|
||||
lodsd // last 4 bytes of b_info
|
||||
mov [4*3 + esp],eax
|
||||
push esi ; &compressed_data
|
||||
call ebp ; decompress(&src, srclen, &dst, &dstlen, b_info.misc)
|
||||
add esp, byte (5+1 + 9)*4 ; (5+1) args to decompress, 9 "args" to mmap
|
||||
ret ; &destination
|
||||
push esi // &compressed_data
|
||||
call ebp // decompress(&src, srclen, &dst, &dstlen, b_info.misc)
|
||||
add esp, (5+1 + 9)*4 // (5+1) args to decompress, 9 "args" to mmap
|
||||
ret // &destination
|
||||
main:
|
||||
pop ebp ; &decompress
|
||||
pop ebp // &decompress
|
||||
call unfold
|
||||
; compressed fold_elf86 follows
|
||||
// compressed fold_elf86 follows
|
||||
eof:
|
||||
; __XTHEENDX__
|
||||
section .data
|
||||
dd -1
|
||||
dw eof
|
||||
|
||||
; vi:ts=8:et:nowrap
|
||||
// vi:ts=8:et:nowrap
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user