mirror of
https://github.com/upx/upx
synced 2025-09-28 19:06:07 +08:00
Packer for Macintosh Darwin Mach-o PowerPC32
Added Files: p_mach.cpp p_mach.h committer: jreiser <jreiser> 1108863998 +0000
This commit is contained in:
parent
c933974174
commit
67a77f1880
376
src/p_mach.cpp
Normal file
376
src/p_mach.cpp
Normal file
|
@ -0,0 +1,376 @@
|
|||
/* p_mach.cpp -- pack Mach Object executable
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 2004 John Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
John Reiser
|
||||
jreiser@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
#include "file.h"
|
||||
#include "filter.h"
|
||||
#include "linker.h"
|
||||
#include "packer.h"
|
||||
#include "p_mach.h"
|
||||
|
||||
static const
|
||||
#include "stub/l_mac_ppc32.h"
|
||||
|
||||
static const
|
||||
#include "stub/fold_machppc32.h"
|
||||
|
||||
PackMachPPC32::PackMachPPC32(InputFile *f) :
|
||||
super(f), n_segment(0), rawmseg(0), msegcmd(0)
|
||||
{
|
||||
}
|
||||
|
||||
PackMachPPC32::~PackMachPPC32()
|
||||
{
|
||||
delete [] msegcmd;
|
||||
delete [] rawmseg;
|
||||
}
|
||||
|
||||
const int *PackMachPPC32::getCompressionMethods(int /*method*/, int /*level*/) const
|
||||
{
|
||||
// There really is no LE bias in M_NRV2E_LE32.
|
||||
static const int m_nrv2e[] = { M_NRV2E_LE32, -1 };
|
||||
return m_nrv2e;
|
||||
}
|
||||
|
||||
|
||||
const int *PackMachPPC32::getFilters() const
|
||||
{
|
||||
static const int filters[] = { 0xd0, -1 };
|
||||
return filters;
|
||||
}
|
||||
|
||||
int
|
||||
PackMachPPC32::buildMachLoader(
|
||||
upx_byte const *const proto,
|
||||
unsigned const szproto,
|
||||
upx_byte const *const fold,
|
||||
unsigned const szfold,
|
||||
Filter const */*ft*/
|
||||
)
|
||||
{
|
||||
int eof_empty = -1;
|
||||
initLoader(&eof_empty, 4096, 0, 0);
|
||||
|
||||
struct b_info h; memset(&h, 0, sizeof(h));
|
||||
unsigned fold_hdrlen = 0;
|
||||
if (0 < szfold) {
|
||||
h.sz_unc = (szfold < fold_hdrlen) ? 0 : (szfold - fold_hdrlen);
|
||||
h.b_method = (unsigned char) ph.method;
|
||||
h.b_ftid = (unsigned char) ph.filter;
|
||||
h.b_cto8 = (unsigned char) ph.filter_cto;
|
||||
}
|
||||
unsigned char const *const uncLoader = fold_hdrlen + fold;
|
||||
|
||||
unsigned char *const cprLoader = new unsigned char[sizeof(h) + h.sz_unc];
|
||||
if (0 < szfold) {
|
||||
unsigned sz_cpr;
|
||||
int r = upx_compress(uncLoader, h.sz_unc, sizeof(h) + cprLoader, &sz_cpr,
|
||||
NULL, ph.method, 10, NULL, NULL );
|
||||
h.sz_cpr = sz_cpr;
|
||||
if (r != UPX_E_OK || h.sz_cpr >= h.sz_unc)
|
||||
throwInternalError("loader compression failed");
|
||||
}
|
||||
memcpy(cprLoader, &h, sizeof(h));
|
||||
|
||||
// This adds the definition to the "library", to be used later.
|
||||
linker->addSection("FOLDEXEC", cprLoader, sizeof(h) + h.sz_cpr);
|
||||
delete [] cprLoader;
|
||||
|
||||
int const GAP = 128; // must match stub/l_mac_ppc.S
|
||||
segcmdo.vmsize += h.sz_unc - h.sz_cpr + GAP + 64;
|
||||
|
||||
linker->addSection("MACOS000", proto, szproto);
|
||||
|
||||
addLoader("MACOS000", 0);
|
||||
addLoader("FOLDEXEC", 0);
|
||||
return getLoaderSize();
|
||||
}
|
||||
|
||||
int
|
||||
PackMachPPC32::buildLoader(const Filter *ft)
|
||||
{
|
||||
return buildMachLoader(
|
||||
l_mac_ppc32_loader, sizeof(l_mac_ppc32_loader),
|
||||
fold_machppc32, sizeof(fold_machppc32), ft );
|
||||
}
|
||||
void PackMachPPC32::patchLoader() { }
|
||||
void PackMachPPC32::updateLoader(OutputFile *) {}
|
||||
|
||||
void
|
||||
PackMachPPC32::patchLoaderChecksum()
|
||||
{
|
||||
unsigned char *const ptr = const_cast<unsigned char *>(getLoader());
|
||||
l_info *const lp = &linfo;
|
||||
// checksum for loader; also some PackHeader info
|
||||
lp->l_checksum = 0;
|
||||
lp->l_magic = UPX_MAGIC_LE32; // LE32 always
|
||||
lp->l_lsize = (unsigned short) lsize;
|
||||
lp->l_version = (unsigned char) ph.version;
|
||||
lp->l_format = (unsigned char) ph.format;
|
||||
// INFO: lp->l_checksum is currently unused
|
||||
lp->l_checksum = upx_adler32(ptr, lsize);
|
||||
}
|
||||
|
||||
static int __acc_cdecl_qsort
|
||||
compare_segment_command(void const *const aa, void const *const bb)
|
||||
{
|
||||
Mach_segment_command const *const a = (Mach_segment_command const *)aa;
|
||||
Mach_segment_command const *const b = (Mach_segment_command const *)bb;
|
||||
unsigned const xa = a->cmd - Mach_segment_command::LC_SEGMENT;
|
||||
unsigned const xb = b->cmd - Mach_segment_command::LC_SEGMENT;
|
||||
if (xa < xb) return -1; // LC_SEGMENT first
|
||||
if (xa > xb) return 1;
|
||||
if (a->vmaddr < b->vmaddr) return -1; // ascending by .vmaddr
|
||||
if (a->vmaddr > b->vmaddr) return 1;
|
||||
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->write(&segcmdo, sizeof(segcmdo));
|
||||
fo->write(&threado, sizeof(threado));
|
||||
fo->write(&linfo, sizeof(linfo));
|
||||
}
|
||||
|
||||
void
|
||||
PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader
|
||||
{
|
||||
BE32 disp;
|
||||
unsigned const zero = 0;
|
||||
unsigned len = fo->getBytesWritten();
|
||||
fo->write(&zero, 3& -len);
|
||||
len += (3& -len) + sizeof(disp);
|
||||
set_be32(&disp, 4+ len - sz_mach_headers); // 4: sizeof(instruction)
|
||||
fo->write(&disp, sizeof(disp));
|
||||
|
||||
threado.state.srr0 = len + segcmdo.vmaddr; /* entry address */
|
||||
super::pack3(fo, ft);
|
||||
}
|
||||
|
||||
void
|
||||
PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body
|
||||
{
|
||||
Extent x;
|
||||
unsigned k;
|
||||
|
||||
ui_total_passes = n_segment;
|
||||
|
||||
// compress extents
|
||||
unsigned total_in = 0;
|
||||
unsigned total_out = 0;
|
||||
|
||||
ui_pass = -1; // Compressing Mach headers is invisible to UI.
|
||||
x.offset = 0;
|
||||
x.size = mhdri.sizeofcmds;
|
||||
{
|
||||
int const old_level = ph.level; ph.level = 10;
|
||||
packExtent(x, total_in, total_out, 0, fo);
|
||||
ph.level = old_level;
|
||||
}
|
||||
|
||||
ui_pass = 0;
|
||||
ft.addvalue = 0;
|
||||
|
||||
int nx = 0;
|
||||
for (k = 0; k < n_segment; ++k)
|
||||
if (Mach_segment_command::LC_SEGMENT==msegcmd[k].cmd
|
||||
&& 0!=msegcmd[k].filesize ) {
|
||||
x.offset = msegcmd[k].fileoff;
|
||||
x.size = msegcmd[k].filesize;
|
||||
if (0 == nx) { // 1st LC_SEGMENT must cover Mach_header at 0==fileoffset
|
||||
unsigned const delta = mhdri.sizeofcmds;
|
||||
x.offset += delta;
|
||||
x.size -= delta;
|
||||
}
|
||||
packExtent(x, total_in, total_out,
|
||||
((Mach_segment_command::VM_PROT_EXECUTE & msegcmd[k].initprot)
|
||||
? &ft : 0 ), fo );
|
||||
++nx;
|
||||
}
|
||||
if ((off_t)total_in < file_size) { // non-LC_SEGMENT stuff
|
||||
x.offset = total_in;
|
||||
x.size = file_size - total_in;
|
||||
packExtent(x, total_in, total_out, 0, fo);
|
||||
}
|
||||
|
||||
if ((off_t)total_in != file_size)
|
||||
throwEOFException();
|
||||
segcmdo.filesize = fo->getBytesWritten();
|
||||
}
|
||||
|
||||
#define PAGE_MASK (~0u<<12)
|
||||
#define PAGE_SIZE -PAGE_MASK
|
||||
void
|
||||
PackMachPPC32::pack1(OutputFile *fo, Filter &/*ft*/) // generate executable header
|
||||
{
|
||||
mhdro = mhdri;
|
||||
mhdro.ncmds = 2;
|
||||
mhdro.sizeofcmds = sizeof(segcmdo) + sizeof(threado);
|
||||
mhdro.flags = Mach_header::MH_NOUNDEFS;
|
||||
fo->write(&mhdro, sizeof(mhdro));
|
||||
|
||||
segcmdo.cmd = Mach_segment_command::LC_SEGMENT;
|
||||
segcmdo.cmdsize = sizeof(segcmdo);
|
||||
strncpy((char *)&segcmdo.segname, "__TEXT", sizeof(segcmdo.segname));
|
||||
segcmdo.vmaddr = PAGE_MASK & (~PAGE_MASK +
|
||||
msegcmd[n_segment -1].vmsize + msegcmd[n_segment -1].vmaddr );
|
||||
segcmdo.vmsize = 0; // adjust later
|
||||
segcmdo.fileoff = 0;
|
||||
segcmdo.filesize = 0; // adjust later
|
||||
segcmdo.initprot = segcmdo.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;
|
||||
fo->write(&segcmdo, sizeof(segcmdo));
|
||||
|
||||
threado.cmd = Mach_segment_command::LC_UNIXTHREAD;
|
||||
threado.cmdsize = sizeof(threado);
|
||||
threado.flavor = Mach_thread_command::PPC_THREAD_STATE;
|
||||
threado.count = Mach_thread_command::PPC_THREAD_STATE_COUNT;
|
||||
memset(&threado.state, 0, sizeof(threado.state));
|
||||
fo->write(&threado, sizeof(threado));
|
||||
sz_mach_headers = fo->getBytesWritten();
|
||||
|
||||
memset((char *)&linfo, 0, sizeof(linfo));
|
||||
fo->write(&linfo, sizeof(linfo));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
PackMachPPC32::unpack(OutputFile *fo)
|
||||
{
|
||||
fi->seek(overlay_offset, SEEK_SET);
|
||||
p_info hbuf;
|
||||
fi->readx(&hbuf, sizeof(hbuf));
|
||||
unsigned orig_file_size = get_native32(&hbuf.p_filesize);
|
||||
blocksize = get_native32(&hbuf.p_blocksize);
|
||||
if (file_size > (off_t)orig_file_size || blocksize > orig_file_size)
|
||||
throwCantUnpack("file header corrupted");
|
||||
|
||||
ibuf.alloc(blocksize + OVERHEAD);
|
||||
b_info bhdr; memset(&bhdr, 0, sizeof(bhdr));
|
||||
fi->readx(&bhdr, sizeof(bhdr));
|
||||
ph.u_len = get_native32(&bhdr.sz_unc);
|
||||
ph.c_len = get_native32(&bhdr.sz_cpr);
|
||||
ph.filter_cto = bhdr.b_cto8;
|
||||
|
||||
// Uncompress Macho headers
|
||||
fi->readx(ibuf, ph.c_len);
|
||||
Mach_header *const mhdr = (Mach_header *)new upx_byte[ph.u_len];
|
||||
decompress(ibuf, (upx_byte *)mhdr, false);
|
||||
|
||||
unsigned total_in = 0;
|
||||
unsigned total_out = 0;
|
||||
unsigned c_adler = upx_adler32(NULL, 0);
|
||||
unsigned u_adler = upx_adler32(NULL, 0);
|
||||
Mach_segment_command const *sc = (Mach_segment_command const *)(1+ mhdr);
|
||||
unsigned k;
|
||||
|
||||
fi->seek(- (off_t)(sizeof(bhdr) + ph.c_len), SEEK_CUR);
|
||||
for (
|
||||
k = 0;
|
||||
k < mhdr->ncmds;
|
||||
(++k), (sc = (Mach_segment_command const *)(sc->cmdsize + (char const *)sc))
|
||||
) {
|
||||
if (Mach_segment_command::LC_SEGMENT==sc->cmd
|
||||
&& 0!=sc->filesize ) {
|
||||
unsigned filesize = get_be32(&sc->filesize);
|
||||
unpackExtent(filesize, fo, total_in, total_out, c_adler, u_adler, false, sizeof(bhdr));
|
||||
}
|
||||
}
|
||||
unsigned const rest = orig_file_size - total_out;
|
||||
if (0!=rest) { // non-LC_SEGMENT stuff
|
||||
if (fo)
|
||||
fo->seek(0, SEEK_END);
|
||||
unpackExtent(rest, fo, total_in, total_out, c_adler, u_adler, false, sizeof(bhdr));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PackMachPPC32::canPack()
|
||||
{
|
||||
fi->seek(0, SEEK_SET);
|
||||
fi->readx(&mhdri, sizeof(mhdri));
|
||||
|
||||
if (Mach_header::MH_MAGIC !=mhdri.magic
|
||||
|| Mach_header::CPU_TYPE_POWERPC !=mhdri.cputype
|
||||
|| Mach_header::MH_EXECUTE !=mhdri.filetype
|
||||
)
|
||||
return false;
|
||||
|
||||
rawmseg = (Mach_segment_command *)new char[mhdri.sizeofcmds];
|
||||
fi->readx(rawmseg, mhdri.sizeofcmds);
|
||||
|
||||
msegcmd = new Mach_segment_command[mhdri.ncmds];
|
||||
unsigned char *ptr = (unsigned char *)rawmseg;
|
||||
for (unsigned j= 0; j < mhdri.ncmds; ++j) {
|
||||
msegcmd[j] = *(Mach_segment_command *)ptr;
|
||||
ptr += ((Mach_segment_command *)ptr)->cmdsize;
|
||||
}
|
||||
|
||||
|
||||
// Put LC_SEGMENT together at the beginning, ascending by .vmaddr.
|
||||
qsort(msegcmd, mhdri.ncmds, sizeof(*msegcmd), compare_segment_command);
|
||||
|
||||
// Check that LC_SEGMENTs form one contiguous chunk of the file.
|
||||
for (unsigned j= 0; j < mhdri.ncmds; ++j) {
|
||||
if (Mach_segment_command::LC_SEGMENT==msegcmd[j].cmd) {
|
||||
if (0xfff & (msegcmd[j].fileoff | msegcmd[j].vmaddr)) {
|
||||
return false;
|
||||
}
|
||||
if (0 < j) {
|
||||
unsigned const sz = ~0xfff
|
||||
& (0xfff + msegcmd[j-1].filesize);
|
||||
if ((sz + msegcmd[j-1].fileoff)!=msegcmd[j].fileoff) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
++n_segment;
|
||||
sz_segment = msegcmd[j].filesize + msegcmd[j].fileoff - msegcmd[0].fileoff;
|
||||
}
|
||||
}
|
||||
// set options
|
||||
opt->o_unix.blocksize = file_size;
|
||||
return 0 < n_segment;
|
||||
}
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
207
src/p_mach.h
Normal file
207
src/p_mach.h
Normal file
|
@ -0,0 +1,207 @@
|
|||
/* p_mach.h --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2004 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_P_MACHO_H
|
||||
#define __UPX_P_MACHO_H
|
||||
|
||||
/*************************************************************************
|
||||
// Mach Mach Object executable
|
||||
**************************************************************************/
|
||||
|
||||
struct Mach_header {
|
||||
BE32 magic;
|
||||
enum {
|
||||
MH_MAGIC = 0xfeedface
|
||||
};
|
||||
BE32 cputype;
|
||||
enum {
|
||||
CPU_TYPE_POWERPC = 18
|
||||
};
|
||||
BE32 cpysubtype;
|
||||
BE32 filetype;
|
||||
enum {
|
||||
MH_EXECUTE = 2
|
||||
};
|
||||
BE32 ncmds;
|
||||
BE32 sizeofcmds;
|
||||
BE32 flags;
|
||||
enum {
|
||||
MH_NOUNDEFS = 1
|
||||
};
|
||||
};
|
||||
|
||||
struct Mach_segment_command {
|
||||
BE32 cmd;
|
||||
enum {
|
||||
LC_SEGMENT = 0x1,
|
||||
LC_THREAD = 0x4,
|
||||
LC_UNIXTHREAD = 0x5,
|
||||
LC_LOAD_DYLINKER = 0xe
|
||||
};
|
||||
BE32 cmdsize;
|
||||
char segname[16];
|
||||
BE32 vmaddr;
|
||||
BE32 vmsize;
|
||||
BE32 fileoff;
|
||||
BE32 filesize;
|
||||
BE32 maxprot;
|
||||
enum {
|
||||
VM_PROT_READ = 1,
|
||||
VM_PROT_WRITE = 2,
|
||||
VM_PROT_EXECUTE = 4
|
||||
};
|
||||
BE32 initprot;
|
||||
BE32 nsects;
|
||||
BE32 flags;
|
||||
};
|
||||
|
||||
struct Mach_section {
|
||||
char sectname[16];
|
||||
char segname[16];
|
||||
BE32 addr; /* memory address */
|
||||
BE32 size; /* size in bytes */
|
||||
BE32 offset; /* file offset */
|
||||
BE32 align; /* power of 2 */
|
||||
BE32 reloff; /* file offset of relocation entries */
|
||||
BE32 nreloc; /* number of relocation entries */
|
||||
BE32 flags; /* section type and attributes */
|
||||
enum {
|
||||
S_REGULAR = 0,
|
||||
S_ZEROFILL,
|
||||
S_CSTRING_LITERALS,
|
||||
S_4BYTE_LITERALS,
|
||||
S_8BYTE_LITERALS,
|
||||
S_LITERAL_POINTERS,
|
||||
S_NON_LAZY_SYMBOL_POINTERS,
|
||||
S_LAZY_SYMBOL_POINTERS,
|
||||
S_SYMBOL_STUBS,
|
||||
S_MOD_INIT_FUNC_POINTERS,
|
||||
S_MOD_TERM_FNC_POINTERS,
|
||||
S_COALESCED
|
||||
};
|
||||
enum {
|
||||
S_ATTR_PURE_INSTRUCTIONS = 0x80000000,
|
||||
S_ATTR_NO_TOC = 0x40000000,
|
||||
S_ATTR_STRIP_STATIC_SYMS = 0x20000000,
|
||||
S_ATTR_SOME_INSTRUCTIONS = 0x00000400,
|
||||
S_ATTR_EXT_RELOC = 0x00000200,
|
||||
S_ATTR_LOC_RELOC = 0x00000100
|
||||
};
|
||||
BE32 reserved1;
|
||||
BE32 reserved2;
|
||||
|
||||
};
|
||||
|
||||
struct Mach_ppc_thread_state {
|
||||
BE32 srr0; /* Instruction address register (PC; entry addr) */
|
||||
BE32 srr1; /* Machine state register (supervisor) */
|
||||
BE32 r0, r1, r2, r3, r4, r5, r6, r7;
|
||||
BE32 r8, r9,r10,r11,r12,r13,r14,r15;
|
||||
BE32 r16,r17,r18,r19,r20,r21,r22,r23;
|
||||
BE32 r24,r25,r26,r27,r28,r29,r30,r31;
|
||||
|
||||
BE32 cr; /* Condition register */
|
||||
BE32 xer; /* User's integer exception register */
|
||||
BE32 lr; /* Link register */
|
||||
BE32 ctr; /* Count register */
|
||||
BE32 mq; /* MQ register (601 only) */
|
||||
|
||||
BE32 vrsave; /* Vector Save Register */
|
||||
};
|
||||
|
||||
struct Mach_thread_command {
|
||||
BE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */
|
||||
BE32 cmdsize; /* total size of this command */
|
||||
BE32 flavor;
|
||||
enum {
|
||||
PPC_THREAD_STATE = 1
|
||||
};
|
||||
BE32 count; /* sizeof(following_thread_state)/4 */
|
||||
enum {
|
||||
PPC_THREAD_STATE_COUNT = sizeof(struct Mach_ppc_thread_state)/4
|
||||
};
|
||||
struct Mach_ppc_thread_state state;
|
||||
};
|
||||
|
||||
#include "p_unix.h"
|
||||
|
||||
class PackMachPPC32 : public PackUnixBe32
|
||||
{
|
||||
typedef PackUnixBe32 super;
|
||||
public:
|
||||
PackMachPPC32(InputFile *f);
|
||||
virtual ~PackMachPPC32();
|
||||
virtual int getVersion() const { return 13; }
|
||||
virtual int getFormat() const { return UPX_F_MACH_PPC32; }
|
||||
virtual const char *getName() const { return "Mach/ppc32"; }
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
// called by the generic pack()
|
||||
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 void unpack(OutputFile *fo);
|
||||
|
||||
virtual bool canPack();
|
||||
|
||||
protected:
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual void patchLoader();
|
||||
virtual void patchLoaderChecksum();
|
||||
virtual void updateLoader(OutputFile *);
|
||||
virtual int buildMachLoader(
|
||||
upx_byte const *const proto,
|
||||
unsigned const szproto,
|
||||
upx_byte const *const fold,
|
||||
unsigned const szfold,
|
||||
Filter const *ft );
|
||||
|
||||
unsigned n_segment;
|
||||
unsigned sz_segment;
|
||||
unsigned sz_mach_headers;
|
||||
Mach_segment_command *rawmseg; // as input, with sections
|
||||
Mach_segment_command *msegcmd; // LC_SEGMENT first, without sections
|
||||
Mach_header mhdri;
|
||||
|
||||
Mach_header mhdro;
|
||||
Mach_segment_command segcmdo;
|
||||
Mach_thread_command threado;
|
||||
struct l_info linfo;
|
||||
};
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user