angr / angr-dev

Some helper scripts to set up an environment for angr development.
BSD 2-Clause "Simplified" License
114 stars 95 forks source link

Exception has occurred: ArchNotFound - Can't find architecture info for architecture image_file_machine_unknown with '' bits and unsure endness #142

Closed ndlgiang closed 2 years ago

ndlgiang commented 2 years ago

Dear Sir / Madam,

Thank you for creating angr tool. I am using it for analyzing some binary files. However, for some "disarmed" binary, the tool throw this exception: Exception has occurred: ArchNotFound - Can't find architecture info for architecture image_file_machine_unknown with '' bits and unsure endness

I am using up-to-date angr-dev master branch.

This is the full tracelog:

File "/angr-dev/archinfo/archinfo/arch.py", line 858, in arch_from_id
    raise ArchNotFound("Can't find architecture info for architecture %s with %s bits and %s endness" % (ident, repr(bits), endness))
  File "/angr-dev/cle/cle/backends/pe/pe.py", line 40, in __init__
    self.set_arch(archinfo.arch_from_id(pefile.MACHINE_TYPE[self._pe.FILE_HEADER.Machine]))
  File "/angr-dev/cle/cle/loader.py", line 850, in _load_object_isolated
    result = backend_cls(binary, binary_stream, is_main_bin=self.main_object is None, loader=self, **options)
  File "/angr-dev/cle/cle/loader.py", line 668, in _internal_load
    obj = self._load_object_isolated(main_spec)
  File "/angr-dev/cle/cle/loader.py", line 133, in __init__
    self.initial_load_objects = self._internal_load(main_binary, *preload_libs, *force_load_libs, preloading=(main_binary, *preload_libs))
  File "/angr-dev/angr/angr/project.py", line 137, in __init__
    self.loader = cle.Loader(self.filename, concrete_target=concrete_target, **load_options)
  File "/Angr_CFG/utils/AngrHelper.py", line 18, in load_project
    p = angr.Project(f'{self.source_dir}/{project_path}', load_options={'auto_load_libs': False})

The root cause I find out is because /angr-dev/cle/cle/backends/pe/pe.py can't detect the binary file architecture.

self._pe = pefile.PE(self.binary, fast_load=True) # This line of code return self._pe.FILE_HEADER.Machine = 0 ==> image_file_machine_unknown
            self._parse_pe_non_reloc_data_directories()
            if not self.is_main_bin:
                # only cache shared libraries, the main binary will not be reused
                self._pefile_cache[self.binary] = self._pe

The binary is attached. 0a0a38fa5884a8b109bad5572b2ab2d568a6fe4621b5f86641c42f7d0d713e79.exe.zip

Could you please suggest the solution or workaround for this issue?

Thank you

rhelmot commented 2 years ago

Your file doesn't have an arch specified in its header, so you have to specify which machine it runs on:

[+] In [1]: import angr

[+] In [2]: p = angr.Project('0a0a.exe', arch='x86_64')

[+] In [3]: p.factory.block(p.entry).pp()
        _start:
40172c  push    0x402444
401731  call    0x401726
ndlgiang commented 2 years ago

Thank @rhelmot ,

I specific the param arch and it works. Just curious, do we have a way to detect the binary architecture without header?

Thank you

rhelmot commented 2 years ago

You can try using some other tool like binwalk? It is extremely uncommon for executable formats like this to not specify which architecture they're built for, so we don't have an in-house solution.

ndlgiang commented 2 years ago

Thank you for your help. Have a nice day :)