i386-linux.elf-fold.S avoids mmap() into stack

modified:   stub/src/i386-linux.elf-fold.S
	modified:   ../.github/travis_testsuite_1.sh
	modified:   stub/i386-linux.elf-fold.h
	modified:   stub/tmp/i386-linux.elf-fold.map
This commit is contained in:
John Reiser
2017-06-09 14:38:08 -07:00
parent eef955a9dd
commit 2d3bd0809a
4 changed files with 83 additions and 76 deletions
+28 -28
View File
@@ -32,8 +32,8 @@
#define STUB_I386_LINUX_ELF_FOLD_SIZE 1834
#define STUB_I386_LINUX_ELF_FOLD_ADLER32 0x91a11027
#define STUB_I386_LINUX_ELF_FOLD_CRC32 0x567b6966
#define STUB_I386_LINUX_ELF_FOLD_ADLER32 0x16aa0b35
#define STUB_I386_LINUX_ELF_FOLD_CRC32 0xbcea1e58
unsigned char stub_i386_linux_elf_fold[1834] = {
/* 0x0000 */ 127, 69, 76, 70, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -44,28 +44,28 @@ unsigned char stub_i386_linux_elf_fold[1834] = {
/* 0x0050 */ 0, 16, 0, 0, 1, 0, 0, 0, 42, 7, 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 */ 88, 90,137,249,137,230,129,236, 0, 48, 0, 0,137,231, 82, 80,
/* 0x0090 */ 81, 83, 85,137,229,173,133,192,171,117,250, 87,171,173,133,192,
/* 0x00a0 */ 171,117,250, 87,173,133,192,171,165,117,249, 64,131,239, 8,185,
/* 0x00b0 */ 10, 0, 0, 0,243,171, 72,171,171, 41,125,248, 87, 86,186,255,
/* 0x00c0 */ 15, 0, 0,137,249,232, 15, 0, 0, 0, 47,112,114,111, 99, 47,
/* 0x00d0 */ 115,101,108,102, 47,101,120,101, 0, 91,184, 85, 0, 0, 0,205,
/* 0x00e0 */ 128,133,192,121, 7,137,217,184, 14, 0, 0, 0,141,116, 1,255,
/* 0x00f0 */ 145,253, 95, 79,176, 0,170,243,164,184, 32, 32, 32, 61,131,239,
/* 0x0100 */ 3,137, 7,139, 69,252,137, 56,193,239, 12, 79,193,231, 12, 87,
/* 0x0110 */ 41,201,184, 5, 0, 0, 0,205,128, 91,185, 0, 16, 0, 0,186,
/* 0x0120 */ 1, 0, 0, 0,190, 18, 0, 0, 0,151, 41,237,184,192, 0, 0,
/* 0x0130 */ 0,205,128,135,223,184, 6, 0, 0, 0,205,128, 94, 90, 1,250,
/* 0x0140 */ 131,239, 4,137,241,131,238, 4, 41,225,193,233, 2,243,165,141,
/* 0x0150 */ 103, 4,137,215,252, 89, 93, 91, 94, 89,129,236, 0, 10, 0, 0,
/* 0x0160 */ 83,139, 83, 72,141,148, 26,255, 31, 0, 0,129,226, 0,240,255,
/* 0x0170 */ 255, 82, 41,192,102,131,123, 16, 3,117, 1,146, 80,141, 4, 25,
/* 0x0180 */ 139, 24,139, 72, 4,131,193, 12,141, 84, 36, 12, 96, 71,232, 79,
/* 0x0190 */ 4, 0, 0,131,196, 36, 89, 91,129,196, 0, 10, 0, 0, 80, 79,
/* 0x01a0 */ 41,192, 60,175,175,117,252, 80, 80, 80, 80, 80, 80, 80, 80, 41,
/* 0x01b0 */ 217,176, 91,255, 39, 85, 83, 86, 87,139, 92, 36, 20,139, 76, 36,
/* 0x01c0 */ 24,139, 84, 36, 28,139,116, 36, 32,139,124, 36, 36,139,108, 36,
/* 0x01d0 */ 40,193,237, 12,184,192, 0, 0, 0,205,128, 95, 94, 91, 93,195,
/* 0x0080 */ 88, 90,137,249,137,230,129,236, 0, 16, 0, 0,137,231, 82, 80,
/* 0x0090 */ 81,106, 0, 83, 85,137,229,173,133,192,171,117,250, 87,171,173,
/* 0x00a0 */ 133,192,171,117,250, 87,173,133,192,171,165,117,249, 64,131,239,
/* 0x00b0 */ 8,185, 10, 0, 0, 0,243,171, 72,171,171, 41,125,248, 87, 86,
/* 0x00c0 */ 186,255, 15, 0, 0,137,249,232, 15, 0, 0, 0, 47,112,114,111,
/* 0x00d0 */ 99, 47,115,101,108,102, 47,101,120,101, 0, 91,184, 85, 0, 0,
/* 0x00e0 */ 0,205,128,133,192,121, 7,137,217,184, 14, 0, 0, 0,141,116,
/* 0x00f0 */ 1,255,145,253, 95, 79,176, 0,170,243,164,184, 32, 32, 32, 61,
/* 0x0100 */ 131,239, 3,137, 7,139, 69,252,137, 56,131,231,252, 41,201,184,
/* 0x0110 */ 5, 0, 0, 0,205,128,137, 69, 8, 94, 90, 1,250,175,137,241,
/* 0x0120 */ 173, 41,225,193,233, 2,243,165,141,103, 4,137,215,252, 89, 93,
/* 0x0130 */ 91, 88, 94, 89,139, 83, 72,141,148, 26, 0, 16, 0, 0, 41,218,
/* 0x0140 */ 82, 83, 80,129,236, 0, 10, 0, 0, 41,192,102,131,123, 16, 3,
/* 0x0150 */ 117, 1,146, 80,141, 4, 25,139, 24,139, 72, 4,131,193, 12,141,
/* 0x0160 */ 84, 36, 12, 96, 71,232,120, 4, 0, 0, 79,129,196, 36, 10, 0,
/* 0x0170 */ 0, 89, 91, 90, 80, 82, 83, 87, 81, 41,237,137,207,190, 2, 0,
/* 0x0180 */ 0, 0,186, 1, 0, 0, 0,185, 0, 16, 0, 0, 41,219,184,192,
/* 0x0190 */ 0, 0, 0,205,128, 91,184, 6, 0, 0, 0,205,128, 95, 41,192,
/* 0x01a0 */ 60,175,175,117,252, 91, 89, 80, 80, 80, 80, 80, 80, 80, 80,176,
/* 0x01b0 */ 91,255, 39, 85, 83, 86, 87,139, 92, 36, 20,139, 76, 36, 24,139,
/* 0x01c0 */ 84, 36, 28,139,116, 36, 32,139,124, 36, 36,139,108, 36, 40,193,
/* 0x01d0 */ 237, 12,184,192, 0, 0, 0,205,128, 95, 94, 91, 93,195, 0, 0,
/* 0x01e0 */ 87, 86,137,206, 83,137,195, 57, 8,139,120, 4,115, 10,106,127,
/* 0x01f0 */ 91,106, 1, 88,205,128,235,254,133,201,116, 8,138, 7, 71,136,
/* 0x0200 */ 2, 66,226,248, 1,115, 4, 41, 51, 91, 94, 95,195, 85,137,229,
@@ -94,7 +94,7 @@ unsigned char stub_i386_linux_elf_fold[1834] = {
/* 0x0370 */ 215,115, 2,137,215,131,193, 32, 75,117,227,129,230, 0,240,255,
/* 0x0380 */ 255, 41,247,137,242,141,159,255, 15, 0, 0,129,227, 0,240,255,
/* 0x0390 */ 255,133,192,117, 22,106, 0,131,200, 34,106,255, 80,106, 0, 83,
/* 0x03a0 */ 86,232, 15,254,255,255,131,196, 24,137,194,141, 4, 26, 41,242,
/* 0x03a0 */ 86,232, 13,254,255,255,131,196, 24,137,194,141, 4, 26, 41,242,
/* 0x03b0 */ 139,117,224,137, 85,200,137, 69,240,102,131,126, 44, 0,199, 69,
/* 0x03c0 */ 196, 0, 0, 0, 0, 15,132,221, 1, 0, 0,131,125,220, 0,116,
/* 0x03d0 */ 32,139, 69,204,131, 56, 6,117, 24,139, 77,200,186, 3, 0, 0,
@@ -105,11 +105,11 @@ unsigned char stub_i386_linux_elf_fold[1834] = {
/* 0x0420 */ 137, 69,236,137, 77,192,139, 78, 20,137,198, 1,193,137, 77,188,
/* 0x0430 */ 137,193,129,225,255, 15, 0, 0, 41,206,131,125,220, 0,141, 60,
/* 0x0440 */ 10,116, 63,106, 0,139, 69,192,106,255,106, 50,131,200, 2, 80,
/* 0x0450 */ 141, 71, 3, 80, 86,232, 91,253,255,255,131,196, 24, 57,198, 15,
/* 0x0450 */ 141, 71, 3, 80, 86,232, 89,253,255,255,131,196, 24, 57,198, 15,
/* 0x0460 */ 133,221, 0, 0, 0,128,227, 4,139, 69,208,117, 2, 49,192, 80,
/* 0x0470 */ 139, 69,220,255,117,228,141, 85,232,232,143,253,255,255, 88, 90,
/* 0x0480 */ 235, 35,139, 93,204,139, 67, 4, 41,200, 80,255,117,228,106, 18,
/* 0x0490 */ 255,117,192, 87, 86,232, 27,253,255,255,131,196, 24, 57,198, 15,
/* 0x0490 */ 255,117,192, 87, 86,232, 25,253,255,255,131,196, 24, 57,198, 15,
/* 0x04a0 */ 133,157, 0, 0, 0,137,248,247,216, 37,255, 15, 0, 0,246, 69,
/* 0x04b0 */ 192, 2,137, 69,184,116, 18,131,125,184, 0,141, 4, 62,116, 9,
/* 0x04c0 */ 139, 77,184,198, 0, 0, 64,226,250,131,125,220, 0,116,125,139,
@@ -122,7 +122,7 @@ unsigned char stub_i386_linux_elf_fold[1834] = {
/* 0x0530 */ 255,255,137,243,137,249,139, 85,192,106,125, 88,205,128,133,192,
/* 0x0540 */ 116, 10,106,127, 91,106, 1, 88,205,128,235,254,139, 85,184,141,
/* 0x0550 */ 4, 23,141, 28, 6, 59, 93,188,115, 30,106, 0,106,255,106, 50,
/* 0x0560 */ 255,117,192, 41, 93,188,255,117,188, 83,232, 70,252,255,255,131,
/* 0x0560 */ 255,117,192, 41, 93,188,255,117,188, 83,232, 68,252,255,255,131,
/* 0x0570 */ 196, 24, 57,195,116, 27,235,202,131,125,220, 0,116, 19,141, 79,
/* 0x0580 */ 3,129,225,255, 15, 0, 0,131,249, 3,119, 5,106, 91, 88,205,
/* 0x0590 */ 128,139, 77,224,255, 69,196, 15,183, 65, 44,131, 69,204, 32, 57,
+47 -40
View File
@@ -76,21 +76,22 @@ fold_begin:
mov ecx,edi // total length of compressed data
mov esi,esp // argv
sub esp,2*PAGE_SIZE + PATH_MAX
sub esp,PATH_MAX
mov edi,esp
push edx // argc
push eax // O_BINFO
push ecx // total length of compressed data
push 0 // space for fd
push ebx // &Elf32_Ehdr
push ebp // f_exp
mov ebp,esp // frame: f_exp,&Elf32_Ehdr,tot_len,O_BINFO,argc
mov ebp,esp // frame: f_exp,&Elf32_Ehdr,0,tot_len,O_BINFO,argc
0:
lodsd; test %eax,%eax; stosd; jne 0b // argv
push edi // &new_env[0]; f_exp,&Elf32_Ehdr,tot_len,O_BINFO,argc
push edi // &new_env[0]; f_exp,&Elf32_Ehdr,0,tot_len,O_BINFO,argc
stosd // space for new_env[0]
0:
lodsd; test %eax,%eax; stosd; jne 0b // env
push edi // &old_auxv,&new_env[0]; f_exp,&Elf32_Ehdr,tot_len,O_BINFO,argc
push edi // &old_auxv,&new_env[0]; f_exp,&Elf32_Ehdr,0,tot_len,O_BINFO,argc
0:
lodsd; test %eax,%eax; stosd; movsd; jne 0b // auxv
@@ -99,8 +100,8 @@ fold_begin:
mov ecx,5*2; rep stosd // 5 extra slots
dec eax; stosd; stosd // {AT_IGNORE}
sub [-2*4 + ebp],edi // -len_aux
push edi // &new_aux[N],-len_aux,&new_env[0]; f_exp,&Elf32_Ehdr,tot_len,O_BINFO,argc
push esi // &strings,&new_aux[N],-len_aux,&new_env[0]; f_exp,&Elf32_Ehdr,tot_len,O_BINFO,argc
push edi // &new_aux[N],-len_aux,&new_env[0]; f_exp,&Elf32_Ehdr,0,tot_len,O_BINFO,argc
push esi // &strings,&new_aux[N],-len_aux,&new_env[0]; f_exp,&Elf32_Ehdr,0,tot_len,O_BINFO,argc
mov edx,-1+ PATH_MAX // buflen
mov ecx,edi // buffer
@@ -117,37 +118,26 @@ fold_begin:
xchg ecx,eax // ecx= byte count
std
pop edi; dec edi // abuts old strings; &new_aux[N],-len_aux,&new_env[0]; f_exp,&Elf32_Ehdr,tot_len,O_BINFO,argc
pop edi; dec edi // abuts old strings; &new_aux[N],-len_aux,&new_env[0]; f_exp,&Elf32_Ehdr,0,tot_len,O_BINFO,argc
mov al,0; stosb // terminate
rep movsb // slide up
mov eax, 0+ ('='<<24)|(' '<<16)|(' '<<8)|(' '<<0) # env var name
sub edi,3; mov [edi],eax
mov eax,[-1*4 + ebp]; mov [eax],edi // new_env[0]
shr edi,12; dec edi; shl edi,12
push edi // &page,&new_aux[N],-len_aux,&new_env[0]; f_exp,&Elf32_Ehdr,tot_len,O_BINFO,argc
and edi,~3 // word align
sub ecx,ecx // O_RDONLY
// mov ebx,ebx // name
mov eax,__NR_open; int 0x80
mov [2*4 + ebp],eax // fd for later mmap
pop ebx // &page; &new_aux[N],-len_aux,&new_env[0]; f_exp,&Elf32_Ehdr,tot_len,O_BINFO,argc
mov ecx,PAGE_SIZE
mov edx,PROT_READ
mov esi,MAP_PRIVATE|MAP_FIXED
xchg eax,edi // fd
sub ebp,ebp // 0 block in file
mov eax,__NR_mmap; int 0x80
xchg edi,ebx // ebx= fd; edi= &page
mov eax,__NR_close; int 0x80
pop esi // &new_aux[N]; -len_aux,&new_env[0]; f_exp,&Elf32_Ehdr,tot_len,O_BINFO,argc
pop edx // -len_aux; &new_env[0]; f_exp,&Elf32_Ehdr,tot_len,O_BINFO,argc
pop esi // &new_aux[N]; -len_aux,&new_env[0]; f_exp,&Elf32_Ehdr,fd,tot_len,O_BINFO,argc
pop edx // -len_aux; &new_env[0]; f_exp,&Elf32_Ehdr,fd,tot_len,O_BINFO,argc
add edx,edi // edx= &final_aux[0]
sub edi,4
scasd // edi -= 4
mov ecx,esi
sub esi,4
lodsd // esi -= 4
sub ecx,esp
shr ecx,2
rep movsd
@@ -158,23 +148,21 @@ fold_begin:
pop ecx // toss &new_env[0]
pop ebp // f_exp
pop ebx // &Elf32_Ehdr
pop eax // fd
pop esi // tot_len
pop ecx // O_BINFO
// stack is back to original state: argc,argv,0,env,0,aux,0,strings,0
mov edx, [p_memsz + szElf32_Ehdr + ebx] // phdr[0].p_memsz
lea edx, [ PAGE_SIZE + edx + ebx] // 1 page for unfold
sub edx,ebx; push edx // length
push ebx // start of unmap region (&Elf32_Ehdr of this stub)
push eax // fd
#define OVERHEAD 2048
#define MAX_ELF_HDR 512
sub esp, MAX_ELF_HDR + OVERHEAD // alloca
push ebx // start of unmap region (&Elf32_Ehdr of this stub)
// Cannot pre-round .p_memsz because kernel requires PF_W to setup .bss,
// but strict SELinux (or PaX, grsecurity) prohibits PF_W with PF_X.
mov edx, [p_memsz + szElf32_Ehdr + ebx] // phdr[0].p_memsz
lea edx, [-1 + 2*PAGE_SIZE + edx + ebx] // 1 page for round, 1 for unfold
and edx, 0-PAGE_SIZE
push edx // end of unmap region
sub eax, eax // 0
cmp word ptr [e_type + ebx], ET_DYN
jne L53
@@ -191,13 +179,30 @@ L53:
inc edi // swap with above 'pusha' to inhibit auxv_up for PT_INTERP
.extern upx_main
call upx_main // returns entry address
add esp, (8 +1)*4 // remove 8 params from pusha, also dynbase
pop ecx // end of unmap region
pop ebx // start of unmap region (&Elf32_Ehdr of this stub)
add esp, MAX_ELF_HDR + OVERHEAD // un-alloca
push eax // save entry address
dec edi
add esp, (8 +1)*4 + MAX_ELF_HDR + OVERHEAD // 8 params, dynbase, un-alloca
pop ecx // fd
pop ebx // base to unmap
pop edx // length
dec edi // auxv table
push eax // entry address
push edx // length
push ebx // base to unmap
push edi // auxv
push ecx // fd, auxv, unmap, length, entry
sub ebp,ebp // 0 block in file
mov edi,ecx // fd
mov esi,MAP_PRIVATE
mov edx,PROT_READ
mov ecx,PAGE_SIZE
sub ebx,ebx // 0 ==> Linux chooses page frame
mov eax,__NR_mmap; int 0x80
pop ebx // fd; auxv, base, length, entry
mov eax,__NR_close; int 0x80
pop edi // auxv table
sub eax,eax // 0, also AT_NULL
.byte 0x3c // "cmpb al, byte ..." like "jmp 1+L60" but 1 byte shorter
L60:
@@ -205,6 +210,8 @@ L60:
scasd // a_type
jne L60 // not AT_NULL
// edi now points at [AT_NULL]a_un.a_ptr which contains result of make_hatch()
pop ebx // base to unmap (&Elf32_Ehdr of this stub)
pop ecx // length
push eax
push eax
@@ -215,7 +222,6 @@ L60:
push eax
push eax // 32 bytes of zeroes now on stack, ready for 'popa'
sub ecx, ebx // length to unmap
mov al, __NR_munmap // eax was 0 from L60
jmp [edi] // unmap ourselves via escape hatch, then goto entry
@@ -233,6 +239,7 @@ mmap: .globl mmap // what happened to the ebx->args_on_stack method?
shr ebp,12
mov eax,__NR_mmap
int 0x80
pop edi
pop esi
pop ebx
+1 -1
View File
@@ -12,7 +12,7 @@ TARGET(elf32-i386)
.text 0x0000000000c01080 0x6ac
*(.text)
.text 0x0000000000c01080 0x160 tmp/i386-linux.elf-fold.o
0x0000000000c011b5 mmap
0x0000000000c011b3 mmap
.text 0x0000000000c011e0 0x54a tmp/i386-linux.elf-main.o
0x0000000000c015e2 upx_main
*(.data)