diff --git a/egghatch/block.py b/egghatch/block.py index cc7f03e..91b75a6 100644 --- a/egghatch/block.py +++ b/egghatch/block.py @@ -8,6 +8,7 @@ "Instruction", ("addr", "size", "mnemonic", "operands") ) + class Block(object): stop_insns = ( "jmp", "jecxz", "ret", "loop", "loope", "loopne", diff --git a/egghatch/main.py b/egghatch/main.py index 9d327ce..d80ef4d 100644 --- a/egghatch/main.py +++ b/egghatch/main.py @@ -7,16 +7,19 @@ from egghatch.misc import str_as_db from egghatch.shellcode import Shellcode + 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() + def as_text(payload): ret, sc = [], Shellcode(payload).to_dict() diff --git a/egghatch/misc.py b/egghatch/misc.py index 4aea991..99866f2 100644 --- a/egghatch/misc.py +++ b/egghatch/misc.py @@ -14,12 +14,12 @@ def str_as_db(s): r2, idx = [], 0 while idx < len(r1): - if isinstance(r1[idx], (int, long)): + if isinstance(r1[idx], (int, float)): r2.append("%s" % r1[idx]) idx += 1 continue jdx = idx - while idx < len(r1) and isinstance(r1[idx], basestring): + while idx < len(r1) and isinstance(r1[idx], str): idx += 1 r2.append("'%s'" % "".join(r1[jdx:idx])) diff --git a/egghatch/shellcode.py b/egghatch/shellcode.py index e055f9d..e7da7e9 100644 --- a/egghatch/shellcode.py +++ b/egghatch/shellcode.py @@ -6,6 +6,7 @@ from egghatch.block import Block + class Shellcode(object): def __init__(self, payload): import capstone @@ -63,14 +64,14 @@ def handle_relative_call(self, block): def add_bbl(self, start, end): bbl_r = dict((v, k) for k, v in self.bbl.items()) for start_, end_ in self.bbl.items(): - if start >= start_ and start < end_: + if start_ <= start < end_: self.bbl[start_] = start self.bbl[start] = end_ break if start < start_ and end == end_: self.bbl[start] = bbl_r.get(start_, start_) break - if end and end > start_ and end <= end_: + if end and start_ < end <= end_: self.bbl[start] = start_ self.bbl[start_] = end if end != end_: @@ -135,7 +136,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 +157,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..4dfc4f4 100755 --- a/setup.py +++ b/setup.py @@ -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 :: 3.8", "Topic :: Security", ], url="https://cuckoosandbox.org/", license="GPLv3", description="Cuckoo Sandbox Shellcode Identification & Formatting", - long_description=open("README.rst", "rb").read(), + long_description=str(open("README.rst", "rb").read()), include_package_data=True, entry_points={ "console_scripts": [ @@ -42,10 +42,10 @@ "capstone-windows==3.0.4", ], ":sys_platform == 'darwin'": [ - "capstone==3.0.5rc2", + "capstone==4.0.2", ], ":sys_platform == 'linux2'": [ - "capstone==3.0.5rc2", + "capstone==4.0.2", ], }, ) diff --git a/tests/test_blocks.py b/tests/test_blocks.py index 8bc31b5..99525f2 100644 --- a/tests/test_blocks.py +++ b/tests/test_blocks.py @@ -4,8 +4,9 @@ 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", ""), @@ -22,6 +23,7 @@ def test_parse(): "data": [], } + def test_add_bbl1(): sc = Shellcode("") sc.parsed[97] = False @@ -39,6 +41,7 @@ def test_add_bbl1(): 136: 192, } + def test_add_bbl2(): sc = Shellcode("") sc.parsed[209] = False @@ -58,6 +61,7 @@ def test_add_bbl2(): 290: 308, } + def test_sd(): sc = Shellcode(open("tests/files/plain/sd.bin", "rb").read()) assert sc.to_dict()["bbl"] == [ @@ -66,6 +70,7 @@ def test_sd(): (0x39, 0x45), ] + def test_bin1(): sc = Shellcode(open("tests/files/plain/1.bin", "rb").read()) assert sc.to_dict()["bbl"] == [ @@ -100,6 +105,7 @@ def test_bin1(): (0x14b, "www.service.chrome-up.date\x00"), ] + def test_bin2(): sc = Shellcode(open("tests/files/plain/2.bin", "rb").read()) assert sc.to_dict()["bbl"] == [ @@ -131,6 +137,7 @@ def test_bin2(): (192, "ddos400.ddns.net\x00"), ] + def test_bin3(): sc = Shellcode(open("tests/files/plain/3.bin", "rb").read()) assert sc.to_dict()["bbl"] == [ diff --git a/tests/test_json.py b/tests/test_json.py index 8192ed2..81e4f1b 100644 --- a/tests/test_json.py +++ b/tests/test_json.py @@ -7,6 +7,7 @@ from egghatch.shellcode import Shellcode + def test_sd(): sc = Shellcode(open("tests/files/plain/sd.bin", "rb").read()) assert json.loads(sc.to_json()) == { @@ -49,6 +50,7 @@ def test_sd(): "data": [], } + def test_bin1(): sc = Shellcode(open("tests/files/plain/1.bin", "rb").read()) assert json.loads(sc.to_json()) == { @@ -60,6 +62,7 @@ def test_bin1(): ], } + def test_bin2(): sc = Shellcode(open("tests/files/plain/1.bin", "rb").read()) assert json.loads(sc.to_json()) == { diff --git a/tests/test_main.py b/tests/test_main.py index 48a6eea..4d41128 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -4,6 +4,7 @@ from egghatch import parse, as_text + def test_parse(): assert parse("\xfc\xeb\xfe") == { "bbl": [ @@ -17,6 +18,7 @@ def test_parse(): "data": [], } + def test_as_text_cld_jmpinf(): assert as_text("\xfc\xeb\xfe") == ( "bbl_0x0000:\n" @@ -25,6 +27,7 @@ def test_as_text_cld_jmpinf(): " 0x0001: jmp 1\n" ) + def test_as_text_sc(): def f(filename): return open("tests/files/plain/%s" % filename, "rb").read() diff --git a/tests/test_misc.py b/tests/test_misc.py index c7908c5..9f17adf 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -4,6 +4,7 @@ from egghatch.misc import str_as_db + def test_str_as_db(): assert str_as_db("\x00") == "0" assert str_as_db("foo") == "'foo'"