1
0
mirror of https://github.com/upx/upx synced 2025-09-28 19:06:07 +08:00

Compression part for Mach dylib i386.

This commit is contained in:
John Reiser 2009-05-13 10:40:21 -07:00
parent 9694ff433f
commit 3a9e0b5be6
6 changed files with 355 additions and 24 deletions

View File

@ -474,6 +474,8 @@ private:
#define UPX_F_VMLINUZ_ARMEL 31 #define UPX_F_VMLINUZ_ARMEL 31
#define UPX_F_MACH_ARMEL 32 #define UPX_F_MACH_ARMEL 32
#define UPX_F_DYLIB_i386 33
#define UPX_F_PLAIN_TEXT 127 #define UPX_F_PLAIN_TEXT 127
#define UPX_F_ATARI_TOS 129 #define UPX_F_ATARI_TOS 129

View File

@ -50,9 +50,9 @@ static const
#include "stub/arm-darwin.macho-fold.h" #include "stub/arm-darwin.macho-fold.h"
template <class T> template <class T>
PackMachBase<T>::PackMachBase(InputFile *f, unsigned cputype, unsigned flavor, PackMachBase<T>::PackMachBase(InputFile *f, unsigned cputype, unsigned filetype,
unsigned count, unsigned size) : unsigned flavor, unsigned count, unsigned size) :
super(f), my_cputype(cputype), my_thread_flavor(flavor), super(f), my_cputype(cputype), my_filetype(filetype), my_thread_flavor(flavor),
my_thread_state_word_count(count), my_thread_command_size(size), my_thread_state_word_count(count), my_thread_command_size(size),
n_segment(0), rawmseg(NULL), msegcmd(NULL) n_segment(0), rawmseg(NULL), msegcmd(NULL)
{ {
@ -207,6 +207,10 @@ void PackMachARMEL::addStubEntrySections(Filter const */*ft*/)
addLoader("MACHMAINY,IDENTSTR,+40,MACHMAINZ,FOLDEXEC", NULL); addLoader("MACHMAINY,IDENTSTR,+40,MACHMAINZ,FOLDEXEC", NULL);
} }
void PackDylibI386::addStubEntrySections(Filter const *ft)
{
super::addStubEntrySections(ft);
}
template <class T> template <class T>
void PackMachBase<T>::defineSymbols(Filter const *) void PackMachBase<T>::defineSymbols(Filter const *)
@ -286,6 +290,12 @@ PackMachARMEL::buildLoader(const Filter *ft)
stub_arm_darwin_macho_fold, sizeof(stub_arm_darwin_macho_fold), ft ); stub_arm_darwin_macho_fold, sizeof(stub_arm_darwin_macho_fold), ft );
} }
void
PackDylibI386::buildLoader(const Filter *ft)
{
super::buildLoader(ft);
}
template <class T> template <class T>
void PackMachBase<T>::patchLoader() { } void PackMachBase<T>::patchLoader() { }
@ -364,6 +374,121 @@ void PackMachARMEL::pack4(OutputFile *fo, Filter &ft) // append PackHeader
fo->rewrite(&linfo, sizeof(linfo)); fo->rewrite(&linfo, sizeof(linfo));
} }
#undef PAGE_MASK
#undef PAGE_SIZE
#define PAGE_MASK (~0u<<12)
#define PAGE_SIZE -PAGE_MASK
void PackDylibI386::pack4(OutputFile *fo, Filter &ft) // append PackHeader
{
unsigned opos = fo->getBytesWritten();
segcmdo.filesize = opos;
segcmdo.vmsize += opos;
rcmd.init_address = threado.state.eip;
fo->seek(sizeof(mhdro), SEEK_SET);
fo->rewrite(&segcmdo, sizeof(segcmdo));
fo->seek(sizeof(mhdro) + mhdro.sizeofcmds - sizeof(rcmd), SEEK_SET);
fo->rewrite(&rcmd, sizeof(rcmd));
fo->rewrite(&linfo, sizeof(linfo));
// Append __IMPORT and __LINKEDIT segments, page aligned.
int slide = 0;
unsigned hdrpos = sizeof(mhdro) + sizeof(segcmdo);
Mach_segment_command const *seg = rawmseg;
Mach_segment_command const *const endseg =
(Mach_segment_command const *)(mhdri.sizeofcmds + (char const *)seg);
for ( ; seg < endseg; seg = (Mach_segment_command const *)(
seg->cmdsize + (char const *)seg )
) switch (~Mach_segment_command::LC_REQ_DYLD & seg->cmd) {
default: // unknown if any file offset field must slide
printf("Unrecognized Macho cmd offset=0x%x cmd=0x%x size=0x%x\n", (char *)seg - (char *)rawmseg, (unsigned)seg->cmd, (unsigned)seg->cmdsize);
// fall through
case Mach_segment_command::LC_THREAD:
case Mach_segment_command::LC_UNIXTHREAD:
case Mach_segment_command::LC_LOAD_DYLIB:
case Mach_segment_command::LC_ID_DYLIB:
case Mach_segment_command::LC_LOAD_DYLINKER:
case Mach_segment_command::LC_ROUTINES:
case Mach_segment_command::LC_SEGMENT_64:
case Mach_segment_command::LC_ROUTINES_64:
case Mach_segment_command::LC_UUID:
case Mach_segment_command::LC_RPATH:
case Mach_segment_command::LC_CODE_SIGNATURE:
case Mach_segment_command::LC_REEXPORT_DYLIB:
hdrpos += seg->cmdsize;
break; // contain no file offset fields
case Mach_segment_command::LC_SEGMENT: {
// __IMPORT and __LINKEDIT must be seen by dylinker before decompression.
// All other segments have been combined into new compressed __TEXT.
if (0==strncmp(&seg->segname[0], "__IMPORT", 1+ 8)
|| 0==strncmp(&seg->segname[0], "__LINKEDIT", 1+ 10)) {
Mach_segment_command segcmdtmp = *seg;
opos += ~PAGE_MASK & (0u - opos); // advance to PAGE_SIZE boundary
slide = opos - segcmdtmp.fileoff;
segcmdtmp.fileoff = opos;
fo->seek(hdrpos, SEEK_SET);
fo->rewrite(&segcmdtmp, sizeof(segcmdtmp));
hdrpos += sizeof(segcmdtmp);
// Update the sections.
Mach_section_command const *secp = (Mach_section_command const *)(1+ seg);
unsigned const nsects = segcmdtmp.nsects;
Mach_section_command seccmdtmp;
for (unsigned j = 0; j < nsects; ++secp, ++j) {
seccmdtmp = *secp;
seccmdtmp.offset += slide;
if (seccmdtmp.nreloc) {
seccmdtmp.reloff += slide;
}
fo->rewrite(&seccmdtmp, sizeof(seccmdtmp));
hdrpos += sizeof(seccmdtmp);
}
fo->seek(opos, SEEK_SET);
fi->seek(seg->fileoff, SEEK_SET);
unsigned const len = seg->filesize;
char data[len];
fi->readx(data, len);
fo->write(data, len);
opos += len;
}
} break;
case Mach_segment_command::LC_SYMTAB: {
Mach_symtab_command cmd = *(Mach_symtab_command const *)seg;
if (opos < cmd.symoff) { cmd.symoff += slide; }
if (opos < cmd.stroff) { cmd.stroff += slide; }
fo->seek(hdrpos, SEEK_SET);
fo->rewrite(&cmd, sizeof(cmd));
hdrpos += sizeof(cmd);
} break;
case Mach_segment_command::LC_DYSYMTAB: {
Mach_dysymtab_command cmd = *(Mach_dysymtab_command const *)seg;
if (opos < cmd.tocoff) { cmd.tocoff += slide; }
if (opos < cmd.modtaboff) { cmd.modtaboff += slide; }
if (opos < cmd.nextrefsymoff) { cmd.extrefsymoff += slide; }
if (opos < cmd.indirectsymoff) { cmd.indirectsymoff += slide; }
if (opos < cmd.extreloff) { cmd.extreloff += slide; }
if (opos < cmd.locreloff) { cmd.locreloff += slide; }
fo->seek(hdrpos, SEEK_SET);
fo->rewrite(&cmd, sizeof(cmd));
hdrpos += sizeof(cmd);
} break;
case Mach_segment_command::LC_SEGMENT_SPLIT_INFO: {
Mach_segsplit_info_command cmd = *(Mach_segsplit_info_command const *)seg;
if (opos < cmd.dataoff) { cmd.dataoff += slide; }
fo->seek(hdrpos, SEEK_SET);
fo->rewrite(&cmd, sizeof(cmd));
hdrpos += sizeof(cmd);
} break;
} // end 'switch'
fo->seek(opos, SEEK_SET); // BUG: "fo->seek(0, SEEK_END);" is broken
// offset of p_info in compressed file
overlay_offset = sizeof(mhdro) + mhdro.sizeofcmds + sizeof(linfo);
PackMachBase<MachClass_LE32>::pack4(fo, ft);
}
void PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader void PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader
{ {
BE32 disp; BE32 disp;
@ -528,11 +653,6 @@ void PackMachBase<T>::pack2(OutputFile *fo, Filter &ft) // append compressed bo
segcmdo.filesize = fo->getBytesWritten(); segcmdo.filesize = fo->getBytesWritten();
} }
#undef PAGE_MASK
#undef PAGE_SIZE
#define PAGE_MASK (~0u<<12)
#define PAGE_SIZE -PAGE_MASK
void PackMachPPC32::pack1_setup_threado(OutputFile *const fo) void PackMachPPC32::pack1_setup_threado(OutputFile *const fo)
{ {
threado.cmd = Mach_segment_command::LC_UNIXTHREAD; threado.cmd = Mach_segment_command::LC_UNIXTHREAD;
@ -567,16 +687,39 @@ template <class T>
void PackMachBase<T>::pack1(OutputFile *const fo, Filter &/*ft*/) // generate executable header void PackMachBase<T>::pack1(OutputFile *const fo, Filter &/*ft*/) // generate executable header
{ {
mhdro = mhdri; mhdro = mhdri;
mhdro.ncmds = 2; if (my_filetype==Mach_header::MH_EXECUTE) {
mhdro.sizeofcmds = sizeof(segcmdo) + my_thread_command_size; mhdro.ncmds = 2;
mhdro.flags = Mach_header::MH_NOUNDEFS; mhdro.sizeofcmds = sizeof(segcmdo) + my_thread_command_size;
mhdro.flags = Mach_header::MH_NOUNDEFS;
}
if (my_filetype==Mach_header::MH_DYLIB) {
mhdro.ncmds += 2; /* new __TEXT, added LC_ROUTINES */
mhdro.sizeofcmds += sizeof(segcmdo) + sizeof(rcmd);
Mach_segment_command const *seg = rawmseg;
Mach_segment_command const *const endseg =
(Mach_segment_command const *)(mhdri.sizeofcmds + (char const *)seg);
for (; seg < endseg; seg = (Mach_segment_command const *)(
seg->cmdsize + (char const *)seg)) {
// All except __IMPORT and __LINKEDIT will be coalesced into __TEXT.
if (0!=strncmp(&seg->segname[0], "__IMPORT", 1+ 8)
&& 0!=strncmp(&seg->segname[0], "__LINKEDIT", 1+ 10)){
mhdro.ncmds -= 1;
mhdro.sizeofcmds -= seg->cmdsize;
}
}
}
fo->write(&mhdro, sizeof(mhdro)); fo->write(&mhdro, sizeof(mhdro));
segcmdo.cmd = Mach_segment_command::LC_SEGMENT; segcmdo.cmd = Mach_segment_command::LC_SEGMENT;
segcmdo.cmdsize = sizeof(segcmdo); segcmdo.cmdsize = sizeof(segcmdo);
strncpy((char *)segcmdo.segname, "__TEXT", sizeof(segcmdo.segname)); strncpy((char *)segcmdo.segname, "__TEXT", sizeof(segcmdo.segname));
segcmdo.vmaddr = PAGE_MASK & (~PAGE_MASK + if (my_filetype==Mach_header::MH_EXECUTE) {
msegcmd[n_segment -1].vmsize + msegcmd[n_segment -1].vmaddr ); segcmdo.vmaddr = PAGE_MASK & (~PAGE_MASK +
msegcmd[n_segment -1].vmsize + msegcmd[n_segment -1].vmaddr );
}
if (my_filetype==Mach_header::MH_DYLIB) {
segcmdo.vmaddr = 0;
}
segcmdo.vmsize = 0; // adjust later segcmdo.vmsize = 0; // adjust later
segcmdo.fileoff = 0; segcmdo.fileoff = 0;
segcmdo.filesize = 0; // adjust later segcmdo.filesize = 0; // adjust later
@ -588,7 +731,25 @@ void PackMachBase<T>::pack1(OutputFile *const fo, Filter &/*ft*/) // generate e
segcmdo.flags = 0; segcmdo.flags = 0;
fo->write(&segcmdo, sizeof(segcmdo)); fo->write(&segcmdo, sizeof(segcmdo));
pack1_setup_threado(fo); if (my_filetype==Mach_header::MH_EXECUTE) {
pack1_setup_threado(fo);
}
if (my_filetype==Mach_header::MH_DYLIB) {
Mach_segment_command const *seg = rawmseg;
Mach_segment_command const *const endseg =
(Mach_segment_command const *)(mhdri.sizeofcmds + (char const *)seg);
for (; seg < endseg; seg = (Mach_segment_command const *)(
seg->cmdsize + (char const *)seg)) {
if (0==strncmp(&seg->segname[0], "__IMPORT", 1+ 8)
|| 0==strncmp(&seg->segname[0], "__LINKEDIT", 1+ 10)){
fo->write(seg, seg->cmdsize);
}
}
memset(&rcmd, 0, sizeof(rcmd));
rcmd.cmd= Mach_segment_command::LC_ROUTINES;
rcmd.cmdsize = sizeof(rcmd);
fo->write(&rcmd, sizeof(rcmd));
}
sz_mach_headers = fo->getBytesWritten(); sz_mach_headers = fo->getBytesWritten();
memset((char *)&linfo, 0, sizeof(linfo)); memset((char *)&linfo, 0, sizeof(linfo));
@ -679,7 +840,7 @@ bool PackMachBase<T>::canPack()
if (Mach_header::MH_MAGIC !=mhdri.magic if (Mach_header::MH_MAGIC !=mhdri.magic
|| my_cputype !=mhdri.cputype || my_cputype !=mhdri.cputype
|| Mach_header::MH_EXECUTE !=mhdri.filetype || my_filetype !=mhdri.filetype
) )
return false; return false;
@ -700,12 +861,12 @@ bool PackMachBase<T>::canPack()
// Check that LC_SEGMENTs form one contiguous chunk of the file. // Check that LC_SEGMENTs form one contiguous chunk of the file.
for (unsigned j= 0; j < mhdri.ncmds; ++j) { for (unsigned j= 0; j < mhdri.ncmds; ++j) {
if (Mach_segment_command::LC_SEGMENT==msegcmd[j].cmd) { if (Mach_segment_command::LC_SEGMENT==msegcmd[j].cmd) {
if (0xfff & (msegcmd[j].fileoff | msegcmd[j].vmaddr)) { if (~PAGE_MASK & (msegcmd[j].fileoff | msegcmd[j].vmaddr)) {
return false; return false;
} }
if (0 < j) { if (0 < j) {
unsigned const sz = ~0xfff unsigned const sz = PAGE_MASK
& (0xfff + msegcmd[j-1].filesize); & (~PAGE_MASK + msegcmd[j-1].filesize);
if ((sz + msegcmd[j-1].fileoff)!=msegcmd[j].fileoff) { if ((sz + msegcmd[j-1].fileoff)!=msegcmd[j].fileoff) {
return false; return false;
} }

View File

@ -139,6 +139,77 @@ __packed_struct(Mach_section_command)
#include "p_mach_enum.h" #include "p_mach_enum.h"
__packed_struct_end() __packed_struct_end()
template <class TMachITypes>
__packed_struct(Mach_symtab_command)
typedef typename TMachITypes::Word Word;
typedef typename TMachITypes::Off Off;
Word cmd; /* LC_SYMTAB */
Word cmdsize; /* sizeof(struct Mach_symtab_command) */
Off symoff; /* symbol table offset */
Word nsyms; /* number of symbol table entries */
Off stroff; /* string table offset */
Word strsize; /* string table size in bytes */
__packed_struct_end()
template <class TMachITypes>
__packed_struct(Mach_dysymtab_command)
typedef typename TMachITypes::Word Word;
typedef typename TMachITypes::Off Off;
Word cmd; /* LC_DYSYMTAB */
Word cmdsize; /* sizeof(struct Mach_dysymtab_command) */
Word ilocalsym; /* index to local symbols */
Word nlocalsym; /* number of local symbols */
Word iextdefsym; /* index to externally defined symbols */
Word nextdefsym; /* number of externally defined symbols */
Word iundefsym; /* index to undefined symbols */
Word nundefsym; /* number of undefined symbols */
Off tocoff; /* file offset to table of contents */
Word ntoc; /* number of entries in table of contents */
Off modtaboff; /* file offset to module table */
Word nmodtab; /* number of module table entries */
Off extrefsymoff; /* offset to referenced symbol table */
Word nextrefsymoff; /* number of referenced symbol table entries */
Off indirectsymoff; /* file offset to the indirect symbol table */
Word nindirectsyms; /* number of indirect symbol table entries */
Off extreloff; /* offset to external relocation entries */
Word nextrel; /* number of external relocation entries */
Off locreloff; /* offset to local relocation entries */
Word nlocrel; /* number of local relocation entries */
__packed_struct_end()
template <class TMachITypes>
__packed_struct(Mach_segsplit_info_command)
typedef typename TMachITypes::Word Word;
typedef typename TMachITypes::Off Off;
Word cmd; /* LC_SEGMENT_SPLIT_INFO */
Word cmdsize; /* sizeof(struct Mach_segsplit_info_command) */
Off dataoff;
Word datasize;
__packed_struct_end()
template <class TMachITypes>
__packed_struct(Mach_routines_command)
typedef typename TMachITypes::Word Word;
typedef typename TMachITypes::Addr Addr;
typedef typename TMachITypes::Off Off;
Word cmd;
Word cmdsize;
Addr init_address;
Word init_module;
Word reserved1;
Word reserved2;
Word reserved3;
Word reserved4;
Word reserved5;
Word reserved6;
#define WANT_MACH_SEGMENT_ENUM 1
#include "p_mach_enum.h"
__packed_struct_end()
template <class TMachITypes> template <class TMachITypes>
__packed_struct(Mach_ppc_thread_state) __packed_struct(Mach_ppc_thread_state)
typedef typename TMachITypes::Addr Addr; typedef typename TMachITypes::Addr Addr;
@ -221,6 +292,26 @@ __packed_struct(Mach_ppc_thread_state64)
Word vrsave; /* Vector Save Register */ Word vrsave; /* Vector Save Register */
__packed_struct_end() __packed_struct_end()
template <class TMachITypes>
__packed_struct(Mach_routines_command_64)
typedef typename TMachITypes::Word Word;
typedef typename TMachITypes::Addr Addr;
typedef typename TMachITypes::Xword Xword;
Word cmd;
Word cmdsize;
Addr init_address;
Xword init_module;
Xword reserved1;
Xword reserved2;
Xword reserved3;
Xword reserved4;
Xword reserved5;
Xword reserved6;
#define WANT_MACH_SEGMENT_ENUM 1
#include "p_mach_enum.h"
__packed_struct_end()
} // namespace N_Mach64 } // namespace N_Mach64
namespace N_Mach { namespace N_Mach {
@ -245,6 +336,10 @@ struct MachClass_32
typedef N_Mach::Mach_header<MachITypes> Mach_header; typedef N_Mach::Mach_header<MachITypes> Mach_header;
typedef N_Mach::Mach_segment_command<MachITypes> Mach_segment_command; typedef N_Mach::Mach_segment_command<MachITypes> Mach_segment_command;
typedef N_Mach::Mach_section_command<MachITypes> Mach_section_command; typedef N_Mach::Mach_section_command<MachITypes> Mach_section_command;
typedef N_Mach::Mach_symtab_command<MachITypes> Mach_symtab_command;
typedef N_Mach::Mach_dysymtab_command<MachITypes> Mach_dysymtab_command;
typedef N_Mach::Mach_segsplit_info_command<MachITypes> Mach_segsplit_info_command;
typedef N_Mach::Mach_routines_command<MachITypes> Mach_routines_command;
typedef N_Mach::Mach_ppc_thread_state<MachITypes> Mach_ppc_thread_state; typedef N_Mach::Mach_ppc_thread_state<MachITypes> Mach_ppc_thread_state;
typedef N_Mach::Mach_i386_thread_state<MachITypes> Mach_i386_thread_state; typedef N_Mach::Mach_i386_thread_state<MachITypes> Mach_i386_thread_state;
typedef N_Mach::Mach_ARM_thread_state<MachITypes> Mach_ARM_thread_state; typedef N_Mach::Mach_ARM_thread_state<MachITypes> Mach_ARM_thread_state;
@ -270,6 +365,10 @@ struct MachClass_64
typedef N_Mach::Mach_header64<MachITypes> Mach_header; typedef N_Mach::Mach_header64<MachITypes> Mach_header;
typedef N_Mach::Mach_segment_command<MachITypes> Mach_segment_command; typedef N_Mach::Mach_segment_command<MachITypes> Mach_segment_command;
typedef N_Mach::Mach_section_command<MachITypes> Mach_section_command; typedef N_Mach::Mach_section_command<MachITypes> Mach_section_command;
typedef N_Mach::Mach_symtab_command<MachITypes> Mach_symtab_command;
typedef N_Mach::Mach_dysymtab_command<MachITypes> Mach_dysymtab_command;
typedef N_Mach::Mach_segsplit_info_command<MachITypes> Mach_segsplit_info_command;
typedef N_Mach::Mach_routines_command<MachITypes> Mach_routines_command;
static void compileTimeAssertions() { static void compileTimeAssertions() {
BeLePolicy::compileTimeAssertions(); BeLePolicy::compileTimeAssertions();
@ -288,21 +387,45 @@ typedef N_Mach::MachClass_64<N_BELE_CTP::LEPolicy> MachClass_LE64;
// shortcuts // shortcuts
typedef MachClass_Host32::Mach_segment_command Mach32_segment_command; typedef MachClass_Host32::Mach_segment_command Mach32_segment_command;
typedef MachClass_Host32::Mach_section_command Mach32_section_command; typedef MachClass_Host32::Mach_section_command Mach32_section_command;
typedef MachClass_Host32::Mach_symtab_command Mach32_symtab_command;
typedef MachClass_Host32::Mach_dysymtab_command Mach32_dysymtab_command;
typedef MachClass_Host32::Mach_segsplit_info_command Mach32_segsplit_info_command;
typedef MachClass_Host32::Mach_routines_command Mach32_routines_command;
typedef MachClass_Host64::Mach_segment_command Mach64_segment_command; typedef MachClass_Host64::Mach_segment_command Mach64_segment_command;
typedef MachClass_Host64::Mach_section_command Mach64_section_command; typedef MachClass_Host64::Mach_section_command Mach64_section_command;
typedef MachClass_Host64::Mach_symtab_command Mach64_symtab_command;
typedef MachClass_Host64::Mach_dysymtab_command Mach64_dysymtab_command;
typedef MachClass_Host64::Mach_segsplit_info_command Mach64_segsplit_info_command;
typedef MachClass_Host64::Mach_routines_command Mach64_routines_command;
typedef MachClass_BE32::Mach_segment_command MachBE32_segment_command; typedef MachClass_BE32::Mach_segment_command MachBE32_segment_command;
typedef MachClass_BE32::Mach_section_command MachBE32_section_command; typedef MachClass_BE32::Mach_section_command MachBE32_section_command;
typedef MachClass_BE32::Mach_symtab_command MachBE32_symtab_command;
typedef MachClass_BE32::Mach_dysymtab_command MachBE32_dysymtab_command;
typedef MachClass_BE32::Mach_segsplit_info_command MachBE32_segsplit_info_command;
typedef MachClass_BE32::Mach_routines_command MachBE32_routines_command;
typedef MachClass_BE64::Mach_segment_command MachBE64_segment_command; typedef MachClass_BE64::Mach_segment_command MachBE64_segment_command;
typedef MachClass_BE64::Mach_section_command MachBE64_section_command; typedef MachClass_BE64::Mach_section_command MachBE64_section_command;
typedef MachClass_BE64::Mach_symtab_command MachBE64_symtab_command;
typedef MachClass_BE64::Mach_dysymtab_command MachBE64_dysymtab_command;
typedef MachClass_BE64::Mach_segsplit_info_command MachBE64_segsplit_info_command;
typedef MachClass_BE64::Mach_routines_command MachBE64_routines_command;
typedef MachClass_LE32::Mach_segment_command MachLE32_segment_command; typedef MachClass_LE32::Mach_segment_command MachLE32_segment_command;
typedef MachClass_LE32::Mach_section_command MachLE32_section_command; typedef MachClass_LE32::Mach_section_command MachLE32_section_command;
typedef MachClass_LE32::Mach_symtab_command MachLE32_symtab_command;
typedef MachClass_LE32::Mach_dysymtab_command MachLE32_dysymtab_command;
typedef MachClass_LE32::Mach_segsplit_info_command MachLE32_segsplit_info_command;
typedef MachClass_LE32::Mach_routines_command MachLE32_routines_command;
typedef MachClass_LE64::Mach_segment_command MachLE64_segment_command; typedef MachClass_LE64::Mach_segment_command MachLE64_segment_command;
typedef MachClass_LE64::Mach_section_command MachLE64_section_command; typedef MachClass_LE64::Mach_section_command MachLE64_section_command;
typedef MachClass_LE64::Mach_symtab_command MachLE64_symtab_command;
typedef MachClass_LE64::Mach_dysymtab_command MachLE64_dysymtab_command;
typedef MachClass_LE64::Mach_segsplit_info_command MachLE64_segsplit_info_command;
typedef MachClass_LE64::Mach_routines_command MachLE64_routines_command;
typedef MachClass_BE32::Mach_ppc_thread_state Mach_ppc_thread_state; typedef MachClass_BE32::Mach_ppc_thread_state Mach_ppc_thread_state;
typedef MachClass_LE32::Mach_i386_thread_state Mach_i386_thread_state; typedef MachClass_LE32::Mach_i386_thread_state Mach_i386_thread_state;
@ -327,9 +450,14 @@ protected:
typedef typename MachClass::Mach_header Mach_header; typedef typename MachClass::Mach_header Mach_header;
typedef typename MachClass::Mach_segment_command Mach_segment_command; typedef typename MachClass::Mach_segment_command Mach_segment_command;
typedef typename MachClass::Mach_section_command Mach_section_command; typedef typename MachClass::Mach_section_command Mach_section_command;
typedef typename MachClass::Mach_symtab_command Mach_symtab_command;
typedef typename MachClass::Mach_dysymtab_command Mach_dysymtab_command;
typedef typename MachClass::Mach_segsplit_info_command Mach_segsplit_info_command;
typedef typename MachClass::Mach_routines_command Mach_routines_command;
public: public:
PackMachBase(InputFile *, unsigned cpuid, unsigned t_flavor, unsigned ts_word_cnt, unsigned tc_size); PackMachBase(InputFile *, unsigned cpuid, unsigned filetype,
unsigned t_flavor, unsigned ts_word_cnt, unsigned tc_size);
virtual ~PackMachBase(); virtual ~PackMachBase();
virtual int getVersion() const { return 13; } virtual int getVersion() const { return 13; }
virtual const int *getCompressionMethods(int method, int level) const; virtual const int *getCompressionMethods(int method, int level) const;
@ -362,6 +490,7 @@ protected:
static int __acc_cdecl_qsort compare_segment_command(void const *aa, void const *bb); static int __acc_cdecl_qsort compare_segment_command(void const *aa, void const *bb);
unsigned my_cputype; unsigned my_cputype;
unsigned my_filetype;
unsigned my_thread_flavor; unsigned my_thread_flavor;
unsigned my_thread_state_word_count; unsigned my_thread_state_word_count;
unsigned my_thread_command_size; unsigned my_thread_command_size;
@ -375,6 +504,7 @@ protected:
Mach_header mhdro; Mach_header mhdro;
Mach_segment_command segcmdo; Mach_segment_command segcmdo;
Mach_routines_command rcmd;
__packed_struct(b_info) // 12-byte header before each compressed block __packed_struct(b_info) // 12-byte header before each compressed block
TE32 sz_unc; // uncompressed_size TE32 sz_unc; // uncompressed_size
@ -419,7 +549,7 @@ class PackMachPPC32 : public PackMachBase<MachClass_BE32>
public: public:
PackMachPPC32(InputFile *f) : super(f, Mach_header::CPU_TYPE_POWERPC, PackMachPPC32(InputFile *f) : super(f, Mach_header::CPU_TYPE_POWERPC,
Mach_thread_command::PPC_THREAD_STATE, Mach_header::MH_EXECUTE, Mach_thread_command::PPC_THREAD_STATE,
sizeof(Mach_ppc_thread_state)>>2, sizeof(threado)) { } sizeof(Mach_ppc_thread_state)>>2, sizeof(threado)) { }
virtual int getFormat() const { return UPX_F_MACH_PPC32; } virtual int getFormat() const { return UPX_F_MACH_PPC32; }
@ -454,7 +584,7 @@ class PackMachI386 : public PackMachBase<MachClass_LE32>
public: public:
PackMachI386(InputFile *f) : super(f, Mach_header::CPU_TYPE_I386, PackMachI386(InputFile *f) : super(f, Mach_header::CPU_TYPE_I386,
(unsigned)Mach_thread_command::i386_THREAD_STATE, Mach_header::MH_EXECUTE, (unsigned)Mach_thread_command::i386_THREAD_STATE,
sizeof(Mach_i386_thread_state)>>2, sizeof(threado)) { } sizeof(Mach_i386_thread_state)>>2, sizeof(threado)) { }
virtual int getFormat() const { return UPX_F_MACH_i386; } virtual int getFormat() const { return UPX_F_MACH_i386; }
@ -483,13 +613,34 @@ protected:
Mach_thread_command threado; Mach_thread_command threado;
}; };
class PackDylibI386 : public PackMachI386 //PackMachBase<MachClass_LE32>
{
typedef PackMachI386 /*PackMachBase<MachClass_LE32>*/ super;
public:
PackDylibI386(InputFile *f) : super(f) { my_filetype = Mach_header::MH_DYLIB; }
virtual int getFormat() const { return UPX_F_DYLIB_i386; }
virtual const char *getName() const { return "Dylib/i386"; }
virtual const char *getFullName(const options_t *) const { return "i386-darwin.dylib"; }
protected:
//virtual void pack1_setup_threado(OutputFile *const fo);
//virtual void pack1(OutputFile *, Filter &); // generate executable header
//virtual void pack2(OutputFile *, Filter &); // append compressed data
//virtual void pack3(OutputFile *, Filter &); // append loader
virtual void pack4(OutputFile *, Filter &); // append PackHeader
//virtual Linker* newLinker() const;
virtual void buildLoader(const Filter *ft);
virtual void addStubEntrySections(Filter const *);
};
class PackMachARMEL : public PackMachBase<MachClass_LE32> class PackMachARMEL : public PackMachBase<MachClass_LE32>
{ {
typedef PackMachBase<MachClass_LE32> super; typedef PackMachBase<MachClass_LE32> super;
public: public:
PackMachARMEL(InputFile *f) : super(f, Mach_header::CPU_TYPE_ARM, PackMachARMEL(InputFile *f) : super(f, Mach_header::CPU_TYPE_ARM,
(unsigned)Mach_thread_command::ARM_THREAD_STATE, Mach_header::MH_EXECUTE, (unsigned)Mach_thread_command::ARM_THREAD_STATE,
sizeof(Mach_ARM_thread_state)>>2, sizeof(threado)) { } sizeof(Mach_ARM_thread_state)>>2, sizeof(threado)) { }
virtual int getFormat() const { return UPX_F_MACH_ARMEL; } virtual int getFormat() const { return UPX_F_MACH_ARMEL; }

View File

@ -50,7 +50,8 @@
CPU_SUBTYPE_ARM_V6 = 6 CPU_SUBTYPE_ARM_V6 = 6
}; };
enum { // filetype enum { // filetype
MH_EXECUTE = 2 MH_EXECUTE = 2,
MH_DYLIB = 6
}; };
enum { // flags enum { // flags
MH_NOUNDEFS = 1 MH_NOUNDEFS = 1
@ -61,10 +62,22 @@
#undef WANT_MACH_SEGMENT_ENUM #undef WANT_MACH_SEGMENT_ENUM
enum { // cmd enum { // cmd
LC_SEGMENT = 0x1, LC_SEGMENT = 0x1,
LC_SYMTAB = 0x2,
LC_THREAD = 0x4, LC_THREAD = 0x4,
LC_UNIXTHREAD = 0x5, LC_UNIXTHREAD = 0x5,
LC_DYSYMTAB = 0xb,
LC_LOAD_DYLIB = 0xc,
LC_ID_DYLIB = 0xd,
LC_LOAD_DYLINKER = 0xe, LC_LOAD_DYLINKER = 0xe,
LC_SEGMENT_64 = 0x19 LC_ROUTINES = 0x11,
LC_SEGMENT_64 = 0x19,
LC_ROUTINES_64 = 0x1a,
LC_UUID = 0x1b,
LC_RPATH = 0x1c,
LC_CODE_SIGNATURE = 0x1d,
LC_SEGMENT_SPLIT_INFO = 0x1e,
LC_REEXPORT_DYLIB = 0x1f,
LC_REQ_DYLD = 0x80000000 // OR'ed ==> must not ignore
}; };
enum { // maxprot enum { // maxprot
VM_PROT_READ = 1, VM_PROT_READ = 1,

View File

@ -218,6 +218,7 @@ const char *Packer::getDecompressorSections() const
|| UPX_F_VMLINUX_PPC32 ==ph.format || UPX_F_VMLINUX_PPC32 ==ph.format
|| UPX_F_MACH_PPC32 ==ph.format || UPX_F_MACH_PPC32 ==ph.format
|| UPX_F_MACH_i386 ==ph.format || UPX_F_MACH_i386 ==ph.format
|| UPX_F_DYLIB_i386 ==ph.format
) { ) {
return opt->small ? lzma_elf_small : lzma_elf_fast; return opt->small ? lzma_elf_small : lzma_elf_fast;
} }
@ -257,6 +258,7 @@ void Packer::defineDecompressorSymbols()
|| UPX_F_VMLINUX_PPC32 ==ph.format || UPX_F_VMLINUX_PPC32 ==ph.format
|| UPX_F_MACH_PPC32 ==ph.format || UPX_F_MACH_PPC32 ==ph.format
|| UPX_F_MACH_i386 ==ph.format || UPX_F_MACH_i386 ==ph.format
|| UPX_F_DYLIB_i386 ==ph.format
) { ) {
// ELF calls the decompressor many times; the parameters change! // ELF calls the decompressor many times; the parameters change!
return; return;

View File

@ -279,6 +279,8 @@ Packer* PackMaster::visitAllPackers(visit_func_t func, InputFile *f, const optio
return p; return p;
if ((p = func(new PackMachARMEL(f), user)) != NULL) if ((p = func(new PackMachARMEL(f), user)) != NULL)
return p; return p;
if ((p = func(new PackDylibI386(f), user)) != NULL)
return p;
return NULL; return NULL;
} }