mirror of
https://github.com/upx/upx
synced 2025-09-28 19:06:07 +08:00
stub loader for Macintosh (Darwin) Mach-o PowerPC32
Added Files: l_mac_ppc32.S fold_machppc32.S m_mac_mach32.c l_mac_ppc32.h fold_machppc32.h [these two created by Makefile] committer: jreiser <jreiser> 1108860254 +0000
This commit is contained in:
parent
46f9256114
commit
9cb8d7bca6
123
src/stub/fold_machppc32.S
Normal file
123
src/stub/fold_machppc32.S
Normal file
|
@ -0,0 +1,123 @@
|
|||
/* fold_machppc32.S -- linkage to C code to process Mach-o binary
|
||||
*
|
||||
* This file is part of the UPX executable compressor.
|
||||
*
|
||||
* Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
||||
* Copyright (C) 1996-2004 Laszlo Molnar
|
||||
* Copyright (C) 2000-2005 John F. 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.
|
||||
*
|
||||
* Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
* <mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
*
|
||||
* John F. Reiser
|
||||
* <jreiser@users.sourceforge.net>
|
||||
*/
|
||||
#include "ppc_regs.h"
|
||||
|
||||
sz_b_info= 12
|
||||
sz_unc= 0
|
||||
sz_cpr= 4
|
||||
|
||||
sz_l_info= 12
|
||||
sz_p_info= 12
|
||||
|
||||
/* Mach_ppc_thread_state */
|
||||
srr0 = 0*4
|
||||
srr1 = 1*4
|
||||
reg0 = 2*4
|
||||
|
||||
reg_cr = 34*4
|
||||
reg_xer = 35*4
|
||||
reg_lr = 36*4
|
||||
reg_ctr = 37*4
|
||||
reg_mq = 38*4
|
||||
reg_vrsave = 39*4
|
||||
|
||||
|
||||
/* In:
|
||||
r31= &decompress; also 8+ (char *)&(offset to {l_info; p_info; b_info})
|
||||
*/
|
||||
fold_begin:
|
||||
call L90
|
||||
#include "ppc_bxx.S"
|
||||
|
||||
L90:
|
||||
li a6,0
|
||||
stwu a6,-4(sp) # default value
|
||||
movr a6,sp # &mhdrp
|
||||
mflr a5 # &ppcbxx: f_unfilter
|
||||
|
||||
lwz a1,-8(r31) # offset to {l_info; p_info; b_info}
|
||||
subf a0,a1,r31 # &l_info
|
||||
lwz a3,sz_unc+sz_p_info+sz_l_info(a0) # sz_mach_headers
|
||||
cmpli 0,a3,2048; bgt L100; li a3,2048 # at least 2KB for /usr/bin/dyld
|
||||
L100:
|
||||
movr r29,sp # remember for restoring later
|
||||
subf sp,a3,sp # alloca
|
||||
movr a2,sp # &temp char[sz_mach_headers]
|
||||
addi sp,sp,-4*6 # linkage area assumed by C code (sp,cr,lr, xx,yy,zz)
|
||||
movr a4,r31 # f_decompress
|
||||
call upx_main # Out: a0= &Mach_ppc_thread_state of dyld
|
||||
|
||||
movr sp,r29 # restore stack pointer
|
||||
lwz t0, srr0(a0); mtctr t0 # entry address
|
||||
/* Next 3 lines probably are not needed, but ... */
|
||||
lwz t0, reg_cr(a0); mtcr t0 # condition code
|
||||
lwz t0,reg_xer(a0); mtxer t0 # extended error reg (CArry, etc.)
|
||||
lwz t0, reg_lr(a0); mtlr t0 # link register
|
||||
|
||||
lmw 4,4*4+reg0(3) # reg 4 thru 31
|
||||
lwz 0,0*4+reg0(3)
|
||||
lwz 2,2*4+reg0(3)
|
||||
lwz 3,3*4+reg0(3)
|
||||
bctr # goto dyld
|
||||
|
||||
SYS_exit =1
|
||||
SYS_fork =2
|
||||
SYS_read =3
|
||||
SYS_write =4
|
||||
SYS_open =5
|
||||
SYS_close =6
|
||||
|
||||
SYS_mmap =197
|
||||
SYS_mprotect= 74
|
||||
|
||||
/* SYS_mmap takes a 64-bit off_t, but gcc-3.4.1-20040827 passes long long
|
||||
in wrong registers. So change C interface to use size_t (32-bits) instead
|
||||
of off_t (64 bits), and convert here.
|
||||
*/
|
||||
mmap: .globl mmap
|
||||
movr a6,a5; li a5,0 # zero extend 6th arg size_t to off_t
|
||||
li 0,SYS_mmap
|
||||
sysgo:
|
||||
sc
|
||||
li a0,-1 # failure return
|
||||
ret
|
||||
|
||||
exit: .globl exit
|
||||
li 0,SYS_exit; b sysgo
|
||||
read: .globl read
|
||||
li 0,SYS_read; b sysgo
|
||||
open: .globl open
|
||||
li 0,SYS_open; b sysgo
|
||||
close: .globl close
|
||||
li 0,SYS_close; b sysgo
|
||||
mprotect: .globl mprotect
|
||||
li 0,SYS_mprotect; b sysgo
|
||||
|
129
src/stub/fold_machppc32.h
Normal file
129
src/stub/fold_machppc32.h
Normal file
|
@ -0,0 +1,129 @@
|
|||
/* fold_machppc32.h -- created from fold_machppc32.bin, 1532 (0x5fc) bytes
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2005 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2005 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
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
#define FOLD_MACHPPC32_ADLER32 0x02240452
|
||||
#define FOLD_MACHPPC32_CRC32 0x810a39d7
|
||||
|
||||
unsigned char fold_machppc32[1532] = {
|
||||
72, 0, 0, 93, 40, 6, 0,208, 76,130, 0, 32, 84,132,240,191, /* 0x 0 */
|
||||
77,130, 0, 32, 56,165, 1, 32,124,103, 27,120, 56, 99,255,252, /* 0x 10 */
|
||||
124,137, 3,166, 72, 0, 0, 32,125, 99, 16, 80,125,107, 58, 20, /* 0x 20 */
|
||||
85,107, 80, 42,125,107, 86,112, 81, 98, 1,186,144, 67, 0, 0, /* 0x 30 */
|
||||
78, 64, 0, 32,132, 67, 0, 4, 84, 75, 85,190,124, 11, 40, 64, /* 0x 40 */
|
||||
65,162,255,216, 66, 0,255,240, 78,128, 0, 32, 57, 32, 0, 0, /* 0x 50 */
|
||||
149, 33,255,252,124, 41, 11,120,125, 8, 2,166,128,159,255,248, /* 0x 60 */
|
||||
124,100,248, 80,128,195, 0, 24, 40, 6, 8, 0, 65,129, 0, 8, /* 0x 70 */
|
||||
56,192, 8, 0,124, 61, 11,120,124, 38, 8, 80,124, 37, 11,120, /* 0x 80 */
|
||||
56, 33,255,232,127,231,251,120, 72, 0, 4, 37,127,161,235,120, /* 0x 90 */
|
||||
128, 67, 0, 0,124, 73, 3,166,128, 67, 0,136,124, 79,241, 32, /* 0x a0 */
|
||||
128, 67, 0,140,124, 65, 3,166,128, 67, 0,144,124, 72, 3,166, /* 0x b0 */
|
||||
184,131, 0, 24,128, 3, 0, 8,128, 67, 0, 16,128, 99, 0, 20, /* 0x c0 */
|
||||
78,128, 4, 32,125, 9, 67,120, 57, 0, 0, 0, 56, 0, 0,197, /* 0x d0 */
|
||||
68, 0, 0, 2, 56, 96,255,255, 78,128, 0, 32, 56, 0, 0, 1, /* 0x e0 */
|
||||
75,255,255,240, 56, 0, 0, 3, 75,255,255,232, 56, 0, 0, 5, /* 0x f0 */
|
||||
75,255,255,224, 56, 0, 0, 6, 75,255,255,216, 56, 0, 0, 74, /* 0x 100 */
|
||||
75,255,255,208,124, 8, 2,166,148, 33,255,240,144, 1, 0, 20, /* 0x 110 */
|
||||
128, 3, 0, 0,129, 35, 0, 4,127,128, 40, 64, 64,188, 0, 12, /* 0x 120 */
|
||||
56, 96, 0,127, 75,255,255,185, 47,133, 0, 0, 65,158, 0, 28, /* 0x 130 */
|
||||
124,169, 3,166,136, 9, 0, 0, 57, 41, 0, 1,152, 4, 0, 0, /* 0x 140 */
|
||||
56,132, 0, 1, 66, 0,255,240,128, 3, 0, 0,129, 35, 0, 4, /* 0x 150 */
|
||||
124, 5, 0, 80,144, 3, 0, 0,125, 41, 42, 20,128, 1, 0, 20, /* 0x 160 */
|
||||
56, 33, 0, 16,145, 35, 0, 4,124, 8, 3,166, 78,128, 0, 32, /* 0x 170 */
|
||||
124, 8, 2,166,148, 33,255,192,191,129, 0, 48,124,159, 35,120, /* 0x 180 */
|
||||
124,126, 27,120,124,188, 43,120,144, 1, 0, 68,124,221, 51,120, /* 0x 190 */
|
||||
128, 4, 0, 0, 47,128, 0, 0, 65,158, 1, 32, 56,160, 0, 12, /* 0x 1a0 */
|
||||
127,195,243,120, 56,129, 0, 16, 75,255,255, 93,129, 33, 0, 16, /* 0x 1b0 */
|
||||
128,161, 0, 20, 47,137, 0, 0, 64,190, 0, 36, 60, 0, 33, 88, /* 0x 1c0 */
|
||||
96, 0, 80, 85,127,133, 0, 0, 64,190, 0, 28,128, 30, 0, 0, /* 0x 1d0 */
|
||||
47,128, 0, 0, 65,190, 0,228, 72, 0, 0, 12, 47,133, 0, 0, /* 0x 1e0 */
|
||||
64,190, 0, 12, 56, 96, 0,127, 75,255,254,245,127, 5, 72, 64, /* 0x 1f0 */
|
||||
65,185,255,244,128, 31, 0, 0,127,137, 0, 64, 65,189,255,232, /* 0x 200 */
|
||||
128, 31, 0, 4, 64,152, 0,132,124,164, 43,120,128,126, 0, 4, /* 0x 210 */
|
||||
124, 5, 3,120, 56,193, 0, 32,136,225, 0, 24,127,136, 3,166, /* 0x 220 */
|
||||
78,128, 0, 33, 47,131, 0, 0, 64,190,255,188,128,129, 0, 32, /* 0x 230 */
|
||||
128, 1, 0, 16,127,132, 0, 0, 64,190,255,172,136,193, 0, 25, /* 0x 240 */
|
||||
49, 61,255,255,124, 9,233, 16,125, 38, 0,208, 85, 41, 15,254, /* 0x 250 */
|
||||
125, 43, 0, 57, 65,162, 0, 20,128,127, 0, 4,127,168, 3,166, /* 0x 260 */
|
||||
136,161, 0, 26, 78,128, 0, 33,129, 97, 0, 20,128, 30, 0, 4, /* 0x 270 */
|
||||
129, 62, 0, 0,124, 0, 90, 20,125, 43, 72, 80,144, 30, 0, 4, /* 0x 280 */
|
||||
145, 62, 0, 0, 72, 0, 0, 16,124, 4, 3,120,127,195,243,120, /* 0x 290 */
|
||||
75,255,254,117,129, 97, 0, 16,129, 63, 0, 0,128, 31, 0, 4, /* 0x 2a0 */
|
||||
125, 43, 72, 80, 47,137, 0, 0,124, 0, 90, 20,144, 31, 0, 4, /* 0x 2b0 */
|
||||
145, 63, 0, 0, 75,255,254,228,128, 1, 0, 68,187,129, 0, 48, /* 0x 2c0 */
|
||||
56, 33, 0, 64,124, 8, 3,166, 78,128, 0, 32,124, 8, 2,166, /* 0x 2d0 */
|
||||
148, 33,255,176,190, 97, 0, 28,125,128, 0, 38, 58,224, 0, 0, /* 0x 2e0 */
|
||||
124,122, 27,120,144, 1, 0, 84,124,155, 35,120,128, 3, 0, 16, /* 0x 2f0 */
|
||||
124,179, 43,120,145,129, 0, 24,124,212, 51,120,127,151, 0, 64, /* 0x 300 */
|
||||
124,245, 59,120,125, 22, 67,120, 59,195, 0, 28, 59, 0, 0, 0, /* 0x 310 */
|
||||
64,156, 1,124,129, 62, 0, 0, 47,137, 0, 1, 64,190, 1, 48, /* 0x 320 */
|
||||
129, 62, 0, 24,129,126, 0, 36, 85, 61, 5, 62,128, 30, 0, 28, /* 0x 330 */
|
||||
127,139,234, 20,145, 97, 0, 8, 46, 28, 0, 0,127, 41, 2, 20, /* 0x 340 */
|
||||
145, 33, 0, 12,127,253, 72, 80, 65,146, 0, 72, 47,155, 0, 0, /* 0x 350 */
|
||||
64,190, 0, 16, 47,139, 0, 0, 56,192, 0, 18, 64,158, 0, 8, /* 0x 360 */
|
||||
56,192, 16, 18, 47,139, 0, 0,126,103,155,120, 64,158, 0, 8, /* 0x 370 */
|
||||
56,224,255,255,129, 30, 0, 32,127,227,251,120,127,132,227,120, /* 0x 380 */
|
||||
56,160, 0, 3, 75,255,253, 65,127,159, 24, 0, 64,158, 0,128, /* 0x 390 */
|
||||
47,155, 0, 0, 65,158, 0, 52,128, 30, 0, 36, 47,128, 0, 0, /* 0x 3a0 */
|
||||
65,158, 0, 40,128, 30, 0, 32, 47,128, 0, 0, 64,158, 0, 8, /* 0x 3b0 */
|
||||
147,244, 0, 0,127, 99,219,120, 56,129, 0, 8,126,165,171,120, /* 0x 3c0 */
|
||||
126,198,179,120, 75,255,253,173,124, 28, 0,208,125, 63,226, 20, /* 0x 3d0 */
|
||||
112, 29, 15,255, 65,130, 0, 24,127,169, 3,166, 56, 0, 0, 0, /* 0x 3e0 */
|
||||
152, 9, 0, 0, 57, 41, 0, 1, 66, 0,255,248, 65,178, 0, 40, /* 0x 3f0 */
|
||||
128,190, 0, 44,127,227,251,120,127,132,227,120, 76,198, 49,130, /* 0x 400 */
|
||||
75,255,252,253, 47,131, 0, 0, 65,190, 0, 12, 56, 96, 0,127, /* 0x 410 */
|
||||
75,255,252,205,124, 28,234, 20,127,255, 2, 20,127,159,200, 64, /* 0x 420 */
|
||||
64,188, 0, 84,128,190, 0, 44,124,159,200, 80,127,227,251,120, /* 0x 430 */
|
||||
56,192, 16, 18, 56,224,255,255, 57, 0, 0, 0, 75,255,252,137, /* 0x 440 */
|
||||
127,159, 24, 0, 65,190, 0, 48, 75,255,255,196, 56, 9,255,252, /* 0x 450 */
|
||||
43,128, 0, 1, 65,157, 0, 32,128, 30, 0, 8, 47,128, 0, 1, /* 0x 460 */
|
||||
64,190, 0, 20,128, 30, 0, 12, 47,128, 0, 40, 64,190, 0, 8, /* 0x 470 */
|
||||
58,254, 0, 16,128, 26, 0, 16, 59, 24, 0, 1,127,152, 0, 64, /* 0x 480 */
|
||||
128, 30, 0, 4,127,222, 2, 20, 75,255,254,136,128, 1, 0, 84, /* 0x 490 */
|
||||
126,227,187,120,129,129, 0, 24,186, 97, 0, 28,124, 8, 3,166, /* 0x 4a0 */
|
||||
56, 33, 0, 80,125,128,129, 32, 78,128, 0, 32,148, 33,255,176, /* 0x 4b0 */
|
||||
124, 8, 2,166,144,129, 0, 8,191, 65, 0, 56,129, 97, 0, 8, /* 0x 4c0 */
|
||||
124,191, 43,120,144, 1, 0, 84, 56, 3, 0, 24, 57,107,255,232, /* 0x 4d0 */
|
||||
144, 1, 0, 20,145, 97, 0, 16,124,253, 59,120,128, 3, 0, 24, /* 0x 4e0 */
|
||||
125, 60, 75,120,200, 1, 0, 16,125, 27, 67,120,124,229, 59,120, /* 0x 4f0 */
|
||||
56, 97, 0, 16, 56,129, 0, 24,124,218, 51,120, 56,192, 0, 0, /* 0x 500 */
|
||||
144, 1, 0, 24,216, 1, 0, 32, 59,192, 0, 0,147,225, 0, 28, /* 0x 510 */
|
||||
75,255,252, 97,127,167,235,120,127,104,219,120,127,227,251,120, /* 0x 520 */
|
||||
127,134,227,120, 56,129, 0, 32, 56,160,255,255, 75,255,253,161, /* 0x 530 */
|
||||
128, 31, 0, 16,124,123, 27,120, 59,191, 0, 28,127,158, 0, 64, /* 0x 540 */
|
||||
64,156, 0,148,128, 29, 0, 0, 59,222, 0, 1, 56,128, 0, 0, /* 0x 550 */
|
||||
56,160, 0, 0, 47,128, 0, 14, 64,190, 0,104,128,125, 0, 8, /* 0x 560 */
|
||||
124,125, 26, 20, 76,198, 49,130, 75,255,251,133,127,228,251,120, /* 0x 570 */
|
||||
124,124, 27,121,127, 69,211,120, 65,128, 0, 44, 76,198, 49,130, /* 0x 580 */
|
||||
75,255,251,101, 56,128, 0, 0,127,154, 24, 0,127,133,227,120, /* 0x 590 */
|
||||
127,227,251,120, 56,192, 0, 0, 56,224, 0, 0, 57, 0, 0, 0, /* 0x 5a0 */
|
||||
65,190, 0, 12, 56, 96, 0,127, 75,255,251, 53, 75,255,253, 33, /* 0x 5b0 */
|
||||
124,123, 27,120,127,131,227,120, 76,198, 49,130, 75,255,251, 57, /* 0x 5c0 */
|
||||
128, 31, 0, 16,129, 61, 0, 4,127,158, 0, 64,127,189, 74, 20, /* 0x 5d0 */
|
||||
75,255,255,112,128, 1, 0, 84,127, 99,219,120,187, 65, 0, 56, /* 0x 5e0 */
|
||||
56, 33, 0, 80,124, 8, 3,166, 78,128, 0, 32 /* 0x 5f0 */
|
||||
};
|
71
src/stub/l_mac_ppc32.S
Normal file
71
src/stub/l_mac_ppc32.S
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* l_mac_ppc32.S -- program entry point & decompressor (PowerPC32 Mach-o)
|
||||
*
|
||||
* This file is part of the UPX executable compressor.
|
||||
*
|
||||
* Copyright (C) 2005 John F. 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 F. Reiser
|
||||
* <jreiser@users.sourceforge.net>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ppc_regs.h"
|
||||
|
||||
/*__MACOS000__*/
|
||||
_start: .globl _start
|
||||
call main # must be exactly 1 instruction; link_register= &decompress
|
||||
#include "ppc_d_nrv2e.S"
|
||||
|
||||
sz_b_info= 12
|
||||
sz_unc= 0
|
||||
sz_cpr= 4
|
||||
|
||||
/* Decompress the rest of this loader, and jump to it. */
|
||||
unfold:
|
||||
mflr t0 # -4+ &{ b_info={sz_unc, sz_cpr, {4 char}}, folded_loader...}
|
||||
|
||||
lwz lsrc,4+sz_cpr(t0); mtctr lsrc # length to copy (and decompress)
|
||||
lwz ldst,4+sz_unc(t0)
|
||||
add dst,lsrc,t0; addi dst,dst,4+sz_b_info
|
||||
add src,ldst,t0; addi src,src,GAP+64 # defend against prefetch and overlap
|
||||
movup: # descending copy moves folded_loader to higher address
|
||||
lbzu r0,-1(dst)
|
||||
stbu r0,-1(src)
|
||||
bdnz+ movup # typical count is about 0x4cb(1227) bytes
|
||||
|
||||
mtctr r31 # &decompress
|
||||
addi dst,t0,GAP # &unfolded result
|
||||
la ldst,-4(sp) # &sz_result [will be ignored]
|
||||
bctr # call decompress: branch to counter register, return to link register
|
||||
|
||||
main:
|
||||
mflr r31 # r31= &decompress
|
||||
call unfold
|
||||
L100: GAP= 128 # > farthest_prefetch; must match ../p_mach.cpp
|
||||
b GAP+L100 # 'isync' has trouble on Macintosh G4?
|
||||
/* { b_info={sz_unc, sz_cpr, {4 char}}, folded_loader...} */
|
||||
|
||||
eof:
|
||||
/*__XTHEENDX__*/
|
||||
|
||||
/*
|
||||
vi:ts=8:et:nowrap
|
||||
*/
|
||||
|
59
src/stub/l_mac_ppc32.h
Normal file
59
src/stub/l_mac_ppc32.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* l_mac_ppc32.h -- created from l_mac_ppc32.bin, 412 (0x19c) bytes
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2005 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2005 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
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
#define L_MAC_PPC32_LOADER_ADLER32 0x30d18ea4
|
||||
#define L_MAC_PPC32_LOADER_CRC32 0x0293d040
|
||||
|
||||
unsigned char l_mac_ppc32_loader[412] = {
|
||||
72, 0, 1,145,144,166, 0, 0,124,132, 26, 20, 60, 0,128, 0, /* 0x 0 */
|
||||
61, 32,128, 0, 56, 99,255,255, 56,165,255,255, 57, 64,255,255, /* 0x 10 */
|
||||
125,168, 2,166, 72, 0, 0, 40, 57, 32, 0, 1,125, 41, 28, 44, /* 0x 20 */
|
||||
56, 99, 0, 4,124, 9, 0, 64,125, 41, 72, 20, 97, 41, 0, 1, /* 0x 30 */
|
||||
78,128, 0, 32,141, 3, 0, 1,157, 5, 0, 1,124, 9, 0, 64, /* 0x 40 */
|
||||
125, 41, 74, 20, 65,162,255,213, 65,129,255,236, 56,224, 0, 1, /* 0x 50 */
|
||||
72, 0, 0, 20, 56,231,255,255,125, 41, 72, 21, 65,162,255,189, /* 0x 60 */
|
||||
124,231, 57, 20,125, 41, 72, 21, 65,162,255,177,124,231, 57, 20, /* 0x 70 */
|
||||
124, 9, 0, 64,125, 41, 74, 20, 65,162,255,161, 65,160,255,216, /* 0x 80 */
|
||||
57, 0, 0, 0, 52,231,255,253, 84,231, 64, 46, 65,128, 0, 32, /* 0x 90 */
|
||||
140, 67, 0, 1,124,234, 16,249,125, 74, 14,112, 65,130, 0,136, /* 0x a0 */
|
||||
112, 66, 0, 1, 65,162, 0, 80, 72, 0, 0, 20,124, 9, 0, 64, /* 0x b0 */
|
||||
125, 41, 74, 20, 65,162,255,101, 65,161, 0, 60, 57, 0, 0, 1, /* 0x c0 */
|
||||
124, 9, 0, 64,125, 41, 74, 20, 65,162,255, 81, 65,161, 0, 40, /* 0x d0 */
|
||||
125, 41, 72, 21, 65,162,255, 69,125, 8, 65, 20,124, 9, 0, 64, /* 0x e0 */
|
||||
125, 41, 74, 20, 65,162,255, 53, 65,160,255,232, 57, 8, 0, 2, /* 0x f0 */
|
||||
72, 0, 0, 16,125, 41, 72, 21, 65,162,255, 33,125, 8, 65, 20, /* 0x 100 */
|
||||
32,234,250,255, 57, 8, 0, 2,125, 8, 1,148,124,234, 42, 20, /* 0x 110 */
|
||||
125, 9, 3,166,141, 7, 0, 1,157, 5, 0, 1, 66, 0,255,248, /* 0x 120 */
|
||||
75,255,255, 28,128, 6, 0, 0,125,168, 3,166, 56,165, 0, 1, /* 0x 130 */
|
||||
56, 99, 0, 1,124,160, 40, 80,124,100, 24, 80,144,166, 0, 0, /* 0x 140 */
|
||||
78,128, 0, 32,124, 72, 2,166,128,130, 0, 8,124,137, 3,166, /* 0x 150 */
|
||||
128,194, 0, 4,124,164, 18, 20, 56,165, 0, 16,124,102, 18, 20, /* 0x 160 */
|
||||
56, 99, 0,192,140, 5,255,255,156, 3,255,255, 66, 0,255,248, /* 0x 170 */
|
||||
127,233, 3,166, 56,162, 0,128, 56,193,255,252, 78,128, 4, 32, /* 0x 180 */
|
||||
127,232, 2,166, 75,255,255,193, 72, 0, 0,128 /* 0x 190 */
|
||||
};
|
430
src/stub/m_mac_mach32.c
Normal file
430
src/stub/m_mac_mach32.c
Normal file
|
@ -0,0 +1,430 @@
|
|||
/* m_mach_ppc32.c -- loader stub for Mach-o PowerPC32
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2004 Laszlo Molnar
|
||||
Copyright (C) 2000-2005 John F. 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.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
|
||||
John F. Reiser
|
||||
<jreiser@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
typedef unsigned int size_t;
|
||||
typedef unsigned long long off_t;
|
||||
typedef unsigned char nrv_byte;
|
||||
typedef unsigned int nrv_uint;
|
||||
|
||||
#define UPX_MAGIC_LE32 0x21585055 // "UPX!"
|
||||
#define PAGE_MASK (~0u<<12)
|
||||
#define PAGE_SIZE -PAGE_MASK
|
||||
#define O_RDONLY 0
|
||||
|
||||
/*extern int exit(int) __attribute__ ((__noreturn__));*/
|
||||
|
||||
/*************************************************************************
|
||||
// configuration section
|
||||
**************************************************************************/
|
||||
|
||||
// In order to make it much easier to move this code at runtime and execute
|
||||
// it at an address different from it load address: there must be no
|
||||
// static data, and no string constants.
|
||||
|
||||
/*************************************************************************
|
||||
// "file" util
|
||||
**************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
size_t size; // must be first to match size[0] uncompressed size
|
||||
char *buf;
|
||||
} Extent;
|
||||
|
||||
|
||||
static void
|
||||
xread(Extent *x, char *buf, size_t count)
|
||||
{
|
||||
char *p=x->buf, *q=buf;
|
||||
size_t j;
|
||||
if (x->size < count) {
|
||||
exit(127);
|
||||
}
|
||||
for (j = count; 0!=j--; ++p, ++q) {
|
||||
*q = *p;
|
||||
}
|
||||
x->buf += count;
|
||||
x->size -= count;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// util
|
||||
**************************************************************************/
|
||||
|
||||
#if 1 //{ save space
|
||||
#define ERR_LAB error: exit(127);
|
||||
#define err_exit(a) goto error
|
||||
#else //}{ save debugging time
|
||||
#define ERR_LAB
|
||||
static void
|
||||
err_exit(int a)
|
||||
{
|
||||
(void)a; // debugging convenience
|
||||
exit(127);
|
||||
}
|
||||
#endif //}
|
||||
|
||||
/*************************************************************************
|
||||
// UPX & NRV stuff
|
||||
**************************************************************************/
|
||||
|
||||
struct l_info { // 12-byte trailer for loader (after macho headers)
|
||||
unsigned l_checksum;
|
||||
unsigned l_magic; // UPX_MAGIC_LE32
|
||||
unsigned short l_lsize;
|
||||
unsigned char l_version;
|
||||
unsigned char l_format;
|
||||
};
|
||||
struct p_info { // 12-byte packed program header
|
||||
unsigned p_progid;
|
||||
unsigned p_filesize;
|
||||
unsigned p_blocksize;
|
||||
};
|
||||
|
||||
struct b_info { // 12-byte header before each compressed block
|
||||
unsigned sz_unc; // uncompressed_size
|
||||
unsigned sz_cpr; // compressed_size
|
||||
unsigned char b_method; // compression algorithm
|
||||
unsigned char b_ftid; // filter id
|
||||
unsigned char b_cto8; // filter parameter
|
||||
unsigned char b_unused;
|
||||
};
|
||||
|
||||
typedef void f_unfilter(
|
||||
nrv_byte *, // also addvalue
|
||||
nrv_uint,
|
||||
unsigned cto8, // junk in high 24 bits
|
||||
unsigned ftid
|
||||
);
|
||||
typedef int f_expand(
|
||||
const nrv_byte *, nrv_uint,
|
||||
nrv_byte *, nrv_uint *, unsigned );
|
||||
|
||||
static void
|
||||
unpackExtent(
|
||||
Extent *const xi, // input
|
||||
Extent *const xo, // output
|
||||
f_expand *const f_decompress,
|
||||
f_unfilter *f_unf
|
||||
)
|
||||
{
|
||||
while (xo->size) {
|
||||
struct b_info h;
|
||||
// Note: if h.sz_unc == h.sz_cpr then the block was not
|
||||
// compressible and is stored in its uncompressed form.
|
||||
|
||||
// Read and check block sizes.
|
||||
xread(xi, (char *)&h, sizeof(h));
|
||||
if (h.sz_unc == 0) { // uncompressed size 0 -> EOF
|
||||
if (h.sz_cpr != UPX_MAGIC_LE32) // h.sz_cpr must be h->magic
|
||||
err_exit(2);
|
||||
if (xi->size != 0) // all bytes must be written
|
||||
err_exit(3);
|
||||
break;
|
||||
}
|
||||
if (h.sz_cpr <= 0) {
|
||||
err_exit(4);
|
||||
ERR_LAB
|
||||
}
|
||||
if (h.sz_cpr > h.sz_unc
|
||||
|| h.sz_unc > xo->size ) {
|
||||
err_exit(5);
|
||||
}
|
||||
// Now we have:
|
||||
// assert(h.sz_cpr <= h.sz_unc);
|
||||
// assert(h.sz_unc > 0 && h.sz_unc <= blocksize);
|
||||
// assert(h.sz_cpr > 0 && h.sz_cpr <= blocksize);
|
||||
|
||||
if (h.sz_cpr < h.sz_unc) { // Decompress block
|
||||
nrv_uint out_len;
|
||||
int const j = (*f_decompress)(xi->buf, h.sz_cpr, xo->buf, &out_len,
|
||||
h.b_method);
|
||||
if (j != 0 || out_len != (nrv_uint)h.sz_unc)
|
||||
err_exit(7);
|
||||
if (h.b_ftid!=0 && f_unf) { // have filter
|
||||
(*f_unf)(xo->buf, out_len, h.b_cto8, h.b_ftid);
|
||||
}
|
||||
xi->buf += h.sz_cpr;
|
||||
xi->size -= h.sz_cpr;
|
||||
}
|
||||
else { // copy literal block
|
||||
xread(xi, xo->buf, h.sz_cpr);
|
||||
}
|
||||
xo->buf += h.sz_unc;
|
||||
xo->size -= h.sz_unc;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
upx_bzero(char *p, size_t len)
|
||||
{
|
||||
if (len) do {
|
||||
*p++= 0;
|
||||
} while (--len);
|
||||
}
|
||||
#define bzero upx_bzero
|
||||
|
||||
|
||||
// The PF_* and PROT_* bits are {1,2,4}; the conversion table fits in 32 bits.
|
||||
#define REP8(x) \
|
||||
((x)|((x)<<4)|((x)<<8)|((x)<<12)|((x)<<16)|((x)<<20)|((x)<<24)|((x)<<28))
|
||||
#define EXP8(y) \
|
||||
((1&(y)) ? 0xf0f0f0f0 : (2&(y)) ? 0xff00ff00 : (4&(y)) ? 0xffff0000 : 0)
|
||||
#define PF_TO_PROT(pf) \
|
||||
((PROT_READ|PROT_WRITE|PROT_EXEC) & ( \
|
||||
( (REP8(PROT_EXEC ) & EXP8(PF_X)) \
|
||||
|(REP8(PROT_READ ) & EXP8(PF_R)) \
|
||||
|(REP8(PROT_WRITE) & EXP8(PF_W)) \
|
||||
) >> ((pf & (PF_R|PF_W|PF_X))<<2) ))
|
||||
|
||||
typedef struct {
|
||||
unsigned magic;
|
||||
unsigned cputype;
|
||||
unsigned cpysubtype;
|
||||
unsigned filetype;
|
||||
unsigned ncmds;
|
||||
unsigned sizeofcmds;
|
||||
unsigned flags;
|
||||
} Mach_header;
|
||||
enum e0 {
|
||||
MH_MAGIC = 0xfeedface
|
||||
};
|
||||
enum e1 {
|
||||
CPU_TYPE_POWERPC = 18
|
||||
};
|
||||
enum e2 {
|
||||
MH_EXECUTE = 2
|
||||
};
|
||||
enum e3 {
|
||||
MH_NOUNDEFS = 1
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
unsigned cmd;
|
||||
unsigned cmdsize;
|
||||
} Mach_load_command;
|
||||
enum e4 {
|
||||
LC_SEGMENT = 0x1,
|
||||
LC_THREAD = 0x4,
|
||||
LC_UNIXTHREAD = 0x5,
|
||||
LC_LOAD_DYLINKER = 0xe
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
unsigned cmd;
|
||||
unsigned cmdsize;
|
||||
char segname[16];
|
||||
unsigned vmaddr;
|
||||
unsigned vmsize;
|
||||
unsigned fileoff;
|
||||
unsigned filesize;
|
||||
unsigned maxprot;
|
||||
unsigned initprot;
|
||||
unsigned nsects;
|
||||
unsigned flags;
|
||||
} Mach_segment_command;
|
||||
enum e5 {
|
||||
VM_PROT_READ = 1,
|
||||
VM_PROT_WRITE = 2,
|
||||
VM_PROT_EXECUTE = 4
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
unsigned srr0; /* Instruction address register (PC; entry addr) */
|
||||
unsigned srr1; /* Machine state register (supervisor) */
|
||||
unsigned r0, r1, r2, r3, r4, r5, r6, r7;
|
||||
unsigned r8, r9,r10,r11,r12,r13,r14,r15;
|
||||
unsigned r16,r17,r18,r19,r20,r21,r22,r23;
|
||||
unsigned r24,r25,r26,r27,r28,r29,r30,r31;
|
||||
|
||||
unsigned cr; /* Condition register */
|
||||
unsigned xer; /* User's integer exception register */
|
||||
unsigned lr; /* Link register */
|
||||
unsigned ctr; /* Count register */
|
||||
unsigned mq; /* MQ register (601 only) */
|
||||
|
||||
unsigned vrsave; /* Vector Save Register */
|
||||
} Mach_ppc_thread_state;
|
||||
|
||||
typedef struct {
|
||||
unsigned cmd; /* LC_THREAD or LC_UNIXTHREAD */
|
||||
unsigned cmdsize; /* total size of this command */
|
||||
unsigned flavor;
|
||||
unsigned count; /* sizeof(following_thread_state)/4 */
|
||||
Mach_ppc_thread_state state;
|
||||
} Mach_thread_command;
|
||||
enum e6 {
|
||||
PPC_THREAD_STATE = 1
|
||||
};
|
||||
enum e7 {
|
||||
PPC_THREAD_STATE_COUNT = sizeof(Mach_ppc_thread_state)/4
|
||||
};
|
||||
|
||||
typedef union {
|
||||
unsigned long offset; /* from start of load command to string */
|
||||
char *ptr;
|
||||
} Mach_lc_str;
|
||||
|
||||
#define MAP_FIXED 0x10
|
||||
#define MAP_PRIVATE 0x02
|
||||
#define MAP_ANON 0x1000
|
||||
#define PROT_READ 1
|
||||
#define PROT_WRITE 2
|
||||
#define PROT_EXEC 4
|
||||
|
||||
/* bug in crosstool/powerpc-750-linux-gnu/gcc-3.4.1-glibc-20040827:
|
||||
unsigned long long off_t goes into registers (9,10) instead of (8,9).
|
||||
Adjust in mmap().
|
||||
*/
|
||||
extern char *mmap(char *, size_t, unsigned, unsigned, int, /*off_t*/size_t);
|
||||
|
||||
static Mach_ppc_thread_state const *
|
||||
do_xmap(
|
||||
Mach_header const *const mhdr,
|
||||
Extent *const xi,
|
||||
int const fdi,
|
||||
Mach_header **mhdrpp,
|
||||
f_expand *const f_decompress,
|
||||
f_unfilter *const f_unf
|
||||
)
|
||||
{
|
||||
Mach_segment_command const *sc = (Mach_segment_command const *)(1+ mhdr);
|
||||
Mach_ppc_thread_state const *entry = 0;
|
||||
int j;
|
||||
|
||||
for ( j=0; j < mhdr->ncmds; ++j,
|
||||
(sc = (Mach_segment_command const *)(sc->cmdsize + (char const *)sc))
|
||||
) if (LC_SEGMENT==sc->cmd) {
|
||||
Extent xo;
|
||||
size_t mlen = xo.size = sc->filesize;
|
||||
char *addr = xo.buf = (char *)sc->vmaddr;
|
||||
char *haddr = sc->vmsize + addr;
|
||||
size_t frag = (int)addr &~ PAGE_MASK;
|
||||
addr -= frag;
|
||||
mlen += frag;
|
||||
|
||||
if (0!=mlen && addr != mmap(addr, mlen, VM_PROT_READ | VM_PROT_WRITE,
|
||||
MAP_FIXED | MAP_PRIVATE |
|
||||
((xi || 0==sc->filesize) ? MAP_ANON : 0),
|
||||
((0==sc->filesize) ? -1 : fdi), sc->fileoff) ) {
|
||||
err_exit(8);
|
||||
}
|
||||
if (xi && 0!=sc->filesize) {
|
||||
if (0==sc->fileoff /*&& 0!=mhdrpp*/) {
|
||||
*mhdrpp = (Mach_header *)addr;
|
||||
}
|
||||
unpackExtent(xi, &xo, f_decompress, f_unf);
|
||||
}
|
||||
/*bzero(addr, frag);*/ // fragment at lo end
|
||||
frag = (-mlen) &~ PAGE_MASK; // distance to next page boundary
|
||||
bzero(mlen+addr, frag); // fragment at hi end
|
||||
if (0!=mlen && 0!=mprotect(addr, mlen, sc->initprot)) {
|
||||
err_exit(10);
|
||||
ERR_LAB
|
||||
}
|
||||
addr += mlen + frag; /* page boundary on hi end */
|
||||
if (addr < haddr) { // need pages for .bss
|
||||
if (addr != mmap(addr, haddr - addr, sc->initprot,
|
||||
MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0 ) ) {
|
||||
err_exit(9);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (LC_UNIXTHREAD==sc->cmd || LC_THREAD==sc->cmd) {
|
||||
Mach_thread_command const *const thrc = (Mach_thread_command const *)sc;
|
||||
if (PPC_THREAD_STATE ==thrc->flavor
|
||||
&& PPC_THREAD_STATE_COUNT==thrc->count ) {
|
||||
entry = &thrc->state;
|
||||
}
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// upx_main - called by our entry code
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
Mach_ppc_thread_state const *
|
||||
upx_main(
|
||||
struct l_info const *const li,
|
||||
size_t volatile sz_compressed, // total length
|
||||
Mach_header *const mhdr, // temp char[sz_mhdr] for decompressing
|
||||
size_t const sz_mhdr,
|
||||
f_expand *const f_decompress,
|
||||
f_unfilter *const f_unf,
|
||||
Mach_header **const mhdrpp // Out: *mhdrpp= &real Mach_header
|
||||
)
|
||||
{
|
||||
Mach_ppc_thread_state const *entry;
|
||||
Extent xi, xo, xi0;
|
||||
xi.buf = (char *)(1+ (struct p_info const *)(1+ li)); // &b_info
|
||||
xi.size = sz_compressed - (sizeof(struct l_info) + sizeof(struct p_info));
|
||||
xo.buf = (char *)mhdr;
|
||||
xo.size = ((struct b_info const *)xi.buf)->sz_unc;
|
||||
xi0 = xi;
|
||||
|
||||
// Uncompress Macho headers
|
||||
unpackExtent(&xi, &xo, f_decompress, 0); // never filtered?
|
||||
|
||||
entry = do_xmap(mhdr, &xi0, -1, mhdrpp, f_decompress, f_unf);
|
||||
|
||||
{ // Map dyld dynamic loader
|
||||
Mach_load_command const *lc = (Mach_load_command const *)(1+ mhdr);
|
||||
int j;
|
||||
|
||||
for (j=0; j < mhdr->ncmds; ++j,
|
||||
(lc = (Mach_load_command const *)(lc->cmdsize + (char const *)lc))
|
||||
) if (LC_LOAD_DYLINKER==lc->cmd) {
|
||||
char const *const dyld_name = ((Mach_lc_str const *)(1+ lc))->offset +
|
||||
(char const *)lc;
|
||||
int const fdi = open(dyld_name, O_RDONLY, 0);
|
||||
if (0 > fdi) {
|
||||
err_exit(18);
|
||||
}
|
||||
if (sz_mhdr!=read(fdi, (void *)mhdr, sz_mhdr)) {
|
||||
ERR_LAB
|
||||
err_exit(19);
|
||||
}
|
||||
entry = do_xmap(mhdr, 0, fdi, 0, 0, 0);
|
||||
close(fdi);
|
||||
}
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user