From cdc01d9a69e0a334578a821d08c7dbe69fba9141 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Wed, 18 Jan 2017 07:42:32 -0800 Subject: [PATCH] linux.sh/i386 interpreter.e_machine must be EM_386; else execve() https://github.com/upx/upx/issues/53 modified: stub/i386-linux.elf.shell-fold.h modified: stub/src/i386-linux.elf.shell-fold.S modified: stub/src/i386-linux.elf.shell-main.c --- src/stub/i386-linux.elf.shell-fold.h | 142 ++++++++++++----------- src/stub/src/i386-linux.elf.shell-fold.S | 68 ++++++++++- src/stub/src/i386-linux.elf.shell-main.c | 7 ++ 3 files changed, 149 insertions(+), 68 deletions(-) diff --git a/src/stub/i386-linux.elf.shell-fold.h b/src/stub/i386-linux.elf.shell-fold.h index 057d5b98..44707c98 100644 --- a/src/stub/i386-linux.elf.shell-fold.h +++ b/src/stub/i386-linux.elf.shell-fold.h @@ -1,5 +1,5 @@ /* i386-linux.elf.shell-fold.h - created from i386-linux.elf.shell-fold.bin, 1198 (0x4ae) bytes + created from i386-linux.elf.shell-fold.bin, 1316 (0x524) bytes This file is part of the UPX executable compressor. @@ -31,84 +31,92 @@ */ -#define STUB_I386_LINUX_ELF_SHELL_FOLD_SIZE 1198 -#define STUB_I386_LINUX_ELF_SHELL_FOLD_ADLER32 0x3a43f85a -#define STUB_I386_LINUX_ELF_SHELL_FOLD_CRC32 0xe0556c54 +#define STUB_I386_LINUX_ELF_SHELL_FOLD_SIZE 1316 +#define STUB_I386_LINUX_ELF_SHELL_FOLD_ADLER32 0xae642600 +#define STUB_I386_LINUX_ELF_SHELL_FOLD_CRC32 0xd07b6b84 -unsigned char stub_i386_linux_elf_shell_fold[1198] = { +unsigned char stub_i386_linux_elf_shell_fold[1316] = { /* 0x0000 */ 127, 69, 76, 70, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0010 */ 2, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, /* 0x0020 */ 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 32, 0, 2, 0, 0, 0, /* 0x0030 */ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 1, -/* 0x0040 */ 0, 0, 64, 1,174, 4, 0, 0,176, 4, 0, 0, 5, 0, 0, 0, -/* 0x0050 */ 0, 16, 0, 0, 1, 0, 0, 0,174, 4, 0, 0, 0, 0, 0, 0, +/* 0x0040 */ 0, 0, 64, 1, 36, 5, 0, 0, 36, 5, 0, 0, 5, 0, 0, 0, +/* 0x0050 */ 0, 16, 0, 0, 1, 0, 0, 0, 36, 5, 0, 0, 0, 0, 0, 0, /* 0x0060 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0070 */ 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0080 */ 137,230,129,236, 80, 1, 0, 0,137,231,173,171,173,171,133,192, /* 0x0090 */ 117,250,173,171,133,192,117,250, 87, 64,106, 82, 89,243,171, 72, /* 0x00a0 */ 171,171, 95,173,133,192,145,173,116, 15,131,249, 42,115,244,137, /* 0x00b0 */ 76,207,248,137, 68,207,252,235,234,129,236, 0, 10, 0, 0,147, -/* 0x00c0 */ 139, 10,139, 90, 4,137,198, 96,232,125, 2, 0, 0, 89, 80, 97, +/* 0x00c0 */ 139, 10,139, 90, 4,137,198, 96,232,231, 2, 0, 0, 89, 80, 97, /* 0x00d0 */ 129,196, 0, 10, 0, 0, 89, 90, 82, 65, 86,131,238, 3,102,199, /* 0x00e0 */ 6, 45, 99, 65, 86, 65, 82, 81, 87,141,188, 36, 0,245,255,255, /* 0x00f0 */ 96,137,227,137,252,185,192, 2, 0, 0, 49,192,243,171,137,220, -/* 0x0100 */ 97,195, 83,141, 92, 36, 8,106, 90, 88,205,128, 91,195, 0, 0, -/* 0x0110 */ 87, 86, 83,137,195,139,124, 36, 16, 57, 56,139,112, 4,115, 10, -/* 0x0120 */ 106,127, 91,106, 1, 88,205,128,235,254,133,255,116, 10,137,249, -/* 0x0130 */ 138, 6, 70,136, 2, 66,226,248, 1,123, 4, 41, 59, 91, 94, 95, -/* 0x0140 */ 195,133,210,137,209,116, 6,198, 0, 0, 64,226,250,195, 85, 49, -/* 0x0150 */ 201,137,229, 87, 86, 83,137,195,131,236, 52,137, 85,240,139, 69, -/* 0x0160 */ 8,137,202,137, 69,236,106, 5, 88,205,128,133,192,137, 69,232, -/* 0x0170 */ 121, 10,106,127, 91,106, 1, 88,205,128,235,254,186, 0, 2, 0, -/* 0x0180 */ 0,139, 93,232,139, 77,240,106, 3, 88,205,128, 61, 0, 2, 0, -/* 0x0190 */ 0,117,223,139, 69,240,139, 85,240, 3, 64, 28, 15,183, 90, 44, -/* 0x01a0 */ 137, 69,228, 49,192,102,131,122, 16, 3,139, 77,228, 15,149,192, -/* 0x01b0 */ 131,207,255,193,224, 4,131,192, 34, 49,210,137, 69,212,137,216, -/* 0x01c0 */ 72,120, 33,137,222,131, 57, 1,117, 20,139, 65, 8, 57,248,115, -/* 0x01d0 */ 2,137,199,139, 89, 20, 1,195, 57,218,115, 2,137,218,131,193, -/* 0x01e0 */ 32, 78,117,225,246, 69,212, 16,116, 7,137,211,106, 45, 88,205, -/* 0x01f0 */ 128,137,251,106, 0,129,227, 0,240,255,255,106,255, 41,218,255, -/* 0x0200 */ 117,212,141,130,255, 15, 0, 0,106, 7, 37, 0,240,255,255, 80, -/* 0x0210 */ 83,232,236,254,255,255,131,196, 24, 41,216,199, 69,220, 0, 0, -/* 0x0220 */ 0, 0,137, 69,224,139, 69,240,102,131,120, 44, 0, 15,132,247, -/* 0x0230 */ 0, 0, 0,139, 85,228,139, 2,131,248, 6,117, 14,139, 66, 8, -/* 0x0240 */ 139, 77,236,137, 65, 20,233,200, 0, 0, 0, 72, 15,133,193, 0, -/* 0x0250 */ 0, 0,139, 93,228,199, 69,216, 64, 98, 81,115,139, 75, 24,139, -/* 0x0260 */ 67, 8,131,225, 7,193,225, 2,137,194,211,109,216,139, 77,228, -/* 0x0270 */ 3, 83, 20,137,195,139,121, 16,129,227,255, 15, 0, 0,139, 77, -/* 0x0280 */ 224, 41,216, 1,223,131,101,216, 7, 1,202,141, 52, 8,137, 85, -/* 0x0290 */ 204,139, 85,228,139, 66, 4, 41,216, 80,255,117,232,106, 18,106, -/* 0x02a0 */ 3, 87, 86,232, 90,254,255,255,131,196, 24, 57,198,117, 48,137, -/* 0x02b0 */ 218,137,240,232,137,254,255,255,137,249,247,217,141, 4, 62,129, -/* 0x02c0 */ 225,255, 15, 0, 0,137,243,137,202,137, 77,208,232,112,254,255, -/* 0x02d0 */ 255,137,249,139, 85,216,106,125, 88,205,128,133,192,116, 10,106, -/* 0x02e0 */ 127, 91,106, 1, 88,205,128,235,254,139, 85,208,141, 4, 23,141, -/* 0x02f0 */ 28, 6, 59, 93,204,115, 28,106, 0,106,255,106, 50,255,117,216, -/* 0x0300 */ 41, 93,204,255,117,204, 83,232,246,253,255,255,131,196, 24, 57, -/* 0x0310 */ 195,117,204,139, 77,240,255, 69,220, 15,183, 65, 44,131, 69,228, -/* 0x0320 */ 32, 57, 69,220, 15,140, 9,255,255,255,139, 93,232,106, 6, 88, -/* 0x0330 */ 205,128,133,192,117,169,139, 69,240,139, 64, 24, 1, 69,224,139, -/* 0x0340 */ 69,224,141,101,244, 91, 94, 95,201,195, 85,137,229, 87, 86, 83, -/* 0x0350 */ 131,236, 36,141,117, 32,139, 69, 16,141, 93, 24,139, 85, 20,137, -/* 0x0360 */ 69,212,139, 69, 36,139,125, 8,137, 85,208, 5, 85, 80, 88, 50, -/* 0x0370 */ 137, 69,240,139, 69,240, 5, 85, 80, 88, 51,131,125, 32, 0,137, -/* 0x0380 */ 69,236, 15,132,140, 0, 0, 0,141, 85,220,137,216,106, 12,232, -/* 0x0390 */ 124,253,255,255, 88,139, 69,220,139, 77,224,133,192,117, 15,129, -/* 0x03a0 */ 249, 85, 80, 88, 33,117, 11,131, 59, 0,116,104,235, 4,133,201, -/* 0x03b0 */ 117, 10,106,127, 91,106, 1, 88,205,128,235,254, 57,193,119,242, -/* 0x03c0 */ 59, 6,119,238, 57,193,115, 45,137, 69,216,141, 69,216,255,117, -/* 0x03d0 */ 228, 80,255,118, 4, 81,255,115, 4,255, 85,212,131,196, 20,133, -/* 0x03e0 */ 192,117,207,139, 69,220, 57, 69,216,117,199,139, 69,224, 1, 67, -/* 0x03f0 */ 4, 41, 3,235, 12,139, 86, 4,137,216, 81,232, 16,253,255,255, -/* 0x0400 */ 88,139, 85,220,139, 6, 1, 86, 4, 41,208,133,192,137, 6,233, -/* 0x0410 */ 110,255,255,255,139, 69,236,139, 85,208,138, 24,139, 69,236,198, -/* 0x0420 */ 0, 0,139, 69,240, 87,232, 35,253,255,255,139, 85,208,137,198, -/* 0x0430 */ 139, 69,236,136, 24, 15,183, 66, 42,199, 71, 16, 3, 0, 0, 0, -/* 0x0440 */ 199, 71, 24, 4, 0, 0, 0,199, 71, 32, 5, 0, 0, 0,137, 71, -/* 0x0450 */ 28, 15,183, 66, 44,199, 71, 44, 0, 16, 0, 0,137,119, 68,131, -/* 0x0460 */ 194, 52,199, 71, 40, 6, 0, 0, 0,137, 71, 36,139, 69,208,199, -/* 0x0470 */ 71, 64, 9, 0, 0, 0,102,139, 88, 44, 89, 49,201,102,133,219, -/* 0x0480 */ 116, 34,131, 58, 3,117, 18,139, 66, 8,106, 0,139, 85,208,232, -/* 0x0490 */ 186,252,255,255,137,198, 88,235, 11, 65, 15,183,195,131,194, 32, -/* 0x04a0 */ 57,193,124,222,141,101,244,137,240, 91, 94, 95,201,195 +/* 0x0100 */ 97,102,131, 60, 36, 1,116, 1,195, 88, 89, 91,141, 20,140, 95, +/* 0x0110 */ 94, 93, 85,172,172,137,243,172, 60, 32,116,249, 60, 9,116,245, +/* 0x0120 */ 137,241,172, 60, 32,116, 8, 60, 9,116, 4, 60, 10,117,241,198, +/* 0x0130 */ 1, 0, 49,201, 60, 10,116, 25,172, 60, 32,116,251, 60, 9,116, +/* 0x0140 */ 247, 60, 10,116, 12,141, 78,255,172, 60, 10,117,251,198, 70,255, +/* 0x0150 */ 0, 86, 87,227, 1, 81, 85,137,225,106, 11, 88,205,128,244, 83, +/* 0x0160 */ 141, 92, 36, 8,106, 90, 88,205,128, 91,195, 0, 87, 86, 83,137, +/* 0x0170 */ 195,139,124, 36, 16, 57, 56,139,112, 4,115, 10,106,127, 91,106, +/* 0x0180 */ 1, 88,205,128,235,254,133,255,116, 10,137,249,138, 6, 70,136, +/* 0x0190 */ 2, 66,226,248, 1,123, 4, 41, 59, 91, 94, 95,195,133,210,137, +/* 0x01a0 */ 209,116, 6,198, 0, 0, 64,226,250,195, 85, 49,201,137,229, 87, +/* 0x01b0 */ 86, 83,137,195,131,236, 52,137, 85,240,139, 69, 8,137,202,137, +/* 0x01c0 */ 69,236,106, 5, 88,205,128,133,192,137, 69,232,121, 10,106,127, +/* 0x01d0 */ 91,106, 1, 88,205,128,235,254,186, 0, 2, 0, 0,139, 93,232, +/* 0x01e0 */ 139, 77,240,106, 3, 88,205,128, 61, 0, 2, 0, 0,117,223,139, +/* 0x01f0 */ 85,240,102,184, 1, 0,102,131,122, 18, 3, 15,133,171, 1, 0, +/* 0x0200 */ 0, 3, 82, 28, 49,192,139, 77,240,102,131,121, 16, 3,137, 85, +/* 0x0210 */ 228,137,209,139, 85,240, 15,149,192, 15,183, 90, 44,193,224, 4, +/* 0x0220 */ 131,192, 34,131,207,255,137, 69,212,137,216, 49,210, 72,120, 33, +/* 0x0230 */ 137,222,131, 57, 1,117, 20,139, 65, 8, 57,248,115, 2,137,199, +/* 0x0240 */ 139, 89, 20, 1,195, 57,218,115, 2,137,218,131,193, 32, 78,117, +/* 0x0250 */ 225,246, 69,212, 16,116, 7,137,211,106, 45, 88,205,128,137,251, +/* 0x0260 */ 106, 0,129,227, 0,240,255,255,106,255, 41,218,255,117,212,141, +/* 0x0270 */ 130,255, 15, 0, 0,106, 7, 37, 0,240,255,255, 80, 83,232,220, +/* 0x0280 */ 254,255,255,131,196, 24, 41,216,199, 69,220, 0, 0, 0, 0,137, +/* 0x0290 */ 69,224,139, 69,240,102,131,120, 44, 0, 15,132,247, 0, 0, 0, +/* 0x02a0 */ 139, 85,228,139, 2,131,248, 6,117, 14,139, 66, 8,139, 77,236, +/* 0x02b0 */ 137, 65, 20,233,200, 0, 0, 0, 72, 15,133,193, 0, 0, 0,139, +/* 0x02c0 */ 93,228,199, 69,216, 64, 98, 81,115,139, 75, 24,139, 67, 8,131, +/* 0x02d0 */ 225, 7,193,225, 2,137,194,211,109,216,139, 77,228, 3, 83, 20, +/* 0x02e0 */ 137,195,139,121, 16,129,227,255, 15, 0, 0,139, 77,224, 41,216, +/* 0x02f0 */ 1,223,131,101,216, 7, 1,202,141, 52, 8,137, 85,204,139, 85, +/* 0x0300 */ 228,139, 66, 4, 41,216, 80,255,117,232,106, 18,106, 3, 87, 86, +/* 0x0310 */ 232, 74,254,255,255,131,196, 24, 57,198,117, 48,137,218,137,240, +/* 0x0320 */ 232,120,254,255,255,137,249,247,217,141, 4, 62,129,225,255, 15, +/* 0x0330 */ 0, 0,137,243,137,202,137, 77,208,232, 95,254,255,255,137,249, +/* 0x0340 */ 139, 85,216,106,125, 88,205,128,133,192,116, 10,106,127, 91,106, +/* 0x0350 */ 1, 88,205,128,235,254,139, 85,208,141, 4, 23,141, 28, 6, 59, +/* 0x0360 */ 93,204,115, 28,106, 0,106,255,106, 50,255,117,216, 41, 93,204, +/* 0x0370 */ 255,117,204, 83,232,230,253,255,255,131,196, 24, 57,195,117,204, +/* 0x0380 */ 139, 77,240,255, 69,220, 15,183, 65, 44,131, 69,228, 32, 57, 69, +/* 0x0390 */ 220, 15,140, 9,255,255,255,139, 93,232,106, 6, 88,205,128,133, +/* 0x03a0 */ 192,117,169,139, 85,240,139, 69,224, 3, 66, 24,141,101,244, 91, +/* 0x03b0 */ 94, 95,201,195, 85,137,229, 87, 86, 83,131,236, 36,141,117, 32, +/* 0x03c0 */ 139, 69, 16,141, 93, 24,139, 85, 20,137, 69,212,139, 69, 36,139, +/* 0x03d0 */ 125, 8,137, 85,208, 5, 85, 80, 88, 50,137, 69,240,139, 69,240, +/* 0x03e0 */ 5, 85, 80, 88, 51,131,125, 32, 0,137, 69,236, 15,132,140, 0, +/* 0x03f0 */ 0, 0,141, 85,220,137,216,106, 12,232,110,253,255,255, 88,139, +/* 0x0400 */ 69,220,139, 77,224,133,192,117, 15,129,249, 85, 80, 88, 33,117, +/* 0x0410 */ 11,131, 59, 0,116,104,235, 4,133,201,117, 10,106,127, 91,106, +/* 0x0420 */ 1, 88,205,128,235,254, 57,193,119,242, 59, 6,119,238, 57,193, +/* 0x0430 */ 115, 45,137, 69,216,141, 69,216,255,117,228, 80,255,118, 4, 81, +/* 0x0440 */ 255,115, 4,255, 85,212,131,196, 20,133,192,117,207,139, 69,220, +/* 0x0450 */ 57, 69,216,117,199,139, 69,224, 1, 67, 4, 41, 3,235, 12,139, +/* 0x0460 */ 86, 4,137,216, 81,232, 2,253,255,255, 89,139, 85,220,139, 6, +/* 0x0470 */ 1, 86, 4, 41,208,133,192,137, 6,233,110,255,255,255,139, 69, +/* 0x0480 */ 236,139, 85,208,138, 24,139, 69,236,198, 0, 0,139, 69,240, 87, +/* 0x0490 */ 232, 21,253,255,255,137,198,139, 69,236,131,254, 1,136, 24,184, +/* 0x04a0 */ 1, 0, 0, 0, 90,116,117,235, 18,139, 66, 8,106, 0,139, 85, +/* 0x04b0 */ 208,232,244,252,255,255,137,198, 88,235, 95,139, 85,208, 49,201, +/* 0x04c0 */ 199, 71, 16, 3, 0, 0, 0, 15,183, 66, 42,199, 71, 24, 4, 0, +/* 0x04d0 */ 0, 0,199, 71, 32, 5, 0, 0, 0,199, 71, 40, 6, 0, 0, 0, +/* 0x04e0 */ 137, 71, 28, 15,183, 66, 44,199, 71, 44, 0, 16, 0, 0,137,119, +/* 0x04f0 */ 68,131,194, 52,199, 71, 64, 9, 0, 0, 0,137, 71, 36,139, 69, +/* 0x0500 */ 208,102,139, 88, 44,102,133,219,116, 16,131, 58, 3,116,154, 65, +/* 0x0510 */ 15,183,195,131,194, 32, 57,193,124,240,137,240,141,101,244, 91, +/* 0x0520 */ 94, 95,201,195 }; diff --git a/src/stub/src/i386-linux.elf.shell-fold.S b/src/stub/src/i386-linux.elf.shell-fold.S index 5f941667..90a35a68 100644 --- a/src/stub/src/i386-linux.elf.shell-fold.S +++ b/src/stub/src/i386-linux.elf.shell-fold.S @@ -158,8 +158,75 @@ L40: // on the stack. So, we would have to dirty a page of the shell // or of /lib/ld-linux.so. It's simpler just to omit the unmapping. popa + cmpw [esp], 1 + je must_execve // 1==e_entry ret +#define __NR_execve 11 +must_execve: // when interpreter is not EM_386 (such as "#!/bin/sh" on amd64) + pop eax // toss the 1 + pop ecx // argc + pop ebx // filename + lea edx, [esp + 4*ecx] // edx= envp (== arg3 for execve) + pop edi // "-c" + pop esi // text of script + pop ebp // filename + push ebp // filename + + lodsb // '#' + lodsb // '!' +pre_shel: + mov ebx, esi // ebx= assumed &shell (== arg1 for execve) + lodsb + cmp al, ' ' + je pre_shel + cmp al, '\t' + je pre_shel +shel_find: + mov ecx, esi // assumed &terminator + lodsb + cmp al, ' ' + je end_shell + cmp al, '\t' + je end_shell + cmp al, '\n' + jne shel_find +end_shell: + movb [ecx], 0 // null-terminate name of shell + xor ecx, ecx // assume no optional-arg + cmp al, '\n' // re-check + je no_opt_arg + +// "#! interpreter [optional-arg]\nscript" +// ==> interpreter [optional-arg] "-c" script filename arg... +pre_opt: + lodsb + cmp al, ' ' + je pre_opt + cmp al, '\t' + je pre_opt + cmp al,'\n' + je no_opt_arg + lea ecx, [esi -1] // &optional-arg +opt_term: + lodsb + cmp al,'\n' + jne opt_term + movb [esi -1], 0 // null-terminate optional-arg +no_opt_arg: + push esi // &command + push edi // "-c" + jecxz 0f + push ecx // optional-arg +0: + push ebp // argv[0] = filename (replaces shell name) + mov ecx, esp // ecx= argv (== arg2 for execve) + + push __NR_execve + pop eax + int 0x80 + hlt + #define __NR_mmap 90 mmap: .globl mmap @@ -171,7 +238,6 @@ mmap: .globl mmap pop ebx ret - .balign 4,0 /* vim:set ts=8 sw=8 et: */ diff --git a/src/stub/src/i386-linux.elf.shell-main.c b/src/stub/src/i386-linux.elf.shell-main.c index 26b827c4..0ac7e92c 100644 --- a/src/stub/src/i386-linux.elf.shell-main.c +++ b/src/stub/src/i386-linux.elf.shell-main.c @@ -229,6 +229,10 @@ xfind_pages(unsigned mflags, Elf32_Phdr const *phdr, int phnum) static Elf32_Addr // entry address do_xmap(int const fdi, Elf32_Ehdr const *const ehdr, Elf32_auxv_t *const av) { +#define EM_386 3 /* Intel 80386 */ + if (EM_386 != ehdr->e_machine) { + return 1; // not an i386 executable! + } Elf32_Phdr const *phdr = (Elf32_Phdr const *) (ehdr->e_phoff + (char const *)ehdr); unsigned long const reloc = xfind_pages( @@ -330,6 +334,9 @@ void *upx_main( char const c = *efn; *efn = 0; // terminator entry = getexec(fn, ehdr, av); *efn = c; // replace terminator character + if (1==entry) { // must execve, such as /bin/sh is amd64 + return (void *)entry; + } // av[AT_PHDR -1].a_un.a_val is set again by do_xmap if PT_PHDR is present. av[AT_PHDR -1].a_type = AT_PHDR ; // av[AT_PHDR-1].a_un.a_val is set by do_xmap