diff --git a/.travis.yml b/.travis.yml index 5cf4d7f..0e335c1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ matrix: fast_finish: true include: - python: 2.7 + - python: 3.6 - os: osx osx_image: xcode9.3beta language: generic @@ -25,6 +26,7 @@ before_install: install: - pip install -U pip setuptools + - pip install '.[dev]' - python setup.py develop - pip install mock pytest pytest-cov codecov coveralls diff --git a/egghatch/main.py b/egghatch/main.py index 9d327ce..3cde3d1 100644 --- a/egghatch/main.py +++ b/egghatch/main.py @@ -9,10 +9,10 @@ def main(): if len(sys.argv) != 2: - print "Usage: python %s " % sys.argv[0] + print("Usage: python %s " % sys.argv[0]) exit(1) - print Shellcode(open(sys.argv[1], "rb").read()).to_json() + print(Shellcode(open(sys.argv[1], "rb").read()).to_json()) def parse(payload): return Shellcode(payload).to_dict() diff --git a/egghatch/misc.py b/egghatch/misc.py index 4aea991..1eb2a03 100644 --- a/egghatch/misc.py +++ b/egghatch/misc.py @@ -2,6 +2,9 @@ # This file is part of Cuckoo Sandbox - https://cuckoosandbox.org/. # See the file 'docs/LICENSE' for copying permission. +from builtins import int +from past.builtins import basestring + def str_as_db(s): r1 = [] for ch in s: @@ -14,7 +17,8 @@ def str_as_db(s): r2, idx = [], 0 while idx < len(r1): - if isinstance(r1[idx], (int, long)): + print(type(r1[idx]),isinstance(r1[idx], str)) + if isinstance(r1[idx], int): r2.append("%s" % r1[idx]) idx += 1 continue diff --git a/egghatch/shellcode.py b/egghatch/shellcode.py index e055f9d..2045e63 100644 --- a/egghatch/shellcode.py +++ b/egghatch/shellcode.py @@ -5,6 +5,8 @@ import json from egghatch.block import Block +from builtins import range +import base64 class Shellcode(object): def __init__(self, payload): @@ -36,7 +38,15 @@ def to_dict(self): ret["bbl"] = sorted(self.bbl.items()) ret["text"] = sorted(self.insns) for idx, data in sorted(self.data.items()): - ret["data"].append((idx, data.decode("latin1"))) + if isinstance(data, str): + # Python2 + ret["data"].append((idx, "".join(data.decode("utf-8")))) + elif isinstance(data, bytes): + # Python3 + ret["data"].append((idx, "".join([chr(x) for x in data]))) + else: + print("Warning, wrong type received in data : %s" % type(data)) + ret = "" return ret def to_json(self): @@ -135,7 +145,7 @@ def basic_taint(self): continue op = insn2.operands - for _ in xrange(64): + for _ in range(64): if insn2.addr + insn2.size not in insns: break @@ -156,7 +166,7 @@ def extract_data(self): parsed[len(self.payload)] = len(self.payload) chunks = sorted(parsed.items()) - for idx in xrange(1, len(chunks)): + for idx in range(1, len(chunks)): _, start = chunks[idx-1] end, _ = chunks[idx] if start != end and start < end: diff --git a/setup.py b/setup.py index a832d62..16ab1fb 100755 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ setuptools.setup( name="egghatch", - version="0.2.3", + version="0.3", author="Jurriaan Bremer", author_email="jbr@cuckoo.sh", packages=[ @@ -22,13 +22,13 @@ "Natural Language :: English", "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", "Operating System :: POSIX :: Linux", - "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 2.7, 3.6", "Topic :: Security", ], url="https://cuckoosandbox.org/", license="GPLv3", description="Cuckoo Sandbox Shellcode Identification & Formatting", - long_description=open("README.rst", "rb").read(), + long_description=open("README.rst", "r").read(), include_package_data=True, entry_points={ "console_scripts": [ @@ -36,16 +36,22 @@ ], }, install_requires=[ + "future", ], extras_require={ ":sys_platform == 'win32'": [ "capstone-windows==3.0.4", ], ":sys_platform == 'darwin'": [ - "capstone==3.0.5rc2", + "capstone==3.0.5", ], ":sys_platform == 'linux2'": [ - "capstone==3.0.5rc2", + "capstone==3.0.5", ], + "dev": [ + "pytest==4.4.1", + "mock==2.0.0", + "capstone==3.0.5", + ] }, ) diff --git a/tests/test_blocks.py b/tests/test_blocks.py index 8bc31b5..2c9af0f 100644 --- a/tests/test_blocks.py +++ b/tests/test_blocks.py @@ -5,7 +5,7 @@ from egghatch.shellcode import Shellcode def test_parse(): - sc = Shellcode("\x90\x75\x02\x90\x90\x90") + sc = Shellcode(b"\x90\x75\x02\x90\x90\x90") assert sc.to_dict() == { "text": [ (0, 1, "nop", ""), diff --git a/tests/test_main.py b/tests/test_main.py index 48a6eea..2da223b 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -5,7 +5,7 @@ from egghatch import parse, as_text def test_parse(): - assert parse("\xfc\xeb\xfe") == { + assert parse(b"\xfc\xeb\xfe") == { "bbl": [ (0, 1), (1, 3), @@ -18,7 +18,7 @@ def test_parse(): } def test_as_text_cld_jmpinf(): - assert as_text("\xfc\xeb\xfe") == ( + assert as_text(b"\xfc\xeb\xfe") == ( "bbl_0x0000:\n" " 0x0000: cld\n" "bbl_0x0001:\n" @@ -29,6 +29,6 @@ def test_as_text_sc(): def f(filename): return open("tests/files/plain/%s" % filename, "rb").read() - assert f("1.bin.txt") == as_text(f("1.bin")) - assert f("2.bin.txt") == as_text(f("2.bin")) - assert f("3.bin.txt") == as_text(f("3.bin")) + assert f("1.bin.txt").decode("utf-8") == as_text(f("1.bin")) + assert f("2.bin.txt").decode("utf-8") == as_text(f("2.bin")) + assert f("3.bin.txt").decode("utf-8") == as_text(f("3.bin"))