奇怪的 ELF 二进制文件

5

我有一个奇怪的ELF二进制文件。我可以在32位linux系统上运行这个二进制文件。

但是如果我用IDA反汇编器打开这个二进制文件,IDA会提示“无效的入口点”。

readelf的结果如下:

root@meltdown-VirtualBox:/home/meltdown# readelf -S -l SimpleVM 

There are no sections in this file.

Elf file type is EXEC (Executable file)
Entry point 0xc023dc
There are 2 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x00c01000 0x00c01000 0x013c7 0x013c7 RWE 0x1000
  LOAD           0x00019c 0x0804b19c 0x0804b19c 0x00000 0x00000 RW  0x1000

这段文字中没有具体的部分名称。我认为这个二进制文件被压缩了。但是,第一个LOAD段的最后虚拟地址是0xc023c7。入口点的虚拟地址是0xc023dc,超出范围了...

有人可以告诉我发生了什么吗?

提前感谢您的帮助。

  • /proc/PID/maps is as follows (two processes are created...)

    root@meltdown-VirtualBox:/proc/3510# cat maps
    00110000-00111000 rwxp 00000000 00:00 0 
    006c0000-006c1000 r-xp 00000000 00:00 0          [vdso]
    007d2000-007d4000 rwxp 00000000 00:00 0 
    00c01000-00c02000 rwxp 00000000 08:01 3801242    /home/meltdown/SimpleVM
    00ca4000-00e43000 r-xp 00000000 08:01 17171359   /lib/i386-linux-gnu/libc-2.15.so
    00e43000-00e45000 r-xp 0019f000 08:01 17171359   /lib/i386-linux-gnu/libc-2.15.so
    00e45000-00e46000 rwxp 001a1000 08:01 17171359   /lib/i386-linux-gnu/libc-2.15.so
    00e46000-00e49000 rwxp 00000000 00:00 0 
    08048000-0804b000 r-xp 00000000 00:00 0 
    0804b000-0804c000 rwxp 00000000 00:00 0 
    b77a7000-b77c7000 r-xp 00000000 08:01 17171339   /lib/i386-linux-gnu/ld-2.15.so
    b77c7000-b77c8000 r-xp 0001f000 08:01 17171339   /lib/i386-linux-gnu/ld-2.15.so
    b77c8000-b77c9000 rwxp 00020000 08:01 17171339   /lib/i386-linux-gnu/ld-2.15.so
    bfa90000-bfab1000 rwxp 00000000 00:00 0          [stack]
    
    root@meltdown-VirtualBox:/proc/3511# cat maps
    00110000-00111000 rwxp 00000000 00:00 0 
    006c0000-006c1000 r-xp 00000000 00:00 0          [vdso]
    007d2000-007d4000 rwxp 00000000 00:00 0 
    00c01000-00c02000 rwxp 00000000 08:01 3801242    /home/meltdown/SimpleVM
    00ca4000-00e43000 r-xp 00000000 08:01 17171359   /lib/i386-linux-gnu/libc-2.15.so
    00e43000-00e45000 r-xp 0019f000 08:01 17171359   /lib/i386-linux-gnu/libc-2.15.so
    00e45000-00e46000 rwxp 001a1000 08:01 17171359   /lib/i386-linux-gnu/libc-2.15.so
    00e46000-00e49000 rwxp 00000000 00:00 0 
    08048000-0804b000 r-xp 00000000 00:00 0 
    0804b000-0804c000 rwxp 00000000 00:00 0 
    b77a7000-b77c7000 r-xp 00000000 08:01 17171339   /lib/i386-linux-gnu/ld-2.15.so
    b77c7000-b77c8000 r-xp 0001f000 08:01 17171339   /lib/i386-linux-gnu/ld-2.15.so
    b77c8000-b77c9000 rwxp 00020000 08:01 17171339   /lib/i386-linux-gnu/ld-2.15.so
    bfa90000-bfab1000 rwxp 00000000 00:00 0          [stack]
    

1
我怀疑,如果这是一个专有程序,那么它的作者想要防止它被反汇编。众所周知,内核对于二进制格式要宽容一些(它可以接受一些略微格式不规范的可执行文件,而反汇编器/调试器则不能),并且利用这个事实来防止二进制文件被逆向工程化。 - user529758
可能是文件格式与所使用的readelf可执行文件不兼容。在运行时,查看/proc/[PID]/maps文件中显示的内容或进行调试可能会很有趣。 - Chris Stratton
当我运行SimpleVM时,它会打印出"输入:"并等待键盘输入。当我输入一些内容并按下回车键时,它会打印出"错误"并终止程序。 - daehee
ldd SimpleVM 告诉我这不是一个动态链接的二进制文件。 - daehee
很明显,该程序在启动后修改了其映射(包括似乎取消映射包含入口点的页面),你应该尝试获取它开始执行前的映射列表。在这种情况下,在二进制文件上运行gdb并执行 break *0xc023dc,然后运行 run,最后执行 info proc mappings - Geoff Reedy
显示剩余3条评论
1个回答

3

可能是由于映射长度的粒度。映射的长度将会被舍入为页面大小的倍数。在我的系统上,页面大小为4k,因此映射将被舍入为4k并包含入口点。即使页面大小为1k,长度也会舍入为0x1400,足以包含入口点。如果文件足够长,则额外的字节可能来自文件而不是页面初始化。


好的,这可能不会立即导致页面错误。 但是入口点是否填充了该系统上填充的任何空页面?如果这有效地是nop,它将执行那些指令,直到运行到页面结尾;但实际上指令可能是任何东西... - Chris Stratton
@ChrisStratton 我假设文件足够大以容纳扩展长度。我将把它添加到答案中。 - Geoff Reedy
这确实是有可能的,特别是如果有人试图偷偷摸摸地依赖于特定程序加载器的行为。看看基于ELF头文件应该是什么文件大小,与实际大小相比会很有趣。 - Chris Stratton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接