Put upx stub loader at high end of ELF output file on linux,

and allow for block-by-block specification of filter and parameters.
	linker.cpp linker.h mem.cpp mem.h p_elf.h
	p_lx_elf.cpp p_lx_elf.h
	p_lx_exc.cpp p_lx_exc.h
	p_lx_sh.cpp  p_lx_sh.h
	p_unix.cpp p_unix.h
	packer.cpp packer.h
	stub/fold_elf86.asm stub/fold_exec86.asm stub/fold_sh86.asm
	stub/l_lx_elf.c  stub/l_lx_elf86.asm  stub/l_lx_elf86.lds
	stub/l_lx_exec.c stub/l_lx_exec86.asm stub/l_lx_exec86.lds
	stub/l_lx_sh.c   stub/l_lx_sh86.asm   stub/l_lx_sh86.lds
	stub/linux.hh

committer: jreiser <jreiser> 981084316 +0000
This commit is contained in:
John Reiser
2001-02-02 03:25:16 +00:00
parent 9005e50049
commit 40fddf1715
28 changed files with 797 additions and 614 deletions
+33 -20
View File
@@ -139,7 +139,7 @@ do_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset)
static int
go_self(char const *tmpname, char *argv[], char *envp[])
{
// FIXME: why not use "/proc/self/fd/XX"? *BSD doesn't have it?
// Old FreeBSD does not have /proc/self, so use /proc/<pid> instead.
// Open the temp file.
int const fdi = open(tmpname, O_RDONLY, 0);
@@ -181,6 +181,11 @@ go_self(char const *tmpname, char *argv[], char *envp[])
// UPX & NRV stuff
**************************************************************************/
typedef void f_unfilter(
nrv_byte *, // also addvalue
nrv_uint,
unsigned cto8 // junk in high 24 bits
);
typedef int f_expand(
const nrv_byte *src, nrv_uint src_len,
nrv_byte *dst, nrv_uint *dst_len );
@@ -193,16 +198,24 @@ typedef int f_expand(
**************************************************************************/
void upx_main(
char *argv[],
f_unfilter *const f_unf,
unsigned cprLen,
f_expand *const f_decompress,
int junk2,
char /*const*/ *cprSrc,
char *envp[],
Elf32_Ehdr const *const my_ehdr,
f_expand *const f_decompress
char *argv[],
int argc
) __asm__("upx_main");
void upx_main(
char *argv[],
f_unfilter *const f_unf,
unsigned cprLen,
f_expand *const f_decompress,
int junk,
char /*const*/ *cprSrc,
char *envp[],
Elf32_Ehdr const *const my_ehdr,
f_expand *const f_decompress
char *argv[],
int argc
)
{
// file descriptor
@@ -213,9 +226,7 @@ void upx_main(
char *tmpname;
Elf32_Phdr const *const phdr = (Elf32_Phdr const *)
(my_ehdr->e_phoff + (char const *)my_ehdr);
struct Extent xi = { phdr[1].p_memsz, (char *)phdr[1].p_vaddr };
struct Extent xi = { cprLen, cprSrc };
char *next_unmap = (char *)(PAGE_MASK & (unsigned)xi.buf);
struct p_info header;
@@ -223,6 +234,8 @@ void upx_main(
// temporary file name
char tmpname_buf[20];
(void)junk;
//
// ----- Step 0: set /proc/self using /proc/<pid> -----
//
@@ -347,18 +360,13 @@ void upx_main(
for (;;)
{
struct {
int32_t sz_unc; // uncompressed
int32_t sz_cpr; // compressed
} h;
// Note: if h.sz_unc == h.sz_cpr then the block was not
// compressible and is stored in its uncompressed form.
struct b_info h;
int i;
// Read and check block sizes.
{
register char *__d0, *__d1;
__asm__ __volatile__( "movsl; movsl"
__asm__ __volatile__( "movsl; movsl; movsl"
: "=&D" (__d0), "=&S" (__d1)
: "0" (&h), "1" (xi.buf)
: "memory");
@@ -373,9 +381,10 @@ void upx_main(
goto error;
break;
}
if (h.sz_cpr <= 0)
goto error;
if (h.sz_cpr > h.sz_unc || h.sz_unc > (int32_t)header.p_blocksize)
// Note: if sz_unc == sz_cpr then the block was not
// compressible and is stored in its uncompressed form.
if (h.sz_cpr > h.sz_unc || h.sz_cpr > header.p_blocksize)
goto error;
// Now we have:
// assert(h.sz_cpr <= h.sz_unc);
@@ -387,6 +396,9 @@ void upx_main(
i = (*f_decompress)(xi.buf, h.sz_cpr, buf, &out_len);
if (i != 0 || out_len != (nrv_uint)h.sz_unc)
goto error;
// Right now, unfilter is combined with decompression.
// (*f_unfilter)(buf, out_len, cto8);
(void)f_unf;
}
else
{
@@ -486,6 +498,7 @@ void upx_main(
waitpid(-1, (int *)0, 0);
// Execute the original program.
(void)argc;
execve(tmpname, argv, envp);