diff --git a/src/stub/i386-darwin.macho-fold.h b/src/stub/i386-darwin.macho-fold.h index f7cc820e..686f69b2 100644 --- a/src/stub/i386-darwin.macho-fold.h +++ b/src/stub/i386-darwin.macho-fold.h @@ -1,5 +1,5 @@ /* 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. @@ -31,78 +31,80 @@ */ -#define STUB_I386_DARWIN_MACHO_FOLD_SIZE 1102 -#define STUB_I386_DARWIN_MACHO_FOLD_ADLER32 0x86e50532 -#define STUB_I386_DARWIN_MACHO_FOLD_CRC32 0x703625c8 +#define STUB_I386_DARWIN_MACHO_FOLD_SIZE 1135 +#define STUB_I386_DARWIN_MACHO_FOLD_ADLER32 0x768a14b0 +#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, -/* 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, /* 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, -/* 0x0050 */ 176, 73,235, 2,176,153,235, 2,176, 6,235, 2,176, 5,235, 2, -/* 0x0060 */ 176,197,235, 2,176, 3, 15,182,192,137,225,232,213,255,255,255, -/* 0x0070 */ 115, 3,131,200,255,195,144,144, 85,137,229, 87, 86,139,125, 8, -/* 0x0080 */ 83,137,195, 57, 56,139,112, 4,115, 7,106,127,232,183,255,255, -/* 0x0090 */ 255,133,255,116, 10,137,249,138, 6, 70,136, 2, 66,226,248, 1, -/* 0x00a0 */ 123, 4, 41, 59,141,101,244, 91, 94, 95,201,195, 85,137,229, 87, -/* 0x00b0 */ 86,137,198, 83,137,211,131,236, 24,139, 69, 8,139,125, 12,137, -/* 0x00c0 */ 69,220,131, 58, 0, 15,132,172, 0, 0, 0,141, 85,228,137,240, -/* 0x00d0 */ 106, 12,232,161,255,255,255,139, 69,228, 90,133,192,139, 77,232, -/* 0x00e0 */ 117, 19,129,249, 85, 80, 88, 33,117, 15,131, 62, 0, 15,132,132, -/* 0x00f0 */ 0, 0, 0,235, 4,133,201,117, 7,106,127,232, 72,255,255,255, -/* 0x0100 */ 57,193,119,245, 59, 3,119,241, 57,193,115, 76,137, 69,224, 15, -/* 0x0110 */ 182, 69,236, 80,141, 69,224, 80,255,115, 4, 81,255,118, 4,255, -/* 0x0120 */ 85,220,131,196, 20,133,192,117,208,139, 85,224, 59, 85,228,117, -/* 0x0130 */ 200,138, 69,237,132,192,116, 22,133,255,116, 18, 15,182,192, 80, -/* 0x0140 */ 15,182, 69,238, 80, 82,255,115, 4,255,215,131,196, 16,139, 69, -/* 0x0150 */ 232, 1, 70, 4, 41, 6,235, 12,139, 83, 4, 81,137,240,232, 21, -/* 0x0160 */ 255,255,255, 88,139, 85,228,139, 3, 1, 83, 4, 41,208,133,192, -/* 0x0170 */ 137, 3,233, 78,255,255,255,141,101,244, 91, 94, 95,201,195, 85, -/* 0x0180 */ 137,229, 87, 86, 83,131,236, 48,137, 69,232,139, 69, 8,137, 85, -/* 0x0190 */ 228,139, 85, 12,199, 69,208, 0, 0, 0, 0,137, 69,224,139, 69, -/* 0x01a0 */ 20,137, 85,220,139, 85, 24,137, 69,216,139, 93,232,139, 69,232, -/* 0x01b0 */ 137, 85,212, 49,210,131,195, 28,199, 69,204, 0, 0, 0, 0, 59, -/* 0x01c0 */ 80, 16, 15,131, 85, 1, 0, 0,139, 3,131,248, 1, 15,133, 28, -/* 0x01d0 */ 1, 0, 0,139, 83, 24,139, 67, 28,139, 75, 36,137,214, 1,208, -/* 0x01e0 */ 137, 85,240,137, 69,200,137,208, 37,255, 15, 0, 0,137,207, 41, -/* 0x01f0 */ 198, 1,199,137, 77,236,116, 68,106, 0,139, 69,228, 3, 67, 32, -/* 0x0200 */ 133,201, 80,139, 69,220,117, 3,131,200,255,131,125,224, 0, 80, -/* 0x0210 */ 117, 9,133,201,184, 18, 0, 0, 0,117, 5,184, 18, 16, 0, 0, -/* 0x0220 */ 131,125,224, 0, 80,106, 3,137,248,116, 3,141, 71, 3, 80, 86, -/* 0x0230 */ 232, 43,254,255,255,131,196, 28, 57,198,117, 94,131,125,224, 0, -/* 0x0240 */ 116, 42,131,123, 36, 0,116, 36,131,123, 32, 0,117, 11,131,125, -/* 0x0250 */ 16, 0,116, 5,139, 85, 16,137, 50,255,117,212,255,117,216,141, -/* 0x0260 */ 85,236,139, 69,224,232, 66,254,255,255, 88, 90,137,248,141, 20, -/* 0x0270 */ 62,247,216, 37,255, 15, 0, 0,137, 69,196,116, 8,137,193,198, -/* 0x0280 */ 2, 0, 66,226,250,133,255,116, 24,255,115, 44, 87, 86,232,185, -/* 0x0290 */ 253,255,255,131,196, 12,133,192,116, 7,106,127,232,167,253,255, -/* 0x02a0 */ 255,139, 85,196,141, 4, 23, 1,198, 59,117,200,115, 35,106, 0, -/* 0x02b0 */ 106, 0,106,255,104, 18, 16, 0, 0,255,115, 44, 41,117,200,255, -/* 0x02c0 */ 117,200, 86,232,152,253,255,255,131,196, 28, 57,198,116, 58,235, -/* 0x02d0 */ 201,131,125,224, 0,116, 50,141, 71, 3, 37,255, 15, 0, 0,131, -/* 0x02e0 */ 248, 3,119, 37, 80, 86,232,101,253,255,255, 89, 94,235, 26,131, -/* 0x02f0 */ 232, 4,131,248, 1,119, 18,131,123, 8, 1,117, 12,131,123, 12, -/* 0x0300 */ 16,117, 6,141, 67, 16,137, 69,208,255, 69,204,139, 85,232,139, -/* 0x0310 */ 69,204, 3, 91, 4, 59, 66, 16,233,165,254,255,255,139, 69,208, -/* 0x0320 */ 141,101,244, 91, 94, 95,201,195, 85,137,229, 87, 86, 83,131,236, -/* 0x0330 */ 32,199, 69,212, 0, 0, 0, 0,139, 85, 32,139, 69, 24,139, 93, -/* 0x0340 */ 16,137, 69,216,139,117, 20,141, 66, 24,137,117,232,137, 69,240, -/* 0x0350 */ 139, 69, 28,131,232, 24,137, 69,236,139, 66, 24,139, 85,240,106, -/* 0x0360 */ 0,137, 69,228,139, 69,236,137, 85,224,137, 69,220,141, 85,228, -/* 0x0370 */ 141, 69,236, 83,232, 51,253,255,255,255,117, 12, 83, 49,210,255, -/* 0x0380 */ 117, 8,141, 69,220,106,255, 80,137,240,232,240,253,255,255, 49, -/* 0x0390 */ 210,137,195,141, 70, 28,131,196, 28,139, 78, 16, 57,202, 15,131, -/* 0x03a0 */ 160, 0, 0, 0,131, 56, 14, 15,133,142, 0, 0, 0, 3, 64, 8, -/* 0x03b0 */ 106, 0,106, 0, 80,232,162,252,255,255,131,196, 12,133,192,137, -/* 0x03c0 */ 199,120, 23,106, 0,255,117,212,255,117,216, 86, 87,232,130,252, -/* 0x03d0 */ 255,255,131,196, 20, 57, 69,216,116, 15,106,127,232,103,252,255, -/* 0x03e0 */ 255,139, 91, 8,137, 93,212,235,218,129, 62,202,254,186,190,117, -/* 0x03f0 */ 42, 15,182, 70, 7,141, 94, 8,107,192, 20,131,192, 8, 80, 86, -/* 0x0400 */ 232, 41,252,255,255, 89, 90, 49,192,139, 86, 4, 57,208,115, 11, -/* 0x0410 */ 131, 59, 7,116,204, 64,131,195, 20,235,241,106, 0,139, 85,212, -/* 0x0420 */ 106, 0,137,240,106, 0, 87,106, 0,232, 81,253,255,255, 87,137, -/* 0x0430 */ 195,232, 34,252,255,255,131,196, 24,235, 9, 3, 64, 4, 66,233, -/* 0x0440 */ 88,255,255,255,141,101,244,137,216, 91, 94, 95,201,195 +/* 0x0040 */ 64, 4,115,242,195, 90, 15, 52,176, 4,235, 2,176, 1,235, 2, +/* 0x0050 */ 176, 74,235, 2,176, 73,235, 2,176,153,235, 2,176, 6,235, 2, +/* 0x0060 */ 176, 5,235, 2,176,197,235, 2,176, 3, 15,182,192,137,225,232, +/* 0x0070 */ 209,255,255,255,115, 3,131,200,255,195,144,144, 85,137,229, 87, +/* 0x0080 */ 86,139,125, 8, 83,137,195, 57, 56,139,112, 4,115, 7,106,127, +/* 0x0090 */ 232,183,255,255,255,133,255,116, 10,137,249,138, 6, 70,136, 2, +/* 0x00a0 */ 66,226,248, 1,123, 4, 41, 59,141,101,244, 91, 94, 95,201,195, +/* 0x00b0 */ 85,137,229, 87, 86,137,198, 83,137,211,131,236, 24,139, 69, 8, +/* 0x00c0 */ 139,125, 12,137, 69,220,131, 58, 0, 15,132,172, 0, 0, 0,141, +/* 0x00d0 */ 85,228,137,240,106, 12,232,161,255,255,255,139, 69,228, 90,133, +/* 0x00e0 */ 192,139, 77,232,117, 19,129,249, 85, 80, 88, 33,117, 15,131, 62, +/* 0x00f0 */ 0, 15,132,132, 0, 0, 0,235, 4,133,201,117, 7,106,127,232, +/* 0x0100 */ 72,255,255,255, 57,193,119,245, 59, 3,119,241, 57,193,115, 76, +/* 0x0110 */ 137, 69,224, 15,182, 69,236, 80,141, 69,224, 80,255,115, 4, 81, +/* 0x0120 */ 255,118, 4,255, 85,220,131,196, 20,133,192,117,208,139, 85,224, +/* 0x0130 */ 59, 85,228,117,200,138, 69,237,132,192,116, 22,133,255,116, 18, +/* 0x0140 */ 15,182,192, 80, 15,182, 69,238, 80, 82,255,115, 4,255,215,131, +/* 0x0150 */ 196, 16,139, 69,232, 1, 70, 4, 41, 6,235, 12,139, 83, 4, 81, +/* 0x0160 */ 137,240,232, 21,255,255,255, 88,139, 85,228,139, 3, 1, 83, 4, +/* 0x0170 */ 41,208,133,192,137, 3,233, 78,255,255,255,141,101,244, 91, 94, +/* 0x0180 */ 95,201,195, 85,137,229, 87, 86, 83,131,236, 56,137, 69,232,139, +/* 0x0190 */ 69, 8,137, 85,228,139, 85, 12,199, 69,208, 0, 0, 0, 0,137, +/* 0x01a0 */ 69,224,139, 69, 20,137, 85,220,139, 85, 24,137, 69,216,139,117, +/* 0x01b0 */ 232,139, 69,232,137, 85,212, 49,210,131,198, 28,199, 69,204, 0, +/* 0x01c0 */ 0, 0, 0, 59, 80, 16, 15,131,106, 1, 0, 0,139, 6,131,248, +/* 0x01d0 */ 1, 15,133, 49, 1, 0, 0,139, 94, 28,133,219, 15,132, 38, 1, +/* 0x01e0 */ 0, 0,139, 86, 24,139, 78, 36,141, 28, 26,137,208, 37,255, 15, +/* 0x01f0 */ 0, 0,137,207,137, 93,200,137,211, 41,195, 1,199,137, 77,236, +/* 0x0200 */ 137, 85,240,116, 76,131,125,224, 0,137,125,196,116, 8,141, 71, +/* 0x0210 */ 3,137, 69,196,235, 11,133,201,199, 69,192, 18, 0, 0, 0,117, +/* 0x0220 */ 7,199, 69,192, 18, 16, 0, 0,133,201,139, 85,220,117, 3,131, +/* 0x0230 */ 202,255,139, 69,228, 3, 70, 32,106, 0, 80, 82,255,117,192,106, +/* 0x0240 */ 3,255,117,196, 83,232, 26,254,255,255,131,196, 28, 57,195,117, +/* 0x0250 */ 94,131,125,224, 0,116, 42,131,126, 36, 0,116, 36,131,126, 32, +/* 0x0260 */ 0,117, 11,131,125, 16, 0,116, 5,139, 85, 16,137, 26,255,117, +/* 0x0270 */ 212,255,117,216,141, 85,236,139, 69,224,232, 49,254,255,255, 88, +/* 0x0280 */ 90,137,248,141, 20, 59,247,216, 37,255, 15, 0, 0,137, 69,188, +/* 0x0290 */ 116, 8,137,193,198, 2, 0, 66,226,250,133,255,116, 24,255,118, +/* 0x02a0 */ 44, 87, 83,232,168,253,255,255,131,196, 12,133,192,116, 7,106, +/* 0x02b0 */ 127,232,150,253,255,255,139, 85,188,141, 4, 23, 1,195, 59, 93, +/* 0x02c0 */ 200,115, 39,133,219,116, 91,106, 0,106, 0,106,255,104, 18, 16, +/* 0x02d0 */ 0, 0,255,118, 44, 41, 93,200,255,117,200, 83,232,131,253,255, +/* 0x02e0 */ 255,131,196, 28, 57,195,116, 58,235,197,131,125,224, 0,116, 50, +/* 0x02f0 */ 141, 71, 3, 37,255, 15, 0, 0,131,248, 3,119, 37, 80, 83,232, +/* 0x0300 */ 80,253,255,255, 89, 91,235, 26,131,232, 4,131,248, 1,119, 18, +/* 0x0310 */ 131,126, 8, 1,117, 12,131,126, 12, 16,117, 6,141, 70, 16,137, +/* 0x0320 */ 69,208,255, 69,204,139, 85,232,139, 69,204, 3,118, 4, 59, 66, +/* 0x0330 */ 16,233,144,254,255,255,139, 69,208,141,101,244, 91, 94, 95,201, +/* 0x0340 */ 195, 85,137,229, 87, 86, 83,131,236, 32,199, 69,212, 0, 0, 0, +/* 0x0350 */ 0,139, 85, 32,139, 69, 24,139, 93, 16,137, 69,216,139,117, 20, +/* 0x0360 */ 141, 66, 24,137,117,232,137, 69,240,139, 69, 28,131,232, 24,137, +/* 0x0370 */ 69,236,139, 66, 24,139, 85,240,106, 0,137, 69,228,139, 69,236, +/* 0x0380 */ 137, 85,224,137, 69,220,141, 85,228,141, 69,236, 83,232, 30,253, +/* 0x0390 */ 255,255,255,117, 12, 83, 49,210,255,117, 8,141, 69,220,106,255, +/* 0x03a0 */ 80,137,240,232,219,253,255,255, 49,210,137,195,141, 70, 28,131, +/* 0x03b0 */ 196, 28,139, 78, 16, 57,202, 15,131,168, 0, 0, 0,131, 56, 14, +/* 0x03c0 */ 15,133,150, 0, 0, 0, 3, 64, 8,106, 0,106, 0, 80,232,141, +/* 0x03d0 */ 252,255,255,131,196, 12,133,192,137,199,120, 23,106, 0,255,117, +/* 0x03e0 */ 212,255,117,216, 86, 87,232,109,252,255,255,131,196, 20, 57, 69, +/* 0x03f0 */ 216,116, 15,106,127,232, 82,252,255,255,139, 91, 8,137, 93,212, +/* 0x0400 */ 235,218,139, 6, 61,202,254,186,190,116, 7, 61,190,186,254,202, +/* 0x0410 */ 117, 42, 15,182, 70, 7,141, 94, 8,107,192, 20,131,192, 8, 80, +/* 0x0420 */ 86,232, 8,252,255,255, 89, 90, 49,192,139, 86, 4, 57,208,115, +/* 0x0430 */ 11,131, 59, 7,116,196, 64,131,195, 20,235,241,106, 0,139, 85, +/* 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 }; diff --git a/src/stub/src/i386-darwin.macho-fold.S b/src/stub/src/i386-darwin.macho-fold.S index 665c658e..c1f59e37 100644 --- a/src/stub/src/i386-darwin.macho-fold.S +++ b/src/stub/src/i386-darwin.macho-fold.S @@ -107,6 +107,8 @@ sysgo: .byte 0x0f, 0x34 # sysenter // lazy jmps enable compression of this code +write: .globl write + mov al,SYS_write; jmps 2+ 0f; 0: exit: .globl exit mov al,SYS_exit; jmps 2+ 0f; 0: mprotect: .globl mprotect diff --git a/src/stub/src/i386-darwin.macho-main.c b/src/stub/src/i386-darwin.macho-main.c index 6535f644..18c20a85 100644 --- a/src/stub/src/i386-darwin.macho-main.c +++ b/src/stub/src/i386-darwin.macho-main.c @@ -32,6 +32,9 @@ #include "include/darwin.h" +#ifndef DEBUG /*{*/ +#define DEBUG 0 +#endif /*}*/ /************************************************************************* // configuration section @@ -41,6 +44,138 @@ // it at an address different from it load address: there must be no // 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 @@ -48,16 +183,20 @@ typedef struct { size_t size; // must be first to match size[0] uncompressed size - char *buf; + void *buf; } 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 -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; + DPRINTF((STR_xread(), x, x->size, x->buf, buf, count)); if (x->size < count) { + DPRINTF((STR_xreadfail(), x, x->size, x->buf, buf, count)); exit(127); } 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 #else //}{ save debugging time #define ERR_LAB /*empty*/ +DEBUG_STRCON(STR_exit, "err_exit %%x\\n"); + static void err_exit(int a) { + DPRINTF((STR_exit(), a)); (void)a; // debugging convenience exit(127); } @@ -122,6 +264,10 @@ typedef int f_expand( const nrv_byte *, nrv_uint, 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 unpackExtent( Extent *const xi, // input @@ -130,13 +276,15 @@ unpackExtent( f_unfilter *f_unf ) { + DPRINTF((STR_unpackExtent(), + xi, xi->size, xi->buf, xo, xo->size, xo->buf, f_decompress, 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)); + xread(xi, (unsigned 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); @@ -150,6 +298,7 @@ ERR_LAB } if (h.sz_cpr > h.sz_unc || h.sz_unc > xo->size ) { + DPRINTF((STR_err5(), h.sz_cpr, h.sz_unc, xo->size)); err_exit(5); } // Now we have: @@ -178,7 +327,7 @@ ERR_LAB } static void -upx_bzero(char *p, size_t len) +upx_bzero(unsigned char *p, size_t len) { if (len) do { *p++= 0; @@ -208,14 +357,16 @@ typedef struct { unsigned cpusubtype; unsigned offset; unsigned size; - unsigned align; /* shift count; log base 2 */ + unsigned align; /* shift count (log base 2) */ } Fat_arch; enum e8 { - FAT_MAGIC = 0xbebafeca // 0xcafebabe in big endian + FAT_MAGIC = 0xcafebabe, + FAT_CIGAM = 0xbebafeca }; enum e9 { CPU_TYPE_I386 = 7, CPU_TYPE_AMD64 = 0x01000007, + CPU_TYPE_ARM = 12, CPU_TYPE_POWERPC = 0x00000012, CPU_TYPE_POWERPC64 = 0x01000012 }; @@ -230,7 +381,8 @@ typedef struct { unsigned flags; } Mach_header; enum e0 { - MH_MAGIC = 0xfeedface + MH_MAGIC = 0xfeedface, + MH_MAGIC64 = 1+0xfeedface }; enum e2 { MH_EXECUTE = 2 @@ -245,6 +397,7 @@ typedef struct { } Mach_load_command; enum e4 { LC_SEGMENT = 0x1, + LC_SEGMENT_64 = 0x19, LC_THREAD = 0x4, LC_UNIXTHREAD = 0x5, LC_LOAD_DYLINKER = 0xe @@ -303,18 +456,23 @@ typedef union { #define PROT_READ 1 #define PROT_WRITE 2 #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. // 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 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 * do_xmap( Mach_header const *const mhdr, - off_t fat_offset, + off_t const fat_offset, Extent *const xi, int const fdi, Mach_header **mhdrpp, @@ -326,24 +484,33 @@ do_xmap( Mach_i386_thread_state const *entry = 0; 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, - (sc = (Mach_segment_command const *)(sc->cmdsize + (char const *)sc)) - ) if (LC_SEGMENT==sc->cmd) { + (sc = (Mach_segment_command const *)(sc->cmdsize + (void const *)sc)) + ) if (LC_SEGMENT==sc->cmd && sc->vmsize!=0) { Extent xo; size_t mlen = xo.size = sc->filesize; - char *addr = xo.buf = (char *)sc->vmaddr; - char *haddr = sc->vmsize + addr; + unsigned char *addr = xo.buf = (unsigned char *)sc->vmaddr; + unsigned char *haddr = sc->vmsize + addr; size_t frag = (int)addr &~ PAGE_MASK; addr -= frag; mlen += frag; - // Decompressor can overrun the destination by 3 bytes. [i386 only] - if (0!=mlen && addr != mmap(addr, mlen + (xi ? 3 : 0), - VM_PROT_READ | VM_PROT_WRITE, - MAP_FIXED | MAP_PRIVATE | - ((xi || 0==sc->filesize) ? MAP_ANON : 0), - ((0==sc->filesize) ? -1 : fdi), sc->fileoff + fat_offset, 0) ) { - err_exit(8); + if (0!=mlen) { + // Decompressor can overrun the destination by 3 bytes. [x86 only] + size_t const mlen3 = mlen + (xi ? 3 : 0); + unsigned const prot = VM_PROT_READ | VM_PROT_WRITE; + unsigned const flags = MAP_FIXED | MAP_PRIVATE | + ((xi || 0==sc->filesize) ? MAP_ANON : 0); + 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 (0==sc->fileoff && 0!=mhdrpp) { @@ -360,7 +527,7 @@ 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, + if (0!=addr && addr != mmap(addr, haddr - addr, sc->initprot, MAP_FIXED | MAP_PRIVATE | MAP_ANON, MAP_ANON_FD, 0, 0 ) ) { 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 * upx_main( Mach_header **const mhdrpp, // Out: *mhdrpp= &real Mach_header @@ -402,23 +573,27 @@ upx_main( Mach_i386_thread_state const *entry; off_t fat_offset = 0; 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)); - xo.buf = (char *)mhdr; - xo.size = ((struct b_info const *)xi.buf)->sz_unc; + xo.buf = (unsigned char *)mhdr; + xo.size = ((struct b_info const *)(void const *)xi.buf)->sz_unc; 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 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 Mach_load_command const *lc = (Mach_load_command const *)(1+ mhdr); unsigned 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) { char const *const dyld_name = ((Mach_lc_str const *)(1+ lc))->offset + (char const *)lc; @@ -433,6 +608,8 @@ ERR_LAB } switch (mhdr->magic) { case MH_MAGIC: break; + case MH_MAGIC64: break; + case FAT_CIGAM: case FAT_MAGIC: { // stupid Apple: waste code and a page fault on EVERY execve Fat_header *const fh = (Fat_header *)mhdr;