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:
parent
9694ff433f
commit
3a9e0b5be6
|
@ -474,6 +474,8 @@ private:
|
|||
#define UPX_F_VMLINUZ_ARMEL 31
|
||||
#define UPX_F_MACH_ARMEL 32
|
||||
|
||||
#define UPX_F_DYLIB_i386 33
|
||||
|
||||
#define UPX_F_PLAIN_TEXT 127
|
||||
|
||||
#define UPX_F_ATARI_TOS 129
|
||||
|
|
185
src/p_mach.cpp
185
src/p_mach.cpp
|
@ -50,9 +50,9 @@ static const
|
|||
#include "stub/arm-darwin.macho-fold.h"
|
||||
|
||||
template <class T>
|
||||
PackMachBase<T>::PackMachBase(InputFile *f, unsigned cputype, unsigned flavor,
|
||||
unsigned count, unsigned size) :
|
||||
super(f), my_cputype(cputype), my_thread_flavor(flavor),
|
||||
PackMachBase<T>::PackMachBase(InputFile *f, unsigned cputype, unsigned filetype,
|
||||
unsigned flavor, unsigned count, unsigned size) :
|
||||
super(f), my_cputype(cputype), my_filetype(filetype), my_thread_flavor(flavor),
|
||||
my_thread_state_word_count(count), my_thread_command_size(size),
|
||||
n_segment(0), rawmseg(NULL), msegcmd(NULL)
|
||||
{
|
||||
|
@ -207,6 +207,10 @@ void PackMachARMEL::addStubEntrySections(Filter const */*ft*/)
|
|||
addLoader("MACHMAINY,IDENTSTR,+40,MACHMAINZ,FOLDEXEC", NULL);
|
||||
}
|
||||
|
||||
void PackDylibI386::addStubEntrySections(Filter const *ft)
|
||||
{
|
||||
super::addStubEntrySections(ft);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
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 );
|
||||
}
|
||||
|
||||
void
|
||||
PackDylibI386::buildLoader(const Filter *ft)
|
||||
{
|
||||
super::buildLoader(ft);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void PackMachBase<T>::patchLoader() { }
|
||||
|
||||
|
@ -364,6 +374,121 @@ void PackMachARMEL::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
|||
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
|
||||
{
|
||||
BE32 disp;
|
||||
|
@ -528,11 +653,6 @@ void PackMachBase<T>::pack2(OutputFile *fo, Filter &ft) // append compressed bo
|
|||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
mhdro = mhdri;
|
||||
if (my_filetype==Mach_header::MH_EXECUTE) {
|
||||
mhdro.ncmds = 2;
|
||||
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));
|
||||
|
||||
segcmdo.cmd = Mach_segment_command::LC_SEGMENT;
|
||||
segcmdo.cmdsize = sizeof(segcmdo);
|
||||
strncpy((char *)segcmdo.segname, "__TEXT", sizeof(segcmdo.segname));
|
||||
if (my_filetype==Mach_header::MH_EXECUTE) {
|
||||
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.fileoff = 0;
|
||||
segcmdo.filesize = 0; // adjust later
|
||||
|
@ -588,7 +731,25 @@ void PackMachBase<T>::pack1(OutputFile *const fo, Filter &/*ft*/) // generate e
|
|||
segcmdo.flags = 0;
|
||||
fo->write(&segcmdo, sizeof(segcmdo));
|
||||
|
||||
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();
|
||||
|
||||
memset((char *)&linfo, 0, sizeof(linfo));
|
||||
|
@ -679,7 +840,7 @@ bool PackMachBase<T>::canPack()
|
|||
|
||||
if (Mach_header::MH_MAGIC !=mhdri.magic
|
||||
|| my_cputype !=mhdri.cputype
|
||||
|| Mach_header::MH_EXECUTE !=mhdri.filetype
|
||||
|| my_filetype !=mhdri.filetype
|
||||
)
|
||||
return false;
|
||||
|
||||
|
@ -700,12 +861,12 @@ bool PackMachBase<T>::canPack()
|
|||
// Check that LC_SEGMENTs form one contiguous chunk of the file.
|
||||
for (unsigned j= 0; j < mhdri.ncmds; ++j) {
|
||||
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;
|
||||
}
|
||||
if (0 < j) {
|
||||
unsigned const sz = ~0xfff
|
||||
& (0xfff + msegcmd[j-1].filesize);
|
||||
unsigned const sz = PAGE_MASK
|
||||
& (~PAGE_MASK + msegcmd[j-1].filesize);
|
||||
if ((sz + msegcmd[j-1].fileoff)!=msegcmd[j].fileoff) {
|
||||
return false;
|
||||
}
|
||||
|
|
159
src/p_mach.h
159
src/p_mach.h
|
@ -139,6 +139,77 @@ __packed_struct(Mach_section_command)
|
|||
#include "p_mach_enum.h"
|
||||
__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>
|
||||
__packed_struct(Mach_ppc_thread_state)
|
||||
typedef typename TMachITypes::Addr Addr;
|
||||
|
@ -221,6 +292,26 @@ __packed_struct(Mach_ppc_thread_state64)
|
|||
Word vrsave; /* Vector Save Register */
|
||||
__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_Mach {
|
||||
|
@ -245,6 +336,10 @@ struct MachClass_32
|
|||
typedef N_Mach::Mach_header<MachITypes> Mach_header;
|
||||
typedef N_Mach::Mach_segment_command<MachITypes> Mach_segment_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_i386_thread_state<MachITypes> Mach_i386_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_segment_command<MachITypes> Mach_segment_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() {
|
||||
BeLePolicy::compileTimeAssertions();
|
||||
|
@ -288,21 +387,45 @@ typedef N_Mach::MachClass_64<N_BELE_CTP::LEPolicy> MachClass_LE64;
|
|||
// shortcuts
|
||||
typedef MachClass_Host32::Mach_segment_command Mach32_segment_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_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_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_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_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_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_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_segment_command Mach_segment_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:
|
||||
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 int getVersion() const { return 13; }
|
||||
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);
|
||||
|
||||
unsigned my_cputype;
|
||||
unsigned my_filetype;
|
||||
unsigned my_thread_flavor;
|
||||
unsigned my_thread_state_word_count;
|
||||
unsigned my_thread_command_size;
|
||||
|
@ -375,6 +504,7 @@ protected:
|
|||
|
||||
Mach_header mhdro;
|
||||
Mach_segment_command segcmdo;
|
||||
Mach_routines_command rcmd;
|
||||
|
||||
__packed_struct(b_info) // 12-byte header before each compressed block
|
||||
TE32 sz_unc; // uncompressed_size
|
||||
|
@ -419,7 +549,7 @@ class PackMachPPC32 : public PackMachBase<MachClass_BE32>
|
|||
|
||||
public:
|
||||
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)) { }
|
||||
|
||||
virtual int getFormat() const { return UPX_F_MACH_PPC32; }
|
||||
|
@ -454,7 +584,7 @@ class PackMachI386 : public PackMachBase<MachClass_LE32>
|
|||
|
||||
public:
|
||||
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)) { }
|
||||
|
||||
virtual int getFormat() const { return UPX_F_MACH_i386; }
|
||||
|
@ -483,13 +613,34 @@ protected:
|
|||
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>
|
||||
{
|
||||
typedef PackMachBase<MachClass_LE32> super;
|
||||
|
||||
public:
|
||||
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)) { }
|
||||
|
||||
virtual int getFormat() const { return UPX_F_MACH_ARMEL; }
|
||||
|
|
|
@ -50,7 +50,8 @@
|
|||
CPU_SUBTYPE_ARM_V6 = 6
|
||||
};
|
||||
enum { // filetype
|
||||
MH_EXECUTE = 2
|
||||
MH_EXECUTE = 2,
|
||||
MH_DYLIB = 6
|
||||
};
|
||||
enum { // flags
|
||||
MH_NOUNDEFS = 1
|
||||
|
@ -61,10 +62,22 @@
|
|||
#undef WANT_MACH_SEGMENT_ENUM
|
||||
enum { // cmd
|
||||
LC_SEGMENT = 0x1,
|
||||
LC_SYMTAB = 0x2,
|
||||
LC_THREAD = 0x4,
|
||||
LC_UNIXTHREAD = 0x5,
|
||||
LC_DYSYMTAB = 0xb,
|
||||
LC_LOAD_DYLIB = 0xc,
|
||||
LC_ID_DYLIB = 0xd,
|
||||
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
|
||||
VM_PROT_READ = 1,
|
||||
|
|
|
@ -218,6 +218,7 @@ const char *Packer::getDecompressorSections() const
|
|||
|| UPX_F_VMLINUX_PPC32 ==ph.format
|
||||
|| UPX_F_MACH_PPC32 ==ph.format
|
||||
|| UPX_F_MACH_i386 ==ph.format
|
||||
|| UPX_F_DYLIB_i386 ==ph.format
|
||||
) {
|
||||
return opt->small ? lzma_elf_small : lzma_elf_fast;
|
||||
}
|
||||
|
@ -257,6 +258,7 @@ void Packer::defineDecompressorSymbols()
|
|||
|| UPX_F_VMLINUX_PPC32 ==ph.format
|
||||
|| UPX_F_MACH_PPC32 ==ph.format
|
||||
|| UPX_F_MACH_i386 ==ph.format
|
||||
|| UPX_F_DYLIB_i386 ==ph.format
|
||||
) {
|
||||
// ELF calls the decompressor many times; the parameters change!
|
||||
return;
|
||||
|
|
|
@ -279,6 +279,8 @@ Packer* PackMaster::visitAllPackers(visit_func_t func, InputFile *f, const optio
|
|||
return p;
|
||||
if ((p = func(new PackMachARMEL(f), user)) != NULL)
|
||||
return p;
|
||||
if ((p = func(new PackDylibI386(f), user)) != NULL)
|
||||
return p;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user