Leave space for code signing on Mac OS X.
This commit is contained in:
parent
0ae9fee350
commit
09b072b908
2
NEWS
2
NEWS
@ -3,6 +3,8 @@ User visible changes for UPX
|
||||
==================================================================
|
||||
|
||||
Changes in 3.09 (XX XXX XXXX):
|
||||
* Allow for code signing on Mac OS X executables.
|
||||
* bug fixes
|
||||
|
||||
Changes in 3.08 (12 Dec 2011):
|
||||
* Fix allocation in runtime stub for darwin.macho-entry (i386 and amd64).
|
||||
|
||||
202
src/p_mach.cpp
202
src/p_mach.cpp
@ -351,7 +351,7 @@ PackMachBase<T>::buildMachLoader(
|
||||
|
||||
int const GAP = 128; // must match stub/l_mac_ppc.S
|
||||
int const NO_LAP = 64; // must match stub/src/*darwin*.S
|
||||
segcmdo.vmsize += h.sz_unc - h.sz_cpr + GAP + NO_LAP;
|
||||
segcmdo[0].vmsize += h.sz_unc - h.sz_cpr + GAP + NO_LAP;
|
||||
|
||||
addStubEntrySections(ft);
|
||||
|
||||
@ -463,62 +463,6 @@ PackMachBase<T>::compare_segment_command(void const *const aa, void const *const
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PackMachPPC32::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
||||
{
|
||||
// offset of p_info in compressed file
|
||||
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + sizeof(threado) + sizeof(linfo);
|
||||
|
||||
super::pack4(fo, ft);
|
||||
segcmdo.filesize = fo->getBytesWritten();
|
||||
segcmdo.vmsize += segcmdo.filesize;
|
||||
fo->seek(sizeof(mhdro), SEEK_SET);
|
||||
fo->rewrite(&segcmdo, sizeof(segcmdo));
|
||||
fo->rewrite(&threado, sizeof(threado));
|
||||
fo->rewrite(&linfo, sizeof(linfo));
|
||||
}
|
||||
|
||||
void PackMachI386::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
||||
{
|
||||
// offset of p_info in compressed file
|
||||
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + sizeof(threado) + sizeof(linfo);
|
||||
|
||||
super::pack4(fo, ft);
|
||||
segcmdo.filesize = fo->getBytesWritten();
|
||||
segcmdo.vmsize += segcmdo.filesize;
|
||||
fo->seek(sizeof(mhdro), SEEK_SET);
|
||||
fo->rewrite(&segcmdo, sizeof(segcmdo));
|
||||
fo->rewrite(&threado, sizeof(threado));
|
||||
fo->rewrite(&linfo, sizeof(linfo));
|
||||
}
|
||||
|
||||
void PackMachAMD64::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
||||
{
|
||||
// offset of p_info in compressed file
|
||||
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + sizeof(threado) + sizeof(linfo);
|
||||
|
||||
super::pack4(fo, ft);
|
||||
segcmdo.filesize = fo->getBytesWritten();
|
||||
segcmdo.vmsize += segcmdo.filesize;
|
||||
fo->seek(sizeof(mhdro), SEEK_SET);
|
||||
fo->rewrite(&segcmdo, sizeof(segcmdo));
|
||||
fo->rewrite(&threado, sizeof(threado));
|
||||
fo->rewrite(&linfo, sizeof(linfo));
|
||||
}
|
||||
|
||||
void PackMachARMEL::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
||||
{
|
||||
// offset of p_info in compressed file
|
||||
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + sizeof(threado) + sizeof(linfo);
|
||||
|
||||
super::pack4(fo, ft);
|
||||
segcmdo.filesize = fo->getBytesWritten();
|
||||
segcmdo.vmsize += segcmdo.filesize;
|
||||
fo->seek(sizeof(mhdro), SEEK_SET);
|
||||
fo->rewrite(&segcmdo, sizeof(segcmdo));
|
||||
fo->rewrite(&threado, sizeof(threado));
|
||||
fo->rewrite(&linfo, sizeof(linfo));
|
||||
}
|
||||
|
||||
#undef PAGE_MASK
|
||||
#undef PAGE_SIZE
|
||||
#define PAGE_MASK (~0u<<12)
|
||||
@ -529,6 +473,102 @@ void PackMachARMEL::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
||||
#define PAGE_MASK64 (~(acc_uint64l_t)0<<12)
|
||||
#define PAGE_SIZE64 -PAGE_MASK64
|
||||
|
||||
void PackMachPPC32::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
||||
{
|
||||
// offset of p_info in compressed file
|
||||
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + sizeof(threado) + sizeof(linfo);
|
||||
if (my_filetype==Mach_header::MH_EXECUTE) {
|
||||
overlay_offset += sizeof(linkedito);
|
||||
}
|
||||
|
||||
super::pack4(fo, ft);
|
||||
segcmdo[0].filesize = fo->getBytesWritten();
|
||||
segcmdo[0].vmsize += segcmdo[0].filesize;
|
||||
unsigned const foff1 = (PAGE_MASK & (~PAGE_MASK + segcmdo[0].filesize));
|
||||
segcmdo[1].fileoff = foff1;
|
||||
segcmdo[1].vmaddr = segcmdo[0].vmaddr + foff1;
|
||||
fo->seek(foff1 - 1, SEEK_SET); fo->write("", 1);
|
||||
fo->seek(sizeof(mhdro), SEEK_SET);
|
||||
fo->rewrite(&segcmdo, sizeof(segcmdo));
|
||||
fo->rewrite(&threado, sizeof(threado));
|
||||
if (my_filetype==Mach_header::MH_EXECUTE) {
|
||||
fo->rewrite(&linkedito, sizeof(linkedito));
|
||||
}
|
||||
fo->rewrite(&linfo, sizeof(linfo));
|
||||
}
|
||||
|
||||
void PackMachI386::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
||||
{
|
||||
// offset of p_info in compressed file
|
||||
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + sizeof(threado) + sizeof(linfo);
|
||||
if (my_filetype==Mach_header::MH_EXECUTE) {
|
||||
overlay_offset += sizeof(linkedito);
|
||||
}
|
||||
|
||||
super::pack4(fo, ft);
|
||||
segcmdo[0].filesize = fo->getBytesWritten();
|
||||
segcmdo[0].vmsize += segcmdo[0].filesize;
|
||||
unsigned const foff1 = (PAGE_MASK & (~PAGE_MASK + segcmdo[0].filesize));
|
||||
segcmdo[1].fileoff = foff1;
|
||||
segcmdo[1].vmaddr = segcmdo[0].vmaddr + foff1;
|
||||
fo->seek(foff1 - 1, SEEK_SET); fo->write("", 1);
|
||||
fo->seek(sizeof(mhdro), SEEK_SET);
|
||||
fo->rewrite(&segcmdo, sizeof(segcmdo));
|
||||
fo->rewrite(&threado, sizeof(threado));
|
||||
if (my_filetype==Mach_header::MH_EXECUTE) {
|
||||
fo->rewrite(&linkedito, sizeof(linkedito));
|
||||
}
|
||||
fo->rewrite(&linfo, sizeof(linfo));
|
||||
}
|
||||
|
||||
void PackMachAMD64::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
||||
{
|
||||
// offset of p_info in compressed file
|
||||
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + sizeof(threado) + sizeof(linfo);
|
||||
if (my_filetype==Mach_header::MH_EXECUTE) {
|
||||
overlay_offset += sizeof(linkedito);
|
||||
}
|
||||
|
||||
super::pack4(fo, ft);
|
||||
segcmdo[0].filesize = fo->getBytesWritten();
|
||||
segcmdo[0].vmsize += segcmdo[0].filesize;
|
||||
unsigned const foff1 = (PAGE_MASK64 & (~PAGE_MASK64 + segcmdo[0].filesize));
|
||||
segcmdo[1].fileoff = foff1;
|
||||
segcmdo[1].vmaddr = segcmdo[0].vmaddr + foff1;
|
||||
fo->seek(foff1 - 1, SEEK_SET); fo->write("", 1);
|
||||
fo->seek(sizeof(mhdro), SEEK_SET);
|
||||
fo->rewrite(&segcmdo, sizeof(segcmdo));
|
||||
fo->rewrite(&threado, sizeof(threado));
|
||||
if (my_filetype==Mach_header::MH_EXECUTE) {
|
||||
fo->rewrite(&linkedito, sizeof(linkedito));
|
||||
}
|
||||
fo->rewrite(&linfo, sizeof(linfo));
|
||||
}
|
||||
|
||||
void PackMachARMEL::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
||||
{
|
||||
// offset of p_info in compressed file
|
||||
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + sizeof(threado) + sizeof(linfo);
|
||||
if (my_filetype==Mach_header::MH_EXECUTE) {
|
||||
overlay_offset += sizeof(linkedito);
|
||||
}
|
||||
|
||||
super::pack4(fo, ft);
|
||||
segcmdo[0].filesize = fo->getBytesWritten();
|
||||
segcmdo[0].vmsize += segcmdo[0].filesize;
|
||||
unsigned const foff1 = (PAGE_MASK & (~PAGE_MASK + segcmdo[0].filesize));
|
||||
segcmdo[1].fileoff = foff1;
|
||||
segcmdo[1].vmaddr = segcmdo[0].vmaddr + foff1;
|
||||
fo->seek(foff1 - 1, SEEK_SET); fo->write("", 1);
|
||||
fo->seek(sizeof(mhdro), SEEK_SET);
|
||||
fo->rewrite(&segcmdo, sizeof(segcmdo));
|
||||
fo->rewrite(&threado, sizeof(threado));
|
||||
if (my_filetype==Mach_header::MH_EXECUTE) {
|
||||
fo->rewrite(&linkedito, sizeof(linkedito));
|
||||
}
|
||||
fo->rewrite(&linfo, sizeof(linfo));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void PackMachBase<T>::pack4dylib( // append PackHeader
|
||||
OutputFile *const fo,
|
||||
@ -737,7 +777,7 @@ void PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader
|
||||
disp = 4+ len - sz_mach_headers; // 4: sizeof(instruction)
|
||||
fo->write(&disp, sizeof(disp));
|
||||
|
||||
threado.state.srr0 = len + segcmdo.vmaddr; /* entry address */
|
||||
threado.state.srr0 = len + segcmdo[0].vmaddr; /* entry address */
|
||||
super::pack3(fo, ft);
|
||||
}
|
||||
|
||||
@ -751,7 +791,7 @@ void PackMachI386::pack3(OutputFile *fo, Filter &ft) // append loader
|
||||
disp = len - sz_mach_headers;
|
||||
fo->write(&disp, sizeof(disp));
|
||||
|
||||
threado.state.eip = len + sizeof(disp) + segcmdo.vmaddr; /* entry address */
|
||||
threado.state.eip = len + sizeof(disp) + segcmdo[0].vmaddr; /* entry address */
|
||||
super::pack3(fo, ft);
|
||||
}
|
||||
|
||||
@ -765,7 +805,7 @@ void PackMachAMD64::pack3(OutputFile *fo, Filter &ft) // append loader
|
||||
disp = len - sz_mach_headers;
|
||||
fo->write(&disp, sizeof(disp));
|
||||
|
||||
threado.state.rip = len + sizeof(disp) + segcmdo.vmaddr; /* entry address */
|
||||
threado.state.rip = len + sizeof(disp) + segcmdo[0].vmaddr; /* entry address */
|
||||
super::pack3(fo, ft);
|
||||
}
|
||||
|
||||
@ -779,7 +819,7 @@ void PackMachARMEL::pack3(OutputFile *fo, Filter &ft) // append loader
|
||||
disp = len - sz_mach_headers;
|
||||
fo->write(&disp, sizeof(disp));
|
||||
|
||||
threado.state.pc = len + sizeof(disp) + segcmdo.vmaddr; /* entry address */
|
||||
threado.state.pc = len + sizeof(disp) + segcmdo[0].vmaddr; /* entry address */
|
||||
super::pack3(fo, ft);
|
||||
}
|
||||
|
||||
@ -987,7 +1027,7 @@ int PackMachBase<T>::pack2(OutputFile *fo, Filter &ft) // append compressed bo
|
||||
if (my_filetype!=Mach_header::MH_DYLIB)
|
||||
if ((off_t)total_in != file_size)
|
||||
throwEOFException();
|
||||
segcmdo.filesize = fo->getBytesWritten();
|
||||
segcmdo[0].filesize = fo->getBytesWritten();
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -1038,34 +1078,42 @@ void PackMachBase<T>::pack1(OutputFile *const fo, Filter &/*ft*/) // generate e
|
||||
unsigned const lc_seg = lc_segment[sizeof(Addr)>>3];
|
||||
mhdro = mhdri;
|
||||
if (my_filetype==Mach_header::MH_EXECUTE) {
|
||||
mhdro.ncmds = 2;
|
||||
mhdro.ncmds = 3;
|
||||
mhdro.sizeofcmds = sizeof(segcmdo) + my_thread_command_size;
|
||||
mhdro.flags = Mach_header::MH_NOUNDEFS;
|
||||
}
|
||||
fo->write(&mhdro, sizeof(mhdro));
|
||||
|
||||
segcmdo.cmd = lc_seg;
|
||||
segcmdo.cmdsize = sizeof(segcmdo);
|
||||
strncpy((char *)segcmdo.segname, "__TEXT", sizeof(segcmdo.segname));
|
||||
segcmdo[0].cmd = lc_seg;
|
||||
segcmdo[0].cmdsize = sizeof(segcmdo[0]);
|
||||
strncpy((char *)segcmdo[0].segname, "__TEXT", sizeof(segcmdo[0].segname));
|
||||
if (my_filetype==Mach_header::MH_EXECUTE) {
|
||||
segcmdo.vmaddr = PAGE_MASK64 & (~PAGE_MASK64 +
|
||||
segcmdo[0].vmaddr = PAGE_MASK64 & (~PAGE_MASK64 +
|
||||
msegcmd[n_segment -1].vmsize + msegcmd[n_segment -1].vmaddr );
|
||||
}
|
||||
if (my_filetype==Mach_header::MH_DYLIB) {
|
||||
segcmdo.vmaddr = 0;
|
||||
segcmdo[0].vmaddr = 0;
|
||||
}
|
||||
segcmdo.vmsize = 0; // adjust later
|
||||
segcmdo.fileoff = 0;
|
||||
segcmdo.filesize = 0; // adjust later
|
||||
segcmdo.initprot = segcmdo.maxprot =
|
||||
segcmdo[0].vmsize = 0; // adjust later
|
||||
segcmdo[0].fileoff = 0;
|
||||
segcmdo[0].filesize = 0; // adjust later
|
||||
segcmdo[0].initprot = segcmdo[0].maxprot =
|
||||
Mach_segment_command::VM_PROT_READ |
|
||||
Mach_segment_command::VM_PROT_WRITE |
|
||||
Mach_segment_command::VM_PROT_EXECUTE;
|
||||
segcmdo.nsects = 0;
|
||||
segcmdo.flags = 0;
|
||||
segcmdo[0].nsects = 0;
|
||||
segcmdo[0].flags = 0;
|
||||
|
||||
segcmdo[1] = segcmdo[0];
|
||||
strncpy((char *)segcmdo[1].segname, "__LINKEDIT", sizeof(segcmdo[1].segname));
|
||||
segcmdo[1].initprot = Mach_segment_command::VM_PROT_READ;
|
||||
// Adjust later: .vmaddr .vmsize .fileoff .filesize
|
||||
|
||||
if (my_filetype==Mach_header::MH_EXECUTE) {
|
||||
fo->write(&segcmdo, sizeof(segcmdo));
|
||||
pack1_setup_threado(fo);
|
||||
memset(&linkedito, 0, sizeof(linkedito));
|
||||
fo->write(&linkedito, sizeof(linkedito));
|
||||
}
|
||||
if (my_filetype==Mach_header::MH_DYLIB) {
|
||||
fo->write(rawmseg, mhdri.sizeofcmds);
|
||||
@ -1086,7 +1134,11 @@ void PackMachBase<T>::unpack(OutputFile *fo)
|
||||
fi->readx(&mhdri, sizeof(mhdri));
|
||||
rawmseg = (Mach_segment_command *)new char[(unsigned) mhdri.sizeofcmds];
|
||||
fi->readx(rawmseg, mhdri.sizeofcmds);
|
||||
overlay_offset = sizeof(mhdri) + mhdri.sizeofcmds + sizeof(linfo);
|
||||
|
||||
// FIXME forgot space left for LC_CODE_SIGNATURE;
|
||||
// but PackUnix::canUnpack() sets overlay_offset anyway.
|
||||
//overlay_offset = sizeof(mhdri) + mhdri.sizeofcmds + sizeof(linfo);
|
||||
|
||||
fi->seek(overlay_offset, SEEK_SET);
|
||||
p_info hbuf;
|
||||
fi->readx(&hbuf, sizeof(hbuf));
|
||||
|
||||
Loading…
Reference in New Issue
Block a user