Giter VIP home page Giter VIP logo

zelos's Introduction

PyPI Build Status codecov Documentation Status PyPI - Python Version License: AGPL v3 Code style: black

Zelos

Zelos (Zeropoint Emulated Lightweight Operating System) is a python-based binary emulation platform. One use of zelos is to quickly assess the dynamic behavior of binaries via command-line or python scripts. All syscalls are emulated to isolate the target binary. Linux x86_64 (32- and 64-bit), ARM and MIPS binaries are supported. Unicorn provides CPU emulation.

Image

Full documentation is available here.

Installation

Use the package manager pip to install zelos.

pip install zelos

Basic Usage

Command-line

To emulate a binary with default options:

$ zelos my_binary

To view the instructions that are being executed, add the --inst flag:

$ zelos --inst my_binary

You can print only the first time each instruction is executed, rather than every execution, using --fasttrace:

$ zelos --inst --fasttrace my_binary

By default, syscalls are emitted on stdout. To write syscalls to a file instead, use the --trace_file flag:

$ zelos --trace_file path/to/file my_binary

Specify any command line arguments after the binary name:

$ zelos my_binary arg1 arg2

Programmatic

import zelos

z = zelos.Zelos("my_binary")
z.start(timeout=3)

Plugins

Zelos supports first- and third-party plugins. Some notable plugins thus far:

  • crashd crash analyzer combining execution trace, dataflow and memory sanitization.
  • overlay (ida plugin): highlights zelos execution trace in IDA with instruction-level comments added.
  • angr integration: enables symbolic execution in zelos.
  • zdbserver: remote control and debugging of emulated binaries.
  • syscall limiter: demonstrates event hooking and provides syscall-based execution and termination options.

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

Local Development Environment

First, create a new python virtual environment. This will ensure no package version conflicts arise:

$ python3 -m venv ~/.venv/zelos
$ source ~/.venv/zelos/bin/activate

Now clone the repository and change into the zelos directory:

(zelos) $ git clone [email protected]:zeropointdynamics/zelos.git
(zelos) $ cd zelos

Install an editable version of zelos into the virtual environment. This makes import zelos available, and any local changes to zelos will be effective immediately:

(zelos) $ pip install -e '.[dev]'

At this point, tests should pass and documentation should build:

(zelos) $ pytest
(zelos) $ cd docs
(zelos) $ make html

Built documentation is found in docs/_build/html/.

Install zelos pre-commit hooks to ensure code style compliance:

(zelos) $ pre-commit install

In addition to automatically running every commit, you can run them anytime with:

(zelos) $ pre-commit run --all-files

Windows Development:

Commands vary slightly on Windows:

C:\> python3 -m venv zelos_venv
C:\> zelos_venv\Scripts\activate.bat
(zelos) C:\> pip install -e .[dev]

License

AGPL v3

zelos's People

Contributors

0zp avatar kvalakuzhyzp avatar kzsnow avatar rcourt-zp avatar valakuzhyk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

zelos's Issues

Issue passing strings beginning with dash as command line arguments.

Describe the bug
You cannot pass command line flags (or strings beginning with a dash) as command line arguments to the executable. While excusable in the command line version of zelos, this is also the case when writing a script.

To Reproduce
z = Zelos("testfile", "--testarg")

Expected behavior
We could support the -- option which indicates further strings are positional arguments.

Skip rep syscall

Is your feature request related to a problem? Please describe.
Once a rep syscall over 50 times, there is no chance to "reenable syscall printing"? Do i have any option to skip only rep syscalls?

   # Disable syscall printing if lots of repetitions occur
    if (
        self._last_syscall_count <= self.rep_syscall_print_limit
        and self.rep_syscall_print_limit > 0
    ):
        rep_print_limit = self.rep_syscall_print_limit
        syscall_manager = zelos.internal_engine.zos.syscall_manager
        if sysname == self._last_syscall:
            self._last_syscall_count += 1
        else:
            self._last_syscall = sysname
            if self._last_syscall_count > rep_print_limit:
                self.logger.info(f"Syscall printing reenabled")
                syscall_manager.should_print_syscalls = True
            self._last_syscall_count = 1

        if self._last_syscall_count == rep_print_limit:
            self.logger.info(
                f"Syscall {self._last_syscall} called over "
                f"{rep_print_limit} times. No longer printing syscalls"
            )
            syscall_manager.should_print_syscalls = False

Plugin yarascan error _xref_cnts at YaraMatch

Describe the bug
I'm testing zelos with yarascan plugin that matches "Hello World" string in memory. I got this error during the test:

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/zelos/engine.py", line 593, in close
    closure()
  File "/usr/local/lib/python3.8/dist-packages/zelos/ext/plugins/yarascan/yarascan.py", line 307, in closure
    list(
  File "/usr/local/lib/python3.8/dist-packages/zelos/ext/plugins/yarascan/yarascan.py", line 378, in matches
    self._log(match.info(brief))
  File "/usr/local/lib/python3.8/dist-packages/zelos/ext/plugins/yarascan/yarascan.py", line 234, in info
    for i, s in enumerate(self.strings):
  File "/usr/local/lib/python3.8/dist-packages/zelos/ext/plugins/yarascan/yarascan.py", line 184, in strings
    self._yara_strings = [
  File "/usr/local/lib/python3.8/dist-packages/zelos/ext/plugins/yarascan/yarascan.py", line 185, in <listcomp>
    YaraString(self.region_address + s[0], s, self._xref_cnts[i])
AttributeError: 'YaraMatch' object has no attribute '_xref_cnts'

To Reproduce
Steps to reproduce the behavior:

  1. Generate test file
#include <stdio.h>

int main() {
  printf("Hello world\n");
  return 0;
}

compile gcc test.c -o run
2. Generate yara rule

rule hello_world: zelos {
  strings:
    $1 = "Hello world"
  condition:
    $1
}

(test binary file with yara has no error)
3. Run command zelos --yara_file basic_rule.yar /tmp/run
4. See error

Expected behavior
I think program should show Matched message.

Screenshots
Screenshot at 2020-11-10 07-55-32

Additional context

  • I installed zelos via pip3 sudo pip3 install zelos.

A block hook seems to execute a different number of times depending on platform

The following script exemplifies this. The value of len(blocks) on the last line will be different depending on host platform. I have found differing values on my local Windows 10 machine in WSL, the azure CI (linux), and the azure CI (windows).

from zelos import Zelos, HookType

z = Zelos("tests/data/static_elf_helloworld")

blocks = []

def block_hook(zelos, address, size):
    blocks.append(address)

z.hook_execution(HookType.EXEC.BLOCK, block_hook)

z.start()

print(len(blocks))

Error And Fix : 'NoneType' object has no attribute 'static_symbols'

Describe the bug
The type error occurred in the check of the variable.
The interpreter is assigned the empty string (“”)when runing my example. But the code uses “None Type” to check the interpreter. It will come into “IF” unexpectedly. And it will cause NoneType Error.

To Reproduce
Error:
File "\zelos_test\venv\lib\site-packages\zelos\ext\platforms\linux\parse.py", line 107, in parse
for symbol in binary.static_symbols:
AttributeError: 'NoneType' object has no attribute 'static_symbols'

Fix
Modify the file:ext\platforms\linux\parse.py
if (interpreter is not None):
to
if (interpreter is not None) and (interpreter is not ""):

XD

A short thank you note.

Hi,

I am the founder and project owner of Qiling Framework. Just incase you never heard of it. Please do pay us a visit at https://qiling.io

Just like to let you know, Qiling's memory management actually "refer/copy/use" some of your code. We did credited zelos in our code. Please refer to:

https://github.com/qilingframework/qiling/blob/dev/qiling/os/memory.py

Thank you for the excellent code and we do really wish can work together in the near future. Again, thank you very much!

sys.stdin.isatty() raise exception - ValueError: I/O operation on closed file

Describe the bug
i cannot figure out reason, zelos python script will raise exception when it works with parallel sometimes. can you please take a look?
e.g. cat test.case.list | parallel -j 5 python base_test.py {}

src/zelos/handles/base_handles.py

15:56:16:syscall_ma:ERROR_:Error in thread 7401_thread_0 (0x7401), PRI: 0, parent: None, IP: 0x409370, blocks_exec'd: 0x0, ThreadState.RUNNING while executing syscall fork Args:
Traceback (most recent call last):
File "_ctypes/callbacks.c", line 232, in 'calling callback function'
File "/home//Envs/zelos/lib/python3.7/site-packages/unicorn-1.0.2rc1-py3.7-linux-x86_64.egg/unicorn/unicorn.py", line 494, in _hook_intr_cb
cb(self, intno, data)
File "/home/
/Envs/zelos/lib/python3.7/site-packages/zelos-0.1.1.dev0-py3.7.egg/zelos/hooks.py", line 638, in interrupt_hook_wrapper
self._hook_interrupt(self._z.api, intno)
File "/home//Envs/zelos/lib/python3.7/site-packages/zelos-0.1.1.dev0-py3.7.egg/zelos/hooks.py", line 677, in _hook_interrupt
handler(zelos.process)
File "/home/
/Envs/zelos/lib/python3.7/site-packages/zelos-0.1.1.dev0-py3.7.egg/zelos/ext/platforms/linux/syscall_manager.py", line 403, in syscall_handler_wrapper
self.handle_syscall(current_process)
File "/home//Envs/zelos/lib/python3.7/site-packages/zelos-0.1.1.dev0-py3.7.egg/zelos/ext/platforms/linux/syscall_manager.py", line 415, in handle_syscall
super(MIPSSyscallManager, self).handle_syscall(*args, kwargs)
File "/home//Envs/zelos/lib/python3.7/site-packages/zelos-0.1.1.dev0-py3.7.egg/zelos/ext/platforms/linux/syscall_manager.py", line 133, in handle_syscall
status = super(LinuxSyscallManager, self).handle_syscall(process)
File "/home/
/Envs/zelos/lib/python3.7/site-packages/zelos-0.1.1.dev0-py3.7.egg/zelos/plugin/syscall_manager_base.py", line 198, in handle_syscall
raise e
File "/home/
/Envs/zelos/lib/python3.7/site-packages/zelos-0.1.1.dev0-py3.7.egg/zelos/plugin/syscall_manager_base.py", line 188, in handle_syscall
retval = sys_fn(self, process)
File "/home/
/Envs/zelos/lib/python3.7/site-packages/zelos-0.1.1.dev0-py3.7.egg/zelos/ext/platforms/linux/syscalls/syscalls.py", line 1252, in sys_fork
child_process = _new_process(sm, p)
File "/home/
/Envs/zelos/lib/python3.7/site-packages/zelos-0.1.1.dev0-py3.7.egg/zelos/ext/platforms/linux/syscalls/syscalls.py", line 1258, in _new_process
child_pid = processes.new_process()
File "/home/
/Envs/zelos/lib/python3.7/site-packages/zelos-0.1.1.dev0-py3.7.egg/zelos/processes.py", line 338, in new_process
hook(process)
File "/home/
**/Envs/zelos/lib/python3.7/site-packages/zelos-0.1.1.dev0-py3.7.egg/zelos/handles/base_handles.py", line 320, in init_handles
if not sys.stdin.isatty() and isinstance(
ValueError: I/O operation on closed file

Missing libm.so.6 causes zelos to fail

Describe the bug
A small prime generator C program that makes use of libm fails because zelos cannot open /lib/x86_64-linux-gnu/x86_64/libm.so.6

To Reproduce
Steps to reproduce the behavior:

  1. compile the attached program, 'gcc -o primes primes.c -lm'
  2. run 'zelos ./primes'
  3. See error

Expected behavior
output from the program to show instructions (see attachment 2)

Screenshots
[StdErr]: 'bytearray(b'./primes')'
[StdErr]: 'bytearray(b': ')'
[StdErr]: 'bytearray(b'error while loading shared libraries')'
[StdErr]: 'bytearray(b': ')'
[StdErr]: 'bytearray(b'libm.so.6')'
[StdErr]: 'bytearray(b': ')'
[StdErr]: 'bytearray(b'cannot open shared object file')'
[StdErr]: 'bytearray(b': ')'
[StdErr]: 'bytearray(b'Operation not permitted')'
[StdErr]: 'bytearray(b'\n')'
[main] [SYSCALL] writev ( fd=0x2 (stderr), *iov=0xff08dfe0 ("./primes: error while loading shared libraries: libm.so.6: cannot open shared object file: Operation not permitted\n"), iovcnt=0xa ) -> 73

Additional context
Attachment 2 was created when I set up a symlink to libm.so.6
Note I'm running on Mageia 6 Linux, a RH derivative.

primes.c.txt
zelos.fixed.txt

cannot emulate linux binary with C++ deps

>>> Zelos("./hard_software",linux_rootfs="x86-64,/",virtual_path=["/","/usr/lib/x86_64/"],virtual_filename=["libstdc++.so.6","libstdc++.so.6.0.30","libc.so.6"]).start()
Plugins: trace, overlay, runner, syscalllimiter, yarascan
[main] [SYSCALL] brk ( addr=0x0 ) -> 90000040
[main] [SYSCALL] openat ( dirfd=0xffffff9c, pathname=0xb229170 ("./libc.so.6"), flags=0x80000 ) -> 10
[main] [SYSCALL] read ( fd=0x10 (file), buf=0x7f000008e708, count=0x340 ) -> 340
[main] [SYSCALL] fstat ( fd=0x10 (file), statbuf=0x7f000008e5a0 ) -> 0
[main] [SYSCALL] getcwd ( buf=0xb229720, size=0x80 ) -> 10
[main] [SYSCALL] mmap ( addr=0x0, length=0x225028, prot=RX, flags=0x802, fd=0x10 (file), offset=0x0 ) -> 1000
[main] [SYSCALL] mprotect ( addr=0x6000, len=0x1ff000, prot=NONE ) -> 0
[main] [SYSCALL] mmap ( addr=0x205000, length=0x22000, prot=RW, flags=0x812, fd=0x10 (file), offset=0x4000 ) -> 205000
[main] [SYSCALL] close ( fd=0x10 (file) ) -> 0
[main] [SYSCALL] uname ( buf=0x7f000008e8e0 ) -> 0
[main] [SYSCALL] access ( pathname=0xb021082 ("/etc/ld.so.nohwcap"), mode=0x0 ) -> -1
[main] [SYSCALL] access ( pathname=0xb023dd0 ("/etc/ld.so.preload"), mode=0x4 ) -> -1
[main] [SYSCALL] openat ( dirfd=0xffffff9c, pathname=0xb021428 ("/etc/ld.so.cache"), flags=0x80000 ) -> -2
[main] [SYSCALL] openat ( dirfd=0xffffff9c, pathname=0x7f000008e270 ("/lib/x86_64-linux-gnu/tls/x86_64/libstdc++.so.6"), flags=0x80000 ) -> -2
[main] [SYSCALL] stat ( pathname=0x7f000008e270 ("/lib/x86_64-linux-gnu/tls/x86_64"), statbuf=0x7f000008e330 ) -> -1
[main] [SYSCALL] openat ( dirfd=0xffffff9c, pathname=0x7f000008e270 ("/lib/x86_64-linux-gnu/tls/libstdc++.so.6"), flags=0x80000 ) -> -2
[main] [SYSCALL] stat ( pathname=0x7f000008e270 ("/lib/x86_64-linux-gnu/tls"), statbuf=0x7f000008e330 ) -> -1
[main] [SYSCALL] openat ( dirfd=0xffffff9c, pathname=0x7f000008e270 ("/lib/x86_64-linux-gnu/x86_64/libstdc++.so.6"), flags=0x80000 ) -> -2
[main] [SYSCALL] stat ( pathname=0x7f000008e270 ("/lib/x86_64-linux-gnu/x86_64"), statbuf=0x7f000008e330 ) -> -1
[main] [SYSCALL] openat ( dirfd=0xffffff9c, pathname=0x7f000008e270 ("/lib/x86_64-linux-gnu/libstdc++.so.6"), flags=0x80000 ) -> -2
[main] [SYSCALL] stat ( pathname=0x7f000008e270 ("/lib/x86_64-linux-gnu"), statbuf=0x7f000008e330 ) -> 0
[main] [SYSCALL] openat ( dirfd=0xffffff9c, pathname=0x7f000008e270 ("/usr/lib/x86_64-linux-gnu/tls/x86_64/libstdc++.so.6"), flags=0x80000 ) -> -2
[main] [SYSCALL] stat ( pathname=0x7f000008e270 ("/usr/lib/x86_64-linux-gnu/tls/x86_64"), statbuf=0x7f000008e330 ) -> -1
[main] [SYSCALL] openat ( dirfd=0xffffff9c, pathname=0x7f000008e270 ("/usr/lib/x86_64-linux-gnu/tls/libstdc++.so.6"), flags=0x80000 ) -> -2
[main] [SYSCALL] stat ( pathname=0x7f000008e270 ("/usr/lib/x86_64-linux-gnu/tls"), statbuf=0x7f000008e330 ) -> -1
[main] [SYSCALL] openat ( dirfd=0xffffff9c, pathname=0x7f000008e270 ("/usr/lib/x86_64-linux-gnu/x86_64/libstdc++.so.6"), flags=0x80000 ) -> -2
[main] [SYSCALL] stat ( pathname=0x7f000008e270 ("/usr/lib/x86_64-linux-gnu/x86_64"), statbuf=0x7f000008e330 ) -> -1
[main] [SYSCALL] openat ( dirfd=0xffffff9c, pathname=0x7f000008e270 ("/usr/lib/x86_64-linux-gnu/libstdc++.so.6"), flags=0x80000 ) -> -2
[main] [SYSCALL] stat ( pathname=0x7f000008e270 ("/usr/lib/x86_64-linux-gnu"), statbuf=0x7f000008e330 ) -> -1
[main] [SYSCALL] openat ( dirfd=0xffffff9c, pathname=0x7f000008e270 ("/lib/tls/x86_64/libstdc++.so.6"), flags=0x80000 ) -> -2
[main] [SYSCALL] stat ( pathname=0x7f000008e270 ("/lib/tls/x86_64"), statbuf=0x7f000008e330 ) -> -1
[main] [SYSCALL] openat ( dirfd=0xffffff9c, pathname=0x7f000008e270 ("/lib/tls/libstdc++.so.6"), flags=0x80000 ) -> -2
[main] [SYSCALL] stat ( pathname=0x7f000008e270 ("/lib/tls"), statbuf=0x7f000008e330 ) -> -1
[main] [SYSCALL] openat ( dirfd=0xffffff9c, pathname=0x7f000008e270 ("/lib/x86_64/libstdc++.so.6"), flags=0x80000 ) -> -2
[main] [SYSCALL] stat ( pathname=0x7f000008e270 ("/lib/x86_64"), statbuf=0x7f000008e330 ) -> -1
[main] [SYSCALL] openat ( dirfd=0xffffff9c, pathname=0x7f000008e270 ("/lib/libstdc++.so.6"), flags=0x80000 ) -> -2
[main] [SYSCALL] stat ( pathname=0x7f000008e270 ("/lib"), statbuf=0x7f000008e330 ) -> 0
[main] [SYSCALL] openat ( dirfd=0xffffff9c, pathname=0x7f000008e270 ("/usr/lib/tls/x86_64/libstdc++.so.6"), flags=0x80000 ) -> -2
[main] [SYSCALL] stat ( pathname=0x7f000008e270 ("/usr/lib/tls/x86_64"), statbuf=0x7f000008e330 ) -> -1
[main] [SYSCALL] openat ( dirfd=0xffffff9c, pathname=0x7f000008e270 ("/usr/lib/tls/libstdc++.so.6"), flags=0x80000 ) -> -2
[main] [SYSCALL] stat ( pathname=0x7f000008e270 ("/usr/lib/tls"), statbuf=0x7f000008e330 ) -> -1
[main] [SYSCALL] openat ( dirfd=0xffffff9c, pathname=0x7f000008e270 ("/usr/lib/x86_64/libstdc++.so.6"), flags=0x80000 ) -> -2
[main] [SYSCALL] stat ( pathname=0x7f000008e270 ("/usr/lib/x86_64"), statbuf=0x7f000008e330 ) -> 0
[main] [SYSCALL] openat ( dirfd=0xffffff9c, pathname=0x7f000008e270 ("/usr/lib/libstdc++.so.6"), flags=0x80000 ) -> -2
[main] [SYSCALL] stat ( pathname=0x7f000008e270 ("/usr/lib"), statbuf=0x7f000008e330 ) -> 0
[StdErr]: 'b'./libc.so.6''
[StdErr]: 'b': ''
[StdErr]: 'b'error while loading shared libraries''
[StdErr]: 'b': ''
[StdErr]: 'b'libstdc++.so.6''
[StdErr]: 'b': ''
[StdErr]: 'b'cannot open shared object file''
[StdErr]: 'b': ''
[StdErr]: 'b'No such file or directory''
[StdErr]: 'b'\n''
[main] [SYSCALL] writev ( fd=0x2 (stderr), *iov=0x7f000008dfe0 ("./libc.so.6: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory\n"), iovcnt=0xa ) -> 7d
[main] [SYSCALL] exit_group ( status=0x7f ) -> void
12:46:05:threads___:ERROR_:Thread main failed: syscall Exit_Group status 127

while I have dependencies
what to do?

Examples not running - "NoneType" error for binary object

Describe the bug
I installed zelos using pip on multiple platforms: Windows 10, Kali Linux 2022.1, Ubuntu 16, using python versions 3.5-3.9 and in all cases, the examples error out when executed.

To Reproduce
Steps to reproduce the behavior:

  1. Install zelos using pip (e.g., python 3.8)
  2. cd into examples/hello directory
  3. Either run the python test program or zelos directly on the binary
  4. Notice the following errors:
    "parse_____:NOTICE:Requested interpreter is blank
    Unknown format"
    "AttributeError: 'NoneType' object has no attribute 'static_symbols'
    (a similar "NoneType" object error occurs when trying to run zelos with the other examples)"

Expected behavior
Examples should execute as described in README

Unicorn2

Hi, I have been watching your projects with high interest. Good job, well done!

I am looking for some budget to develop Unicorn 2, to get to the latest Qemu version, plus some advanced features for dynamic analysis. Let me know if you are interested.

unicorn-engine/unicorn#1217

Keep it up, cheers.

Unresolved symbols when using musl interpreter

Describe the bug
I tried to run a dynamically linked binary compiled against musl, but zelos cannot load the program correctly

To Reproduce
Steps to reproduce the behavior:

  1. Download the following musl binary uname with ld-musl-x86_64.so.1 (You can also obtain from Alpine Linux distribution)
    musl_binary.zip
  2. Put ld-musl-x86_64.so.1 in /lib folder
  3. uname should be able to run correctly when directly called in terminal
  4. uname cannot be run when calling zelos uname

Expected behavior
The interpreter should be found and loaded, and all symbols should be resolved.

Screenshots
zelos uname --mount=x86,/lib/ld-musl-x86_64.so.1,/lib/ld-musl-x86_64.so.1
16:28:00:parse_____:NOTICE:No default interpreter for this arch
Traceback (most recent call last):
File "/home/shaoyu/.local/bin/zelos", line 8, in
sys.exit(main())
File "/home/shaoyu/.local/lib/python3.8/site-packages/zelos/main.py", line 23, in main
z = ZelosCmdline(sys.argv[1:])
File "/home/shaoyu/.local/lib/python3.8/site-packages/zelos/api/zelos_api.py", line 721, in init
self._setup(config)
File "/home/shaoyu/.local/lib/python3.8/site-packages/zelos/api/zelos_api.py", line 78, in _setup
e = Engine(config=config, api=self)
File "/home/shaoyu/.local/lib/python3.8/site-packages/zelos/engine.py", line 123, in init
self.load_executable(binary, entrypoint_override=config.startat)
File "/home/shaoyu/.local/lib/python3.8/site-packages/zelos/engine.py", line 315, in load_executable
file = self._first_parse(module_path)
File "/home/shaoyu/.local/lib/python3.8/site-packages/zelos/engine.py", line 289, in _first_parse
return self._parse_file_data(module_path, file_data)
File "/home/shaoyu/.local/lib/python3.8/site-packages/zelos/engine.py", line 297, in _parse_file_data
parsed_file = self.os_plugins.parse(filename, filedata)
File "/home/shaoyu/.local/lib/python3.8/site-packages/zelos/plugin/plugin.py", line 168, in parse
parsed_file = os_plugin.parse(path, binary)
File "/home/shaoyu/.local/lib/python3.8/site-packages/zelos/ext/platforms/linux/linux.py", line 80, in parse
parsed_file = LiefELF(self.z.files, path, binary)
File "/home/shaoyu/.local/lib/python3.8/site-packages/zelos/ext/platforms/linux/parse.py", line 33, in init
self.parse(path, binary)
File "/home/shaoyu/.local/lib/python3.8/site-packages/zelos/ext/platforms/linux/parse.py", line 106, in parse
for symbol in binary.static_symbols:
AttributeError: 'NoneType' object has no attribute 'static_symbols'

Additional context
Add any other context about the problem here.

How to save the emulation results

When I run the given examples (e.g. hello.bin),the output will show on the console. Is there a way that to record them in a log file?

Mips error (NOTICE:Requested interpreter is blank)

I am trying to get syscalls for system call traces for MIPS arachticures

$$ file malware.bin
-> ELF 32-bit MSB executable, MIPS, MIPS-I version 1 (SYSV), statically linked, not stripped
$$ zelos malware.bin
-> AttributeError: 'NoneType' object has no attribute 'static_symbols'
$$ uname -m
x86_64

I run it on different samples and get the same error, also I run it on different architectures but same problem, any solution?

AttributeError: 'NoneType' object has no attribute 'socket'

Describe the bug

Hi,

another sample will raise exception, please refer to the sample below.
https://www.virustotal.com/gui/file/c7c281190bc1be69375e32247060748e24d7d917872fd2ef7fa5552302f7497b/detection

thank you

15:06:37:hooks_____:INFO__:Reached entrypoint 0x4001b1
[main] [SYSCALL] arch_prctl ( option=0x1002 (ARCH_SET_FS), addr=0x615718 ) -> 0
[main] [SYSCALL] set_tid_address ( tidptr=0x61591c ) -> 7400
[main] [SYSCALL] clock_gettime ( clk_id=0x2, res=0x7f000008eb10 ) -> 0
15:06:37:kernel_bas:ERROR_:Error in thread main (0x7400), PRI: 0, parent: None, IP: 0x413964, blocks_exec'd: 0x0, ThreadState.RUNNING while executing syscall recvfrom Args: sockfd=0xffffffffffffffff, buf=0x0, len=0x0, flags=0x0, src_addr=0x0, addrlen=0x0
Traceback (most recent call last):
  File "/home/*********/Envs/zelosOrg/bin/zelos", line 33, in <module>
    sys.exit(load_entry_point('zelos', 'console_scripts', 'zelos')())
  File "/home/*********/*****/src/zelos/__main__.py", line 26, in main
    z.start(z.config.timeout)
  File "/home/*********/*****/src/zelos/api/zelos_api.py", line 355, in start
    return self.internal_engine.start(timeout=timeout)
  File "/home/*********/*****/src/zelos/engine.py", line 509, in start
    while self._should_continue():
  File "/home/*********/*****/src/zelos/engine.py", line 580, in _should_continue
    if self.scheduler._resolve_end_reasons() is False:
  File "/home/*********/*****/src/zelos/scheduler.py", line 99, in _resolve_end_reasons
    if action() is False:
  File "/home/*********/*****/src/zelos/ext/platforms/linux/kernel.py", line 261, in handle_syscall
    super().handle_syscall(*args, **kwargs)
  File "/home/*********/*****/src/zelos/ext/platforms/linux/kernel.py", line 133, in handle_syscall
    status = super(LinuxKernel, self).handle_syscall(process)
  File "/home/*********/*****/src/zelos/plugin/kernel_base.py", line 201, in handle_syscall
    raise e
  File "/home/*********/*****/src/zelos/plugin/kernel_base.py", line 192, in handle_syscall
    retval = sys_fn(self, process)
  File "/home/*********/*****/src/zelos/ext/platforms/linux/syscalls/syscalls.py", line 1173, in sys_recvfrom
    return socketcall.recvfrom(k, p, -1)
  File "/home/*********/*****/src/zelos/ext/platforms/linux/syscalls/syscalls_socket.py", line 449, in recvfrom
    sock = socket_handle.socket
AttributeError: 'NoneType' object has no attribute 'socket'

wrong old_mmap define

Describe the bug
params copy form user stack space, not via register.... can you please fix this bug?

zelos define

https://github.com/zeropointdynamics/zelos/blob/f670a6288788fe1a0de31725ea1ff58c5f9ea1d2/src/zelos/ext/platforms/linux/syscalls/syscalls.py
def sys_mmap(sm, p):
args = sm.get_args(
[
("void*", "addr"),
("size_t", "length"),
("int", "prot"),
("int", "flags"),
("int", "fd"),
("off_t", "offset"),
]
)
try:
return mmapx(sm, p, "mmap", args, args.offset)
except Exception as e:
sm.print("mmap exception: " + str(e))
return -1

old_mmap define

https://github.com/torvalds/linux/blob/a5ad5742f671de906adbf29fbedf0a04705cebad/arch/x86/kernel/sys_ia32.c
COMPAT_SYSCALL_DEFINE1(ia32_mmap, struct mmap_arg_struct32 __user *, arg)
{
struct mmap_arg_struct32 a;

if (copy_from_user(&a, arg, sizeof(a)))
	return -EFAULT;

Implement MIPS Comment Generator in the Trace plugin

Related to #121 , there is no mips comment generator class. At the moment for MIPS binaries, we instead use the EmptyCommentGenerator which is just a placeholder that does nothing. x86, x86_64, and Arm have comment generators that add comments to the instruction trace denoting the value of operands at runtime. This is especially useful for indirect function calls when used in conjunction with the IDA overlay plugin.

AttributeError: 'EmptyCommentGenerator' object has no attribute 'functions_called'

Describe the bug
18:18:50:engine____:ERROR_:Exception while trying to close Zelos
Traceback (most recent call last):
File "/home/aaaaa/Envs/zelos/lib/python3.7/site-packages/zelos-0.1.1.dev0-py3.7.egg/zelos/engine.py", line 603, in close
closure()
File "/home/aaaaa/Envs/zelos/lib/python3.7/site-packages/zelos-0.1.1.dev0-py3.7.egg/zelos/ext/plugins/overlay/overlay.py", line 71, in closure
f, trace=self.export_trace, mem=self.export_mem
File "/home/aaaaa/Envs/zelos/lib/python3.7/site-packages/zelos-0.1.1.dev0-py3.7.egg/zelos/ext/plugins/overlay/overlay.py", line 212, in export
for addr in self.zelos.plugins.trace.functions_called.keys():
File "/home/aaaaa/Envs/zelos/lib/python3.7/site-packages/zelos-0.1.1.dev0-py3.7.egg/zelos/ext/plugins/trace.py", line 133, in functions_called
return self.comment_generator.functions_called
AttributeError: 'EmptyCommentGenerator' object has no attribute 'functions_called'

it happens when i use "--export_trace --inst --fasttrace".
sorry, I can't provide relevant test file, can you please check this issue?

"Standalone execution is not supported yet"

Hello, can you please share correct x64&MIPS version of ld-uClibc.so? The current version does not support Standalone execution.

thank you very much!

Describe the bug
Plugins: trace, overlay, runner, syscalllimiter, yarascan
[main] [SYSCALL] mmap ( addr=0x0, length=0x1000, prot=RW, flags=0x22, fd=0xffffffffffffffff (unknown), offset=0x0 ) -> 1000
[StdErr]: 'b'Standalone execution is not supported yet\n''
[main] [SYSCALL] write ( fd=0x2 (stderr), buf=0x1000 ("Standalone execution is not supported yet\n"), count=0x2a ) -> 2a
[main] [SYSCALL] munmap ( addr=0x1000, length=0x1000 ) -> 0
[main] [SYSCALL] exit ( status=0x1 ) -> void
12:02:04:threads___:ERROR_:Thread main failed: syscall Exit_Group status 1

Invalid PC value on ARM, EABI5 version 1 (SYSV)

Describe the bug
It appears that PC register on 32 bit ARM has an invalid value, resulting in invalid PC-relative resolution.

To Reproduce
Steps to reproduce the behavior:

  1. Download this
  2. Type py -3 -m zelos ./libzlib.so
  3. See an error message
  4. Open this place in IDA and see correct address resolution (0x15FD8 instead of 0x15FD0)

Expected behavior
Correct PC value should not point at the exact address like IP on x86

Screenshots
Not applicable

Additional context
According to the ARM IC.

In ARM state, the value of the PC is the address of the current instruction plus 8 bytes.
In Thumb state:

  • For B, BL, CBNZ, and CBZ instructions, the value of the PC is the address of the current instruction plus 4 bytes.
  • For all other instructions that use labels, the value of the PC is the address of the current instruction plus 4 bytes, with bit[1] of the result cleared to 0 to make it word-aligned.

wrong SocketType define on MIPS

Describe the bug

can you please fix this bug? x86, ARM define SOCK_STREAM = 1, SOCK_DGRAM = 2.

class SocketType(enum.IntEnum):
    """
    Socket Types:
    https://github.com/torvalds/linux/blob/master/include/linux/net.h
    """

    SOCK_STREAM = 1
    SOCK_DGRAM = 2

But MIPS define, SOCKET_STREM = 2, SOCKET_DGRAM = 1.

https://github.com/torvalds/linux/blob/6f0d349d922ba44e4348a17a78ea51b7135965b1/arch/mips/include/asm/socket.h

enum sock_type {
	SOCK_DGRAM	= 1,
	SOCK_STREAM	= 2,

MIPS, socket, set_return_value(), set v0 is not enough

Describe the bug
On MIPS, the wrapper of syscall socket will check reg $a3, so set $v0 as return value is not enough.

IDA dis code:
li $v0, 0x1057 # __NR_socket
syscall 0
la $t9, lib___errno_location
beqz $a3, loc_420404 <---------will check reg $a3
move $s0, $v0

zelos code:
def set_return_value(self, value):
self.emu.set_reg("v0", value)

Could you help upgrade the vulnerble shared library introduced by package zelos?

Hi, @kvalakuzhyzp , @RCourt , I'd like to report a vulnerability issue in zelos_0.2.0.

Issue Description

zelos_0.2.0 directly or transitively depends on 111 C libraries (.so). However, I noticed that some C libraries are vulnerable, containing the following CVEs:
ld-linux-armhf.so.3 libc.so.6 ld-linux-x86-64.so.2 ld-2.27.so ld-linux.so.2 libanl-2.27.so libanl.so.1 libBrokenLocale-2.27.so libBrokenLocale.so.1 libc-2.27.so libcidn-2.27.so libcidn.so.1 libcrypt-2.27.so libcrypt.so.1 libdl-2.27.so libdl.so.2 libm-2.27.so libm.so.6 libmemusage.so libnsl-2.27.so libnsl.so.1 libnss_compat-2.27.so libnss_compat.so.2 libnss_dns-2.27.so libnss_dns.so.2 libnss_files-2.27.so libnss_files.so.2 libnss_hesiod-2.27.so libnss_hesiod.so.2 libnss_nis-2.27.so libnss_nis.so.2 libnss_nisplus-2.27.so libnss_nisplus.so.2 libpcprofile.so libpthread-2.27.so libpthread.so.0 libresolv-2.27.so libresolv.so.2 librt-2.27.so librt.so.1 libSegFault.so libthread_db-1.0.so libthread_db.so.1 libutil-2.27.so libutil.so.1 from C project glibc(version:2.27) exposed 22 vulnerabilities:
CVE-2015-8985, CVE-2019-7309, CVE-2020-1751, CVE-2020-10029, CVE-2019-9169, CVE-2019-6488, CVE-2020-6096, CVE-2020-1752, CVE-2020-27618, CVE-2021-3326, CVE-2021-33574, CVE-2019-25013, CVE-2021-38604, CVE-2021-35942, CVE-2019-19126, CVE-2019-9192, CVE-2018-20796, CVE-2009-5155, CVE-2016-10739, CVE-2018-11237, CVE-2017-18269, CVE-2018-11236,

Suggested Vulnerability Patch Versions

glibc has fixed the vulnerabilities in versions >=2.35

Python build tools cannot report vulnerable C libraries, which may induce potential security issues to many downstream Python projects. Could you please upgrade the above shared libraries to their patch versions?

Thanks for your help~
Best regards,
Joe Gardner

Wrapper around emulated/host file paths

Is your feature request related to a problem? Please describe.
Within Zelos, there are file paths that are within the emulated system, and paths in the host system. We want to ensure that a emulated path never gets accessed as a host path and vice versa.
Host path used as emulated path (Information leakage in host machine)
Emulated path used as host path (potential modification of files outside of the sandbox)

Describe the solution you'd like
We could use a wrapper around paths to keep track of whether the path is an emulated path or host path, and validate when they are used to ensure that we are using the appropriate path.

Describe alternatives you've considered
We currently do validation in methods that use these paths in kernel.py, we should probably do a bit more.

giving filepath as argument, openat returns -2.

Describe the bug
if a program expects filename as argument, file open fails. error code -2.

To Reproduce

  1. compile this program:
    https://github.com/hardik05/Damn_Vulnerable_C_Program/blob/master/imgRead.c
    gcc imgRead.c -o imgRead

  2. this program expects a file name as argument.
    create a sample file:
    echo "Hello" > 1.img

  3. run compiled binary with zelos as below:
    zelos imgRead 1.img

file open will fail, following message will be displayed:

10:12:39:hooks_____:INFO__:Reached entrypoint 0x20c0
[main] [SYSCALL] brk ( addr=0x0 ) -> 90000040
[main] [SYSCALL] brk ( addr=0x90021040 ) -> 90021040
[main] [SYSCALL] brk ( addr=0x90022000 ) -> 90022000
[main] [SYSCALL] openat ( dirfd=0xffffff9c, pathname=0x7f000008eebb ("imgread"), flags=0x0 ) -> -2
[main] [SYSCALL] fstat ( fd=0x1 (stdout), statbuf=0x7f000008e460 ) -> 0
IOCTL: 186814848
[main] [SYSCALL] ioctl ( fd=0x1 (stdout), request=0x5401, data=0x7f000008e3c0 ) -> -1
[StdOut]: 'b"\nCan't open file or file doesn't exist."'
[main] [SYSCALL] write ( fd=0x1 (stdout), buf=0x900004d0 ("\nCan't open file or file doesn't exist."), count=0x27 ) -> 27

Expected behavior
file open should be successful. is it a file path issue? may be i am giving it wrong?

Screenshots
NA

Additional context
NA

a little wrong comment

Describe the bug
Hi, the comment of pack() is wrong :)

    def pack(
        self,
        x: int,
        bytes: int = None,
        little_endian: bool = None,
        signed: bool = False,
    ) -> bytes:
        """
  Unpacks an integer from a byte format. Defaults to the
        current architecture bytes and endianness.
        """

Configure MAC address

Created from #23

Enable a central location to be able to modify the MAC address of the emulated machine.
There are two known methods for ##linux

  1. Through ioctl syscall using SIOCGIFHWADDR,
  2. Accessing /sys/class/net/*/address

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.