mirror of
https://github.com/upx/upx
synced 2025-10-05 19:20:23 +08:00
Mach-o MH_EXECUTE rewrite; work-in-progress
The stub for amd64 gets into the de-compressed folded code. modified: p_mach.cpp modified: stub/amd64-darwin.macho-entry.h modified: stub/src/amd64-darwin.macho-entry.S modified: stub/src/amd64-darwin.macho-upxmain.c modified: stub/tmp/amd64-darwin.macho-entry.bin.dump
This commit is contained in:
parent
4f6979967d
commit
c6d6378005
|
@ -356,11 +356,8 @@ void PackMachI386::addStubEntrySections(Filter const *ft)
|
||||||
|
|
||||||
void PackMachAMD64::addStubEntrySections(Filter const * /*ft*/)
|
void PackMachAMD64::addStubEntrySections(Filter const * /*ft*/)
|
||||||
{
|
{
|
||||||
if (my_filetype==Mach_header::MH_DYLIB) {
|
addLoader("MACHMAINX", NULL); // different for MY_DYLIB vs MH_EXECUTE
|
||||||
addLoader("MACHMAINX", NULL);
|
if (my_filetype==Mach_header::MH_EXECUTE) {
|
||||||
}
|
|
||||||
else {
|
|
||||||
addLoader("AMD64BXX", NULL);
|
|
||||||
addLoader("MACH_UNC", NULL);
|
addLoader("MACH_UNC", NULL);
|
||||||
}
|
}
|
||||||
//addLoader(getDecompressorSections(), NULL);
|
//addLoader(getDecompressorSections(), NULL);
|
||||||
|
@ -372,10 +369,7 @@ void PackMachAMD64::addStubEntrySections(Filter const * /*ft*/)
|
||||||
: NULL), NULL);
|
: NULL), NULL);
|
||||||
if (hasLoaderSection("CFLUSH"))
|
if (hasLoaderSection("CFLUSH"))
|
||||||
addLoader("CFLUSH");
|
addLoader("CFLUSH");
|
||||||
addLoader("MACHMAINY,IDENTSTR,+40,MACHMAINZ", NULL);
|
addLoader("MACHMAINY,IDENTSTR,+40,MACHMAINZ,FOLDEXEC", NULL);
|
||||||
if (my_filetype!=Mach_header::MH_EXECUTE) {
|
|
||||||
addLoader("FOLDEXEC", NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackMachPPC32::addStubEntrySections(Filter const * /*ft*/)
|
void PackMachPPC32::addStubEntrySections(Filter const * /*ft*/)
|
||||||
|
@ -562,6 +556,8 @@ PackMachBase<T>::compare_segment_command(void const *const aa, void const *const
|
||||||
#define PAGE_MASK64 (~(upx_uint64_t)0<<12)
|
#define PAGE_MASK64 (~(upx_uint64_t)0<<12)
|
||||||
#define PAGE_SIZE64 ((upx_uint64_t)0-PAGE_MASK64)
|
#define PAGE_SIZE64 ((upx_uint64_t)0-PAGE_MASK64)
|
||||||
|
|
||||||
|
// Note: "readelf --segments" ==> "otool -hl" or "otool -hlv" etc. (Xcode on MacOS)
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void PackMachBase<T>::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
void PackMachBase<T>::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
||||||
{
|
{
|
||||||
|
@ -954,9 +950,10 @@ off_t PackMachBase<T>::pack3(OutputFile *fo, Filter &ft) // append loader
|
||||||
disp = len - sz_mach_headers; // backward offset to start of compressed data
|
disp = len - sz_mach_headers; // backward offset to start of compressed data
|
||||||
fo->write(&disp, sizeof(disp));
|
fo->write(&disp, sizeof(disp));
|
||||||
len += sizeof(disp);
|
len += sizeof(disp);
|
||||||
|
segTEXT.vmsize = segLINK.vmaddr - segTEXT.vmaddr; // must protect this much
|
||||||
threado_setPC(entryVMA= len + segTEXT.vmaddr);
|
threado_setPC(entryVMA= len + segTEXT.vmaddr);
|
||||||
|
|
||||||
return segTEXT.vmsize = super::pack3(fo, ft);
|
return super::pack3(fo, ft);
|
||||||
}
|
}
|
||||||
|
|
||||||
off_t PackDylibI386::pack3(OutputFile *fo, Filter &ft) // append loader
|
off_t PackDylibI386::pack3(OutputFile *fo, Filter &ft) // append loader
|
||||||
|
@ -1329,6 +1326,7 @@ void PackMachBase<T>::pack1(OutputFile *const fo, Filter &/*ft*/) // generate e
|
||||||
segLINK.initprot = Mach_command::VM_PROT_READ;
|
segLINK.initprot = Mach_command::VM_PROT_READ;
|
||||||
// Adjust later: .vmaddr .vmsize .fileoff .filesize
|
// Adjust later: .vmaddr .vmsize .fileoff .filesize
|
||||||
|
|
||||||
|
unsigned gap = 0;
|
||||||
if (my_filetype == Mach_header::MH_EXECUTE) {
|
if (my_filetype == Mach_header::MH_EXECUTE) {
|
||||||
unsigned cmdsize = mhdro.sizeofcmds;
|
unsigned cmdsize = mhdro.sizeofcmds;
|
||||||
Mach_header const *const ptr0 = (Mach_header const *)stub_main;
|
Mach_header const *const ptr0 = (Mach_header const *)stub_main;
|
||||||
|
@ -1355,11 +1353,13 @@ void PackMachBase<T>::pack1(OutputFile *const fo, Filter &/*ft*/) // generate e
|
||||||
pos += cmdsize;
|
pos += cmdsize;
|
||||||
fo->write((char const *)ptr1, cmdsize);
|
fo->write((char const *)ptr1, cmdsize);
|
||||||
|
|
||||||
sz_mach_headers = fo->getBytesWritten();
|
gap = 400 + threado_size();
|
||||||
|
secTEXT.addr = gap + pos;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sz_mach_headers = fo->getBytesWritten();
|
||||||
}
|
}
|
||||||
else if (my_filetype == Mach_header::MH_DYLIB) {
|
else if (my_filetype == Mach_header::MH_DYLIB) {
|
||||||
Mach_command const *ptr = (Mach_command const *)rawmseg;
|
Mach_command const *ptr = (Mach_command const *)rawmseg;
|
||||||
|
@ -1393,13 +1393,13 @@ void PackMachBase<T>::pack1(OutputFile *const fo, Filter &/*ft*/) // generate e
|
||||||
fo->write(&linkitem, sizeof(linkitem));
|
fo->write(&linkitem, sizeof(linkitem));
|
||||||
fo->write(rawmseg, mhdri.sizeofcmds);
|
fo->write(rawmseg, mhdri.sizeofcmds);
|
||||||
|
|
||||||
sz_mach_headers = fo->getBytesWritten();
|
gap = secTEXT.offset - sz_mach_headers;
|
||||||
unsigned gap = secTEXT.offset - sz_mach_headers;
|
|
||||||
MemBuffer filler(gap);
|
|
||||||
memset(filler, 0, gap);
|
|
||||||
fo->write(filler, gap);
|
|
||||||
sz_mach_headers += gap;
|
|
||||||
}
|
}
|
||||||
|
sz_mach_headers = fo->getBytesWritten();
|
||||||
|
MemBuffer filler(gap);
|
||||||
|
memset(filler, 0, gap);
|
||||||
|
fo->write(filler, gap);
|
||||||
|
sz_mach_headers += gap;
|
||||||
|
|
||||||
memset((char *)&linfo, 0, sizeof(linfo));
|
memset((char *)&linfo, 0, sizeof(linfo));
|
||||||
fo->write(&linfo, sizeof(linfo));
|
fo->write(&linfo, sizeof(linfo));
|
||||||
|
@ -1971,12 +1971,13 @@ bool PackMachBase<T>::canPack()
|
||||||
fsm.segZERO.nsects = 0;
|
fsm.segZERO.nsects = 0;
|
||||||
fsm.segZERO.flags = 0;
|
fsm.segZERO.flags = 0;
|
||||||
|
|
||||||
|
unsigned const slop = 400;
|
||||||
fsm.segTEXT.cmd = fsm.segZERO.cmd;
|
fsm.segTEXT.cmd = fsm.segZERO.cmd;
|
||||||
fsm.segTEXT.cmdsize = sizeof(Mach_segment_command)
|
fsm.segTEXT.cmdsize = sizeof(Mach_segment_command)
|
||||||
+ sizeof(Mach_section_command);
|
+ sizeof(Mach_section_command);
|
||||||
strncpy(fsm.segTEXT.segname, "__TEXT", sizeof(fsm.segTEXT.segname));
|
strncpy(fsm.segTEXT.segname, "__TEXT", sizeof(fsm.segTEXT.segname));
|
||||||
fsm.segTEXT.vmaddr = fsm.segZERO.vmsize; // dummy?
|
fsm.segTEXT.vmaddr = fsm.segZERO.vmsize;
|
||||||
fsm.segTEXT.vmsize = 0;
|
fsm.segTEXT.vmsize = slop + threado_size() + sizeof(fsm); // dummy
|
||||||
fsm.segTEXT.fileoff = 0;
|
fsm.segTEXT.fileoff = 0;
|
||||||
fsm.segTEXT.filesize = fsm.segTEXT.vmsize; // dummy
|
fsm.segTEXT.filesize = fsm.segTEXT.vmsize; // dummy
|
||||||
fsm.segTEXT.maxprot = VM_PROT_EXECUTE | VM_PROT_READ;
|
fsm.segTEXT.maxprot = VM_PROT_EXECUTE | VM_PROT_READ;
|
||||||
|
@ -1986,7 +1987,7 @@ bool PackMachBase<T>::canPack()
|
||||||
|
|
||||||
strncpy(fsm.secTEXT.sectname, "__text", sizeof(fsm.secTEXT.sectname));
|
strncpy(fsm.secTEXT.sectname, "__text", sizeof(fsm.secTEXT.sectname));
|
||||||
memcpy(fsm.secTEXT.segname, fsm.segTEXT.segname, sizeof(fsm.secTEXT.segname));
|
memcpy(fsm.secTEXT.segname, fsm.segTEXT.segname, sizeof(fsm.secTEXT.segname));
|
||||||
unsigned const d = 400 + fsm.mhdri.sizeofcmds;
|
unsigned const d = slop + fsm.mhdri.sizeofcmds;
|
||||||
fsm.secTEXT.addr = fsm.segTEXT.vmaddr + d; // dummy
|
fsm.secTEXT.addr = fsm.segTEXT.vmaddr + d; // dummy
|
||||||
fsm.secTEXT.size = fsm.segTEXT.vmsize - d; // dummy
|
fsm.secTEXT.size = fsm.segTEXT.vmsize - d; // dummy
|
||||||
fsm.secTEXT.offset = d; // dummy
|
fsm.secTEXT.offset = d; // dummy
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -37,11 +37,20 @@ NBPW= 8
|
||||||
#include "arch/amd64/regs.h"
|
#include "arch/amd64/regs.h"
|
||||||
|
|
||||||
mlc_cmd = 0
|
mlc_cmd = 0
|
||||||
|
LC_SEGMENT_64= 0x19
|
||||||
mlc_cmdsize = 4
|
mlc_cmdsize = 4
|
||||||
|
|
||||||
mseg_segname = 8
|
sz_Mach_header64= 8*4
|
||||||
mseg_vmsize = 4+4+16+NBPW
|
mhdr_ncmds= 4*4
|
||||||
mseg_initprot = 4+4+16+(4*NBPW)+4
|
|
||||||
|
sz_Mach_segment= 2*4 + 16 + 4*NBPW + 4*4
|
||||||
|
mseg_segname= 2*4
|
||||||
|
mseg_vmaddr= 2*4 + 16
|
||||||
|
mseg_vmsize= 2*4 + 16 + NBPW
|
||||||
|
mseg_initprot= 2*4 + 16 + (4*NBPW) + 4
|
||||||
|
|
||||||
|
msec_addr= 2*16
|
||||||
|
msec_size= 2*16 + NBPW
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// program entry point
|
// program entry point
|
||||||
|
@ -56,9 +65,10 @@ PROT_WRITE = 2
|
||||||
PROT_EXEC = 4
|
PROT_EXEC = 4
|
||||||
MAP_ANON_FD = -1
|
MAP_ANON_FD = -1
|
||||||
|
|
||||||
SYS_mmap =0xc5
|
SYSBASE= 0x02000000
|
||||||
SYS_mprotect =0x4a
|
SYS_mmap =0xc5 + SYSBASE
|
||||||
SYS_munmap =0x49
|
SYS_mprotect =0x4a + SYSBASE
|
||||||
|
SYS_munmap =0x49 + SYSBASE
|
||||||
|
|
||||||
#define __c4(a,b,c,d) (((a)<<(0*8)) | ((b)<<(1*8)) | ((c)<<(2*8)) | ((d)<<(3*8)))
|
#define __c4(a,b,c,d) (((a)<<(0*8)) | ((b)<<(1*8)) | ((c)<<(2*8)) | ((d)<<(3*8)))
|
||||||
#define __c8(a,b,c,d,e,f,g,h) (__c4(a,b,c,d) | (__c4(e,f,g,h) << 32))
|
#define __c8(a,b,c,d,e,f,g,h) (__c4(a,b,c,d) | (__c4(e,f,g,h) << 32))
|
||||||
|
@ -78,52 +88,51 @@ SYS_munmap =0x49
|
||||||
// "executable_file=0x1000008,0x2209ce"
|
// "executable_file=0x1000008,0x2209ce"
|
||||||
// when %rsp was 0x7ffeefbffaf0.
|
// when %rsp was 0x7ffeefbffaf0.
|
||||||
|
|
||||||
|
// Notes:
|
||||||
|
// Command-line debugger from Xcode: lldb foo; "process launch -s"
|
||||||
|
|
||||||
section MACHMAINX
|
section MACHMAINX
|
||||||
_start: .globl _start
|
_start: .globl _start
|
||||||
// int3
|
// int3
|
||||||
|
#define r_cmdp rbx
|
||||||
|
#define r_ncmds r12d
|
||||||
|
#define r_reloc r15
|
||||||
lea -2*4+_start(%rip),%rbp; movl (%rbp),%eax; sub %rax,%rbp // &Mach_header64
|
lea -2*4+_start(%rip),%rbp; movl (%rbp),%eax; sub %rax,%rbp // &Mach_header64
|
||||||
mov mhdr_ncmds(%rbp),%r12d
|
push %rbp // P_01 &Mach_header64 before argc
|
||||||
lea sz_Mach_header64(%rbp),%rbx // ptr
|
mov mhdr_ncmds(%rbp),%r_ncmds
|
||||||
|
lea sz_Mach_header64(%rbp),%r_cmdp // ptr
|
||||||
L20:
|
L20:
|
||||||
cmpl $LC_SEGMENT_64,mlc_cmd(%rbx); jne L50
|
cmpl $LC_SEGMENT_64,mlc_cmd(%r_cmdp); jne L50
|
||||||
cmpl $__c4('T','E','X','T'),2+mseg_segname(%rbx); jne L40
|
cmpl $__c4('T','E','X','T'),2+mseg_segname(%r_cmdp); jne L40
|
||||||
sub %arg1l,%arg1l // 0 addr
|
sub %arg1l,%arg1l // 0 addr
|
||||||
mov %arg1,%arg6 // 0 off_t
|
mov %arg1,%arg6 // 0 off_t
|
||||||
lea -1(%rdi),%arg5 // MAP_ANON_FD
|
lea -1(%arg1),%arg5 // MAP_ANON_FD
|
||||||
mov $MAP_PRIVATE|MAP_ANON,%sys4l
|
mov $MAP_PRIVATE|MAP_ANON,%sys4l
|
||||||
mov $PROT_WRITE|PROT_READ,%arg3l
|
mov $PROT_WRITE|PROT_READ,%arg3l
|
||||||
mov mseg_vmsize(%rbx),%arg2
|
mov mseg_vmsize(%r_cmdp),%arg2
|
||||||
|
movl sz_unc+FOLD(%rip),%eax
|
||||||
|
add %rax,%arg2; mov %arg2,%r14
|
||||||
mov $SYS_mmap,%eax; syscall
|
mov $SYS_mmap,%eax; syscall
|
||||||
mov %rax,%r15 // vmaddr
|
mov %rax,%r_reloc // vmaddr
|
||||||
|
sub %rbp,%r_reloc // reloc
|
||||||
|
push %rax // P_02
|
||||||
|
|
||||||
movq mseg_vmsize(%rbx),%arg3
|
// Copy only compression data, not Macho headers
|
||||||
movq mseg_vmaddr(%rbx),%arg2
|
movl msec_size + sz_Mach_segment(%r_cmdp),%ecx
|
||||||
mov %rax,%arg1
|
movq msec_addr + sz_Mach_segment(%r_cmdp),%rsi
|
||||||
call memcpy
|
mov %rax,%rdi
|
||||||
|
add $7,%ecx; shr $3,%ecx; rep movsq
|
||||||
movl mseg_initprot,%arg3l
|
jmp L60 // break;
|
||||||
movq mseg_vmsize(%rbx),%arg2
|
|
||||||
mov %rax,%arg1
|
|
||||||
mov $SYS_mprotect,%eax; syscall
|
|
||||||
|
|
||||||
sub 2*NBPW(%rsp),%r15 // reloc
|
|
||||||
call goto_clone
|
|
||||||
jmp L50
|
|
||||||
|
|
||||||
goto_clone:
|
goto_clone:
|
||||||
addq %r15,(%rsp) // retaddr += reloc
|
addq %r_reloc,(%rsp) // retaddr += reloc
|
||||||
ret
|
|
||||||
memcpy:
|
|
||||||
mov %arg3,%rcx; shr $3,%rcx; rep movsq
|
|
||||||
ret
|
ret
|
||||||
|
L40: // not TEXT
|
||||||
|
|
||||||
L40:
|
L50: // not LC_SEGMENT64
|
||||||
movabsq $__c8('L','I','N','K','E','D','I','T'),%rcx; cmp %rcx,2+mseg_segname(%rbx); jne L50
|
mov mlc_cmdsize(%r_cmdp),%eax; add %rax,%r_cmdp
|
||||||
|
sub $1,%r_ncmds; jne L20
|
||||||
L50:
|
L60:
|
||||||
mov mlc_cmdsize(%rbx),%eax; add %rax,%rbx
|
|
||||||
sub $1,%ebp; jne L20
|
|
||||||
|
|
||||||
call main // push &decompress
|
call main // push &decompress
|
||||||
ret_main:
|
ret_main:
|
||||||
|
|
||||||
|
@ -269,36 +278,32 @@ sz_b_info= 12
|
||||||
|
|
||||||
// Decompress the rest of this loader, and jump to it.
|
// Decompress the rest of this loader, and jump to it.
|
||||||
unfold:
|
unfold:
|
||||||
pop %rbx // &{ b_info:{sz_unc, sz_cpr, 4{byte}}, compressed_data...}
|
pop %rsi // &{ b_info:{sz_unc, sz_cpr, 4{byte}}, compressed_fold...}
|
||||||
mov sz_cpr(%rbx),%ecx
|
|
||||||
lea -1+ sz_b_info(%rcx,%rbx),%rsi // &hi_byte folded original
|
|
||||||
#if 0
|
|
||||||
mov sz_unc(%rbx),%edi
|
|
||||||
#else
|
|
||||||
// sz_unc == 0
|
|
||||||
mov (%rbx),%edi
|
|
||||||
#endif
|
|
||||||
lea GAP + NO_LAP -1+ sz_b_info(%rdi,%rbx),%rdi // &hi_byte folded copy
|
|
||||||
std; rep movsb // copy descending
|
|
||||||
|
|
||||||
lea GAP (%rbx),%arg3 // &unfolded
|
pop %rcx // P_02
|
||||||
mov %rbx,%rsi // &b_info
|
push %rdi; pop %arg3 // dst
|
||||||
lea 1(%rdi),%arg1 // &lo_byte folded copy
|
push %rdi // P_03 entry addr to folded stub
|
||||||
push %arg3 // return to unfolded code
|
push %rcx // P_04 &copied data
|
||||||
|
lodsl; push %rax // P_05 allocate slot on stack
|
||||||
cld
|
movq %rsp,%arg4 // &dstlen ==> used by lzma for EOF
|
||||||
lodsl; push %rax // allocate slot on stack
|
lodsl; push %rax // P_06 sz_cpr XXX: 4GB
|
||||||
movq %rsp,%arg4 // &len_dst ==> used by lzma for EOF
|
|
||||||
lodsl; push %rax // sz_cpr XXX: 4GB
|
|
||||||
lodsl; movzbl %al,%arg5l // b_method
|
lodsl; movzbl %al,%arg5l // b_method
|
||||||
pop %arg2 // sz_cpr
|
push %rsi; pop %arg1 // src
|
||||||
call *%rbp // decompress(&src, srclen, &dst, &dstlen, b_info.misc)
|
pop %arg2 // P_06 sz_cpr
|
||||||
pop %rcx // discard len_dst
|
call *%rbp // decompress(src, srclen, dst, &dstlen, b_info.misc)
|
||||||
|
pop %rcx // P_05 discard len_dst
|
||||||
|
|
||||||
|
push $PROT_EXEC|PROT_READ; pop %arg3
|
||||||
|
mov %r14,%arg2 // len
|
||||||
|
pop %arg1 // P_04 &copied data
|
||||||
|
mov $SYS_mprotect,%rax; syscall
|
||||||
|
|
||||||
lea -4+ _start - ret_main(%rbp),%rbx // &total_length for fold:
|
lea -4+ _start - ret_main(%rbp),%rbx // &total_length for fold:
|
||||||
ret
|
ret // P_03
|
||||||
main:
|
main:
|
||||||
pop %rbp // &decompress
|
pop %rbp // &decompress
|
||||||
call unfold
|
call unfold
|
||||||
|
FOLD:
|
||||||
// compressed fold_elf86 follows
|
// compressed fold_elf86 follows
|
||||||
|
|
||||||
/* vim:set ts=8 sw=8 et: */
|
/* vim:set ts=8 sw=8 et: */
|
||||||
|
|
|
@ -689,86 +689,4 @@ ERR_LAB
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t cmd;
|
|
||||||
uint32_t cmdsize;
|
|
||||||
uint32_t data[2]; // because cmdsize >= 16
|
|
||||||
} Mach_command; // generic prefix
|
|
||||||
|
|
||||||
// Go to the clone.
|
|
||||||
extern void goto_clone(ptrdiff_t reloc);
|
|
||||||
//{
|
|
||||||
// add %arg1,(%rsp) // relocate return address
|
|
||||||
// ret
|
|
||||||
//}
|
|
||||||
|
|
||||||
extern void *memcpy(void *, void const *, size_t);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Build on Mac OS X: (where gcc is really clang)
|
|
||||||
// gcc -o amd64-darwin.macho-upxmain.exe \
|
|
||||||
// -Os -fPIC -fno-stack-protector \
|
|
||||||
// amd64-darwin.macho-upxmain.c \
|
|
||||||
// amd64-darwin.macho-upxsubr.S \
|
|
||||||
// -Wl,-pagezero_size,0xf0000000 \
|
|
||||||
// -Wl,-no_pie \
|
|
||||||
// -Wl,-no_uuid \
|
|
||||||
// -Wl,-no_function_starts \
|
|
||||||
// -Wl,-bind_at_load \
|
|
||||||
// -Wl,-headerpad,0x400 \
|
|
||||||
//
|
|
||||||
//# -Wl,-unexported_symbols_list unexport-upxload.txt \
|
|
||||||
//# strip -u -r amd64-darwin.macho-upxmain.exe
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
// Entry via JMP (with no parameters) instead of CALL
|
|
||||||
asm("movl 1*8(%%rbp),%0; leaq 2*8(%%rbp),%1" : "=r" (argc), "=r" (argv) : );
|
|
||||||
|
|
||||||
Mach_header64 const *mhdr0 = (Mach_header64 const *)((~0ul<<16) & (unsigned long)&main);
|
|
||||||
Mach_command const *ptr = (Mach_command const *)(1+ mhdr0);
|
|
||||||
ptrdiff_t reloc = 0;
|
|
||||||
f_unfilter *f_unf;
|
|
||||||
f_expand *f_exp;
|
|
||||||
char *payload;
|
|
||||||
size_t paysize;
|
|
||||||
|
|
||||||
unsigned j;
|
|
||||||
for (j=0; j < mhdr0->ncmds; ++j,
|
|
||||||
ptr = (Mach_command const *)(ptr->cmdsize + (char const *)ptr))
|
|
||||||
if (LC_SEGMENT_64==ptr->cmd) {
|
|
||||||
Mach_segment_command const *const seg = (Mach_segment_command const *)ptr;
|
|
||||||
// Compare 4 bytes
|
|
||||||
if (*(int const *)(&"__TEXT"[2]) == *(int const *)(&seg->segname[2])) {
|
|
||||||
Addr const vmaddr = (Addr)mmap(0, seg->vmsize, PROT_WRITE | PROT_READ,
|
|
||||||
MAP_PRIVATE | MAP_ANON, MAP_ANON_FD, 0);
|
|
||||||
memcpy(vmaddr, (void const *)seg->vmaddr, seg->vmsize);
|
|
||||||
mprotect(vmaddr, seg->vmsize, seg->initprot);
|
|
||||||
reloc = vmaddr - (Addr)mhdr0;
|
|
||||||
ptr = (Mach_command const *)(reloc + (Addr)ptr);
|
|
||||||
goto_clone(reloc);
|
|
||||||
} else
|
|
||||||
// Compare 8 bytes
|
|
||||||
if (*(long const *)(&"__LINKEDIT"[2]) == *(long const *)(&seg->segname[2])) {
|
|
||||||
Addr const vm2 = (Addr)(seg->vmaddr + reloc);
|
|
||||||
f_unf = (f_unfilter *)(sizeof(unsigned short) + vm2);
|
|
||||||
f_exp = (f_expand *)(*(unsigned short const *)vm2 + vm2);
|
|
||||||
unsigned const *q = (unsigned const *)vm2;
|
|
||||||
while (!(paysize = *--q)) /*empty*/ ;
|
|
||||||
payload = (char *)(-paysize + (char const *)q);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
char mhdr[16384];
|
|
||||||
uint64_t entry = upx_main((struct l_info const *)payload, paysize,
|
|
||||||
(Mach_header64 *)mhdr, sizeof(mhdr),
|
|
||||||
f_exp, f_unf, (Mach_header64 **)&argv[-2]);
|
|
||||||
|
|
||||||
argv[-1] = (char *)(long)argc;
|
|
||||||
munmap(payload, paysize); // leaving __LINKEDIT
|
|
||||||
asm("lea -2*8(%1),%%rsp; jmp *%0" : : "r" (entry), "r" (argv));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|
|
@ -3,19 +3,19 @@ file format elf64-x86-64
|
||||||
Sections:
|
Sections:
|
||||||
Idx Name Size VMA LMA File off Algn Flags
|
Idx Name Size VMA LMA File off Algn Flags
|
||||||
0 AMD64BXX 0000004c 0000000000000000 0000000000000000 00000040 2**0 CONTENTS, READONLY
|
0 AMD64BXX 0000004c 0000000000000000 0000000000000000 00000040 2**0 CONTENTS, READONLY
|
||||||
1 MACHMAINX 000000b7 0000000000000000 0000000000000000 0000008c 2**0 CONTENTS, RELOC, READONLY
|
1 MACHMAINX 00000082 0000000000000000 0000000000000000 0000008c 2**0 CONTENTS, RELOC, READONLY
|
||||||
2 MACH_UNC 00000008 0000000000000000 0000000000000000 00000143 2**0 CONTENTS, READONLY
|
2 MACH_UNC 00000008 0000000000000000 0000000000000000 0000010e 2**0 CONTENTS, READONLY
|
||||||
3 NRV_HEAD 00000067 0000000000000000 0000000000000000 0000014b 2**0 CONTENTS, READONLY
|
3 NRV_HEAD 00000067 0000000000000000 0000000000000000 00000116 2**0 CONTENTS, READONLY
|
||||||
4 NRV2E 000000b7 0000000000000000 0000000000000000 000001b2 2**0 CONTENTS, RELOC, READONLY
|
4 NRV2E 000000b7 0000000000000000 0000000000000000 0000017d 2**0 CONTENTS, RELOC, READONLY
|
||||||
5 NRV2D 0000009e 0000000000000000 0000000000000000 00000269 2**0 CONTENTS, RELOC, READONLY
|
5 NRV2D 0000009e 0000000000000000 0000000000000000 00000234 2**0 CONTENTS, RELOC, READONLY
|
||||||
6 NRV2B 00000090 0000000000000000 0000000000000000 00000307 2**0 CONTENTS, RELOC, READONLY
|
6 NRV2B 00000090 0000000000000000 0000000000000000 000002d2 2**0 CONTENTS, RELOC, READONLY
|
||||||
7 LZMA_ELF00 00000064 0000000000000000 0000000000000000 00000397 2**0 CONTENTS, RELOC, READONLY
|
7 LZMA_ELF00 00000064 0000000000000000 0000000000000000 00000362 2**0 CONTENTS, RELOC, READONLY
|
||||||
8 LZMA_DEC10 000009f7 0000000000000000 0000000000000000 000003fb 2**0 CONTENTS, READONLY
|
8 LZMA_DEC10 000009f7 0000000000000000 0000000000000000 000003c6 2**0 CONTENTS, READONLY
|
||||||
9 LZMA_DEC20 000009f7 0000000000000000 0000000000000000 00000df2 2**0 CONTENTS, READONLY
|
9 LZMA_DEC20 000009f7 0000000000000000 0000000000000000 00000dbd 2**0 CONTENTS, READONLY
|
||||||
10 LZMA_DEC30 00000014 0000000000000000 0000000000000000 000017e9 2**0 CONTENTS, READONLY
|
10 LZMA_DEC30 00000014 0000000000000000 0000000000000000 000017b4 2**0 CONTENTS, READONLY
|
||||||
11 NRV_TAIL 00000000 0000000000000000 0000000000000000 000017fd 2**0 CONTENTS, READONLY
|
11 NRV_TAIL 00000000 0000000000000000 0000000000000000 000017c8 2**0 CONTENTS, READONLY
|
||||||
12 MACHMAINY 00000011 0000000000000000 0000000000000000 000017fd 2**0 CONTENTS, READONLY
|
12 MACHMAINY 00000011 0000000000000000 0000000000000000 000017c8 2**0 CONTENTS, READONLY
|
||||||
13 MACHMAINZ 00000044 0000000000000000 0000000000000000 0000180e 2**0 CONTENTS, READONLY
|
13 MACHMAINZ 00000036 0000000000000000 0000000000000000 000017d9 2**0 CONTENTS, READONLY
|
||||||
SYMBOL TABLE:
|
SYMBOL TABLE:
|
||||||
0000000000000000 l d NRV_HEAD 0000000000000000 NRV_HEAD
|
0000000000000000 l d NRV_HEAD 0000000000000000 NRV_HEAD
|
||||||
0000000000000000 l d LZMA_DEC30 0000000000000000 LZMA_DEC30
|
0000000000000000 l d LZMA_DEC30 0000000000000000 LZMA_DEC30
|
||||||
|
@ -32,20 +32,13 @@ SYMBOL TABLE:
|
||||||
0000000000000000 l d LZMA_DEC20 0000000000000000 LZMA_DEC20
|
0000000000000000 l d LZMA_DEC20 0000000000000000 LZMA_DEC20
|
||||||
0000000000000000 l d NRV_TAIL 0000000000000000 NRV_TAIL
|
0000000000000000 l d NRV_TAIL 0000000000000000 NRV_TAIL
|
||||||
0000000000000000 g MACHMAINX 0000000000000000 _start
|
0000000000000000 g MACHMAINX 0000000000000000 _start
|
||||||
0000000000000000 *UND* 0000000000000000 mhdr_ncmds
|
|
||||||
0000000000000000 *UND* 0000000000000000 sz_Mach_header64
|
|
||||||
0000000000000000 *UND* 0000000000000000 LC_SEGMENT_64
|
|
||||||
0000000000000000 *UND* 0000000000000000 mseg_vmaddr
|
|
||||||
0000000000000011 g MACHMAINY 0000000000000000 end_decompress
|
0000000000000011 g MACHMAINY 0000000000000000 end_decompress
|
||||||
|
|
||||||
RELOCATION RECORDS FOR [MACHMAINX]:
|
RELOCATION RECORDS FOR [MACHMAINX]:
|
||||||
OFFSET TYPE VALUE
|
OFFSET TYPE VALUE
|
||||||
0000000000000003 R_X86_64_PC32 _start+0xfffffffffffffff4
|
0000000000000003 R_X86_64_PC32 _start+0xfffffffffffffff4
|
||||||
0000000000000010 R_X86_64_32S mhdr_ncmds
|
000000000000003f R_X86_64_PC32 MACHMAINZ+0x0000000000000032
|
||||||
0000000000000017 R_X86_64_32S sz_Mach_header64
|
000000000000007e R_X86_64_PC32 MACHMAINZ+0x000000000000002c
|
||||||
000000000000001e R_X86_64_32 LC_SEGMENT_64
|
|
||||||
0000000000000056 R_X86_64_32S mseg_vmaddr
|
|
||||||
00000000000000b3 R_X86_64_PC32 MACHMAINZ+0x000000000000003a
|
|
||||||
|
|
||||||
RELOCATION RECORDS FOR [NRV2E]:
|
RELOCATION RECORDS FOR [NRV2E]:
|
||||||
OFFSET TYPE VALUE
|
OFFSET TYPE VALUE
|
||||||
|
|
Loading…
Reference in New Issue
Block a user