diff --git a/docs/conf.py b/docs/conf.py index 82b7d21..fa6847c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -22,7 +22,7 @@ author = 'CERT Polska' # The full version, including alpha/beta/rc tags -release = '1.1.0' +release = '1.2.0' # -- General configuration --------------------------------------------------- diff --git a/malduck/crypto/rc.py b/malduck/crypto/rc.py index 740a9b1..408ab4d 100644 --- a/malduck/crypto/rc.py +++ b/malduck/crypto/rc.py @@ -2,7 +2,7 @@ # This file is part of Roach - https://github.com/jbremer/roach. # See the file 'docs/LICENSE.txt' for copying permission. -from Crypto.Cipher import ARC4 +from Cryptodome.Cipher import ARC4 ARC4.key_size = range(3, 256+1) diff --git a/malduck/crypto/rsa.py b/malduck/crypto/rsa.py index 6433784..35ae08c 100644 --- a/malduck/crypto/rsa.py +++ b/malduck/crypto/rsa.py @@ -4,7 +4,7 @@ import io -from Crypto.PublicKey import RSA as RSA_ +from Cryptodome.PublicKey import RSA as RSA_ from itertools import takewhile from .winhdr import BLOBHEADER, BaseBlob diff --git a/malduck/ints.py b/malduck/ints.py index 0ebd3c6..9801e55 100644 --- a/malduck/ints.py +++ b/malduck/ints.py @@ -198,7 +198,7 @@ def pack(self): return pack(self.fmt, long(self)) @classmethod - def unpack(cls, other, offset=0): + def unpack(cls, other, offset=0, fixed=True): """ Unpacks single value from provided buffer @@ -206,13 +206,18 @@ def unpack(cls, other, offset=0): :type other: bytes :param offset: Buffer offset :type offset: int + :param fixed: Convert to fixed-size integer (IntType instance) + :type fixed: bool (default: True) :rtype: IntType instance or None if there are not enough data to unpack + + .. warning:: + Fixed-size integer operations are 4-5 times slower than equivalent on built-in integer types """ try: ret = unpack_from(cls.fmt, other, offset=offset) except error: return None - return cls(ret[0]) + return cls(ret[0]) if fixed else ret[0] # Unsigned types diff --git a/malduck/procmem/cuckoomem.py b/malduck/procmem/cuckoomem.py index df0978d..cdd70e2 100644 --- a/malduck/procmem/cuckoomem.py +++ b/malduck/procmem/cuckoomem.py @@ -24,7 +24,10 @@ def __init__(self, buf, base=None, **kwargs): ) ptr += size if base is None: - self.imgbase = self.regions[0].addr + if self.regions: + self.imgbase = self.regions[0].addr + else: + self.imgbase = 0 def store(self): """ TODO """ diff --git a/malduck/procmem/procmem.py b/malduck/procmem/procmem.py index ef011bf..94a16ef 100644 --- a/malduck/procmem/procmem.py +++ b/malduck/procmem/procmem.py @@ -369,37 +369,37 @@ def patchv(self, addr, buf): raise ValueError("Cross-region patching is not supported") return self.patchp(region.offset + addr - region.addr, buf) - def uint8p(self, offset): + def uint8p(self, offset, fixed=False): """Read unsigned 8-bit value at offset.""" - return uint8(self.readp(offset, 1)) + return uint8(self.readp(offset, 1), fixed=fixed) - def uint16p(self, offset): + def uint16p(self, offset, fixed=False): """Read unsigned 16-bit value at offset.""" - return uint16(self.readp(offset, 2)) + return uint16(self.readp(offset, 2), fixed=fixed) - def uint32p(self, offset): + def uint32p(self, offset, fixed=False): """Read unsigned 32-bit value at offset.""" - return uint32(self.readp(offset, 4)) + return uint32(self.readp(offset, 4), fixed=fixed) - def uint64p(self, offset): + def uint64p(self, offset, fixed=False): """Read unsigned 64-bit value at offset.""" - return uint64(self.readp(offset, 8)) + return uint64(self.readp(offset, 8), fixed=fixed) - def uint8v(self, addr): + def uint8v(self, addr, fixed=False): """Read unsigned 8-bit value at address.""" - return uint8(self.readv(addr, 1)) + return uint8(self.readv(addr, 1), fixed=fixed) - def uint16v(self, addr): + def uint16v(self, addr, fixed=False): """Read unsigned 16-bit value at address.""" - return uint16(self.readv(addr, 2)) + return uint16(self.readv(addr, 2), fixed=fixed) - def uint32v(self, addr): + def uint32v(self, addr, fixed=False): """Read unsigned 32-bit value at address.""" - return uint32(self.readv(addr, 4)) + return uint32(self.readv(addr, 4), fixed=fixed) - def uint64v(self, addr): + def uint64v(self, addr, fixed=False): """Read unsigned 64-bit value at address.""" - return uint64(self.readv(addr, 8)) + return uint64(self.readv(addr, 8), fixed=fixed) def asciiz(self, addr): """Read a nul-terminated ASCII string at address.""" @@ -505,7 +505,7 @@ def regexv(self, query, addr=None, length=None): for entry in re.finditer(query, chunk, re.DOTALL): yield chunk_addr + entry.start() - def disasmv(self, addr, size): + def disasmv(self, addr, size, x64=False): """ Disassembles code under specified address @@ -513,9 +513,11 @@ def disasmv(self, addr, size): :type addr: int :param size: Size of disassembled buffer :type size: int + :param x64: Assembly is 64bit + :type x64: bool (optional) :return: :class:`Disassemble` """ - return disasm(self.readv(addr, size), addr) + return disasm(self.readv(addr, size), addr, x64=x64) def _findbytes(self, regex_fn, query, addr, length): query = ensure_string(query) diff --git a/requirements.txt b/requirements.txt index 3285071..0e98979 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ click==6.6 cryptography>=2.1 pefile==2019.4.18 -pycryptodome == 3.8.2 +pycryptodomex==3.8.2 capstone==4.0.1 six diff --git a/setup.py b/setup.py index 2fc3528..22e1073 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setup( name="malduck", - version="1.1.0", + version="1.2.0", description="Malduck is your ducky companion in malware analysis journeys", author="CERT Polska", author_email="info@cert.pl",