convert i386-bsd.elf-entry.asm

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