amd64-darwin.dylib hacking
modified: p_mach.cpp modified: p_mach.h modified: p_mach_enum.h modified: stub/src/amd64-darwin.dylib-entry.S modified: stub/amd64-darwin.dylib-entry.h modified: stub/tmp/amd64-darwin.dylib-entry.bin.dump
This commit is contained in:
+192
-217
@@ -89,14 +89,14 @@ static const
|
|||||||
|
|
||||||
static const unsigned lc_segment[2] = {
|
static const unsigned lc_segment[2] = {
|
||||||
0x1, 0x19
|
0x1, 0x19
|
||||||
//Mach_segment_command::LC_SEGMENT,
|
//Mach_command::LC_SEGMENT,
|
||||||
//Mach_segment_command::LC_SEGMENT_64
|
//Mach_command::LC_SEGMENT_64
|
||||||
};
|
};
|
||||||
|
|
||||||
static const unsigned lc_routines[2] = {
|
static const unsigned lc_routines[2] = {
|
||||||
0x11, 0x1a
|
0x11, 0x1a
|
||||||
//Mach_segment_command::LC_ROUTINES,
|
//Mach_command::LC_ROUTINES,
|
||||||
//Mach_segment_command::LC_ROUTINES_64
|
//Mach_command::LC_ROUTINES_64
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
@@ -564,62 +564,35 @@ template <class T>
|
|||||||
void PackMachBase<T>::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
void PackMachBase<T>::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
||||||
{
|
{
|
||||||
// offset of p_info in compressed file
|
// offset of p_info in compressed file
|
||||||
overlay_offset = sizeof(mhdro) + sizeof(segZERO)
|
overlay_offset = secTEXT.addr + sizeof(linfo);
|
||||||
+ sizeof(segXHDR) + sizeof(secXHDR)
|
|
||||||
+ sizeof(segTEXT) + sizeof(secTEXT)
|
|
||||||
+ sizeof(cmdUUID) + sizeof(cmdSRCVER) + sizeof(cmdVERMIN) + sizeof(Mach_main_command)
|
|
||||||
+ sizeof(Mach_dyld_info_only_command) + sizeof(Mach_dysymtab_command)
|
|
||||||
+ sizeof(Mach_load_dylinker_command) + sizeof(Mach_load_dylib_command)
|
|
||||||
+ sizeof(Mach_function_starts_command) + sizeof(Mach_data_in_code_command)
|
|
||||||
+ sizeof(linfo);
|
|
||||||
if (my_filetype==Mach_header::MH_EXECUTE) {
|
|
||||||
overlay_offset = PAGE_SIZE; // FIXME
|
|
||||||
overlay_offset += sizeof(linfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
super::pack4(fo, ft);
|
super::pack4(fo, ft);
|
||||||
if (my_filetype == Mach_header::MH_EXECUTE) {
|
|
||||||
|
if (Mach_header::MH_EXECUTE == my_filetype) {
|
||||||
upx_uint64_t const zero = 0;
|
upx_uint64_t const zero = 0;
|
||||||
unsigned const len = fo->getBytesWritten();
|
unsigned const len = fo->getBytesWritten();
|
||||||
fo->write(&zero, 7& (0u-len));
|
fo->write(&zero, 7& (0u-len));
|
||||||
}
|
|
||||||
unsigned const eofcmpr = fo->getBytesWritten();
|
unsigned const eofcmpr = fo->getBytesWritten();
|
||||||
if (Mach_header::CPU_TYPE_X86_64 == my_cputype) {
|
if (Mach_header::CPU_TYPE_X86_64 == my_cputype) {
|
||||||
// sneak in a little below 4GiB
|
// sneak in a little below 4GiB
|
||||||
segTEXT.vmaddr = segZERO.vmaddr + segZERO.vmsize;
|
segTEXT.vmaddr = segZERO.vmaddr + segZERO.vmsize;
|
||||||
}
|
|
||||||
else {
|
|
||||||
// ::pack1 set segTEXT.vmaddr to be va_hi: no conflict
|
|
||||||
}
|
|
||||||
segTEXT.filesize = eofcmpr;
|
|
||||||
segTEXT.vmsize += eofcmpr; // utilize GAP + NO_LAP + sz_unc - sz_cpr
|
|
||||||
secTEXT.offset = overlay_offset - sizeof(linfo);
|
|
||||||
secTEXT.addr = segTEXT.vmaddr + secTEXT.offset;
|
|
||||||
secTEXT.size = segTEXT.filesize - secTEXT.offset;
|
|
||||||
secXHDR.offset = overlay_offset - sizeof(linfo);
|
|
||||||
if (my_filetype==Mach_header::MH_EXECUTE) {
|
|
||||||
secXHDR.offset -= sizeof(linkitem);
|
|
||||||
}
|
|
||||||
secXHDR.addr += secXHDR.offset;
|
|
||||||
unsigned offLINK = segLINK.fileoff;
|
|
||||||
segLINK.vmaddr = segTEXT.vmaddr + offLINK;
|
|
||||||
if (my_filetype != Mach_header::MH_EXECUTE) {
|
|
||||||
fo->seek(offLINK - 1, SEEK_SET); fo->write("", 1);
|
|
||||||
fo->seek(sizeof(mhdro), SEEK_SET);
|
|
||||||
fo->rewrite(&segZERO, sizeof(segZERO));
|
|
||||||
fo->rewrite(&segXHDR, sizeof(segXHDR));
|
|
||||||
fo->rewrite(&secXHDR, sizeof(secXHDR));
|
|
||||||
fo->rewrite(&segTEXT, sizeof(segTEXT));
|
|
||||||
fo->rewrite(&secTEXT, sizeof(secTEXT));
|
|
||||||
fo->rewrite(&cmdUUID, sizeof(cmdUUID));
|
|
||||||
fo->rewrite(&segLINK, sizeof(segLINK));
|
|
||||||
threado_rewrite(fo);
|
|
||||||
if (my_filetype==Mach_header::MH_EXECUTE) {
|
|
||||||
fo->rewrite(&linkitem, sizeof(linkitem));
|
|
||||||
}
|
}
|
||||||
fo->rewrite(&linfo, sizeof(linfo));
|
else {
|
||||||
}
|
// ::pack1 set segTEXT.vmaddr to be va_hi: no conflict
|
||||||
if (my_filetype == Mach_header::MH_EXECUTE) {
|
}
|
||||||
|
segTEXT.filesize = eofcmpr;
|
||||||
|
segTEXT.vmsize += eofcmpr; // utilize GAP + NO_LAP + sz_unc - sz_cpr
|
||||||
|
secTEXT.offset = overlay_offset - sizeof(linfo);
|
||||||
|
secTEXT.addr = segTEXT.vmaddr + secTEXT.offset;
|
||||||
|
secTEXT.size = segTEXT.filesize - secTEXT.offset;
|
||||||
|
secXHDR.offset = overlay_offset - sizeof(linfo);
|
||||||
|
if (my_filetype==Mach_header::MH_EXECUTE) {
|
||||||
|
secXHDR.offset -= sizeof(linkitem);
|
||||||
|
}
|
||||||
|
secXHDR.addr += secXHDR.offset;
|
||||||
|
unsigned offLINK = segLINK.fileoff;
|
||||||
|
segLINK.vmaddr = segTEXT.vmaddr + offLINK;
|
||||||
|
|
||||||
// Get a writeable copy of the stub to make editing easier.
|
// Get a writeable copy of the stub to make editing easier.
|
||||||
ByteArray(upxstub, sz_stub_main);
|
ByteArray(upxstub, sz_stub_main);
|
||||||
memcpy(upxstub, stub_main, sz_stub_main);
|
memcpy(upxstub, stub_main, sz_stub_main);
|
||||||
@@ -644,8 +617,8 @@ void PackMachBase<T>::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
|||||||
lcp_next = (Mach_command *)(sz_cmd + (char *)lcp);
|
lcp_next = (Mach_command *)(sz_cmd + (char *)lcp);
|
||||||
|
|
||||||
switch (lcp->cmd) {
|
switch (lcp->cmd) {
|
||||||
case Mach_segment_command::LC_SEGMENT: // fall through
|
case Mach_command::LC_SEGMENT: // fall through
|
||||||
case Mach_segment_command::LC_SEGMENT_64: {
|
case Mach_command::LC_SEGMENT_64: {
|
||||||
Mach_segment_command *const segptr = (Mach_segment_command *)lcp;
|
Mach_segment_command *const segptr = (Mach_segment_command *)lcp;
|
||||||
if (!strcmp("__PAGEZERO", segptr->segname)) {
|
if (!strcmp("__PAGEZERO", segptr->segname)) {
|
||||||
if (pagezero_vmsize < 0xF0000000ull) {
|
if (pagezero_vmsize < 0xF0000000ull) {
|
||||||
@@ -705,7 +678,7 @@ void PackMachBase<T>::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
|||||||
segXHDR.vmsize = offLINK - segTEXT.vmsize;
|
segXHDR.vmsize = offLINK - segTEXT.vmsize;
|
||||||
segXHDR.fileoff = segTEXT.filesize + segTEXT.fileoff; // XXX FIXME: assumes no __DATA in stub
|
segXHDR.fileoff = segTEXT.filesize + segTEXT.fileoff; // XXX FIXME: assumes no __DATA in stub
|
||||||
segXHDR.filesize = offLINK - segTEXT.filesize; // XXX FIXME: assumes no __DATA in stub;
|
segXHDR.filesize = offLINK - segTEXT.filesize; // XXX FIXME: assumes no __DATA in stub;
|
||||||
segXHDR.maxprot = Mach_segment_command::VM_PROT_READ;
|
segXHDR.maxprot = Mach_command::VM_PROT_READ;
|
||||||
segXHDR.nsects = 0;
|
segXHDR.nsects = 0;
|
||||||
if (!segtxt) { // replace __DATA with segXHDR
|
if (!segtxt) { // replace __DATA with segXHDR
|
||||||
va_next = segXHDR.vmsize + segXHDR.vmaddr;
|
va_next = segXHDR.vmsize + segXHDR.vmaddr;
|
||||||
@@ -722,8 +695,8 @@ void PackMachBase<T>::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!strcmp("__LINKEDIT", segptr->segname)) {
|
if (!strcmp("__LINKEDIT", segptr->segname)) {
|
||||||
segLINK.initprot = Mach_segment_command::VM_PROT_READ
|
segLINK.initprot = Mach_command::VM_PROT_READ
|
||||||
| Mach_segment_command::VM_PROT_EXECUTE;
|
| Mach_command::VM_PROT_EXECUTE;
|
||||||
delta = offLINK - segptr->fileoff; // relocation constant
|
delta = offLINK - segptr->fileoff; // relocation constant
|
||||||
|
|
||||||
// Update the __LINKEDIT header
|
// Update the __LINKEDIT header
|
||||||
@@ -738,7 +711,7 @@ void PackMachBase<T>::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
|||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case Mach_segment_command::LC_DYLD_INFO_ONLY: {
|
case Mach_command::LC_DYLD_INFO_ONLY: {
|
||||||
Mach_dyld_info_only_command *p = (Mach_dyld_info_only_command *)lcp;
|
Mach_dyld_info_only_command *p = (Mach_dyld_info_only_command *)lcp;
|
||||||
if (p->rebase_off) p->rebase_off += delta;
|
if (p->rebase_off) p->rebase_off += delta;
|
||||||
if (p->bind_off) p->bind_off += delta;
|
if (p->bind_off) p->bind_off += delta;
|
||||||
@@ -749,7 +722,7 @@ void PackMachBase<T>::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
|||||||
p->export_size = 0;
|
p->export_size = 0;
|
||||||
skip = 1;
|
skip = 1;
|
||||||
} break;
|
} break;
|
||||||
case Mach_segment_command::LC_SYMTAB: {
|
case Mach_command::LC_SYMTAB: {
|
||||||
// Apple codesign requires that string table is last in the file.
|
// Apple codesign requires that string table is last in the file.
|
||||||
Mach_symtab_command *p = (Mach_symtab_command *)lcp;
|
Mach_symtab_command *p = (Mach_symtab_command *)lcp;
|
||||||
p->symoff = segLINK.filesize + segLINK.fileoff;
|
p->symoff = segLINK.filesize + segLINK.fileoff;
|
||||||
@@ -758,7 +731,7 @@ void PackMachBase<T>::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
|||||||
p->strsize = segLINK.filesize;
|
p->strsize = segLINK.filesize;
|
||||||
skip = 1;
|
skip = 1;
|
||||||
} break;
|
} break;
|
||||||
case Mach_segment_command::LC_DYSYMTAB: {
|
case Mach_command::LC_DYSYMTAB: {
|
||||||
Mach_dysymtab_command *p = (Mach_dysymtab_command *)lcp;
|
Mach_dysymtab_command *p = (Mach_dysymtab_command *)lcp;
|
||||||
if (p->tocoff) p->tocoff += delta;
|
if (p->tocoff) p->tocoff += delta;
|
||||||
if (p->modtaboff) p->modtaboff += delta;
|
if (p->modtaboff) p->modtaboff += delta;
|
||||||
@@ -775,12 +748,7 @@ void PackMachBase<T>::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
|||||||
p->nundefsym = 0;
|
p->nundefsym = 0;
|
||||||
skip = 1;
|
skip = 1;
|
||||||
} break;
|
} break;
|
||||||
case Mach_segment_command::LC_FUNCTION_STARTS: {
|
case Mach_command::LC_MAIN: {
|
||||||
Mach_function_starts_command *p = (Mach_function_starts_command *)lcp;
|
|
||||||
if (p->dataoff) p->dataoff += delta;
|
|
||||||
skip = 1;
|
|
||||||
} break;
|
|
||||||
case Mach_segment_command::LC_MAIN: {
|
|
||||||
// Replace later with LC_UNIXTHREAD.
|
// Replace later with LC_UNIXTHREAD.
|
||||||
// LC_MAIN requires libSystem.B.dylib to provide the environment for main(), and CALLs the entryoff.
|
// LC_MAIN requires libSystem.B.dylib to provide the environment for main(), and CALLs the entryoff.
|
||||||
// LC_UNIXTHREAD does not need libSystem.B.dylib, and JMPs to the .rip with %rsp/argc and argv= 8+%rsp
|
// LC_UNIXTHREAD does not need libSystem.B.dylib, and JMPs to the .rip with %rsp/argc and argv= 8+%rsp
|
||||||
@@ -788,31 +756,33 @@ void PackMachBase<T>::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
|||||||
(((Mach_main_command const *)lcp)->entryoff - segTEXT.fileoff));
|
(((Mach_main_command const *)lcp)->entryoff - segTEXT.fileoff));
|
||||||
skip = 1;
|
skip = 1;
|
||||||
} break;
|
} break;
|
||||||
case Mach_segment_command::LC_UNIXTHREAD: { // pre-LC_MAIN
|
case Mach_command::LC_UNIXTHREAD: { // pre-LC_MAIN
|
||||||
threado_setPC(secTEXT.addr +
|
threado_setPC(secTEXT.addr +
|
||||||
(threadc_getPC(lcp) - txt_addr));
|
(threadc_getPC(lcp) - txt_addr));
|
||||||
skip = 1;
|
skip = 1;
|
||||||
} break;
|
} break;
|
||||||
case Mach_segment_command::LC_LOAD_DYLIB: {
|
case Mach_command::LC_LOAD_DYLIB: {
|
||||||
skip = 1;
|
skip = 1;
|
||||||
} break;
|
} break;
|
||||||
case Mach_segment_command::LC_DATA_IN_CODE: {
|
|
||||||
Mach_data_in_code_command *p = (Mach_data_in_code_command *)lcp;
|
case Mach_command::LC_FUNCTION_STARTS:
|
||||||
|
case Mach_command::LC_DATA_IN_CODE: {
|
||||||
|
Mach_linkedit_data_command *p = (Mach_linkedit_data_command *)lcp;
|
||||||
if (p->dataoff) p->dataoff += delta;
|
if (p->dataoff) p->dataoff += delta;
|
||||||
skip = 1;
|
skip = 1;
|
||||||
} break;
|
} break;
|
||||||
case Mach_segment_command::LC_LOAD_DYLINKER: {
|
case Mach_command::LC_LOAD_DYLINKER: {
|
||||||
skip = 1;
|
skip = 1;
|
||||||
} break;
|
} break;
|
||||||
case Mach_segment_command::LC_SOURCE_VERSION: { // copy from saved original
|
case Mach_command::LC_SOURCE_VERSION: { // copy from saved original
|
||||||
memcpy(lcp, &cmdSRCVER, sizeof(cmdSRCVER));
|
memcpy(lcp, &cmdSRCVER, sizeof(cmdSRCVER));
|
||||||
if (Mach_segment_command::LC_SOURCE_VERSION != cmdSRCVER.cmd) {
|
if (Mach_command::LC_SOURCE_VERSION != cmdSRCVER.cmd) {
|
||||||
skip = 1; // was not seen
|
skip = 1; // was not seen
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case Mach_segment_command::LC_VERSION_MIN_MACOSX: { // copy from saved original
|
case Mach_command::LC_VERSION_MIN_MACOSX: { // copy from saved original
|
||||||
memcpy(lcp, &cmdVERMIN, sizeof(cmdVERMIN));
|
memcpy(lcp, &cmdVERMIN, sizeof(cmdVERMIN));
|
||||||
if (Mach_segment_command::LC_VERSION_MIN_MACOSX != cmdVERMIN.cmd) {
|
if (Mach_command::LC_VERSION_MIN_MACOSX != cmdVERMIN.cmd) {
|
||||||
skip = 1; // was not seen
|
skip = 1; // was not seen
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@@ -854,8 +824,7 @@ next:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// At 2013-02-03 part of the source for codesign was
|
// At 2013-02-03 part of the source for codesign was // http://opensource.apple.com/source/cctools/cctools-836/libstuff/ofile.c
|
||||||
// http://opensource.apple.com/source/cctools/cctools-836/libstuff/ofile.c
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void PackMachBase<T>::pack4dylib( // append PackHeader
|
void PackMachBase<T>::pack4dylib( // append PackHeader
|
||||||
@@ -864,8 +833,10 @@ void PackMachBase<T>::pack4dylib( // append PackHeader
|
|||||||
Addr init_address
|
Addr init_address
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
fo->seek(0, SEEK_SET);
|
||||||
|
fo->rewrite(&mhdro, sizeof(mhdro)); // segTEXT.nsect=1 (only secTEXT)
|
||||||
|
fo->rewrite(&segTEXT, sizeof(segTEXT)); // .vmsize
|
||||||
unsigned opos = sizeof(mhdro);
|
unsigned opos = sizeof(mhdro);
|
||||||
fo->seek(opos, SEEK_SET);
|
|
||||||
|
|
||||||
// Append each non-__TEXT segment, page aligned.
|
// Append each non-__TEXT segment, page aligned.
|
||||||
int slide = 0;
|
int slide = 0;
|
||||||
@@ -876,35 +847,58 @@ void PackMachBase<T>::pack4dylib( // append PackHeader
|
|||||||
(Mach_segment_command const *)(mhdri.sizeofcmds + (char const *)seg);
|
(Mach_segment_command const *)(mhdri.sizeofcmds + (char const *)seg);
|
||||||
for ( ; seg < endseg; seg = (Mach_segment_command const *)(
|
for ( ; seg < endseg; seg = (Mach_segment_command const *)(
|
||||||
seg->cmdsize + (char const *)seg )
|
seg->cmdsize + (char const *)seg )
|
||||||
) switch (seg->cmd & ~Mach_segment_command::LC_REQ_DYLD) {
|
) switch (seg->cmd & ~Mach_command::LC_REQ_DYLD) {
|
||||||
default: // unknown if any file offset field must slide
|
default: // unknown if any file offset field must slide
|
||||||
printf("Unrecognized Macho cmd offset=0x%lx cmd=0x%lx size=0x%lx\n", (unsigned long)((const char *)seg - (const char *)rawmseg), (unsigned long)seg->cmd, (unsigned long)seg->cmdsize);
|
fprintf(stderr, "Unrecognized Macho cmd offset=0x%lx cmd=0x%lx size=0x%lx\n",
|
||||||
|
(unsigned long)((const char *)seg - (const char *)rawmseg),
|
||||||
|
(unsigned long)seg->cmd, (unsigned long)seg->cmdsize);
|
||||||
// fall through
|
// fall through
|
||||||
case Mach_segment_command::LC_DYLD_INFO_ONLY & ~Mach_segment_command::LC_REQ_DYLD:
|
case Mach_command::LC_VERSION_MIN_MACOSX:
|
||||||
case Mach_segment_command::LC_VERSION_MIN_MACOSX:
|
case Mach_command::LC_SOURCE_VERSION:
|
||||||
case Mach_segment_command::LC_FUNCTION_STARTS: // points into __LINKEDIT
|
case Mach_command::LC_THREAD:
|
||||||
case Mach_segment_command::LC_DATA_IN_CODE: // points into __LINKEDIT
|
case Mach_command::LC_UNIXTHREAD:
|
||||||
case Mach_segment_command::LC_SOURCE_VERSION:
|
case Mach_command::LC_LOAD_DYLIB:
|
||||||
case Mach_segment_command::LC_THREAD:
|
case Mach_command::LC_ID_DYLIB:
|
||||||
case Mach_segment_command::LC_UNIXTHREAD:
|
case Mach_command::LC_LOAD_DYLINKER:
|
||||||
case Mach_segment_command::LC_LOAD_DYLIB:
|
case Mach_command::LC_UUID:
|
||||||
case Mach_segment_command::LC_ID_DYLIB:
|
case Mach_command::LC_RPATH:
|
||||||
case Mach_segment_command::LC_LOAD_DYLINKER:
|
case Mach_command::LC_REEXPORT_DYLIB: { // contain no file offset fields
|
||||||
case Mach_segment_command::LC_UUID:
|
fo->seek(hdrpos, SEEK_SET);
|
||||||
case Mach_segment_command::LC_RPATH:
|
fo->rewrite(seg, seg->cmdsize);
|
||||||
case Mach_segment_command::LC_CODE_SIGNATURE:
|
|
||||||
case Mach_segment_command::LC_REEXPORT_DYLIB:
|
|
||||||
hdrpos += seg->cmdsize;
|
hdrpos += seg->cmdsize;
|
||||||
break; // contain no file offset fields
|
} break;
|
||||||
case Mach_segment_command::LC_TWOLEVEL_HINTS: {
|
|
||||||
|
case Mach_command::LC_CODE_SIGNATURE:
|
||||||
|
case Mach_command::LC_SEGMENT_SPLIT_INFO:
|
||||||
|
case Mach_command::LC_DYLIB_CODE_SIGN_DRS:
|
||||||
|
case Mach_command::LC_DATA_IN_CODE:
|
||||||
|
case Mach_command::LC_FUNCTION_STARTS: {
|
||||||
|
Mach_linkedit_data_command cmd; memcpy(&cmd, seg, sizeof(cmd));
|
||||||
|
if (o_end_txt <= cmd.dataoff) { cmd.dataoff += slide; }
|
||||||
|
fo->seek(hdrpos, SEEK_SET);
|
||||||
|
fo->rewrite(&cmd, sizeof(cmd));
|
||||||
|
hdrpos += sizeof(cmd);
|
||||||
|
} break;
|
||||||
|
case Mach_command::LC_DYLD_INFO_ONLY & ~Mach_command::LC_REQ_DYLD: {
|
||||||
|
Mach_dyld_info_only_command cmd; memcpy(&cmd, seg, sizeof(cmd));
|
||||||
|
if (o_end_txt <= cmd.rebase_off) { cmd.rebase_off += slide; }
|
||||||
|
if (o_end_txt <= cmd.bind_off) { cmd.bind_off += slide; }
|
||||||
|
if (o_end_txt <= cmd.weak_bind_off) { cmd.weak_bind_off += slide; }
|
||||||
|
if (o_end_txt <= cmd.lazy_bind_off) { cmd.lazy_bind_off += slide; }
|
||||||
|
if (o_end_txt <= cmd.export_off) { cmd.export_off += slide; }
|
||||||
|
fo->seek(hdrpos, SEEK_SET);
|
||||||
|
fo->rewrite(&cmd, sizeof(cmd));
|
||||||
|
hdrpos += sizeof(cmd);
|
||||||
|
} break;
|
||||||
|
case Mach_command::LC_TWOLEVEL_HINTS: {
|
||||||
Mach_twolevel_hints_command cmd; memcpy(&cmd, seg, sizeof(cmd));
|
Mach_twolevel_hints_command cmd; memcpy(&cmd, seg, sizeof(cmd));
|
||||||
if (o_end_txt <= cmd.offset) { cmd.offset += slide; }
|
if (o_end_txt <= cmd.offset) { cmd.offset += slide; }
|
||||||
fo->seek(hdrpos, SEEK_SET);
|
fo->seek(hdrpos, SEEK_SET);
|
||||||
fo->rewrite(&cmd, sizeof(cmd));
|
fo->rewrite(&cmd, sizeof(cmd));
|
||||||
hdrpos += sizeof(cmd);
|
hdrpos += sizeof(cmd);
|
||||||
} break;
|
} break;
|
||||||
case Mach_segment_command::LC_ROUTINES_64:
|
case Mach_command::LC_ROUTINES_64:
|
||||||
case Mach_segment_command::LC_ROUTINES: {
|
case Mach_command::LC_ROUTINES: {
|
||||||
Mach_routines_command cmd; memcpy(&cmd, seg, sizeof(cmd));
|
Mach_routines_command cmd; memcpy(&cmd, seg, sizeof(cmd));
|
||||||
cmd.reserved1 = cmd.init_address;
|
cmd.reserved1 = cmd.init_address;
|
||||||
cmd.init_address = init_address;
|
cmd.init_address = init_address;
|
||||||
@@ -912,17 +906,17 @@ void PackMachBase<T>::pack4dylib( // append PackHeader
|
|||||||
fo->rewrite(&cmd, sizeof(cmd));
|
fo->rewrite(&cmd, sizeof(cmd));
|
||||||
hdrpos += sizeof(cmd);
|
hdrpos += sizeof(cmd);
|
||||||
} break;
|
} break;
|
||||||
case Mach_segment_command::LC_SEGMENT_64:
|
case Mach_command::LC_SEGMENT_64:
|
||||||
case Mach_segment_command::LC_SEGMENT: {
|
case Mach_command::LC_SEGMENT: {
|
||||||
// non-__TEXT might be observed and relocated by dyld before us.
|
// non-__TEXT might be observed and relocated by dyld before us.
|
||||||
Mach_segment_command segcmdtmp = *seg;
|
Mach_segment_command segcmdtmp = *seg;
|
||||||
bool const is_text = 0==strncmp(&seg->segname[0], "__TEXT", 1+ 6);
|
bool const is_text = 0==strncmp(&seg->segname[0], "__TEXT", 1+ 6);
|
||||||
{
|
{
|
||||||
if (is_text) {
|
if (is_text) {
|
||||||
slide = 0;
|
slide = 0;
|
||||||
segcmdtmp.filesize = fo->getBytesWritten();
|
segTEXT.filesize = fo->getBytesWritten();
|
||||||
segcmdtmp.maxprot |= Mach_segment_command::VM_PROT_WRITE;
|
segTEXT.maxprot |= Mach_command::VM_PROT_WRITE;
|
||||||
segcmdtmp.initprot |= Mach_segment_command::VM_PROT_WRITE;
|
segcmdtmp = segTEXT;
|
||||||
opos = o_end_txt = segcmdtmp.filesize + segcmdtmp.fileoff;
|
opos = o_end_txt = segcmdtmp.filesize + segcmdtmp.fileoff;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -936,81 +930,43 @@ void PackMachBase<T>::pack4dylib( // append PackHeader
|
|||||||
hdrpos += sizeof(segcmdtmp);
|
hdrpos += sizeof(segcmdtmp);
|
||||||
|
|
||||||
// Update the sections.
|
// Update the sections.
|
||||||
Mach_section_command const *secp = (Mach_section_command const *)(const void*)(const char*)(1+ seg);
|
Mach_section_command const *secp =
|
||||||
unsigned const nsects = segcmdtmp.nsects;
|
(Mach_section_command const *)(const void*)(const char*)(1+ seg);
|
||||||
|
if (is_text) {
|
||||||
|
secTEXT.offset = secp->offset;
|
||||||
|
secTEXT.addr = segTEXT.vmaddr + secTEXT.offset;
|
||||||
|
secTEXT.size = segTEXT.filesize - secTEXT.offset;
|
||||||
|
secp = &secTEXT;
|
||||||
|
}
|
||||||
|
unsigned const nsects = (is_text ? 1 : segcmdtmp.nsects);
|
||||||
Mach_section_command seccmdtmp;
|
Mach_section_command seccmdtmp;
|
||||||
for (unsigned j = 0; j < nsects; ++secp, ++j) {
|
for (unsigned j = 0; j < nsects; ++secp, ++j) {
|
||||||
seccmdtmp = *secp;
|
seccmdtmp = *secp;
|
||||||
if (o_end_txt <= seccmdtmp.offset) { seccmdtmp.offset += slide; }
|
if (o_end_txt <= seccmdtmp.offset) { seccmdtmp.offset += slide; }
|
||||||
if (o_end_txt <= seccmdtmp.reloff) { seccmdtmp.reloff += slide; }
|
if (o_end_txt <= seccmdtmp.reloff) { seccmdtmp.reloff += slide; }
|
||||||
if (0==strncmp(&seccmdtmp.sectname[0], "__mod_init_func", 1+ 15)) {
|
|
||||||
if (seccmdtmp.flags==9 // FIXME: S_MOD_INIT_FUNC_POINTERS
|
|
||||||
&& seccmdtmp.nreloc==0 && seccmdtmp.size==sizeof(Addr) ) {
|
|
||||||
seccmdtmp.addr = seccmdtmp.offset = init_address -4*4 - 8;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
infoWarning("unknown __mod_init_func section");
|
|
||||||
}
|
|
||||||
#if 0 /*{*/
|
|
||||||
// 2010-03-12 Stop work because I don't understand what is going on,
|
|
||||||
// and I cannot find good documentation on the meaning of various parts
|
|
||||||
// of .dylib. amd64(x86_64) is almost certain to fail in the dynamic
|
|
||||||
// loader, before the upx stub gets control. For instance:
|
|
||||||
//
|
|
||||||
// Program received signal EXC_BAD_ACCESS, Could not access memory.
|
|
||||||
// Reason: KERN_INVALID_ADDRESS at address: 0x000000015f00329a
|
|
||||||
// 0x00007fff5fc10ce3 in __dyld__ZN16ImageLoaderMachO23setupLazyPointerHandlerERKN11ImageLoader11LinkContextE ()
|
|
||||||
// (gdb) bt
|
|
||||||
// #0 0x00007fff5fc10ce3 in __dyld__ZN16ImageLoaderMachO23setupLazyPointerHandlerERKN11ImageLoader11LinkContextE ()
|
|
||||||
// #1 0x00007fff5fc138c2 in __dyld__ZN16ImageLoaderMachO6doBindERKN11ImageLoader11LinkContextEb ()
|
|
||||||
// #2 0x00007fff5fc0c0ab in __dyld__ZN11ImageLoader13recursiveBindERKNS_11LinkContextEb ()
|
|
||||||
// #3 0x00007fff5fc0c08f in __dyld__ZN11ImageLoader13recursiveBindERKNS_11LinkContextEb ()
|
|
||||||
// #4 0x00007fff5fc0f49e in __dyld__ZN11ImageLoader4linkERKNS_11LinkContextEbbRKNS_10RPathChainE ()
|
|
||||||
// #5 0x00007fff5fc04c56 in __dyld__ZN4dyld4linkEP11ImageLoaderbRKNS0_10RPathChainE ()
|
|
||||||
// #6 0x00007fff5fc06e04 in __dyld__ZN4dyld5_mainEPK11mach_headermiPPKcS5_S5_ ()
|
|
||||||
// #7 0x00007fff5fc01695 in __dyld__ZN13dyldbootstrap5startEPK11mach_headeriPPKcl ()
|
|
||||||
// #8 0x00007fff5fc0103a in __dyld__dyld_start ()
|
|
||||||
// #9 0x0000000100000000 in ?? ()
|
|
||||||
// #10 0x0000000000000001 in ?? ()
|
|
||||||
// #11 0x00007fff5fbffbd0 in ?? ()
|
|
||||||
//
|
|
||||||
// The various paragraphs below are experiments in "commenting out" pieces of
|
|
||||||
// the compressed .dylib, trying to isolate the bug(s).
|
|
||||||
// FIXME
|
|
||||||
unsigned const t = seccmdtmp.flags & 0xff;
|
|
||||||
if (t==6 // FIXME: S_NON_LAZY_SYMBOL_POINTERS
|
|
||||||
|| t==7 // FIXME: S_LAZY_SYMBOL_POINTERS
|
|
||||||
|| t==8 // FIXME: S_SYMBOL_STUBS
|
|
||||||
|| t==11 // FIXME: S_COALESCED
|
|
||||||
) {
|
|
||||||
seccmdtmp.flags = 0; // FIXME: S_REGULAR
|
|
||||||
strcpy(seccmdtmp.sectname, "__data");
|
|
||||||
}
|
|
||||||
// FIXME
|
|
||||||
if (0==strncmp("__stub_helper", &seccmdtmp.sectname[0], 1+ 13)) {
|
|
||||||
strcpy(seccmdtmp.sectname, "__text");
|
|
||||||
}
|
|
||||||
// FIXME
|
|
||||||
if (0==strncmp("__dyld", &seccmdtmp.sectname[0], 1+ 6)) {
|
|
||||||
strcpy(seccmdtmp.sectname, "__text");
|
|
||||||
}
|
|
||||||
#endif /*}*/
|
|
||||||
fo->rewrite(&seccmdtmp, sizeof(seccmdtmp));
|
fo->rewrite(&seccmdtmp, sizeof(seccmdtmp));
|
||||||
hdrpos += sizeof(seccmdtmp);
|
hdrpos += sizeof(seccmdtmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_text) {
|
if (!is_text) {
|
||||||
fo->seek(opos, SEEK_SET);
|
|
||||||
fi->seek(seg->fileoff, SEEK_SET);
|
|
||||||
unsigned const len = seg->filesize;
|
unsigned const len = seg->filesize;
|
||||||
MemBuffer data(len);
|
MemBuffer data(len);
|
||||||
|
fi->seek(seg->fileoff, SEEK_SET);
|
||||||
fi->readx(data, len);
|
fi->readx(data, len);
|
||||||
|
unsigned const pos = o__mod_init_func - seg->fileoff;
|
||||||
|
if (pos < seg->filesize) {
|
||||||
|
if (*(unsigned *)(pos + data) != (unsigned)prev_mod_init_func) {
|
||||||
|
throwCantPack("__mod_init_func inconsistent");
|
||||||
|
}
|
||||||
|
*(unsigned *)(pos + data) = (unsigned)entryVMA;
|
||||||
|
}
|
||||||
|
fo->seek(opos, SEEK_SET);
|
||||||
fo->write(data, len);
|
fo->write(data, len);
|
||||||
opos += len;
|
opos += len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case Mach_segment_command::LC_SYMTAB: {
|
case Mach_command::LC_SYMTAB: {
|
||||||
Mach_symtab_command cmd; memcpy(&cmd, seg, sizeof(cmd));
|
Mach_symtab_command cmd; memcpy(&cmd, seg, sizeof(cmd));
|
||||||
if (o_end_txt <= cmd.symoff) { cmd.symoff += slide; }
|
if (o_end_txt <= cmd.symoff) { cmd.symoff += slide; }
|
||||||
if (o_end_txt <= cmd.stroff) { cmd.stroff += slide; }
|
if (o_end_txt <= cmd.stroff) { cmd.stroff += slide; }
|
||||||
@@ -1018,7 +974,7 @@ void PackMachBase<T>::pack4dylib( // append PackHeader
|
|||||||
fo->rewrite(&cmd, sizeof(cmd));
|
fo->rewrite(&cmd, sizeof(cmd));
|
||||||
hdrpos += sizeof(cmd);
|
hdrpos += sizeof(cmd);
|
||||||
} break;
|
} break;
|
||||||
case Mach_segment_command::LC_DYSYMTAB: {
|
case Mach_command::LC_DYSYMTAB: {
|
||||||
Mach_dysymtab_command cmd; memcpy(&cmd, seg, sizeof(cmd));
|
Mach_dysymtab_command cmd; memcpy(&cmd, seg, sizeof(cmd));
|
||||||
if (o_end_txt <= cmd.tocoff) { cmd.tocoff += slide; }
|
if (o_end_txt <= cmd.tocoff) { cmd.tocoff += slide; }
|
||||||
if (o_end_txt <= cmd.modtaboff) { cmd.modtaboff += slide; }
|
if (o_end_txt <= cmd.modtaboff) { cmd.modtaboff += slide; }
|
||||||
@@ -1030,18 +986,9 @@ void PackMachBase<T>::pack4dylib( // append PackHeader
|
|||||||
fo->rewrite(&cmd, sizeof(cmd));
|
fo->rewrite(&cmd, sizeof(cmd));
|
||||||
hdrpos += sizeof(cmd);
|
hdrpos += sizeof(cmd);
|
||||||
} break;
|
} break;
|
||||||
case Mach_segment_command::LC_SEGMENT_SPLIT_INFO: {
|
|
||||||
Mach_segsplit_info_command cmd; memcpy(&cmd, seg, sizeof(cmd));
|
|
||||||
if (o_end_txt <= cmd.dataoff) { cmd.dataoff += slide; }
|
|
||||||
fo->seek(hdrpos, SEEK_SET);
|
|
||||||
fo->rewrite(&cmd, sizeof(cmd));
|
|
||||||
hdrpos += sizeof(cmd);
|
|
||||||
} break;
|
|
||||||
} // end 'switch'
|
} // end 'switch'
|
||||||
fo->seek(opos, SEEK_SET); // BUG: "fo->seek(0, SEEK_END);" is broken
|
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<T>::pack4(fo, ft);
|
PackMachBase<T>::pack4(fo, ft);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1069,7 +1016,7 @@ template <class T>
|
|||||||
void PackMachBase<T>::pack3(OutputFile *fo, Filter &ft) // append loader
|
void PackMachBase<T>::pack3(OutputFile *fo, Filter &ft) // append loader
|
||||||
{
|
{
|
||||||
TE32 disp;
|
TE32 disp;
|
||||||
upx_uint32_t const zero = 0;
|
upx_uint64_t const zero = 0;
|
||||||
unsigned len = fo->getBytesWritten();
|
unsigned len = fo->getBytesWritten();
|
||||||
fo->write(&zero, 3& (0u-len));
|
fo->write(&zero, 3& (0u-len));
|
||||||
len += (3& (0u-len));
|
len += (3& (0u-len));
|
||||||
@@ -1078,15 +1025,18 @@ void PackMachBase<T>::pack3(OutputFile *fo, Filter &ft) // append loader
|
|||||||
fo->write(&disp, sizeof(disp));
|
fo->write(&disp, sizeof(disp));
|
||||||
len += sizeof(disp);
|
len += sizeof(disp);
|
||||||
|
|
||||||
char page[~PAGE_MASK]; memset(page, 0, sizeof(page));
|
if (Mach_header::MH_DYLIB != my_filetype) {
|
||||||
fo->write(page, ~PAGE_MASK & (0u - len));
|
// Why does MH_EXECUTE do this?
|
||||||
len += ~PAGE_MASK & (0u - len);
|
char page[~PAGE_MASK]; memset(page, 0, sizeof(page));
|
||||||
segLINK.fileoff = len;
|
fo->write(page, ~PAGE_MASK & (0u - len));
|
||||||
|
len += ~PAGE_MASK & (0u - len);
|
||||||
|
segLINK.fileoff = len;
|
||||||
|
}
|
||||||
|
|
||||||
threado_setPC(len + segTEXT.vmaddr); /* entry address */
|
threado_setPC(entryVMA= len + segTEXT.vmaddr); /* entry address */
|
||||||
super::pack3(fo, ft);
|
super::pack3(fo, ft);
|
||||||
len = fo->getBytesWritten();
|
fo->write(&zero, 7& (0u-len)); // FIXME: align(4) ?
|
||||||
fo->write(&zero, 7& (0u-len));
|
segTEXT.vmsize = len = fo->getBytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackDylibI386::pack3(OutputFile *fo, Filter &ft) // append loader
|
void PackDylibI386::pack3(OutputFile *fo, Filter &ft) // append loader
|
||||||
@@ -1100,7 +1050,7 @@ void PackDylibI386::pack3(OutputFile *fo, Filter &ft) // append loader
|
|||||||
disp = prev_mod_init_func;
|
disp = prev_mod_init_func;
|
||||||
fo->write(&disp, sizeof(disp)); // user .init_address
|
fo->write(&disp, sizeof(disp)); // user .init_address
|
||||||
|
|
||||||
disp = sizeof(mhdro) + mhdro.sizeofcmds + sizeof(l_info) + sizeof(p_info);
|
disp = secTEXT.offset + sizeof(l_info) + sizeof(p_info);
|
||||||
fo->write(&disp, sizeof(disp)); // src offset(compressed __TEXT)
|
fo->write(&disp, sizeof(disp)); // src offset(compressed __TEXT)
|
||||||
|
|
||||||
disp = len - disp - 3*sizeof(disp);
|
disp = len - disp - 3*sizeof(disp);
|
||||||
@@ -1127,11 +1077,11 @@ void PackDylibAMD64::pack3(OutputFile *fo, Filter &ft) // append loader
|
|||||||
disp = prev_mod_init_func;
|
disp = prev_mod_init_func;
|
||||||
fo->write(&disp, sizeof(disp)); // user .init_address
|
fo->write(&disp, sizeof(disp)); // user .init_address
|
||||||
|
|
||||||
disp = sizeof(mhdro) + mhdro.sizeofcmds + sizeof(l_info) + sizeof(p_info);
|
disp = secTEXT.offset + sizeof(l_info) + sizeof(p_info);
|
||||||
fo->write(&disp, sizeof(disp)); // src offset(compressed __TEXT)
|
fo->write(&disp, sizeof(disp)); // src offset(b_info)
|
||||||
|
|
||||||
disp = len - disp - 3*sizeof(disp);
|
disp = rawmseg[0].vmsize;
|
||||||
fo->write(&disp, sizeof(disp)); // length(compressed __TEXT)
|
fo->write(&disp, sizeof(disp)); // __TEXT.vmsize when expanded
|
||||||
|
|
||||||
unsigned const save_sz_mach_headers(sz_mach_headers);
|
unsigned const save_sz_mach_headers(sz_mach_headers);
|
||||||
sz_mach_headers = 0;
|
sz_mach_headers = 0;
|
||||||
@@ -1150,7 +1100,7 @@ void PackDylibPPC32::pack3(OutputFile *fo, Filter &ft) // append loader
|
|||||||
disp = prev_mod_init_func;
|
disp = prev_mod_init_func;
|
||||||
fo->write(&disp, sizeof(disp)); // user .init_address
|
fo->write(&disp, sizeof(disp)); // user .init_address
|
||||||
|
|
||||||
disp = sizeof(mhdro) + mhdro.sizeofcmds + sizeof(l_info) + sizeof(p_info);
|
disp = secTEXT.offset + sizeof(l_info) + sizeof(p_info);
|
||||||
fo->write(&disp, sizeof(disp)); // src offset(compressed __TEXT)
|
fo->write(&disp, sizeof(disp)); // src offset(compressed __TEXT)
|
||||||
|
|
||||||
disp = len - disp - 3*sizeof(disp);
|
disp = len - disp - 3*sizeof(disp);
|
||||||
@@ -1173,7 +1123,7 @@ void PackDylibPPC64LE::pack3(OutputFile *fo, Filter &ft) // append loader
|
|||||||
disp = prev_mod_init_func;
|
disp = prev_mod_init_func;
|
||||||
fo->write(&disp, sizeof(disp)); // user .init_address
|
fo->write(&disp, sizeof(disp)); // user .init_address
|
||||||
|
|
||||||
disp = sizeof(mhdro) + mhdro.sizeofcmds + sizeof(l_info) + sizeof(p_info);
|
disp = secTEXT.offset + sizeof(l_info) + sizeof(p_info);
|
||||||
fo->write(&disp, sizeof(disp)); // src offset(compressed __TEXT)
|
fo->write(&disp, sizeof(disp)); // src offset(compressed __TEXT)
|
||||||
|
|
||||||
disp = len - disp - 3*sizeof(disp);
|
disp = len - disp - 3*sizeof(disp);
|
||||||
@@ -1261,7 +1211,7 @@ int PackMachBase<T>::pack2(OutputFile *fo, Filter &ft) // append compressed bo
|
|||||||
unsigned exe_filesize_max = 0;
|
unsigned exe_filesize_max = 0;
|
||||||
for (k = 0; k < n_segment; ++k)
|
for (k = 0; k < n_segment; ++k)
|
||||||
if (lc_seg==msegcmd[k].cmd
|
if (lc_seg==msegcmd[k].cmd
|
||||||
&& 0!=(Mach_segment_command::VM_PROT_EXECUTE & msegcmd[k].initprot)
|
&& 0!=(Mach_command::VM_PROT_EXECUTE & msegcmd[k].initprot)
|
||||||
&& exe_filesize_max < msegcmd[k].filesize) {
|
&& exe_filesize_max < msegcmd[k].filesize) {
|
||||||
exe_filesize_max = (unsigned) msegcmd[k].filesize;
|
exe_filesize_max = (unsigned) msegcmd[k].filesize;
|
||||||
}
|
}
|
||||||
@@ -1278,7 +1228,7 @@ int PackMachBase<T>::pack2(OutputFile *fo, Filter &ft) // append compressed bo
|
|||||||
x.size -= delta;
|
x.size -= delta;
|
||||||
}
|
}
|
||||||
bool const do_filter = (msegcmd[k].filesize==exe_filesize_max)
|
bool const do_filter = (msegcmd[k].filesize==exe_filesize_max)
|
||||||
&& 0!=(Mach_segment_command::VM_PROT_EXECUTE & msegcmd[k].initprot);
|
&& 0!=(Mach_command::VM_PROT_EXECUTE & msegcmd[k].initprot);
|
||||||
packExtent(x, total_in, total_out,
|
packExtent(x, total_in, total_out,
|
||||||
(do_filter ? &ft : 0 ), fo, hdr_u_len );
|
(do_filter ? &ft : 0 ), fo, hdr_u_len );
|
||||||
if (do_filter) {
|
if (do_filter) {
|
||||||
@@ -1310,7 +1260,7 @@ int PackMachBase<T>::pack2(OutputFile *fo, Filter &ft) // append compressed bo
|
|||||||
|
|
||||||
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_command::LC_UNIXTHREAD;
|
||||||
threado.cmdsize = sizeof(threado);
|
threado.cmdsize = sizeof(threado);
|
||||||
threado.flavor = my_thread_flavor;
|
threado.flavor = my_thread_flavor;
|
||||||
threado.count = my_thread_state_word_count;
|
threado.count = my_thread_state_word_count;
|
||||||
@@ -1320,7 +1270,7 @@ void PackMachPPC32::pack1_setup_threado(OutputFile *const fo)
|
|||||||
|
|
||||||
void PackMachPPC64LE::pack1_setup_threado(OutputFile *const fo)
|
void PackMachPPC64LE::pack1_setup_threado(OutputFile *const fo)
|
||||||
{
|
{
|
||||||
threado.cmd = Mach_segment_command::LC_UNIXTHREAD;
|
threado.cmd = Mach_command::LC_UNIXTHREAD;
|
||||||
threado.cmdsize = sizeof(threado);
|
threado.cmdsize = sizeof(threado);
|
||||||
threado.flavor = my_thread_flavor;
|
threado.flavor = my_thread_flavor;
|
||||||
threado.count = my_thread_state_word_count;
|
threado.count = my_thread_state_word_count;
|
||||||
@@ -1330,7 +1280,7 @@ void PackMachPPC64LE::pack1_setup_threado(OutputFile *const fo)
|
|||||||
|
|
||||||
void PackMachI386::pack1_setup_threado(OutputFile *const fo)
|
void PackMachI386::pack1_setup_threado(OutputFile *const fo)
|
||||||
{
|
{
|
||||||
threado.cmd = Mach_segment_command::LC_UNIXTHREAD;
|
threado.cmd = Mach_command::LC_UNIXTHREAD;
|
||||||
threado.cmdsize = sizeof(threado);
|
threado.cmdsize = sizeof(threado);
|
||||||
threado.flavor = my_thread_flavor;
|
threado.flavor = my_thread_flavor;
|
||||||
threado.count = my_thread_state_word_count;
|
threado.count = my_thread_state_word_count;
|
||||||
@@ -1340,7 +1290,7 @@ void PackMachI386::pack1_setup_threado(OutputFile *const fo)
|
|||||||
|
|
||||||
void PackMachAMD64::pack1_setup_threado(OutputFile *const fo)
|
void PackMachAMD64::pack1_setup_threado(OutputFile *const fo)
|
||||||
{
|
{
|
||||||
threado.cmd = Mach_segment_command::LC_UNIXTHREAD;
|
threado.cmd = Mach_command::LC_UNIXTHREAD;
|
||||||
threado.cmdsize = sizeof(threado);
|
threado.cmdsize = sizeof(threado);
|
||||||
threado.flavor = my_thread_flavor;
|
threado.flavor = my_thread_flavor;
|
||||||
threado.count = my_thread_state_word_count;
|
threado.count = my_thread_state_word_count;
|
||||||
@@ -1350,7 +1300,7 @@ void PackMachAMD64::pack1_setup_threado(OutputFile *const fo)
|
|||||||
|
|
||||||
void PackMachARMEL::pack1_setup_threado(OutputFile *const fo)
|
void PackMachARMEL::pack1_setup_threado(OutputFile *const fo)
|
||||||
{
|
{
|
||||||
threado.cmd = Mach_segment_command::LC_UNIXTHREAD;
|
threado.cmd = Mach_command::LC_UNIXTHREAD;
|
||||||
threado.cmdsize = sizeof(threado);
|
threado.cmdsize = sizeof(threado);
|
||||||
threado.flavor = my_thread_flavor;
|
threado.flavor = my_thread_flavor;
|
||||||
threado.count = my_thread_state_word_count;
|
threado.count = my_thread_state_word_count;
|
||||||
@@ -1360,7 +1310,7 @@ void PackMachARMEL::pack1_setup_threado(OutputFile *const fo)
|
|||||||
|
|
||||||
void PackMachARM64EL::pack1_setup_threado(OutputFile *const fo)
|
void PackMachARM64EL::pack1_setup_threado(OutputFile *const fo)
|
||||||
{
|
{
|
||||||
threado.cmd = Mach_segment_command::LC_UNIXTHREAD;
|
threado.cmd = Mach_command::LC_UNIXTHREAD;
|
||||||
threado.cmdsize = sizeof(threado);
|
threado.cmdsize = sizeof(threado);
|
||||||
threado.flavor = my_thread_flavor;
|
threado.flavor = my_thread_flavor;
|
||||||
threado.count = my_thread_state_word_count;
|
threado.count = my_thread_state_word_count;
|
||||||
@@ -1416,12 +1366,12 @@ void PackMachBase<T>::pack1(OutputFile *const fo, Filter &/*ft*/) // generate e
|
|||||||
segTEXT.fileoff = 0;
|
segTEXT.fileoff = 0;
|
||||||
segTEXT.filesize = 0; // adjust later
|
segTEXT.filesize = 0; // adjust later
|
||||||
segTEXT.maxprot =
|
segTEXT.maxprot =
|
||||||
Mach_segment_command::VM_PROT_READ |
|
Mach_command::VM_PROT_READ |
|
||||||
Mach_segment_command::VM_PROT_WRITE |
|
Mach_command::VM_PROT_WRITE |
|
||||||
Mach_segment_command::VM_PROT_EXECUTE;
|
Mach_command::VM_PROT_EXECUTE;
|
||||||
segTEXT.initprot =
|
segTEXT.initprot =
|
||||||
Mach_segment_command::VM_PROT_READ |
|
Mach_command::VM_PROT_READ |
|
||||||
Mach_segment_command::VM_PROT_EXECUTE;
|
Mach_command::VM_PROT_EXECUTE;
|
||||||
segTEXT.nsects = 1; // secTEXT
|
segTEXT.nsects = 1; // secTEXT
|
||||||
segTEXT.flags = 0;
|
segTEXT.flags = 0;
|
||||||
|
|
||||||
@@ -1452,8 +1402,8 @@ void PackMachBase<T>::pack1(OutputFile *const fo, Filter &/*ft*/) // generate e
|
|||||||
segLINK.cmdsize = sizeof(segLINK);
|
segLINK.cmdsize = sizeof(segLINK);
|
||||||
strncpy((char *)segLINK.segname, "__LINKEDIT", sizeof(segLINK.segname));
|
strncpy((char *)segLINK.segname, "__LINKEDIT", sizeof(segLINK.segname));
|
||||||
segLINK.nsects = 0;
|
segLINK.nsects = 0;
|
||||||
segLINK.initprot = Mach_segment_command::VM_PROT_READ
|
segLINK.initprot = Mach_command::VM_PROT_READ
|
||||||
| Mach_segment_command::VM_PROT_EXECUTE;
|
| Mach_command::VM_PROT_EXECUTE;
|
||||||
// Adjust later: .vmaddr .vmsize .fileoff .filesize
|
// Adjust later: .vmaddr .vmsize .fileoff .filesize
|
||||||
|
|
||||||
if (my_filetype == Mach_header::MH_EXECUTE) {
|
if (my_filetype == Mach_header::MH_EXECUTE) {
|
||||||
@@ -1463,8 +1413,8 @@ void PackMachBase<T>::pack1(OutputFile *const fo, Filter &/*ft*/) // generate e
|
|||||||
for (unsigned j = 0; j < mhdro.ncmds -1; ++j,
|
for (unsigned j = 0; j < mhdro.ncmds -1; ++j,
|
||||||
(cmdsize -= ptr1->cmdsize),
|
(cmdsize -= ptr1->cmdsize),
|
||||||
ptr1 = (Mach_command const *)(ptr1->cmdsize + (char const *)ptr1)) {
|
ptr1 = (Mach_command const *)(ptr1->cmdsize + (char const *)ptr1)) {
|
||||||
Mach_segment_command const *const segptr = (Mach_segment_command const *)ptr1;
|
|
||||||
if (lc_seg == ptr1->cmd) {
|
if (lc_seg == ptr1->cmd) {
|
||||||
|
Mach_segment_command const *const segptr = (Mach_segment_command const *)ptr1;
|
||||||
if (!strcmp("__LINKEDIT", segptr->segname)) {
|
if (!strcmp("__LINKEDIT", segptr->segname)) {
|
||||||
// Mach_command before __LINKEDIT
|
// Mach_command before __LINKEDIT
|
||||||
pos += (char const *)ptr1 - (char const *)(1+ ptr0);
|
pos += (char const *)ptr1 - (char const *)(1+ ptr0);
|
||||||
@@ -1481,20 +1431,45 @@ void PackMachBase<T>::pack1(OutputFile *const fo, Filter &/*ft*/) // generate e
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { // not MH_EXECUTE; thus MH_DYLIB
|
else if (my_filetype == Mach_header::MH_DYLIB) {
|
||||||
fo->write(&segZERO, sizeof(segZERO));
|
Mach_command const *ptr = (Mach_command const *)rawmseg;
|
||||||
fo->write(&segXHDR, sizeof(segXHDR));
|
unsigned cmdsize = mhdri.sizeofcmds;
|
||||||
fo->write(&secXHDR, sizeof(secXHDR));
|
for (unsigned j = 0; j < mhdri.ncmds; ++j, (cmdsize -= ptr->cmdsize),
|
||||||
fo->write(&segTEXT, sizeof(segTEXT));
|
ptr = (Mach_command const *)(ptr->cmdsize + (char const *)ptr)) {
|
||||||
fo->write(&secTEXT, sizeof(secTEXT));
|
if (lc_seg == ptr->cmd) {
|
||||||
fo->write(&cmdUUID, sizeof(cmdUUID));
|
Mach_segment_command const *const segptr = (Mach_segment_command const *)ptr;
|
||||||
fo->write(&segLINK, sizeof(segLINK));
|
Mach_section_command const *const secptr = (Mach_section_command const *)(1+ segptr);
|
||||||
pack1_setup_threado(fo);
|
if (!strcmp("__TEXT", segptr->segname)) {
|
||||||
|
if (!(1 <= segptr->nsects)) {
|
||||||
|
throwCantPack("TEXT.nsects == 0");
|
||||||
|
}
|
||||||
|
mhdro.sizeofcmds += segTEXT.cmdsize - ptr->cmdsize;
|
||||||
|
strncpy((char *)secTEXT.sectname, "upxTEXT", sizeof(secTEXT.sectname));
|
||||||
|
secTEXT.addr = secptr->addr;
|
||||||
|
secTEXT.size = secptr->size; // update later
|
||||||
|
secTEXT.offset = secptr->offset;
|
||||||
|
secTEXT.align = secptr->align;
|
||||||
|
fo->write(&segTEXT, sizeof(segTEXT));
|
||||||
|
fo->write(&secTEXT, sizeof(secTEXT));
|
||||||
|
}
|
||||||
|
else { // not __TEXT
|
||||||
|
fo->write(ptr, ptr->cmdsize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { // not LC_SEGMENT*
|
||||||
|
fo->write(ptr, ptr->cmdsize);
|
||||||
|
}
|
||||||
|
}
|
||||||
memset(&linkitem, 0, sizeof(linkitem));
|
memset(&linkitem, 0, sizeof(linkitem));
|
||||||
fo->write(&linkitem, sizeof(linkitem));
|
fo->write(&linkitem, sizeof(linkitem));
|
||||||
fo->write(rawmseg, mhdri.sizeofcmds);
|
fo->write(rawmseg, mhdri.sizeofcmds);
|
||||||
}
|
}
|
||||||
sz_mach_headers = fo->getBytesWritten();
|
sz_mach_headers = fo->getBytesWritten();
|
||||||
|
unsigned gap = secTEXT.offset - sz_mach_headers;
|
||||||
|
MemBuffer filler(gap);
|
||||||
|
memset(filler, 0, gap);
|
||||||
|
fo->write(filler, gap);
|
||||||
|
sz_mach_headers += gap;
|
||||||
|
|
||||||
memset((char *)&linfo, 0, sizeof(linfo));
|
memset((char *)&linfo, 0, sizeof(linfo));
|
||||||
fo->write(&linfo, sizeof(linfo));
|
fo->write(&linfo, sizeof(linfo));
|
||||||
@@ -1691,7 +1666,7 @@ int PackMachBase<T>::canUnpack()
|
|||||||
}
|
}
|
||||||
pos_next = segptr->filesize + segptr->fileoff;
|
pos_next = segptr->filesize + segptr->fileoff;
|
||||||
}
|
}
|
||||||
else if (Mach_segment_command::LC_UNIXTHREAD==ptr->cmd) {
|
else if (Mach_command::LC_UNIXTHREAD==ptr->cmd) {
|
||||||
rip = entryVMA = threadc_getPC(ptr);
|
rip = entryVMA = threadc_getPC(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1875,7 +1850,7 @@ bool PackMachBase<T>::canPack()
|
|||||||
}
|
}
|
||||||
switch (((Mach_uuid_command const *)ptr)->cmd) {
|
switch (((Mach_uuid_command const *)ptr)->cmd) {
|
||||||
default: break;
|
default: break;
|
||||||
case Mach_segment_command::LC_UUID: {
|
case Mach_command::LC_UUID: {
|
||||||
memcpy(&cmdUUID, ptr, sizeof(cmdUUID)); // remember the UUID
|
memcpy(&cmdUUID, ptr, sizeof(cmdUUID)); // remember the UUID
|
||||||
// Set output UUID to be 1 more than the input UUID.
|
// Set output UUID to be 1 more than the input UUID.
|
||||||
for (unsigned k = 0; k < sizeof(cmdUUID.uuid); ++k) {
|
for (unsigned k = 0; k < sizeof(cmdUUID.uuid); ++k) {
|
||||||
@@ -1884,10 +1859,10 @@ bool PackMachBase<T>::canPack()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case Mach_segment_command::LC_VERSION_MIN_MACOSX: {
|
case Mach_command::LC_VERSION_MIN_MACOSX: {
|
||||||
memcpy(&cmdVERMIN, ptr, sizeof(cmdVERMIN));
|
memcpy(&cmdVERMIN, ptr, sizeof(cmdVERMIN));
|
||||||
} break;
|
} break;
|
||||||
case Mach_segment_command::LC_SOURCE_VERSION: {
|
case Mach_command::LC_SOURCE_VERSION: {
|
||||||
memcpy(&cmdSRCVER, ptr, sizeof(cmdSRCVER));
|
memcpy(&cmdSRCVER, ptr, sizeof(cmdSRCVER));
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-39
@@ -287,7 +287,9 @@ template <class TMachITypes>
|
|||||||
__packed_struct(Mach_linkedit_data_command)
|
__packed_struct(Mach_linkedit_data_command)
|
||||||
typedef typename TMachITypes::Word Word;
|
typedef typename TMachITypes::Word Word;
|
||||||
|
|
||||||
Word cmd;
|
Word cmd; // LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO,
|
||||||
|
// LC_FUNCTION_STARTS, LC_DATA_IN_CODE,
|
||||||
|
// LC_DYLIB_CODE_SIGN_DRS, LC_LINKER_OPTIMIZATION_HINT
|
||||||
Word cmdsize;
|
Word cmdsize;
|
||||||
Word dataoff; // file offset of data in __LINKEDIT segment
|
Word dataoff; // file offset of data in __LINKEDIT segment
|
||||||
Word datasize; // file size of data in __LINKEDIT segment
|
Word datasize; // file size of data in __LINKEDIT segment
|
||||||
@@ -391,26 +393,6 @@ __packed_struct(Mach_load_dylib_command)
|
|||||||
Mach_dylib<TMachITypes> dylib;
|
Mach_dylib<TMachITypes> dylib;
|
||||||
__packed_struct_end()
|
__packed_struct_end()
|
||||||
|
|
||||||
template <class TMachITypes>
|
|
||||||
__packed_struct(Mach_function_starts_command)
|
|
||||||
typedef typename TMachITypes::Word Word;
|
|
||||||
|
|
||||||
Word cmd;
|
|
||||||
Word cmdsize;
|
|
||||||
Word dataoff;
|
|
||||||
Word datasize;
|
|
||||||
__packed_struct_end()
|
|
||||||
|
|
||||||
template <class TMachITypes>
|
|
||||||
__packed_struct(Mach_data_in_code_command)
|
|
||||||
typedef typename TMachITypes::Word Word;
|
|
||||||
|
|
||||||
Word cmd;
|
|
||||||
Word cmdsize;
|
|
||||||
Word dataoff;
|
|
||||||
Word datasize;
|
|
||||||
__packed_struct_end()
|
|
||||||
|
|
||||||
} // namespace N_Mach
|
} // namespace N_Mach
|
||||||
|
|
||||||
namespace N_Mach32 {
|
namespace N_Mach32 {
|
||||||
@@ -558,8 +540,6 @@ struct MachClass_32
|
|||||||
typedef N_Mach::Mach_twolevel_hints_command<MachITypes> Mach_twolevel_hints_command;
|
typedef N_Mach::Mach_twolevel_hints_command<MachITypes> Mach_twolevel_hints_command;
|
||||||
typedef N_Mach::Mach_linkedit_data_command<MachITypes> Mach_linkedit_data_command;
|
typedef N_Mach::Mach_linkedit_data_command<MachITypes> Mach_linkedit_data_command;
|
||||||
typedef N_Mach::Mach_uuid_command<MachITypes> Mach_uuid_command;
|
typedef N_Mach::Mach_uuid_command<MachITypes> Mach_uuid_command;
|
||||||
typedef N_Mach::Mach_data_in_code_command<MachITypes> Mach_data_in_code_command;
|
|
||||||
typedef N_Mach::Mach_function_starts_command<MachITypes> Mach_function_starts_command;
|
|
||||||
typedef N_Mach::Mach_load_dylib_command<MachITypes> Mach_load_dylib_command;
|
typedef N_Mach::Mach_load_dylib_command<MachITypes> Mach_load_dylib_command;
|
||||||
typedef N_Mach::Mach_dylib<MachITypes> Mach_dylib;
|
typedef N_Mach::Mach_dylib<MachITypes> Mach_dylib;
|
||||||
typedef N_Mach::Mach_load_dylinker_command<MachITypes> Mach_load_dylinker_command;
|
typedef N_Mach::Mach_load_dylinker_command<MachITypes> Mach_load_dylinker_command;
|
||||||
@@ -602,8 +582,6 @@ struct MachClass_64
|
|||||||
typedef N_Mach::Mach_twolevel_hints_command<MachITypes> Mach_twolevel_hints_command;
|
typedef N_Mach::Mach_twolevel_hints_command<MachITypes> Mach_twolevel_hints_command;
|
||||||
typedef N_Mach::Mach_linkedit_data_command<MachITypes> Mach_linkedit_data_command;
|
typedef N_Mach::Mach_linkedit_data_command<MachITypes> Mach_linkedit_data_command;
|
||||||
typedef N_Mach::Mach_uuid_command<MachITypes> Mach_uuid_command;
|
typedef N_Mach::Mach_uuid_command<MachITypes> Mach_uuid_command;
|
||||||
typedef N_Mach::Mach_data_in_code_command<MachITypes> Mach_data_in_code_command;
|
|
||||||
typedef N_Mach::Mach_function_starts_command<MachITypes> Mach_function_starts_command;
|
|
||||||
typedef N_Mach::Mach_load_dylib_command<MachITypes> Mach_load_dylib_command;
|
typedef N_Mach::Mach_load_dylib_command<MachITypes> Mach_load_dylib_command;
|
||||||
typedef N_Mach::Mach_dylib<MachITypes> Mach_dylib;
|
typedef N_Mach::Mach_dylib<MachITypes> Mach_dylib;
|
||||||
typedef N_Mach::Mach_load_dylinker_command<MachITypes> Mach_load_dylinker_command;
|
typedef N_Mach::Mach_load_dylinker_command<MachITypes> Mach_load_dylinker_command;
|
||||||
@@ -642,8 +620,6 @@ typedef MachClass_Host32::Mach_twolevel_hints_command Mach32_twolevel_hints_comm
|
|||||||
typedef MachClass_Host32::Mach_linkedit_data_command Mach32_linkedit_data_command;
|
typedef MachClass_Host32::Mach_linkedit_data_command Mach32_linkedit_data_command;
|
||||||
typedef MachClass_Host32::Mach_uuid_command Mach32_uuid_command;
|
typedef MachClass_Host32::Mach_uuid_command Mach32_uuid_command;
|
||||||
typedef MachClass_Host32::Mach_main_command Mach32_main_command;
|
typedef MachClass_Host32::Mach_main_command Mach32_main_command;
|
||||||
typedef MachClass_Host32::Mach_data_in_code_command Mach32_data_in_code_command;
|
|
||||||
typedef MachClass_Host32::Mach_function_starts_command Mach32_function_starts_command;
|
|
||||||
typedef MachClass_Host32::Mach_load_dylib_command Mach32_load_dylib_command;
|
typedef MachClass_Host32::Mach_load_dylib_command Mach32_load_dylib_command;
|
||||||
typedef MachClass_Host32::Mach_dylib Mach32_dylib;
|
typedef MachClass_Host32::Mach_dylib Mach32_dylib;
|
||||||
typedef MachClass_Host32::Mach_load_dylinker_command Mach32_load_dylinker_command;
|
typedef MachClass_Host32::Mach_load_dylinker_command Mach32_load_dylinker_command;
|
||||||
@@ -661,8 +637,6 @@ typedef MachClass_Host64::Mach_twolevel_hints_command Mach64_twolevel_hints_comm
|
|||||||
typedef MachClass_Host64::Mach_linkedit_data_command Mach64_linkedit_data_command;
|
typedef MachClass_Host64::Mach_linkedit_data_command Mach64_linkedit_data_command;
|
||||||
typedef MachClass_Host64::Mach_uuid_command Mach64_uuid_command;
|
typedef MachClass_Host64::Mach_uuid_command Mach64_uuid_command;
|
||||||
typedef MachClass_Host64::Mach_main_command Mach64_main_command;
|
typedef MachClass_Host64::Mach_main_command Mach64_main_command;
|
||||||
typedef MachClass_Host64::Mach_data_in_code_command Mach64_data_in_code_command;
|
|
||||||
typedef MachClass_Host64::Mach_function_starts_command Mach64_function_starts_command;
|
|
||||||
typedef MachClass_Host64::Mach_load_dylib_command Mach64_load_dylib_command;
|
typedef MachClass_Host64::Mach_load_dylib_command Mach64_load_dylib_command;
|
||||||
typedef MachClass_Host64::Mach_dylib Mach64_dylib;
|
typedef MachClass_Host64::Mach_dylib Mach64_dylib;
|
||||||
typedef MachClass_Host64::Mach_load_dylinker_command Mach64_load_dylinker_command;
|
typedef MachClass_Host64::Mach_load_dylinker_command Mach64_load_dylinker_command;
|
||||||
@@ -680,8 +654,6 @@ typedef MachClass_BE32::Mach_twolevel_hints_command MachBE32_twolevel_hints_co
|
|||||||
typedef MachClass_BE32::Mach_linkedit_data_command MachBE32_linkedit_data_command;
|
typedef MachClass_BE32::Mach_linkedit_data_command MachBE32_linkedit_data_command;
|
||||||
typedef MachClass_BE32::Mach_uuid_command MachBE32_uuid_command;
|
typedef MachClass_BE32::Mach_uuid_command MachBE32_uuid_command;
|
||||||
typedef MachClass_BE32::Mach_main_command MachBE32_main_command;
|
typedef MachClass_BE32::Mach_main_command MachBE32_main_command;
|
||||||
typedef MachClass_BE32::Mach_data_in_code_command MachBE32_data_in_code_command;
|
|
||||||
typedef MachClass_BE32::Mach_function_starts_command MachBE32_function_starts_command;
|
|
||||||
typedef MachClass_BE32::Mach_load_dylib_command MachBE32_load_dylib_command;
|
typedef MachClass_BE32::Mach_load_dylib_command MachBE32_load_dylib_command;
|
||||||
typedef MachClass_BE32::Mach_dylib MachBE32_dylib;
|
typedef MachClass_BE32::Mach_dylib MachBE32_dylib;
|
||||||
typedef MachClass_BE32::Mach_load_dylinker_command MachBE32_load_dylinker_command;
|
typedef MachClass_BE32::Mach_load_dylinker_command MachBE32_load_dylinker_command;
|
||||||
@@ -699,8 +671,6 @@ typedef MachClass_BE64::Mach_twolevel_hints_command MachBE64_twolevel_hints_co
|
|||||||
typedef MachClass_BE64::Mach_linkedit_data_command MachBE64_linkedit_data_command;
|
typedef MachClass_BE64::Mach_linkedit_data_command MachBE64_linkedit_data_command;
|
||||||
typedef MachClass_BE64::Mach_uuid_command MachBE64_uuid_command;
|
typedef MachClass_BE64::Mach_uuid_command MachBE64_uuid_command;
|
||||||
typedef MachClass_BE64::Mach_main_command MachBE64_main_command;
|
typedef MachClass_BE64::Mach_main_command MachBE64_main_command;
|
||||||
typedef MachClass_BE64::Mach_data_in_code_command MachBE64_data_in_code_command;
|
|
||||||
typedef MachClass_BE64::Mach_function_starts_command MachBE64_function_starts_command;
|
|
||||||
typedef MachClass_BE64::Mach_load_dylib_command MachBE64_load_dylib_command;
|
typedef MachClass_BE64::Mach_load_dylib_command MachBE64_load_dylib_command;
|
||||||
typedef MachClass_BE64::Mach_dylib MachBE64_dylib;
|
typedef MachClass_BE64::Mach_dylib MachBE64_dylib;
|
||||||
typedef MachClass_BE64::Mach_load_dylinker_command MachBE64_load_dylinker_command;
|
typedef MachClass_BE64::Mach_load_dylinker_command MachBE64_load_dylinker_command;
|
||||||
@@ -718,8 +688,6 @@ typedef MachClass_LE32::Mach_twolevel_hints_command MachLE32_twolevel_hints_co
|
|||||||
typedef MachClass_LE32::Mach_linkedit_data_command MachLE32_linkedit_data_command;
|
typedef MachClass_LE32::Mach_linkedit_data_command MachLE32_linkedit_data_command;
|
||||||
typedef MachClass_LE32::Mach_uuid_command MachLE32_uuid_command;
|
typedef MachClass_LE32::Mach_uuid_command MachLE32_uuid_command;
|
||||||
typedef MachClass_LE32::Mach_main_command MachLE32_main_command;
|
typedef MachClass_LE32::Mach_main_command MachLE32_main_command;
|
||||||
typedef MachClass_LE32::Mach_data_in_code_command MachLE32_data_in_code_command;
|
|
||||||
typedef MachClass_LE32::Mach_function_starts_command MachLE32_function_starts_command;
|
|
||||||
typedef MachClass_LE32::Mach_load_dylib_command MachLE32_load_dylib_command;
|
typedef MachClass_LE32::Mach_load_dylib_command MachLE32_load_dylib_command;
|
||||||
typedef MachClass_LE32::Mach_dylib MachLE32_dylib;
|
typedef MachClass_LE32::Mach_dylib MachLE32_dylib;
|
||||||
typedef MachClass_LE32::Mach_load_dylinker_command MachLE32_load_dylinker_command;
|
typedef MachClass_LE32::Mach_load_dylinker_command MachLE32_load_dylinker_command;
|
||||||
@@ -737,8 +705,6 @@ typedef MachClass_LE64::Mach_twolevel_hints_command MachLE64_twolevel_hints_co
|
|||||||
typedef MachClass_LE64::Mach_linkedit_data_command MachLE64_linkedit_data_command;
|
typedef MachClass_LE64::Mach_linkedit_data_command MachLE64_linkedit_data_command;
|
||||||
typedef MachClass_LE64::Mach_uuid_command MachLE64_uuid_command;
|
typedef MachClass_LE64::Mach_uuid_command MachLE64_uuid_command;
|
||||||
typedef MachClass_LE64::Mach_main_command MachLE64_main_command;
|
typedef MachClass_LE64::Mach_main_command MachLE64_main_command;
|
||||||
typedef MachClass_LE64::Mach_data_in_code_command MachLE64_data_in_code_command;
|
|
||||||
typedef MachClass_LE64::Mach_function_starts_command MachLE64_function_starts_command;
|
|
||||||
typedef MachClass_LE64::Mach_load_dylib_command MachLE64_load_dylib_command;
|
typedef MachClass_LE64::Mach_load_dylib_command MachLE64_load_dylib_command;
|
||||||
typedef MachClass_LE64::Mach_dylib MachLE64_dylib;
|
typedef MachClass_LE64::Mach_dylib MachLE64_dylib;
|
||||||
typedef MachClass_LE64::Mach_load_dylinker_command MachLE64_load_dylinker_command;
|
typedef MachClass_LE64::Mach_load_dylinker_command MachLE64_load_dylinker_command;
|
||||||
@@ -781,8 +747,6 @@ protected:
|
|||||||
typedef typename MachClass::Mach_linkedit_data_command Mach_linkedit_data_command;
|
typedef typename MachClass::Mach_linkedit_data_command Mach_linkedit_data_command;
|
||||||
typedef typename MachClass::Mach_uuid_command Mach_uuid_command;
|
typedef typename MachClass::Mach_uuid_command Mach_uuid_command;
|
||||||
typedef typename MachClass::Mach_main_command Mach_main_command;
|
typedef typename MachClass::Mach_main_command Mach_main_command;
|
||||||
typedef typename MachClass::Mach_data_in_code_command Mach_data_in_code_command;
|
|
||||||
typedef typename MachClass::Mach_function_starts_command Mach_function_starts_command;
|
|
||||||
typedef typename MachClass::Mach_load_dylib_command Mach_load_dylib_command;
|
typedef typename MachClass::Mach_load_dylib_command Mach_load_dylib_command;
|
||||||
typedef typename MachClass::Mach_dylib Mach_dylib;
|
typedef typename MachClass::Mach_dylib Mach_dylib;
|
||||||
typedef typename MachClass::Mach_load_dylinker_command Mach_load_dylinker_command;
|
typedef typename MachClass::Mach_load_dylinker_command Mach_load_dylinker_command;
|
||||||
|
|||||||
+9
-1
@@ -83,23 +83,31 @@
|
|||||||
LC_LOAD_DYLINKER = 0xe,
|
LC_LOAD_DYLINKER = 0xe,
|
||||||
LC_ROUTINES = 0x11,
|
LC_ROUTINES = 0x11,
|
||||||
LC_TWOLEVEL_HINTS= 0x16,
|
LC_TWOLEVEL_HINTS= 0x16,
|
||||||
|
LC_LOAD_WEAK_DYLIB= (0x18 | LC_REQ_DYLD),
|
||||||
LC_SEGMENT_64 = 0x19,
|
LC_SEGMENT_64 = 0x19,
|
||||||
LC_ROUTINES_64 = 0x1a,
|
LC_ROUTINES_64 = 0x1a,
|
||||||
LC_UUID = 0x1b,
|
LC_UUID = 0x1b,
|
||||||
LC_RPATH = 0x1c,
|
LC_RPATH = 0x1c,
|
||||||
LC_CODE_SIGNATURE = 0x1d,
|
LC_CODE_SIGNATURE = 0x1d,
|
||||||
LC_SEGMENT_SPLIT_INFO = 0x1e,
|
LC_SEGMENT_SPLIT_INFO = 0x1e,
|
||||||
LC_REEXPORT_DYLIB = 0x1f,
|
LC_REEXPORT_DYLIB = (0x1f | LC_REQ_DYLD),
|
||||||
LC_LAZY_LOAD_DYLIB= 0x20,
|
LC_LAZY_LOAD_DYLIB= 0x20,
|
||||||
LC_ENCRYPTION_INFO= 0x21,
|
LC_ENCRYPTION_INFO= 0x21,
|
||||||
LC_DYLD_INFO = 0x22, // compressed dyld information (10.6.x)
|
LC_DYLD_INFO = 0x22, // compressed dyld information (10.6.x)
|
||||||
LC_DYLD_INFO_ONLY = (0x22|LC_REQ_DYLD),
|
LC_DYLD_INFO_ONLY = (0x22|LC_REQ_DYLD),
|
||||||
LC_VERSION_MIN_MACOSX= 0x24,
|
LC_VERSION_MIN_MACOSX= 0x24,
|
||||||
|
LC_VERSION_MIN_IPHONEOS= 0x25,
|
||||||
LC_FUNCTION_STARTS= 0x26,
|
LC_FUNCTION_STARTS= 0x26,
|
||||||
|
LC_DYLD_ENVIRONMENT= 0x27, // string as environment variable
|
||||||
LC_MAIN = (0x28|LC_REQ_DYLD),
|
LC_MAIN = (0x28|LC_REQ_DYLD),
|
||||||
LC_DATA_IN_CODE = 0x29,
|
LC_DATA_IN_CODE = 0x29,
|
||||||
LC_SOURCE_VERSION = 0x2a,
|
LC_SOURCE_VERSION = 0x2a,
|
||||||
|
LC_DYLIB_CODE_SIGN_DRS= 0x2B,
|
||||||
|
LC_ENCRYPTION_INFO_64= 0x2C,
|
||||||
|
LC_VERSION_MIN_TVOS= 0x2F,
|
||||||
|
LC_VERSION_MIN_WATCHOS= 0x30,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum { // maxprot
|
enum { // maxprot
|
||||||
VM_PROT_READ = 1,
|
VM_PROT_READ = 1,
|
||||||
VM_PROT_WRITE = 2,
|
VM_PROT_WRITE = 2,
|
||||||
|
|||||||
+600
-604
File diff suppressed because it is too large
Load Diff
@@ -37,9 +37,10 @@
|
|||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// We have been CALLed as a subroutine from dyld; C-language rules apply.
|
// We have been CALLed as a subroutine from dyld; C-language rules apply.
|
||||||
|
// init(%edi=argc, %rsi=argv, %rdx=envp, %rcx=apple, %r8=...)
|
||||||
// -4*4+_start: .int32 offset(user_init_function)
|
// -4*4+_start: .int32 offset(user_init_function)
|
||||||
// -3*4+_start: .int32 offset(&b_info of compressed Mach_headers)
|
// -3*4+_start: .int32 offset(&b_info of compressed Mach_headers)
|
||||||
// -2*4+_start: .int32 length(compressed __TEXT)
|
// -2*4+_start: .int32 segTEXT.vmsize
|
||||||
// -1*4+_start: .int32 total_length # of preceding bytes in file
|
// -1*4+_start: .int32 total_length # of preceding bytes in file
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
@@ -47,10 +48,15 @@ section MACHMAINX
|
|||||||
_start: .globl _start
|
_start: .globl _start
|
||||||
L100: pause; jmp L100 // FIXME
|
L100: pause; jmp L100 // FIXME
|
||||||
int3 // FIXME
|
int3 // FIXME
|
||||||
push %rax // space for &user_init function
|
push $~0 // space for &user_init function
|
||||||
|
push %rdi; push %rsi; push %rdx; push %rcx; push %r8 // args
|
||||||
push %rbp // callee-save registers
|
push %rbp // callee-save registers
|
||||||
push %rbx
|
push %rbx
|
||||||
call main // push &decompress
|
call main // push &escape
|
||||||
|
escape:
|
||||||
|
syscall
|
||||||
|
pop %rcx; pop %rdx; pop %rsi; pop %rdi
|
||||||
|
ret
|
||||||
|
|
||||||
/* Returns 0 on success; non-zero on failure. */
|
/* Returns 0 on success; non-zero on failure. */
|
||||||
decompress: // (uchar const *src, size_t lsrc, uchar *dst, u32 &ldst, uint method)
|
decompress: // (uchar const *src, size_t lsrc, uchar *dst, u32 &ldst, uint method)
|
||||||
@@ -187,7 +193,9 @@ end_decompress: .globl end_decompress
|
|||||||
/* IDENTSTR goes here */
|
/* IDENTSTR goes here */
|
||||||
|
|
||||||
section MACHMAINZ
|
section MACHMAINZ
|
||||||
SYS_mmap = 0x02000000 + 197
|
SYS_mmap = 0x2000000 + 197
|
||||||
|
SYS_mprotect = 0x2000000 + 0x4a
|
||||||
|
SYS_munmap = 0x2000000 + 73
|
||||||
PAGE_SIZE= ( 1<<12)
|
PAGE_SIZE= ( 1<<12)
|
||||||
|
|
||||||
sz_Mach_header= 7*4
|
sz_Mach_header= 7*4
|
||||||
@@ -212,54 +220,69 @@ PROT_WRITE= 2
|
|||||||
PROT_EXEC= 4
|
PROT_EXEC= 4
|
||||||
|
|
||||||
|
|
||||||
|
main:
|
||||||
|
pop %rbp # &escape
|
||||||
|
|
||||||
|
// Get temp pages for compressed __TEXT and this stub
|
||||||
|
lea -1*4 + _start - escape(%rbp),%rbx
|
||||||
|
mov (%rbx),%eax; sub %rax,%rbx # our &Mach_header
|
||||||
|
mov -4*4 + _start - escape(%rbp),%edx # offset(user_init_fn)
|
||||||
|
add %rbx,%rdx; mov %rdx,7*8(%rsp) # reloc(user_init_fn)
|
||||||
|
mov -3*4 + _start - escape(%rbp),%edx # offset(b_info)
|
||||||
|
sub %edx,%eax; add %rbx,%rdx
|
||||||
|
sub $-4+ _start,%eax
|
||||||
|
add $ dy_top,%eax; push %rax # P_02 length(tmppag)
|
||||||
|
push %rdx # P_01 &b_info
|
||||||
|
xchg %eax,%arg2l # length
|
||||||
|
|
||||||
|
xor %arg6,%arg6 # 0 offset
|
||||||
|
or $~0,%arg5l # -1 fd
|
||||||
|
mov $MAP_ANON|MAP_PRIVATE,%sys4l
|
||||||
|
push $PROT_READ|PROT_WRITE; pop %arg3
|
||||||
|
xor %arg1l,%arg1l # 0 addr
|
||||||
|
mov $SYS_mmap,%eax; syscall; jc bad_mmap
|
||||||
|
|
||||||
|
// Copy compressed__TEXT and this stub to temp pages
|
||||||
|
pop %rsi # P_01 &b_info src
|
||||||
|
pop %rcx; push %rcx # P_02 length(tmppag)
|
||||||
|
push %rax # P_03 addr(tmppag)
|
||||||
|
push %rax; pop %rdi # dst
|
||||||
|
add %rcx,%rax # reloc(dy_top)
|
||||||
|
sub %rsi,%rbp
|
||||||
|
add %rdi,%rbp # reloc(&escape)
|
||||||
|
push %rdi # P_05 reloc(&b_info)
|
||||||
|
add $7,%ecx; shr $3,%ecx; rep movsq
|
||||||
|
pop %rcx # P_05 reloc(&b_info)
|
||||||
|
|
||||||
|
// Make temp pages executable, and go there
|
||||||
|
pop %arg1 # P_03 src (tmppag)
|
||||||
|
pop %arg2 # P_02 length(tmppag)
|
||||||
|
push $PROT_READ|PROT_EXEC; pop %arg3
|
||||||
|
push %arg2 # P_02 length(tmppag)
|
||||||
|
push %arg1 # P_03 src(tmppag)
|
||||||
|
push %rcx # P_06 reloc(&b_info)
|
||||||
|
push %rax # P_04 reloc(dy_top)
|
||||||
|
mov $SYS_mprotect,%eax; syscall; jc bad_mmap
|
||||||
|
|
||||||
|
pop %rax # P_04 reloc(dy_top)
|
||||||
|
add $dy_reloc - dy_top,%rax
|
||||||
|
jmp *%rax
|
||||||
|
|
||||||
bad_mmap:
|
bad_mmap:
|
||||||
hlt
|
hlt
|
||||||
jmp bad_mmap
|
jmp bad_mmap
|
||||||
main:
|
|
||||||
pop %rbp # &decompress
|
|
||||||
lea -4+ _start - decompress(%rbp),%rbx # &total_length
|
|
||||||
mov -1*4(%rbx),%eax # length(compressed __TEXT)
|
|
||||||
add $dy_top,%eax
|
|
||||||
sub $decompress,%eax
|
|
||||||
|
|
||||||
push %rax # length for eventual munmap
|
|
||||||
|
|
||||||
mov $0,%arg6l # offset
|
|
||||||
mov $0,%arg5l # fd
|
|
||||||
mov $MAP_ANON|MAP_PRIVATE,%sys4l
|
|
||||||
mov $PROT_READ|PROT_WRITE,%arg3l
|
|
||||||
mov %eax,%arg2l # length
|
|
||||||
sub %arg1l,%arg1l # 0 addr
|
|
||||||
mov $SYS_mmap,%eax
|
|
||||||
syscall
|
|
||||||
jc bad_mmap
|
|
||||||
|
|
||||||
push %rax # addr for eventual munmap
|
|
||||||
|
|
||||||
// Copy interval [decompress, dy_top).
|
|
||||||
mov %rbp,%rsi # decompressor
|
|
||||||
mov %rax,%rbp # new location
|
|
||||||
mov %rax,%rdi # dst for decompressor
|
|
||||||
mov $dy_top,%ecx
|
|
||||||
sub $decompress,%ecx
|
|
||||||
cld; rep movsb
|
|
||||||
|
|
||||||
// Goto the copied dy_reloc.
|
|
||||||
lea -(dy_top - dy_reloc)(%rdi),%rax
|
|
||||||
jmp *%rax
|
|
||||||
dy_reloc:
|
dy_reloc:
|
||||||
|
|
||||||
// Copy compressed __TEXT.
|
// Make __TEXT writeable
|
||||||
push %rdi # remember start of compressed __TEXT
|
push %rbx; pop %arg1 # our &Mach_header
|
||||||
mov %rbx,%rdx # &total_length
|
mov -2*4 + _start - escape(%rbp),%arg2l
|
||||||
mov -4*4(%rbx),%eax # offset(user_init_function)
|
push $PROT_READ|PROT_WRITE; pop %arg3
|
||||||
sub (%rbx),%edx # runtime base address
|
mov $SYS_mprotect,%eax; syscall; jc bad_mmap
|
||||||
add %rdx,%rax; mov %rax,(1+2+2)*4(%rsp) # relocate &user_init_function
|
|
||||||
mov -2*4(%rbx),%esi; add %rdx,%rsi
|
pop %rsi # P_06 reloc(&b_info)
|
||||||
mov -1*4(%rbx),%ecx
|
push %rbx; pop %rdi # our &Mach_header
|
||||||
rep movsb
|
add $decompress - escape,%rbp
|
||||||
pop %rsi # &b_info for Mach_header
|
|
||||||
mov %rdx,%rdi # runtime base address
|
|
||||||
|
|
||||||
// Decompress __TEXT, but do not overwrite Mach_headers
|
// Decompress __TEXT, but do not overwrite Mach_headers
|
||||||
// in order to maintain consistency with dyld partial caching of them.
|
// in order to maintain consistency with dyld partial caching of them.
|
||||||
@@ -271,44 +294,47 @@ dy_uncpr:
|
|||||||
push %rsi; push %rdi # save in case unfilter
|
push %rsi; push %rdi # save in case unfilter
|
||||||
|
|
||||||
lodsl; test %eax,%eax; jz dy_done
|
lodsl; test %eax,%eax; jz dy_done
|
||||||
push %rax // sz_uncompressed (maximum dstlen for lzma)
|
push %rax // P_09 sz_unc (maximum dstlen for lzma)
|
||||||
mov %rsp,%arg4 // &dstlen
|
mov %rsp,%arg4 // &dstlen (%rcx)
|
||||||
mov %rdi,%arg3 // dst
|
add %rdi,%rax; push %rax // P_07 next dst
|
||||||
add %rdi,%rax; push %rax // next dst
|
lodsl; xchg %eax,%edx // sz_cpr (srclen)
|
||||||
lodsl; mov %eax,%arg2l // sz_compressed (srclen)
|
lodsl; xchg %eax,%arg5l // last 4 bytes of b_info
|
||||||
mov %rax,%rcx
|
lea (%rsi,%rdx),%rax; push %rax // P_08 next src
|
||||||
lodsl; mov %eax,%arg5l // last 4 bytes of b_info
|
push %rdx // P_10 sz_cpr
|
||||||
mov %rsi,%arg1 // &compressed __TEXT
|
mov %rdi,%arg3 // %rdx dst
|
||||||
add %rsi,%rcx; push %rcx // next src
|
mov %rsi,%arg1 // %rdi &compressed __TEXT
|
||||||
|
pop %arg2 // P_10 sz_cpr (srclen)
|
||||||
call *%rbp // decompress(1=rdi=src, 2=rsi=srclen, 3=rdx=dst, 4=rcx=&dstlen, 5=r8=b_info.misc)
|
call *%rbp // decompress(1=rdi=src, 2=rsi=srclen, 3=rdx=dst, 4=rcx=&dstlen, 5=r8=b_info.misc)
|
||||||
pop %rsi // next src
|
pop %rsi // P_08 next src
|
||||||
pop %rdi // next dst
|
pop %rdi // P_07 next dst
|
||||||
pop %rcx // dstlen (junk)
|
pop %rcx // P_09 dstlen (junk)
|
||||||
|
|
||||||
pop %rdx; pop %rax # rdx= old dst; rax= old &b_info
|
pop %rdi; pop %rcx # rdi= old dst; rcx= old &b_info
|
||||||
movzbl 1+ b_method(%rax),%arg4l # ftid
|
mov (%rcx),%esi # sz_unc
|
||||||
test %arg4l,%arg4l; je dy_uncpr # no filter
|
movzbl 2+ b_method(%rcx),%edx # cto8
|
||||||
movzbl 2+ b_method(%rax),%arg3l # cto8
|
movzbl 1+ b_method(%rcx),%ecx # ftid
|
||||||
#if 0
|
test %ecx,%ecx; je dy_done
|
||||||
mov sz_unc(%rax),%arg2l
|
|
||||||
#else
|
|
||||||
// sz_unc == 0
|
|
||||||
mov (%rax),%arg2l
|
|
||||||
#endif
|
|
||||||
mov %rdx,%arg1 # dst
|
|
||||||
call f_unfilter # f_unfilter(1=rdi=dst, 2=rsi=dstlen, 3=rdx=cto8, 4=rcx=ftid)
|
call f_unfilter # f_unfilter(1=rdi=dst, 2=rsi=dstlen, 3=rdx=cto8, 4=rcx=ftid)
|
||||||
jmp dy_uncpr
|
jmp dy_done
|
||||||
|
|
||||||
SYS_munmap= 0x02000000 + 73
|
|
||||||
dy_done:
|
dy_done:
|
||||||
pop %rax; pop %rcx # discard
|
sz_Mach_header64 = 0x20
|
||||||
mov $PAGE_SIZE,%arg2l // length for munmap
|
// Make __TEXT executable
|
||||||
pop %arg1 // addr for munmap
|
push %rbx; pop %arg1 # our &Mach_header
|
||||||
pop %rbx; pop %rbp // saved registers
|
mov escape - decompress(%rbp),%rax # 8 bytes of instructions
|
||||||
|
add $8+ 2*4 + sz_Mach_header64,%rbx # &segname[8] after "__TEXT\0\0"
|
||||||
|
mov %rax,(%rbx)
|
||||||
|
mov -2*4 + _start - decompress(%rbp),%arg2l
|
||||||
|
push $PROT_READ|PROT_EXEC; pop %arg3
|
||||||
|
mov $SYS_mprotect,%eax; syscall; jc bad_mmap
|
||||||
|
|
||||||
|
pop %arg1 # P_03 tmppag
|
||||||
|
pop %arg2 # P_02 len(tmppag)
|
||||||
mov $SYS_munmap,%eax
|
mov $SYS_munmap,%eax
|
||||||
lea -4(%rdi),%rdx # steal some space at high end of __TEXT
|
push %rbx; pop %rcx
|
||||||
movl $0x90c3050f,(%rdx) # syscall; ret; nop
|
pop %rbx; pop %rbp // saved registers
|
||||||
jmp *%rdx
|
pop %r8
|
||||||
|
jmp *%rcx
|
||||||
|
|
||||||
#undef off
|
#undef off
|
||||||
#undef len
|
#undef len
|
||||||
|
|||||||
@@ -2,24 +2,24 @@ file format elf64-x86-64
|
|||||||
|
|
||||||
Sections:
|
Sections:
|
||||||
Idx Name Size VMA LMA File off Algn Flags
|
Idx Name Size VMA LMA File off Algn Flags
|
||||||
0 MACHMAINX 00000015 0000000000000000 0000000000000000 00000040 2**0 CONTENTS, RELOC, READONLY
|
0 MACHMAINX 00000023 0000000000000000 0000000000000000 00000040 2**0 CONTENTS, RELOC, READONLY
|
||||||
1 NRV_HEAD 00000066 0000000000000000 0000000000000000 00000055 2**0 CONTENTS, READONLY
|
1 NRV_HEAD 00000066 0000000000000000 0000000000000000 00000063 2**0 CONTENTS, READONLY
|
||||||
2 NRV2E 000000b7 0000000000000000 0000000000000000 000000bb 2**0 CONTENTS, RELOC, READONLY
|
2 NRV2E 000000b7 0000000000000000 0000000000000000 000000c9 2**0 CONTENTS, RELOC, READONLY
|
||||||
3 NRV2D 0000009e 0000000000000000 0000000000000000 00000172 2**0 CONTENTS, RELOC, READONLY
|
3 NRV2D 0000009e 0000000000000000 0000000000000000 00000180 2**0 CONTENTS, RELOC, READONLY
|
||||||
4 NRV2B 00000090 0000000000000000 0000000000000000 00000210 2**0 CONTENTS, RELOC, READONLY
|
4 NRV2B 00000090 0000000000000000 0000000000000000 0000021e 2**0 CONTENTS, RELOC, READONLY
|
||||||
5 LZMA_ELF00 00000064 0000000000000000 0000000000000000 000002a0 2**0 CONTENTS, RELOC, READONLY
|
5 LZMA_ELF00 00000064 0000000000000000 0000000000000000 000002ae 2**0 CONTENTS, RELOC, READONLY
|
||||||
6 LZMA_DEC10 000009f7 0000000000000000 0000000000000000 00000304 2**0 CONTENTS, READONLY
|
6 LZMA_DEC10 000009f7 0000000000000000 0000000000000000 00000312 2**0 CONTENTS, READONLY
|
||||||
7 LZMA_DEC20 000009f7 0000000000000000 0000000000000000 00000cfb 2**0 CONTENTS, READONLY
|
7 LZMA_DEC20 000009f7 0000000000000000 0000000000000000 00000d09 2**0 CONTENTS, READONLY
|
||||||
8 LZMA_DEC30 00000014 0000000000000000 0000000000000000 000016f2 2**0 CONTENTS, READONLY
|
8 LZMA_DEC30 00000014 0000000000000000 0000000000000000 00001700 2**0 CONTENTS, READONLY
|
||||||
9 NRV_TAIL 00000000 0000000000000000 0000000000000000 00001706 2**0 CONTENTS, READONLY
|
9 NRV_TAIL 00000000 0000000000000000 0000000000000000 00001714 2**0 CONTENTS, READONLY
|
||||||
10 MACHMAINY 00000011 0000000000000000 0000000000000000 00001706 2**0 CONTENTS, READONLY
|
10 MACHMAINY 00000011 0000000000000000 0000000000000000 00001714 2**0 CONTENTS, READONLY
|
||||||
11 MACHMAINZ 0000012e 0000000000000000 0000000000000000 00001717 2**0 CONTENTS, RELOC, READONLY
|
11 MACHMAINZ 00000163 0000000000000000 0000000000000000 00001725 2**0 CONTENTS, RELOC, READONLY
|
||||||
SYMBOL TABLE:
|
SYMBOL TABLE:
|
||||||
0000000000000000 l d MACHMAINX 0000000000000000 MACHMAINX
|
|
||||||
0000000000000000 l d NRV_HEAD 0000000000000000 NRV_HEAD
|
0000000000000000 l d NRV_HEAD 0000000000000000 NRV_HEAD
|
||||||
0000000000000000 l d LZMA_DEC30 0000000000000000 LZMA_DEC30
|
0000000000000000 l d LZMA_DEC30 0000000000000000 LZMA_DEC30
|
||||||
0000000000000000 l d MACHMAINY 0000000000000000 MACHMAINY
|
0000000000000000 l d MACHMAINY 0000000000000000 MACHMAINY
|
||||||
0000000000000000 l d MACHMAINZ 0000000000000000 MACHMAINZ
|
0000000000000000 l d MACHMAINZ 0000000000000000 MACHMAINZ
|
||||||
|
0000000000000000 l d MACHMAINX 0000000000000000 MACHMAINX
|
||||||
0000000000000000 l d NRV2E 0000000000000000 NRV2E
|
0000000000000000 l d NRV2E 0000000000000000 NRV2E
|
||||||
0000000000000000 l d NRV2D 0000000000000000 NRV2D
|
0000000000000000 l d NRV2D 0000000000000000 NRV2D
|
||||||
0000000000000000 l d NRV2B 0000000000000000 NRV2B
|
0000000000000000 l d NRV2B 0000000000000000 NRV2B
|
||||||
@@ -32,7 +32,7 @@ SYMBOL TABLE:
|
|||||||
|
|
||||||
RELOCATION RECORDS FOR [MACHMAINX]:
|
RELOCATION RECORDS FOR [MACHMAINX]:
|
||||||
OFFSET TYPE VALUE
|
OFFSET TYPE VALUE
|
||||||
0000000000000009 R_X86_64_PC32 MACHMAINZ+0xffffffffffffffff
|
0000000000000010 R_X86_64_PC32 MACHMAINZ+0xfffffffffffffffc
|
||||||
|
|
||||||
RELOCATION RECORDS FOR [NRV2E]:
|
RELOCATION RECORDS FOR [NRV2E]:
|
||||||
OFFSET TYPE VALUE
|
OFFSET TYPE VALUE
|
||||||
@@ -55,7 +55,5 @@ OFFSET TYPE VALUE
|
|||||||
|
|
||||||
RELOCATION RECORDS FOR [MACHMAINZ]:
|
RELOCATION RECORDS FOR [MACHMAINZ]:
|
||||||
OFFSET TYPE VALUE
|
OFFSET TYPE VALUE
|
||||||
000000000000000f R_X86_64_32 MACHMAINZ+0x000000000000012e
|
0000000000000027 R_X86_64_32 _start+0xfffffffffffffffc
|
||||||
0000000000000014 R_X86_64_32 MACHMAINX+0x000000000000000d
|
000000000000002c R_X86_64_32 MACHMAINZ+0x0000000000000163
|
||||||
0000000000000048 R_X86_64_32 MACHMAINZ+0x000000000000012e
|
|
||||||
000000000000004e R_X86_64_32 MACHMAINX+0x000000000000000d
|
|
||||||
|
|||||||
Reference in New Issue
Block a user