1
0
mirror of https://github.com/upx/upx synced 2025-09-28 19:06:07 +08:00

implement DEBUG

This commit is contained in:
John Reiser 2012-08-23 14:22:55 -07:00
parent be96c28b77
commit dee47ba2d8
3 changed files with 280 additions and 99 deletions

View File

@ -1,5 +1,5 @@
/* i386-darwin.macho-fold.h /* i386-darwin.macho-fold.h
created from i386-darwin.macho-fold.bin, 1102 (0x44e) bytes created from i386-darwin.macho-fold.bin, 1135 (0x46f) bytes
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
@ -31,78 +31,80 @@
*/ */
#define STUB_I386_DARWIN_MACHO_FOLD_SIZE 1102 #define STUB_I386_DARWIN_MACHO_FOLD_SIZE 1135
#define STUB_I386_DARWIN_MACHO_FOLD_ADLER32 0x86e50532 #define STUB_I386_DARWIN_MACHO_FOLD_ADLER32 0x768a14b0
#define STUB_I386_DARWIN_MACHO_FOLD_CRC32 0x703625c8 #define STUB_I386_DARWIN_MACHO_FOLD_CRC32 0x8d0be2e9
unsigned char stub_i386_darwin_macho_fold[1102] = { unsigned char stub_i386_darwin_macho_fold[1135] = {
/* 0x0000 */ 106, 0,137,231,141,117, 2,139, 19,137,217, 41,209,139, 89, 24, /* 0x0000 */ 106, 0,137,231,141,117, 2,139, 19,137,217, 41,209,139, 89, 24,
/* 0x0010 */ 184, 0, 8, 0, 0, 57,216,118, 2,137,195, 41,220, 96,232, 5, /* 0x0010 */ 184, 0, 8, 0, 0, 57,216,118, 2,137,195, 41,220, 96,232, 30,
/* 0x0020 */ 3, 0, 0,139, 76, 36, 16,141,100, 12, 32,255, 96, 40,139, 68, /* 0x0020 */ 3, 0, 0,139, 76, 36, 16,141,100, 12, 32,255, 96, 40,139, 68,
/* 0x0030 */ 36, 4,139, 76, 36, 8,139, 16, 15,202,137, 16,131,233, 4,141, /* 0x0030 */ 36, 4,139, 76, 36, 8,139, 16, 15,202,137, 16,131,233, 4,141,
/* 0x0040 */ 64, 4,115,242,195, 90, 15, 52,176, 1,235, 2,176, 74,235, 2, /* 0x0040 */ 64, 4,115,242,195, 90, 15, 52,176, 4,235, 2,176, 1,235, 2,
/* 0x0050 */ 176, 73,235, 2,176,153,235, 2,176, 6,235, 2,176, 5,235, 2, /* 0x0050 */ 176, 74,235, 2,176, 73,235, 2,176,153,235, 2,176, 6,235, 2,
/* 0x0060 */ 176,197,235, 2,176, 3, 15,182,192,137,225,232,213,255,255,255, /* 0x0060 */ 176, 5,235, 2,176,197,235, 2,176, 3, 15,182,192,137,225,232,
/* 0x0070 */ 115, 3,131,200,255,195,144,144, 85,137,229, 87, 86,139,125, 8, /* 0x0070 */ 209,255,255,255,115, 3,131,200,255,195,144,144, 85,137,229, 87,
/* 0x0080 */ 83,137,195, 57, 56,139,112, 4,115, 7,106,127,232,183,255,255, /* 0x0080 */ 86,139,125, 8, 83,137,195, 57, 56,139,112, 4,115, 7,106,127,
/* 0x0090 */ 255,133,255,116, 10,137,249,138, 6, 70,136, 2, 66,226,248, 1, /* 0x0090 */ 232,183,255,255,255,133,255,116, 10,137,249,138, 6, 70,136, 2,
/* 0x00a0 */ 123, 4, 41, 59,141,101,244, 91, 94, 95,201,195, 85,137,229, 87, /* 0x00a0 */ 66,226,248, 1,123, 4, 41, 59,141,101,244, 91, 94, 95,201,195,
/* 0x00b0 */ 86,137,198, 83,137,211,131,236, 24,139, 69, 8,139,125, 12,137, /* 0x00b0 */ 85,137,229, 87, 86,137,198, 83,137,211,131,236, 24,139, 69, 8,
/* 0x00c0 */ 69,220,131, 58, 0, 15,132,172, 0, 0, 0,141, 85,228,137,240, /* 0x00c0 */ 139,125, 12,137, 69,220,131, 58, 0, 15,132,172, 0, 0, 0,141,
/* 0x00d0 */ 106, 12,232,161,255,255,255,139, 69,228, 90,133,192,139, 77,232, /* 0x00d0 */ 85,228,137,240,106, 12,232,161,255,255,255,139, 69,228, 90,133,
/* 0x00e0 */ 117, 19,129,249, 85, 80, 88, 33,117, 15,131, 62, 0, 15,132,132, /* 0x00e0 */ 192,139, 77,232,117, 19,129,249, 85, 80, 88, 33,117, 15,131, 62,
/* 0x00f0 */ 0, 0, 0,235, 4,133,201,117, 7,106,127,232, 72,255,255,255, /* 0x00f0 */ 0, 15,132,132, 0, 0, 0,235, 4,133,201,117, 7,106,127,232,
/* 0x0100 */ 57,193,119,245, 59, 3,119,241, 57,193,115, 76,137, 69,224, 15, /* 0x0100 */ 72,255,255,255, 57,193,119,245, 59, 3,119,241, 57,193,115, 76,
/* 0x0110 */ 182, 69,236, 80,141, 69,224, 80,255,115, 4, 81,255,118, 4,255, /* 0x0110 */ 137, 69,224, 15,182, 69,236, 80,141, 69,224, 80,255,115, 4, 81,
/* 0x0120 */ 85,220,131,196, 20,133,192,117,208,139, 85,224, 59, 85,228,117, /* 0x0120 */ 255,118, 4,255, 85,220,131,196, 20,133,192,117,208,139, 85,224,
/* 0x0130 */ 200,138, 69,237,132,192,116, 22,133,255,116, 18, 15,182,192, 80, /* 0x0130 */ 59, 85,228,117,200,138, 69,237,132,192,116, 22,133,255,116, 18,
/* 0x0140 */ 15,182, 69,238, 80, 82,255,115, 4,255,215,131,196, 16,139, 69, /* 0x0140 */ 15,182,192, 80, 15,182, 69,238, 80, 82,255,115, 4,255,215,131,
/* 0x0150 */ 232, 1, 70, 4, 41, 6,235, 12,139, 83, 4, 81,137,240,232, 21, /* 0x0150 */ 196, 16,139, 69,232, 1, 70, 4, 41, 6,235, 12,139, 83, 4, 81,
/* 0x0160 */ 255,255,255, 88,139, 85,228,139, 3, 1, 83, 4, 41,208,133,192, /* 0x0160 */ 137,240,232, 21,255,255,255, 88,139, 85,228,139, 3, 1, 83, 4,
/* 0x0170 */ 137, 3,233, 78,255,255,255,141,101,244, 91, 94, 95,201,195, 85, /* 0x0170 */ 41,208,133,192,137, 3,233, 78,255,255,255,141,101,244, 91, 94,
/* 0x0180 */ 137,229, 87, 86, 83,131,236, 48,137, 69,232,139, 69, 8,137, 85, /* 0x0180 */ 95,201,195, 85,137,229, 87, 86, 83,131,236, 56,137, 69,232,139,
/* 0x0190 */ 228,139, 85, 12,199, 69,208, 0, 0, 0, 0,137, 69,224,139, 69, /* 0x0190 */ 69, 8,137, 85,228,139, 85, 12,199, 69,208, 0, 0, 0, 0,137,
/* 0x01a0 */ 20,137, 85,220,139, 85, 24,137, 69,216,139, 93,232,139, 69,232, /* 0x01a0 */ 69,224,139, 69, 20,137, 85,220,139, 85, 24,137, 69,216,139,117,
/* 0x01b0 */ 137, 85,212, 49,210,131,195, 28,199, 69,204, 0, 0, 0, 0, 59, /* 0x01b0 */ 232,139, 69,232,137, 85,212, 49,210,131,198, 28,199, 69,204, 0,
/* 0x01c0 */ 80, 16, 15,131, 85, 1, 0, 0,139, 3,131,248, 1, 15,133, 28, /* 0x01c0 */ 0, 0, 0, 59, 80, 16, 15,131,106, 1, 0, 0,139, 6,131,248,
/* 0x01d0 */ 1, 0, 0,139, 83, 24,139, 67, 28,139, 75, 36,137,214, 1,208, /* 0x01d0 */ 1, 15,133, 49, 1, 0, 0,139, 94, 28,133,219, 15,132, 38, 1,
/* 0x01e0 */ 137, 85,240,137, 69,200,137,208, 37,255, 15, 0, 0,137,207, 41, /* 0x01e0 */ 0, 0,139, 86, 24,139, 78, 36,141, 28, 26,137,208, 37,255, 15,
/* 0x01f0 */ 198, 1,199,137, 77,236,116, 68,106, 0,139, 69,228, 3, 67, 32, /* 0x01f0 */ 0, 0,137,207,137, 93,200,137,211, 41,195, 1,199,137, 77,236,
/* 0x0200 */ 133,201, 80,139, 69,220,117, 3,131,200,255,131,125,224, 0, 80, /* 0x0200 */ 137, 85,240,116, 76,131,125,224, 0,137,125,196,116, 8,141, 71,
/* 0x0210 */ 117, 9,133,201,184, 18, 0, 0, 0,117, 5,184, 18, 16, 0, 0, /* 0x0210 */ 3,137, 69,196,235, 11,133,201,199, 69,192, 18, 0, 0, 0,117,
/* 0x0220 */ 131,125,224, 0, 80,106, 3,137,248,116, 3,141, 71, 3, 80, 86, /* 0x0220 */ 7,199, 69,192, 18, 16, 0, 0,133,201,139, 85,220,117, 3,131,
/* 0x0230 */ 232, 43,254,255,255,131,196, 28, 57,198,117, 94,131,125,224, 0, /* 0x0230 */ 202,255,139, 69,228, 3, 70, 32,106, 0, 80, 82,255,117,192,106,
/* 0x0240 */ 116, 42,131,123, 36, 0,116, 36,131,123, 32, 0,117, 11,131,125, /* 0x0240 */ 3,255,117,196, 83,232, 26,254,255,255,131,196, 28, 57,195,117,
/* 0x0250 */ 16, 0,116, 5,139, 85, 16,137, 50,255,117,212,255,117,216,141, /* 0x0250 */ 94,131,125,224, 0,116, 42,131,126, 36, 0,116, 36,131,126, 32,
/* 0x0260 */ 85,236,139, 69,224,232, 66,254,255,255, 88, 90,137,248,141, 20, /* 0x0260 */ 0,117, 11,131,125, 16, 0,116, 5,139, 85, 16,137, 26,255,117,
/* 0x0270 */ 62,247,216, 37,255, 15, 0, 0,137, 69,196,116, 8,137,193,198, /* 0x0270 */ 212,255,117,216,141, 85,236,139, 69,224,232, 49,254,255,255, 88,
/* 0x0280 */ 2, 0, 66,226,250,133,255,116, 24,255,115, 44, 87, 86,232,185, /* 0x0280 */ 90,137,248,141, 20, 59,247,216, 37,255, 15, 0, 0,137, 69,188,
/* 0x0290 */ 253,255,255,131,196, 12,133,192,116, 7,106,127,232,167,253,255, /* 0x0290 */ 116, 8,137,193,198, 2, 0, 66,226,250,133,255,116, 24,255,118,
/* 0x02a0 */ 255,139, 85,196,141, 4, 23, 1,198, 59,117,200,115, 35,106, 0, /* 0x02a0 */ 44, 87, 83,232,168,253,255,255,131,196, 12,133,192,116, 7,106,
/* 0x02b0 */ 106, 0,106,255,104, 18, 16, 0, 0,255,115, 44, 41,117,200,255, /* 0x02b0 */ 127,232,150,253,255,255,139, 85,188,141, 4, 23, 1,195, 59, 93,
/* 0x02c0 */ 117,200, 86,232,152,253,255,255,131,196, 28, 57,198,116, 58,235, /* 0x02c0 */ 200,115, 39,133,219,116, 91,106, 0,106, 0,106,255,104, 18, 16,
/* 0x02d0 */ 201,131,125,224, 0,116, 50,141, 71, 3, 37,255, 15, 0, 0,131, /* 0x02d0 */ 0, 0,255,118, 44, 41, 93,200,255,117,200, 83,232,131,253,255,
/* 0x02e0 */ 248, 3,119, 37, 80, 86,232,101,253,255,255, 89, 94,235, 26,131, /* 0x02e0 */ 255,131,196, 28, 57,195,116, 58,235,197,131,125,224, 0,116, 50,
/* 0x02f0 */ 232, 4,131,248, 1,119, 18,131,123, 8, 1,117, 12,131,123, 12, /* 0x02f0 */ 141, 71, 3, 37,255, 15, 0, 0,131,248, 3,119, 37, 80, 83,232,
/* 0x0300 */ 16,117, 6,141, 67, 16,137, 69,208,255, 69,204,139, 85,232,139, /* 0x0300 */ 80,253,255,255, 89, 91,235, 26,131,232, 4,131,248, 1,119, 18,
/* 0x0310 */ 69,204, 3, 91, 4, 59, 66, 16,233,165,254,255,255,139, 69,208, /* 0x0310 */ 131,126, 8, 1,117, 12,131,126, 12, 16,117, 6,141, 70, 16,137,
/* 0x0320 */ 141,101,244, 91, 94, 95,201,195, 85,137,229, 87, 86, 83,131,236, /* 0x0320 */ 69,208,255, 69,204,139, 85,232,139, 69,204, 3,118, 4, 59, 66,
/* 0x0330 */ 32,199, 69,212, 0, 0, 0, 0,139, 85, 32,139, 69, 24,139, 93, /* 0x0330 */ 16,233,144,254,255,255,139, 69,208,141,101,244, 91, 94, 95,201,
/* 0x0340 */ 16,137, 69,216,139,117, 20,141, 66, 24,137,117,232,137, 69,240, /* 0x0340 */ 195, 85,137,229, 87, 86, 83,131,236, 32,199, 69,212, 0, 0, 0,
/* 0x0350 */ 139, 69, 28,131,232, 24,137, 69,236,139, 66, 24,139, 85,240,106, /* 0x0350 */ 0,139, 85, 32,139, 69, 24,139, 93, 16,137, 69,216,139,117, 20,
/* 0x0360 */ 0,137, 69,228,139, 69,236,137, 85,224,137, 69,220,141, 85,228, /* 0x0360 */ 141, 66, 24,137,117,232,137, 69,240,139, 69, 28,131,232, 24,137,
/* 0x0370 */ 141, 69,236, 83,232, 51,253,255,255,255,117, 12, 83, 49,210,255, /* 0x0370 */ 69,236,139, 66, 24,139, 85,240,106, 0,137, 69,228,139, 69,236,
/* 0x0380 */ 117, 8,141, 69,220,106,255, 80,137,240,232,240,253,255,255, 49, /* 0x0380 */ 137, 85,224,137, 69,220,141, 85,228,141, 69,236, 83,232, 30,253,
/* 0x0390 */ 210,137,195,141, 70, 28,131,196, 28,139, 78, 16, 57,202, 15,131, /* 0x0390 */ 255,255,255,117, 12, 83, 49,210,255,117, 8,141, 69,220,106,255,
/* 0x03a0 */ 160, 0, 0, 0,131, 56, 14, 15,133,142, 0, 0, 0, 3, 64, 8, /* 0x03a0 */ 80,137,240,232,219,253,255,255, 49,210,137,195,141, 70, 28,131,
/* 0x03b0 */ 106, 0,106, 0, 80,232,162,252,255,255,131,196, 12,133,192,137, /* 0x03b0 */ 196, 28,139, 78, 16, 57,202, 15,131,168, 0, 0, 0,131, 56, 14,
/* 0x03c0 */ 199,120, 23,106, 0,255,117,212,255,117,216, 86, 87,232,130,252, /* 0x03c0 */ 15,133,150, 0, 0, 0, 3, 64, 8,106, 0,106, 0, 80,232,141,
/* 0x03d0 */ 255,255,131,196, 20, 57, 69,216,116, 15,106,127,232,103,252,255, /* 0x03d0 */ 252,255,255,131,196, 12,133,192,137,199,120, 23,106, 0,255,117,
/* 0x03e0 */ 255,139, 91, 8,137, 93,212,235,218,129, 62,202,254,186,190,117, /* 0x03e0 */ 212,255,117,216, 86, 87,232,109,252,255,255,131,196, 20, 57, 69,
/* 0x03f0 */ 42, 15,182, 70, 7,141, 94, 8,107,192, 20,131,192, 8, 80, 86, /* 0x03f0 */ 216,116, 15,106,127,232, 82,252,255,255,139, 91, 8,137, 93,212,
/* 0x0400 */ 232, 41,252,255,255, 89, 90, 49,192,139, 86, 4, 57,208,115, 11, /* 0x0400 */ 235,218,139, 6, 61,202,254,186,190,116, 7, 61,190,186,254,202,
/* 0x0410 */ 131, 59, 7,116,204, 64,131,195, 20,235,241,106, 0,139, 85,212, /* 0x0410 */ 117, 42, 15,182, 70, 7,141, 94, 8,107,192, 20,131,192, 8, 80,
/* 0x0420 */ 106, 0,137,240,106, 0, 87,106, 0,232, 81,253,255,255, 87,137, /* 0x0420 */ 86,232, 8,252,255,255, 89, 90, 49,192,139, 86, 4, 57,208,115,
/* 0x0430 */ 195,232, 34,252,255,255,131,196, 24,235, 9, 3, 64, 4, 66,233, /* 0x0430 */ 11,131, 59, 7,116,196, 64,131,195, 20,235,241,106, 0,139, 85,
/* 0x0440 */ 88,255,255,255,141,101,244,137,216, 91, 94, 95,201,195 /* 0x0440 */ 212,106, 0,137,240,106, 0, 87,106, 0,232, 52,253,255,255, 87,
/* 0x0450 */ 137,195,232, 5,252,255,255,131,196, 24,235, 9, 3, 64, 4, 66,
/* 0x0460 */ 233, 80,255,255,255,141,101,244,137,216, 91, 94, 95,201,195
}; };

View File

@ -107,6 +107,8 @@ sysgo:
.byte 0x0f, 0x34 # sysenter .byte 0x0f, 0x34 # sysenter
// lazy jmps enable compression of this code // lazy jmps enable compression of this code
write: .globl write
mov al,SYS_write; jmps 2+ 0f; 0:
exit: .globl exit exit: .globl exit
mov al,SYS_exit; jmps 2+ 0f; 0: mov al,SYS_exit; jmps 2+ 0f; 0:
mprotect: .globl mprotect mprotect: .globl mprotect

View File

@ -32,6 +32,9 @@
#include "include/darwin.h" #include "include/darwin.h"
#ifndef DEBUG /*{*/
#define DEBUG 0
#endif /*}*/
/************************************************************************* /*************************************************************************
// configuration section // configuration section
@ -41,6 +44,138 @@
// it at an address different from it load address: there must be no // it at an address different from it load address: there must be no
// static data, and no string constants. // static data, and no string constants.
#if !DEBUG /*{*/
#define DPRINTF(a) /* empty: no debug drivel */
#define DEBUG_STRCON(name, value) /* empty */
#else /*}{ DEBUG */
extern int write(int, void const *, size_t);
#if 0
#include "stdarg.h"
#else
#define va_arg __builtin_va_arg
#define va_end __builtin_va_end
#define va_list __builtin_va_list
#define va_start __builtin_va_start
#endif
#if defined(__i386__) || defined(__x86_64__) /*{*/
#define PIC_STRING(value, var) \
__asm__ __volatile__ ( \
"call 0f; .asciz \"" value "\"; \
0: pop %0;" : "=r"(var) : \
)
#elif defined(__arm__) /*}{*/
#define PIC_STRING(value, var) \
__asm__ __volatile__ ( \
"mov %0,pc; b 0f; \
.asciz \"" value "\"; .balign 4; \
0: " : "=r"(var) \
)
#elif defined(__mips__) /*}{*/
#define PIC_STRING(value, var) \
__asm__ __volatile__ ( \
".set noreorder; bal 0f; move %0,$31; .set reorder; \
.asciz \"" value "\"; .balign 4; \
0: " \
: "=r"(var) : : "ra" \
)
#endif /*}*/
#define DEBUG_STRCON(name, strcon) \
static char const *name(void) { \
register char const *rv; PIC_STRING(strcon, rv); \
return rv; \
}
#ifdef __arm__ /*{*/
extern unsigned div10(unsigned);
#else /*}{*/
static unsigned
div10(unsigned x)
{
return x / 10u;
}
#endif /*}*/
static int
unsimal(unsigned x, char *ptr, int n)
{
if (10<=x) {
unsigned const q = div10(x);
x -= 10 * q;
n = unsimal(q, ptr, n);
}
ptr[n] = '0' + x;
return 1+ n;
}
static int
decimal(int x, char *ptr, int n)
{
if (x < 0) {
x = -x;
*ptr[n++] = '-';
}
return unsimal(x, ptr, n);
}
DEBUG_STRCON(STR_hex, "0123456789abcdef");
static int
heximal(unsigned long x, char *ptr, int n)
{
if (16<=x) {
n = heximal(x>>4, ptr, n);
x &= 0xf;
}
ptr[n] = STR_hex()[x];
return 1+ n;
}
#define DPRINTF(a) dprintf a
static int
dprintf(char const *fmt, ...)
{
char c;
int n= 0;
char *ptr;
char buf[20];
va_list va; va_start(va, fmt);
ptr= &buf[0];
while (0!=(c= *fmt++)) if ('%'!=c) goto literal;
else switch (c= *fmt++) {
default: {
literal:
n+= write(2, fmt-1, 1);
} break;
case 0: goto done; /* early */
case 'u': {
n+= write(2, buf, unsimal(va_arg(va, unsigned), buf, 0));
} break;
case 'd': {
n+= write(2, buf, decimal(va_arg(va, int), buf, 0));
} break;
case 'p': {
buf[0] = '0';
buf[1] = 'x';
n+= write(2, buf, heximal((unsigned long)va_arg(va, void *), buf, 2));
} break;
case 'x': {
buf[0] = '0';
buf[1] = 'x';
n+= write(2, buf, heximal(va_arg(va, int), buf, 2));
} break;
}
done:
va_end(va);
return n;
}
#endif /*}*/
/************************************************************************* /*************************************************************************
// "file" util // "file" util
@ -48,16 +183,20 @@
typedef struct { typedef struct {
size_t size; // must be first to match size[0] uncompressed size size_t size; // must be first to match size[0] uncompressed size
char *buf; void *buf;
} Extent; } Extent;
DEBUG_STRCON(STR_xread, "xread %%p(%%x %%p) %%p %%x\\n")
DEBUG_STRCON(STR_xreadfail, "xreadfail %%p(%%x %%p) %%p %%x\\n")
static void static void
xread(Extent *x, char *buf, size_t count) xread(Extent *x, void *buf, size_t count)
{ {
char *p=x->buf, *q=buf; unsigned char *p=x->buf, *q=buf;
size_t j; size_t j;
DPRINTF((STR_xread(), x, x->size, x->buf, buf, count));
if (x->size < count) { if (x->size < count) {
DPRINTF((STR_xreadfail(), x, x->size, x->buf, buf, count));
exit(127); exit(127);
} }
for (j = count; 0!=j--; ++p, ++q) { for (j = count; 0!=j--; ++p, ++q) {
@ -77,9 +216,12 @@ xread(Extent *x, char *buf, size_t count)
#define err_exit(a) goto error #define err_exit(a) goto error
#else //}{ save debugging time #else //}{ save debugging time
#define ERR_LAB /*empty*/ #define ERR_LAB /*empty*/
DEBUG_STRCON(STR_exit, "err_exit %%x\\n");
static void static void
err_exit(int a) err_exit(int a)
{ {
DPRINTF((STR_exit(), a));
(void)a; // debugging convenience (void)a; // debugging convenience
exit(127); exit(127);
} }
@ -122,6 +264,10 @@ typedef int f_expand(
const nrv_byte *, nrv_uint, const nrv_byte *, nrv_uint,
nrv_byte *, nrv_uint *, unsigned ); nrv_byte *, nrv_uint *, unsigned );
DEBUG_STRCON(STR_unpackExtent,
"unpackExtent in=%%p(%%x %%p) out=%%p(%%x %%p) %%p %%p\\n");
DEBUG_STRCON(STR_err5, "sz_cpr=%%x sz_unc=%%x xo->size=%%x\\n");
static void static void
unpackExtent( unpackExtent(
Extent *const xi, // input Extent *const xi, // input
@ -130,13 +276,15 @@ unpackExtent(
f_unfilter *f_unf f_unfilter *f_unf
) )
{ {
DPRINTF((STR_unpackExtent(),
xi, xi->size, xi->buf, xo, xo->size, xo->buf, f_decompress, f_unf));
while (xo->size) { while (xo->size) {
struct b_info h; struct b_info h;
// Note: if h.sz_unc == h.sz_cpr then the block was not // Note: if h.sz_unc == h.sz_cpr then the block was not
// compressible and is stored in its uncompressed form. // compressible and is stored in its uncompressed form.
// Read and check block sizes. // Read and check block sizes.
xread(xi, (char *)&h, sizeof(h)); xread(xi, (unsigned char *)&h, sizeof(h));
if (h.sz_unc == 0) { // uncompressed size 0 -> EOF if (h.sz_unc == 0) { // uncompressed size 0 -> EOF
if (h.sz_cpr != UPX_MAGIC_LE32) // h.sz_cpr must be h->magic if (h.sz_cpr != UPX_MAGIC_LE32) // h.sz_cpr must be h->magic
err_exit(2); err_exit(2);
@ -150,6 +298,7 @@ ERR_LAB
} }
if (h.sz_cpr > h.sz_unc if (h.sz_cpr > h.sz_unc
|| h.sz_unc > xo->size ) { || h.sz_unc > xo->size ) {
DPRINTF((STR_err5(), h.sz_cpr, h.sz_unc, xo->size));
err_exit(5); err_exit(5);
} }
// Now we have: // Now we have:
@ -178,7 +327,7 @@ ERR_LAB
} }
static void static void
upx_bzero(char *p, size_t len) upx_bzero(unsigned char *p, size_t len)
{ {
if (len) do { if (len) do {
*p++= 0; *p++= 0;
@ -208,14 +357,16 @@ typedef struct {
unsigned cpusubtype; unsigned cpusubtype;
unsigned offset; unsigned offset;
unsigned size; unsigned size;
unsigned align; /* shift count; log base 2 */ unsigned align; /* shift count (log base 2) */
} Fat_arch; } Fat_arch;
enum e8 { enum e8 {
FAT_MAGIC = 0xbebafeca // 0xcafebabe in big endian FAT_MAGIC = 0xcafebabe,
FAT_CIGAM = 0xbebafeca
}; };
enum e9 { enum e9 {
CPU_TYPE_I386 = 7, CPU_TYPE_I386 = 7,
CPU_TYPE_AMD64 = 0x01000007, CPU_TYPE_AMD64 = 0x01000007,
CPU_TYPE_ARM = 12,
CPU_TYPE_POWERPC = 0x00000012, CPU_TYPE_POWERPC = 0x00000012,
CPU_TYPE_POWERPC64 = 0x01000012 CPU_TYPE_POWERPC64 = 0x01000012
}; };
@ -230,7 +381,8 @@ typedef struct {
unsigned flags; unsigned flags;
} Mach_header; } Mach_header;
enum e0 { enum e0 {
MH_MAGIC = 0xfeedface MH_MAGIC = 0xfeedface,
MH_MAGIC64 = 1+0xfeedface
}; };
enum e2 { enum e2 {
MH_EXECUTE = 2 MH_EXECUTE = 2
@ -245,6 +397,7 @@ typedef struct {
} Mach_load_command; } Mach_load_command;
enum e4 { enum e4 {
LC_SEGMENT = 0x1, LC_SEGMENT = 0x1,
LC_SEGMENT_64 = 0x19,
LC_THREAD = 0x4, LC_THREAD = 0x4,
LC_UNIXTHREAD = 0x5, LC_UNIXTHREAD = 0x5,
LC_LOAD_DYLINKER = 0xe LC_LOAD_DYLINKER = 0xe
@ -303,18 +456,23 @@ typedef union {
#define PROT_READ 1 #define PROT_READ 1
#define PROT_WRITE 2 #define PROT_WRITE 2
#define PROT_EXEC 4 #define PROT_EXEC 4
#define MAP_ANON_FD -1 #define MAP_ANON_FD -1
// We have off_t as 32 bits, but syscalls consider off_t as 64 bits. // We have off_t as 32 bits, but syscalls consider off_t as 64 bits.
// Make the top 32 bits explicit, and pass a 0. // Make the top 32 bits explicit, and pass a 0.
extern char *mmap(char *, size_t, unsigned, unsigned, int, off_t, unsigned); extern void *mmap(void *, size_t, unsigned, unsigned, int, off_t, unsigned);
extern ssize_t pread(int, void *, size_t, off_t, unsigned); extern ssize_t pread(int, void *, size_t, off_t, unsigned);
extern void bswap(void *, unsigned); extern void bswap(void *, unsigned);
DEBUG_STRCON(STR_mmap,
"mmap addr=%%p len=%%p prot=%%x flags=%%x fd=%%d off=%%p\\n");
DEBUG_STRCON(STR_do_xmap,
"do_xmap fdi=%%x mhdr=%%p xi=%%p(%%x %%p) f_unf=%%p\\n")
static Mach_i386_thread_state const * static Mach_i386_thread_state const *
do_xmap( do_xmap(
Mach_header const *const mhdr, Mach_header const *const mhdr,
off_t fat_offset, off_t const fat_offset,
Extent *const xi, Extent *const xi,
int const fdi, int const fdi,
Mach_header **mhdrpp, Mach_header **mhdrpp,
@ -326,24 +484,33 @@ do_xmap(
Mach_i386_thread_state const *entry = 0; Mach_i386_thread_state const *entry = 0;
unsigned j; unsigned j;
DPRINTF((STR_do_xmap(),
fdi, mhdr, xi, (xi? xi->size: 0), (xi? xi->buf: 0), f_unf));
for ( j=0; j < mhdr->ncmds; ++j, for ( j=0; j < mhdr->ncmds; ++j,
(sc = (Mach_segment_command const *)(sc->cmdsize + (char const *)sc)) (sc = (Mach_segment_command const *)(sc->cmdsize + (void const *)sc))
) if (LC_SEGMENT==sc->cmd) { ) if (LC_SEGMENT==sc->cmd && sc->vmsize!=0) {
Extent xo; Extent xo;
size_t mlen = xo.size = sc->filesize; size_t mlen = xo.size = sc->filesize;
char *addr = xo.buf = (char *)sc->vmaddr; unsigned char *addr = xo.buf = (unsigned char *)sc->vmaddr;
char *haddr = sc->vmsize + addr; unsigned char *haddr = sc->vmsize + addr;
size_t frag = (int)addr &~ PAGE_MASK; size_t frag = (int)addr &~ PAGE_MASK;
addr -= frag; addr -= frag;
mlen += frag; mlen += frag;
// Decompressor can overrun the destination by 3 bytes. [i386 only] if (0!=mlen) {
if (0!=mlen && addr != mmap(addr, mlen + (xi ? 3 : 0), // Decompressor can overrun the destination by 3 bytes. [x86 only]
VM_PROT_READ | VM_PROT_WRITE, size_t const mlen3 = mlen + (xi ? 3 : 0);
MAP_FIXED | MAP_PRIVATE | unsigned const prot = VM_PROT_READ | VM_PROT_WRITE;
((xi || 0==sc->filesize) ? MAP_ANON : 0), unsigned const flags = MAP_FIXED | MAP_PRIVATE |
((0==sc->filesize) ? -1 : fdi), sc->fileoff + fat_offset, 0) ) { ((xi || 0==sc->filesize) ? MAP_ANON : 0);
err_exit(8); int const fdm = ((0==sc->filesize) ? MAP_ANON_FD : fdi);
off_t const offset = sc->fileoff + fat_offset;
DPRINTF((STR_mmap(), addr, mlen3, prot, flags, fdm, offset));
if (addr != mmap(addr, mlen3, prot, flags, fdm, offset, 0)) {
err_exit(8);
}
} }
if (xi && 0!=sc->filesize) { if (xi && 0!=sc->filesize) {
if (0==sc->fileoff && 0!=mhdrpp) { if (0==sc->fileoff && 0!=mhdrpp) {
@ -360,7 +527,7 @@ ERR_LAB
} }
addr += mlen + frag; /* page boundary on hi end */ addr += mlen + frag; /* page boundary on hi end */
if (addr < haddr) { // need pages for .bss if (addr < haddr) { // need pages for .bss
if (addr != mmap(addr, haddr - addr, sc->initprot, if (0!=addr && addr != mmap(addr, haddr - addr, sc->initprot,
MAP_FIXED | MAP_PRIVATE | MAP_ANON, MAP_ANON_FD, 0, 0 ) ) { MAP_FIXED | MAP_PRIVATE | MAP_ANON, MAP_ANON_FD, 0, 0 ) ) {
err_exit(9); err_exit(9);
} }
@ -388,6 +555,10 @@ ERR_LAB
// //
**************************************************************************/ **************************************************************************/
DEBUG_STRCON(STR_upx_main,
"upx_main szc=%%x f_dec=%%p f_unf=%%p "
" xo=%%p(%%x %%p) xi=%%p(%%x %%p) mhdrpp=%%p\\n")
Mach_i386_thread_state const * Mach_i386_thread_state const *
upx_main( upx_main(
Mach_header **const mhdrpp, // Out: *mhdrpp= &real Mach_header Mach_header **const mhdrpp, // Out: *mhdrpp= &real Mach_header
@ -402,23 +573,27 @@ upx_main(
Mach_i386_thread_state const *entry; Mach_i386_thread_state const *entry;
off_t fat_offset = 0; off_t fat_offset = 0;
Extent xi, xo, xi0; Extent xi, xo, xi0;
xi.buf = CONST_CAST(char *, 1+ (struct p_info const *)(1+ li)); // &b_info xi.buf = CONST_CAST(unsigned char *, 1+ (struct p_info const *)(1+ li)); // &b_info
xi.size = sz_compressed - (sizeof(struct l_info) + sizeof(struct p_info)); xi.size = sz_compressed - (sizeof(struct l_info) + sizeof(struct p_info));
xo.buf = (char *)mhdr; xo.buf = (unsigned char *)mhdr;
xo.size = ((struct b_info const *)xi.buf)->sz_unc; xo.size = ((struct b_info const *)(void const *)xi.buf)->sz_unc;
xi0 = xi; xi0 = xi;
DPRINTF((STR_upx_main(),
sz_compressed, f_decompress, f_unf, &xo, xo.size, xo.buf,
&xi, xi.size, xi.buf, mhdrpp));
// Uncompress Macho headers // Uncompress Macho headers
unpackExtent(&xi, &xo, f_decompress, 0); // never filtered? unpackExtent(&xi, &xo, f_decompress, 0); // never filtered?
entry = do_xmap(mhdr, fat_offset, &xi0, -1, mhdrpp, f_decompress, f_unf); entry = do_xmap(mhdr, fat_offset, &xi0, MAP_ANON_FD, mhdrpp, f_decompress, f_unf);
{ // Map dyld dynamic loader { // Map dyld dynamic loader
Mach_load_command const *lc = (Mach_load_command const *)(1+ mhdr); Mach_load_command const *lc = (Mach_load_command const *)(1+ mhdr);
unsigned j; unsigned j;
for (j=0; j < mhdr->ncmds; ++j, for (j=0; j < mhdr->ncmds; ++j,
(lc = (Mach_load_command const *)(lc->cmdsize + (char const *)lc)) (lc = (Mach_load_command const *)(lc->cmdsize + (void const *)lc))
) if (LC_LOAD_DYLINKER==lc->cmd) { ) if (LC_LOAD_DYLINKER==lc->cmd) {
char const *const dyld_name = ((Mach_lc_str const *)(1+ lc))->offset + char const *const dyld_name = ((Mach_lc_str const *)(1+ lc))->offset +
(char const *)lc; (char const *)lc;
@ -433,6 +608,8 @@ ERR_LAB
} }
switch (mhdr->magic) { switch (mhdr->magic) {
case MH_MAGIC: break; case MH_MAGIC: break;
case MH_MAGIC64: break;
case FAT_CIGAM:
case FAT_MAGIC: { case FAT_MAGIC: {
// stupid Apple: waste code and a page fault on EVERY execve // stupid Apple: waste code and a page fault on EVERY execve
Fat_header *const fh = (Fat_header *)mhdr; Fat_header *const fh = (Fat_header *)mhdr;