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_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
|
||||||
|
|
197
src/p_mach.cpp
197
src/p_mach.cpp
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
159
src/p_mach.h
159
src/p_mach.h
|
@ -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; }
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user