Ubuntu 执行某些x64二进制文件时出现execve ENOMEM(无法分配内存)错误
当我在ubuntu 17.10中执行一些静态链接的二进制文件时, 其他二进制文件也可以,但一些特定的二进制文件是个问题Ubuntu 执行某些x64二进制文件时出现execve ENOMEM(无法分配内存)错误,ubuntu,binary,execve,Ubuntu,Binary,Execve,当我在ubuntu 17.10中执行一些静态链接的二进制文件时, 其他二进制文件也可以,但一些特定的二进制文件是个问题 gdb-peda$ x/15i 0x4000f0 0x4000f0: push 0x400105 0x4000f5: push 0x0 0x4000f7: xor rax,rax 0x4000fa: mov edx,0x10000 0x4000ff: mov rsi,rsp 0x4001
gdb-peda$ x/15i 0x4000f0
0x4000f0: push 0x400105
0x4000f5: push 0x0
0x4000f7: xor rax,rax
0x4000fa: mov edx,0x10000
0x4000ff: mov rsi,rsp
0x400102: xor rdi,rdi
0x400105: syscall
0x400107: mov eax,0x1
0x40010c: mov edx,0x1000
0x400111: pop rsi
0x400112: mov edi,0x1
0x400117: syscall
0x400119: mov eax,0x3c
0x40011e: ret
所有代码都类似于上面的代码。
如果运行此二进制文件,则会得到以下错误语句:
root@ubuntu:/home/hitcon/Desktop# ./biglittle
Segmentation fault
我用strace追踪它因为这个二进制是静态链接的,
我知道了
root@ubuntu:/home/hitcon/Desktop# strace -fFi ./biglittle
[00007f9eaed12fa7] execve("./biglittle", ["./biglittle"], [/* 53 vars */]) = -1 ENOMEM (Cannot allocate memory)
[00007f9eaed12fa7] --- SIGSEGV {si_signo=SIGSEGV, si_code=SI_KERNEL, si_addr=NULL} ---
[????????????????] +++ killed by SIGSEGV +++
Segmentation fault (core dumped)
有人能给我一些建议来修复它吗?我在一个特殊的二进制文件上使用了完全相同的
strace
。让我们命名一个比二进制文件更简单的foo.elf
在docker中运行时,在流控制到达elf入口点之前,在内核空间中运行foo.elf
segfaults*。正如您所展示的:execve
返回ENOMEM,然后strace
进程本身通过si_code=si_内核
接收奇怪的SIGSEGV
*更准确地说,segfaults不是由foo.elf
进程引起的(该进程甚至从未开始运行),而是由其post-fork()父进程获得SIGSEGV
但是,foo.elf
在主机系统上运行良好
令人费解
这就是我在我的案例中发现的。My
foo.elf
可执行文件是静态链接的:
⚓ file foo.elf
foo.elf: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), statically linked, stripped
-请参阅,没有INTERP
部分。与基线动态可执行文件比较:
⚓ readelf --segments /bin/ls
Elf file type is EXEC (Executable file)
Entry point 0x404b48
There are 9 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040
0x00000000000001f8 0x00000000000001f8 R E 8
INTERP 0x0000000000000238 0x0000000000400238 0x0000000000400238
0x000000000000001c 0x000000000000001c R 1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x00000000000193fc 0x00000000000193fc R E 200000
LOAD 0x000000000001a328 0x000000000061a328 0x000000000061a328
0x00000000000012d8 0x0000000000001ff8 RW 200000
DYNAMIC 0x000000000001ada8 0x000000000061ada8 0x000000000061ada8
0x0000000000000200 0x0000000000000200 RW 8
NOTE 0x0000000000000254 0x0000000000400254 0x0000000000400254
0x0000000000000044 0x0000000000000044 R 4
GNU_EH_FRAME 0x0000000000016650 0x0000000000416650 0x0000000000416650
0x0000000000000744 0x0000000000000744 R 4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 10
GNU_RELRO 0x000000000001a328 0x000000000061a328 0x000000000061a328
0x0000000000000cd8 0x0000000000000cd8 R 1
Section to Segment mapping:
Segment Sections...
00
01 .interp
[...]
这个很好用。在docker或其他情况下,无故障。呜呼,难题解决了!希望这对其他人有所帮助:)我在一个特殊的二进制文件上使用了完全相同的
strace
。让我们命名一个比二进制文件更简单的foo.elf
在docker中运行时,在流控制到达elf入口点之前,在内核空间中运行foo.elf
segfaults*。正如您所展示的:execve
返回ENOMEM,然后strace
进程本身通过si_code=si_内核
接收奇怪的SIGSEGV
*更准确地说,segfaults不是由foo.elf
进程引起的(该进程甚至从未开始运行),而是由其post-fork()父进程获得SIGSEGV
但是,foo.elf
在主机系统上运行良好
令人费解
这就是我在我的案例中发现的。My
foo.elf
可执行文件是静态链接的:
⚓ file foo.elf
foo.elf: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), statically linked, stripped
-请参阅,没有INTERP
部分。与基线动态可执行文件比较:
⚓ readelf --segments /bin/ls
Elf file type is EXEC (Executable file)
Entry point 0x404b48
There are 9 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040
0x00000000000001f8 0x00000000000001f8 R E 8
INTERP 0x0000000000000238 0x0000000000400238 0x0000000000400238
0x000000000000001c 0x000000000000001c R 1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x00000000000193fc 0x00000000000193fc R E 200000
LOAD 0x000000000001a328 0x000000000061a328 0x000000000061a328
0x00000000000012d8 0x0000000000001ff8 RW 200000
DYNAMIC 0x000000000001ada8 0x000000000061ada8 0x000000000061ada8
0x0000000000000200 0x0000000000000200 RW 8
NOTE 0x0000000000000254 0x0000000000400254 0x0000000000400254
0x0000000000000044 0x0000000000000044 R 4
GNU_EH_FRAME 0x0000000000016650 0x0000000000416650 0x0000000000416650
0x0000000000000744 0x0000000000000744 R 4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 10
GNU_RELRO 0x000000000001a328 0x000000000061a328 0x000000000061a328
0x0000000000000cd8 0x0000000000000cd8 R 1
Section to Segment mapping:
Segment Sections...
00
01 .interp
[...]
这个很好用。在docker或其他情况下,无故障。呜呼,难题解决了!希望这对其他人有所帮助:)
⚓ readelf --file-header foo.elf
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x14b5b0
Start of program headers: 64 (bytes into file)
Start of section headers: 0 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 3
Size of section headers: 64 (bytes)
Number of section headers: 0
Section header string table index: 0
foo.elf.nopie: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped