diff --git a/capa/features/__init__.py b/capa/features/__init__.py index be4a7c70..9fec2d76 100644 --- a/capa/features/__init__.py +++ b/capa/features/__init__.py @@ -1,5 +1,6 @@ import codecs import logging +import sys import capa.engine @@ -8,6 +9,13 @@ logger = logging.getLogger(__name__) MAX_BYTES_FEATURE_SIZE = 0x100 +def bytes_to_str(b): + if sys.version_info[0] >= 3: + return str(codecs.encode(b, 'hex').decode('utf-8')) + else: + return codecs.encode(b, 'hex') + + class Feature(object): def __init__(self, args): super(Feature, self).__init__() @@ -100,14 +108,14 @@ class Bytes(Feature): def __str__(self): if self.symbol: - return 'bytes(0x%s = %s)' % (codecs.encode(self.value, 'hex').upper(), self.symbol) + return 'bytes(0x%s = %s)' % (bytes_to_str(self.value).upper(), self.symbol) else: - return 'bytes(0x%s)' % (codecs.encode(self.value, 'hex').upper()) + return 'bytes(0x%s)' % (bytes_to_str(self.value).upper()) def freeze_serialize(self): return (self.__class__.__name__, - map(lambda x: codecs.encode(x, 'hex').upper(), self.args)) + [bytes_to_str(x).upper() for x in self.args]) @classmethod def freeze_deserialize(cls, args): - return cls(*map(lambda x: codecs.decode(x, 'hex'), args)) + return cls(*[codecs.decode(x, 'hex') for x in args]) diff --git a/capa/render/__init__.py b/capa/render/__init__.py index 36f39daf..cafa7aac 100644 --- a/capa/render/__init__.py +++ b/capa/render/__init__.py @@ -1,4 +1,5 @@ import json +import six import capa.engine @@ -261,7 +262,7 @@ def render_default(rules, capabilities): class CapaJsonObjectEncoder(json.JSONEncoder): def default(self, obj): - if isinstance(obj, (list, dict, str, unicode, int, float, bool, type(None))): + if isinstance(obj, (list, dict, int, float, bool, type(None))) or isinstance(obj, six.string_types): return json.JSONEncoder.default(self, obj) elif isinstance(obj, set): return list(sorted(obj))