eliben / pyelftools

Parsing ELF and DWARF in Python

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

pyelftools failed to with an exception

Ruturaj4 opened this issue · comments

Failed to run pyelftools on:

I have a suspicion that it is possible that the binary is may be corrupted.

I am using following binary:

https://github.com/vusec/typearmor/blob/master/server-bins/sshd

Is there a way to circumvent this error?

Backtrace:

Traceback (most recent call last):
  File "/users/r668v698/.local/lib/python3.10/site-packages/elftools/construct/core.py", line 351, in _parse
    return self.packer.unpack(_read_stream(stream, self.length))[0]
  File "/users/r668v698/.local/lib/python3.10/site-packages/elftools/construct/core.py", line 293, in _read_stream
    raise FieldError("expected %d, found %d" % (length, len(data)))
elftools.construct.core.FieldError: expected 1, found 0

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/users/r668v698/.local/lib/python3.10/site-packages/elftools/construct/core.py", line 426, in _parse
    obj.append(self.subcon._parse(stream, context))
  File "/users/r668v698/.local/lib/python3.10/site-packages/elftools/construct/core.py", line 353, in _parse
    raise FieldError(ex)
elftools.construct.core.FieldError: expected 1, found 0

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/users/r668v698/.local/lib/python3.10/site-packages/elftools/common/utils.py", line 41, in struct_parse
    return struct.parse_stream(stream)
  File "/users/r668v698/.local/lib/python3.10/site-packages/elftools/construct/core.py", line 190, in parse_stream
    return self._parse(stream, Container())
  File "/users/r668v698/.local/lib/python3.10/site-packages/elftools/construct/core.py", line 276, in _parse
    return self._decode(self.subcon._parse(stream, context), context)
  File "/users/r668v698/.local/lib/python3.10/site-packages/elftools/construct/core.py", line 707, in _parse
    subobj = sc._parse(stream, context)
  File "/users/r668v698/.local/lib/python3.10/site-packages/elftools/construct/core.py", line 429, in _parse
    raise ArrayError("expected %d, found %d" % (count, c), ex)
elftools.construct.core.ArrayError: ('expected 118, found 80', FieldError(FieldError('expected 1, found 0')))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/panfs/panfs.ittc.ku.edu/scratch/r668v698/ghyali/ghidra_10.3.1_PUBLIC/Ghidra/Extensions/Ghidrathon/data/python/jeprunscript.py", line 31, in jep_runscript
    exec(compile(source, path, "exec"), {**globals(), **additional_globals})
  File "/volatile/zephyr/Ruturaj/pcfi/framework/ghrun/yali.py", line 356, in <module>
    main()
  File "/volatile/zephyr/Ruturaj/pcfi/framework/ghrun/yali.py", line 350, in main
    process_dwarf()
  File "/volatile/zephyr/Ruturaj/pcfi/framework/ghrun/yali.py", line 340, in process_dwarf
    fun_params = get_parameters(DIE)
  File "/volatile/zephyr/Ruturaj/pcfi/framework/ghrun/yali.py", line 156, in get_parameters
    typeDIE = child.cu.get_DIE_from_refaddr(child.cu.cu_offset\
  File "/users/r668v698/.local/lib/python3.10/site-packages/elftools/dwarf/compileunit.py", line 130, in get_DIE_from_refaddr
    return self._get_cached_DIE(refaddr)
  File "/users/r668v698/.local/lib/python3.10/site-packages/elftools/dwarf/compileunit.py", line 241, in _get_cached_DIE
    die = DIE(cu=self, stream=top_die_stream, offset=offset)
  File "/users/r668v698/.local/lib/python3.10/site-packages/elftools/dwarf/die.py", line 95, in __init__
    self._parse_DIE()
  File "/users/r668v698/.local/lib/python3.10/site-packages/elftools/dwarf/die.py", line 254, in _parse_DIE
    raw_value = struct_parse(structs.Dwarf_dw_form[form], self.stream)
  File "/users/r668v698/.local/lib/python3.10/site-packages/elftools/common/utils.py", line 43, in struct_parse
    raise ELFParseError(str(e))
elftools.common.exceptions.ELFParseError: ('expected 118, found 80', FieldError(FieldError('expected 1, found 0')))

Handling corrupt binaries is out of scope for pyelftools

Handling corrupt binaries is out of scope for pyelftools

I agree as it makes perfect sense (And, it is just my speculation that the binary might be corrupted).

However, objectdump and readelf work just fine:

$readelf -wi sshd.elf | less

Contents of the .debug_info section:

  Compilation Unit @ offset 0x0:
   Length:        0x2694 (32-bit)
   Version:       4
   Abbrev Offset: 0x0
   Pointer Size:  8
 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
    <c>   DW_AT_producer    : (indirect string, offset: 0x0): clang version 3.4 (tags/RELEASE_34/final 249356) (llvm/tags/RELEASE_34/final 249354)
    <10>   DW_AT_language    : 12       (ANSI C99)
    <12>   DW_AT_name        : (indirect string, offset: 0x55): sshd.c
    <16>   DW_AT_low_pc      : 0x0
    <1e>   DW_AT_stmt_list   : 0x0
    <22>   DW_AT_comp_dir    : (indirect string, offset: 0x5c): /home/vvdveen/src/typearmor-runtime/apps/openssh-3.5p1
 <1><26>: Abbrev Number: 2 (DW_TAG_variable)
    <27>   DW_AT_name        : (indirect string, offset: 0x93): config_file_name

The binary, and the DWARF in it, looks fine to me.

The error happens in the method CU.get_DIE_from_refaddr(), as called from get_parameters() in yali.py:156. The surrounding script is trying to follow a DIE reference. That call might be miswritten - passing a bogus DIE offset, one that causes the library to look in the wrong place. For one thing, I can tell that it treats whatever attribute contents are there as a CU-relative offset, which may not be the case.

It's yali.py that needs debugging, not pyelftools proper.

@Ruturaj4 : what's the status of this? I won't mind taking a look at yali.py, if you care to share.

@Ruturaj4 : what's the status of this? I won't mind taking a look at yali.py, if you care to share.

Yeah, I can't open source yali.py now, but I am working on some other things and don't have time to take a look at that, thanks nonetheless

If you think the issue may be closed, please do. It does not seem like a problem with pyelftools anyway.