Compress the compiled C code in the stub on lx_exec86 (saves 157 bytes).

Also make 'fold_begin' processing more robust.
	p_lx_elf.cpp p_lx_sh.cpp p_unix.cpp
	stub/Makefile stub/l_lx_exec86.asm

committer: jreiser <jreiser> 958923851 +0000
This commit is contained in:
John Reiser
2000-05-21 15:44:11 +00:00
parent fdebd78d50
commit 6bb104b39f
5 changed files with 154 additions and 56 deletions
+103 -37
View File
@@ -1,10 +1,13 @@
; l_lx_exec86.asm -- Linux program entry point & decompressor (execve)
; l_lx_exec86.asm -- Linux program entry point & decompressor (kernel exec)
;
; This file is part of the UPX executable compressor.
;
; Copyright (C) 1996-2000 Markus Franz Xaver Johannes Oberhumer
; Copyright (C) 1996-2000 Laszlo Molnar
;
; Integration of virtual exec() with decompression is
; Copyright (C) 2000 John F. Reiser. All rights reserved.
;
; UPX and the UCL library are free software; you can redistribute them
; and/or modify them under the terms of the GNU General Public License as
; published by the Free Software Foundation; either version 2 of
@@ -23,6 +26,8 @@
; Markus F.X.J. Oberhumer Laszlo Molnar
; markus.oberhumer@jk.uni-linz.ac.at ml1050@cdata.tvnet.hu
;
; John F. Reiser
; jreiser@BitWagon.com
BITS 32
@@ -48,8 +53,8 @@
%endif
%include "ident.ash"
%include "ident.ash"
; /*************************************************************************
; // program entry point
@@ -57,28 +62,45 @@
; **************************************************************************/
GLOBAL _start
EXTERN upx_main
_start:
call main ; push &decompress
;;;; 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
;; define g
;; stepi
;; x/i $pc
;; end
;; and a step-over macro such as
;; define h
;; x/2i $pc
;; tbreak *$_
;; continue
;; x/i $pc
;; end
;; Step through the code; remember that <Enter> repeats the previous command.
;;
%if 0
; personality(PER_LINUX)
mov eax, 136 ; syscall_personality
xor ebx, ebx ; PER_LINUX
int 0x80
%endif
call main ; push address of decompress subroutine
; /*************************************************************************
; // C callable decompressor
; **************************************************************************/
%define INP dword [esp+24+4]
%define INS dword [esp+24+8]
%define OUTP dword [esp+24+12]
%define OUTS dword [esp+24+16]
%define INP dword [esp+8*4+4]
%define INS dword [esp+8*4+8]
%define OUTP dword [esp+8*4+12]
%define OUTS dword [esp+8*4+16]
decompress:
push ebp
push edi
push esi
push ebx
push ecx
push edx
cld
pusha
; cld
mov esi, INP
mov edi, OUTP
@@ -110,36 +132,80 @@ decompress:
mov edx, OUTS
mov [edx], edi
pop edx
pop ecx
pop ebx
pop esi
pop edi
pop ebp
mov [7*4 + esp], eax
popa
ret
; /*************************************************************************
; // prepare arguments and call upx_main
; **************************************************************************/
%define PAGE_MASK (~0<<12)
%define PAGE_SIZE ( 1<<12)
%define szElf32_Ehdr 0x34
%define szElf32_Phdr 8*4
%define p_filesz 4*4
%define p_memsz 5*4
%define a_val 4
%define MAP_FIXED 0x10
%define MAP_PRIVATE 0x02
%define MAP_ANONYMOUS 0x20
%define PROT_READ 1
%define PROT_WRITE 2
%define PROT_EXEC 4
%define __NR_mmap 90
%define __NR_munmap 91
; Decompress the rest of this loader, and jump to it
unfold:
pop esi ; &fold_begin = src
push esi ; &dst
mov ecx, ebp ; &decompress
and ecx, dword PAGE_MASK ; &my_elfhdr
mov ebx, ecx ; save &my_elfhdr for later
;; Compressed code now begins at fold_begin.
;; We want decompressed code to begin at fold_begin, too.
;; Move the compressed code to the high end of the page.
;; Assume non-overlapping so that forward movsb is OK.
lea edi, [-PAGE_MASK + ecx] ; high end of page
add ecx, [p_filesz + szElf32_Ehdr + ecx] ; beyond src
sub ecx, esi ; srclen
push ecx ; srclen
sub edi, ecx
push edi ; &src
cld
rep movsb
call ebp ; decompress(&src, srclen, &dst, &dstlen)
pop eax ; discard &src
pop eax ; discard srclen
pop eax ; &dst == fold_begin
;; icache lookahead of compressed code after "call unfold" is still there.
;; Synchronize with dcache of decompressed code.
pushf
push cs
push eax
iret ; back to fold_begin!
main:
pop ebp ; &decompress
%if 0
; personality(PER_LINUX)
mov eax, 136 ; syscall_personality
xor ebx, ebx ; PER_LINUX
int 0x80
%endif
pop ebp ; &decompress
push eax ; place to store dstlen
push esp ; &dstlen
call unfold
fold_begin: ;; this label is known to the Makefile
pop eax ; discard &dstlen
pop eax ; discard dstlen
pop eax ; Pop the argument count
mov ecx, esp ; argv starts just at the current stack top
lea edx, [ecx+eax*4+4] ; envp = &argv[argc + 1]
push eax ; Restore the stack
push ebp ; argument: &decompress
%define PAGE_MASK (~0<<12)
and ebp, PAGE_MASK
push ebp ; argument: &Elf32_Ehdr
push edx ; Push third argument: envp
push ecx ; Push second argument: argv
;;; push eax ; Push first argument: argc
push ebx ; argument: &my_elfhdr
push edx ; argument: envp
push ecx ; argument: argv
EXTERN upx_main
call upx_main ; Call the UPX main function
hlt ; Crash if somehow upx_main does return