diff --git a/src/p_lx_exc.cpp b/src/p_lx_exc.cpp index c16e2c7e..78297daa 100644 --- a/src/p_lx_exc.cpp +++ b/src/p_lx_exc.cpp @@ -166,8 +166,7 @@ PackLinuxI386::pack4(OutputFile *fo, Filter &ft) (elfout.ehdr.e_phentsize * elfout.ehdr.e_phnum) + sizeof(l_info) + ((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) ; - unsigned len = fo->getBytesWritten(); - set_native32(&elfout.phdr[0].p_filesz, len); + elfout.phdr[0].p_filesz = fo->getBytesWritten(); super::pack4(fo, ft); // write PackHeader and overlay_offset @@ -186,38 +185,38 @@ PackLinuxI386::pack4(OutputFile *fo, Filter &ft) // Supply a "linking view" that covers everything, // so that 'strip' does not omit everything. - Elf32_Shdr shdr; + Elf_LE32_Shdr shdr; // The section header string table. char const shstrtab[] = "\0.\0.shstrtab"; unsigned eod = elfout.phdr[0].p_filesz; - set_native32(&elfout.ehdr.e_shoff, eod); - set_native16(&elfout.ehdr.e_shentsize, sizeof(shdr)); - set_native16(&elfout.ehdr.e_shnum, 3); - set_native16(&elfout.ehdr.e_shstrndx, 2); + elfout.ehdr.e_shoff = eod; + elfout.ehdr.e_shentsize = sizeof(shdr); + elfout.ehdr.e_shnum = 3; + elfout.ehdr.e_shstrndx = 2; // An empty Elf32_Shdr for space as a null index. memset(&shdr, 0, sizeof(shdr)); - set_native32(&shdr.sh_type, Elf32_Shdr::SHT_NULL); + shdr.sh_type = Elf32_Shdr::SHT_NULL; fo->write(&shdr, sizeof(shdr)); // Cover all the bits we need at runtime. memset(&shdr, 0, sizeof(shdr)); - set_native32(&shdr.sh_name, 1); - set_native32(&shdr.sh_type, Elf32_Shdr::SHT_PROGBITS); - set_native32(&shdr.sh_flags, Elf32_Shdr::SHF_ALLOC); - set_native32(&shdr.sh_addr, elfout.phdr[0].p_vaddr); - set_native32(&shdr.sh_offset, overlay_offset); - set_native32(&shdr.sh_size, eod - overlay_offset); - set_native32(&shdr.sh_addralign, 4096); + shdr.sh_name = 1; + shdr.sh_type = Elf32_Shdr::SHT_PROGBITS; + shdr.sh_flags = Elf32_Shdr::SHF_ALLOC; + shdr.sh_addr = elfout.phdr[0].p_vaddr; + shdr.sh_offset = overlay_offset; + shdr.sh_size = eod - overlay_offset; + shdr.sh_addralign = 4096; fo->write(&shdr, sizeof(shdr)); // A section header for the section header string table. memset(&shdr, 0, sizeof(shdr)); - set_native32(&shdr.sh_name, 3); - set_native32(&shdr.sh_type, Elf32_Shdr::SHT_STRTAB); - set_native32(&shdr.sh_offset, 3*sizeof(shdr) + eod); - set_native32(&shdr.sh_size, sizeof(shstrtab)); + shdr.sh_name = 3; + shdr.sh_type = Elf32_Shdr::SHT_STRTAB; + shdr.sh_offset = 3*sizeof(shdr) + eod; + shdr.sh_size = sizeof(shstrtab); fo->write(&shdr, sizeof(shdr)); fo->write(shstrtab, sizeof(shstrtab)); @@ -273,7 +272,7 @@ PackLinuxI386::buildLinuxLoader( fold_hdrlen = umax(0x80, fold_hdrlen); } h.sz_unc = (szfold < fold_hdrlen) ? 0 : (szfold - fold_hdrlen); - h.b_method = (unsigned char) ph.method; + h.b_method = (unsigned char) ph.method; // FIXME: endian trouble h.b_ftid = (unsigned char) ph.filter; h.b_cto8 = (unsigned char) ph.filter_cto; } @@ -286,6 +285,7 @@ PackLinuxI386::buildLinuxLoader( h.sz_cpr = sz_cpr; } // This adds the definition to the "library", to be used later. + // NOTE: the stub is NOT compressed! The savings is not worth it. linker->addSection("FOLDEXEC", cprLoader, h.sz_cpr); delete [] cprLoader; diff --git a/src/p_lx_exc.h b/src/p_lx_exc.h index 50bcf67b..460e92d2 100644 --- a/src/p_lx_exc.h +++ b/src/p_lx_exc.h @@ -86,22 +86,22 @@ protected: unsigned n_mru; struct cprElfHdr1 { - Elf32_Ehdr ehdr; - Elf32_Phdr phdr[1]; + Elf_LE32_Ehdr ehdr; + Elf_LE32_Phdr phdr[1]; l_info linfo; } __attribute_packed; struct cprElfHdr2 { - Elf32_Ehdr ehdr; - Elf32_Phdr phdr[2]; + Elf_LE32_Ehdr ehdr; + Elf_LE32_Phdr phdr[2]; l_info linfo; } __attribute_packed; struct cprElfHdr3 { - Elf32_Ehdr ehdr; - Elf32_Phdr phdr[3]; + Elf_LE32_Ehdr ehdr; + Elf_LE32_Phdr phdr[3]; l_info linfo; } __attribute_packed; diff --git a/src/stub/src/i386-linux.elf.shell-entry.asm b/src/stub/src/i386-linux.elf.shell-entry.asm index 7a110e84..9914878e 100644 --- a/src/stub/src/i386-linux.elf.shell-entry.asm +++ b/src/stub/src/i386-linux.elf.shell-entry.asm @@ -133,46 +133,28 @@ decompress: %define p_filesize 4 ; Decompress the rest of this loader, and jump to it -unfold: - pop esi ; &{ sz_uncompressed, sz_compressed, compressed_data...} - cld - lodsd - push eax ; sz_uncompressed of folded stub (junk, actually) - push esp ; &sz_uncompressed - mov edx, 0x01400000 ; origin of this program - mov eax, [p_memsz + szElf32_Ehdr + edx] ; length of loaded pages - add eax, edx - add edx, szElf32_Ehdr + 2*szElf32_Phdr ; convenient ptr - push eax ; &destination +main: + pop ebp ; &decompress + mov eax,0x1400000 ; &Elf32_Ehdr of this stub + lea edx,[0x80 + szp_info + eax] ; &cprScript + add eax,[p_memsz + szElf32_Ehdr + eax] ; after .text + add eax,PAGE_SIZE -1 + and eax, -PAGE_SIZE ; round up to next page - ; mmap space for unfolded stub, and uncompressed script - mov ecx, [szl_info + p_filesize + edx] ; script size - add ecx, 1+ 3+ (3 -1)+ PAGE_SIZE ; '\0' + "-c" + decompr_overrun + stub - - push eax ; offset (ignored when MAP_ANONYMOUS) - push byte -1 ; fd [required by *BSD for MAP_ANONYMOUS] + push byte 0 + push byte -1 push byte MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS - push byte PROT_READ | PROT_WRITE | PROT_EXEC - push ecx ; length - push eax ; destination - mov ebx, esp ; address of parameter vector for __NR_mmap + push byte PROT_READ | PROT_WRITE + push dword [edx] ; sz_unc length + push eax ; address + mov ebx,esp push byte __NR_mmap pop eax int 0x80 - lea ebx, [3+ PAGE_SIZE + eax] ; place for uncompressed script - add esp, byte 6*4 ; discard args to mmap + add esp, byte 6*4 ; remove arguments - lodsd - push eax ; sz_compressed of folded stub - lodsd ; junk cto8, algo, unused[2] - push esi ; &compressed_data - call ebp ; decompress(&src, srclen, &dst, &dstlen) - pop eax ; discard &compressed_data - pop eax ; discard sz_compressed - ret ; &destination -main: - pop ebp ; &decompress - call unfold + lea ebx,[3+ eax] ; space for "-c" +; fall into fold [not compressed!] eof: ; __XTHEENDX__ diff --git a/src/stub/src/i386-linux.elf.shell-fold.asm b/src/stub/src/i386-linux.elf.shell-fold.asm index 5d107557..c9e262bc 100644 --- a/src/stub/src/i386-linux.elf.shell-fold.asm +++ b/src/stub/src/i386-linux.elf.shell-fold.asm @@ -44,10 +44,7 @@ %define a_val 4 %define sz_auxv 8 -fold_begin: ; enter: %ebx= uncDst - ; also edx= szElf32_Ehdr + 2*szElf32_Phdr + &Elf32_Ehdr - pop eax ; discard &sz_uncompressed - pop eax ; discard sz_uncompressed +fold_begin: ; In: %ebx= uncDst; edx= &b_info cprSrc; ebp = &decompress ; Move argc,argv,envp down to make room for complete Elf_auxv table. ; Linux kernel 2.4.2 and earlier give only AT_HWCAP and AT_PLATFORM @@ -111,7 +108,6 @@ L40: sub esp, dword MAX_ELF_HDR + OVERHEAD xchg eax, ebx ; eax= uncDst - lea edx, [szl_info + szp_info + edx] ; cprSrc mov ecx, [ edx] ; sz_unc mov ebx, [4+ edx] ; sz_cpr mov esi, eax ; extra copy of uncDst