fix i386-linux.elf.shell
This commit is contained in:
parent
dd5b7825d5
commit
431f4b9b0d
@ -166,8 +166,7 @@ PackLinuxI386::pack4(OutputFile *fo, Filter &ft)
|
|||||||
(elfout.ehdr.e_phentsize * elfout.ehdr.e_phnum) +
|
(elfout.ehdr.e_phentsize * elfout.ehdr.e_phnum) +
|
||||||
sizeof(l_info) +
|
sizeof(l_info) +
|
||||||
((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) ;
|
((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) ;
|
||||||
unsigned len = fo->getBytesWritten();
|
elfout.phdr[0].p_filesz = fo->getBytesWritten();
|
||||||
set_native32(&elfout.phdr[0].p_filesz, len);
|
|
||||||
super::pack4(fo, ft); // write PackHeader and overlay_offset
|
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,
|
// Supply a "linking view" that covers everything,
|
||||||
// so that 'strip' does not omit everything.
|
// so that 'strip' does not omit everything.
|
||||||
Elf32_Shdr shdr;
|
Elf_LE32_Shdr shdr;
|
||||||
// The section header string table.
|
// The section header string table.
|
||||||
char const shstrtab[] = "\0.\0.shstrtab";
|
char const shstrtab[] = "\0.\0.shstrtab";
|
||||||
|
|
||||||
unsigned eod = elfout.phdr[0].p_filesz;
|
unsigned eod = elfout.phdr[0].p_filesz;
|
||||||
set_native32(&elfout.ehdr.e_shoff, eod);
|
elfout.ehdr.e_shoff = eod;
|
||||||
set_native16(&elfout.ehdr.e_shentsize, sizeof(shdr));
|
elfout.ehdr.e_shentsize = sizeof(shdr);
|
||||||
set_native16(&elfout.ehdr.e_shnum, 3);
|
elfout.ehdr.e_shnum = 3;
|
||||||
set_native16(&elfout.ehdr.e_shstrndx, 2);
|
elfout.ehdr.e_shstrndx = 2;
|
||||||
|
|
||||||
// An empty Elf32_Shdr for space as a null index.
|
// An empty Elf32_Shdr for space as a null index.
|
||||||
memset(&shdr, 0, sizeof(shdr));
|
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));
|
fo->write(&shdr, sizeof(shdr));
|
||||||
|
|
||||||
// Cover all the bits we need at runtime.
|
// Cover all the bits we need at runtime.
|
||||||
memset(&shdr, 0, sizeof(shdr));
|
memset(&shdr, 0, sizeof(shdr));
|
||||||
set_native32(&shdr.sh_name, 1);
|
shdr.sh_name = 1;
|
||||||
set_native32(&shdr.sh_type, Elf32_Shdr::SHT_PROGBITS);
|
shdr.sh_type = Elf32_Shdr::SHT_PROGBITS;
|
||||||
set_native32(&shdr.sh_flags, Elf32_Shdr::SHF_ALLOC);
|
shdr.sh_flags = Elf32_Shdr::SHF_ALLOC;
|
||||||
set_native32(&shdr.sh_addr, elfout.phdr[0].p_vaddr);
|
shdr.sh_addr = elfout.phdr[0].p_vaddr;
|
||||||
set_native32(&shdr.sh_offset, overlay_offset);
|
shdr.sh_offset = overlay_offset;
|
||||||
set_native32(&shdr.sh_size, eod - overlay_offset);
|
shdr.sh_size = eod - overlay_offset;
|
||||||
set_native32(&shdr.sh_addralign, 4096);
|
shdr.sh_addralign = 4096;
|
||||||
fo->write(&shdr, sizeof(shdr));
|
fo->write(&shdr, sizeof(shdr));
|
||||||
|
|
||||||
// A section header for the section header string table.
|
// A section header for the section header string table.
|
||||||
memset(&shdr, 0, sizeof(shdr));
|
memset(&shdr, 0, sizeof(shdr));
|
||||||
set_native32(&shdr.sh_name, 3);
|
shdr.sh_name = 3;
|
||||||
set_native32(&shdr.sh_type, Elf32_Shdr::SHT_STRTAB);
|
shdr.sh_type = Elf32_Shdr::SHT_STRTAB;
|
||||||
set_native32(&shdr.sh_offset, 3*sizeof(shdr) + eod);
|
shdr.sh_offset = 3*sizeof(shdr) + eod;
|
||||||
set_native32(&shdr.sh_size, sizeof(shstrtab));
|
shdr.sh_size = sizeof(shstrtab);
|
||||||
fo->write(&shdr, sizeof(shdr));
|
fo->write(&shdr, sizeof(shdr));
|
||||||
|
|
||||||
fo->write(shstrtab, sizeof(shstrtab));
|
fo->write(shstrtab, sizeof(shstrtab));
|
||||||
@ -273,7 +272,7 @@ PackLinuxI386::buildLinuxLoader(
|
|||||||
fold_hdrlen = umax(0x80, fold_hdrlen);
|
fold_hdrlen = umax(0x80, fold_hdrlen);
|
||||||
}
|
}
|
||||||
h.sz_unc = (szfold < fold_hdrlen) ? 0 : (szfold - 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_ftid = (unsigned char) ph.filter;
|
||||||
h.b_cto8 = (unsigned char) ph.filter_cto;
|
h.b_cto8 = (unsigned char) ph.filter_cto;
|
||||||
}
|
}
|
||||||
@ -286,6 +285,7 @@ PackLinuxI386::buildLinuxLoader(
|
|||||||
h.sz_cpr = sz_cpr;
|
h.sz_cpr = sz_cpr;
|
||||||
}
|
}
|
||||||
// This adds the definition to the "library", to be used later.
|
// 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);
|
linker->addSection("FOLDEXEC", cprLoader, h.sz_cpr);
|
||||||
delete [] cprLoader;
|
delete [] cprLoader;
|
||||||
|
|
||||||
|
|||||||
@ -86,22 +86,22 @@ protected:
|
|||||||
unsigned n_mru;
|
unsigned n_mru;
|
||||||
|
|
||||||
struct cprElfHdr1 {
|
struct cprElfHdr1 {
|
||||||
Elf32_Ehdr ehdr;
|
Elf_LE32_Ehdr ehdr;
|
||||||
Elf32_Phdr phdr[1];
|
Elf_LE32_Phdr phdr[1];
|
||||||
l_info linfo;
|
l_info linfo;
|
||||||
}
|
}
|
||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|
||||||
struct cprElfHdr2 {
|
struct cprElfHdr2 {
|
||||||
Elf32_Ehdr ehdr;
|
Elf_LE32_Ehdr ehdr;
|
||||||
Elf32_Phdr phdr[2];
|
Elf_LE32_Phdr phdr[2];
|
||||||
l_info linfo;
|
l_info linfo;
|
||||||
}
|
}
|
||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|
||||||
struct cprElfHdr3 {
|
struct cprElfHdr3 {
|
||||||
Elf32_Ehdr ehdr;
|
Elf_LE32_Ehdr ehdr;
|
||||||
Elf32_Phdr phdr[3];
|
Elf_LE32_Phdr phdr[3];
|
||||||
l_info linfo;
|
l_info linfo;
|
||||||
}
|
}
|
||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|||||||
@ -133,46 +133,28 @@ decompress:
|
|||||||
%define p_filesize 4
|
%define p_filesize 4
|
||||||
|
|
||||||
; Decompress the rest of this loader, and jump to it
|
; Decompress the rest of this loader, and jump to it
|
||||||
unfold:
|
main:
|
||||||
pop esi ; &{ sz_uncompressed, sz_compressed, compressed_data...}
|
pop ebp ; &decompress
|
||||||
cld
|
mov eax,0x1400000 ; &Elf32_Ehdr of this stub
|
||||||
lodsd
|
lea edx,[0x80 + szp_info + eax] ; &cprScript
|
||||||
push eax ; sz_uncompressed of folded stub (junk, actually)
|
add eax,[p_memsz + szElf32_Ehdr + eax] ; after .text
|
||||||
push esp ; &sz_uncompressed
|
add eax,PAGE_SIZE -1
|
||||||
mov edx, 0x01400000 ; origin of this program
|
and eax, -PAGE_SIZE ; round up to next page
|
||||||
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
|
|
||||||
|
|
||||||
; mmap space for unfolded stub, and uncompressed script
|
push byte 0
|
||||||
mov ecx, [szl_info + p_filesize + edx] ; script size
|
push byte -1
|
||||||
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 MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS
|
push byte MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS
|
||||||
push byte PROT_READ | PROT_WRITE | PROT_EXEC
|
push byte PROT_READ | PROT_WRITE
|
||||||
push ecx ; length
|
push dword [edx] ; sz_unc length
|
||||||
push eax ; destination
|
push eax ; address
|
||||||
mov ebx, esp ; address of parameter vector for __NR_mmap
|
mov ebx,esp
|
||||||
push byte __NR_mmap
|
push byte __NR_mmap
|
||||||
pop eax
|
pop eax
|
||||||
int 0x80
|
int 0x80
|
||||||
lea ebx, [3+ PAGE_SIZE + eax] ; place for uncompressed script
|
add esp, byte 6*4 ; remove arguments
|
||||||
add esp, byte 6*4 ; discard args to mmap
|
|
||||||
|
|
||||||
lodsd
|
lea ebx,[3+ eax] ; space for "-c"
|
||||||
push eax ; sz_compressed of folded stub
|
; fall into fold [not compressed!]
|
||||||
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
|
|
||||||
|
|
||||||
eof:
|
eof:
|
||||||
; __XTHEENDX__
|
; __XTHEENDX__
|
||||||
|
|||||||
@ -44,10 +44,7 @@
|
|||||||
%define a_val 4
|
%define a_val 4
|
||||||
%define sz_auxv 8
|
%define sz_auxv 8
|
||||||
|
|
||||||
fold_begin: ; enter: %ebx= uncDst
|
fold_begin: ; In: %ebx= uncDst; edx= &b_info cprSrc; ebp = &decompress
|
||||||
; also edx= szElf32_Ehdr + 2*szElf32_Phdr + &Elf32_Ehdr
|
|
||||||
pop eax ; discard &sz_uncompressed
|
|
||||||
pop eax ; discard sz_uncompressed
|
|
||||||
|
|
||||||
; Move argc,argv,envp down to make room for complete Elf_auxv table.
|
; 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
|
; 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
|
sub esp, dword MAX_ELF_HDR + OVERHEAD
|
||||||
|
|
||||||
xchg eax, ebx ; eax= uncDst
|
xchg eax, ebx ; eax= uncDst
|
||||||
lea edx, [szl_info + szp_info + edx] ; cprSrc
|
|
||||||
mov ecx, [ edx] ; sz_unc
|
mov ecx, [ edx] ; sz_unc
|
||||||
mov ebx, [4+ edx] ; sz_cpr
|
mov ebx, [4+ edx] ; sz_cpr
|
||||||
mov esi, eax ; extra copy of uncDst
|
mov esi, eax ; extra copy of uncDst
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user