示例#1
0
 def __init__(self, idascope_config):
     print("[|] loading YaraScanner")
     self.os = os
     self.re = re
     self.time = time
     self.yara = yara
     self.YaraRule = YaraRule
     self.ida_proxy = IdaProxy()
     self.yrl = YaraRuleLoader()
     # fields
     self.idascope_config = idascope_config
     self.num_files_loaded = 0
     self._compiled_rules = []
     self._yara_rules = []
     self._results = []
     self.segment_offsets = []
示例#2
0
 def __init__(self, idascope_config):
     print ("[|] loading YaraScanner")
     self.os = os
     self.re = re
     self.time = time
     self.yara = yara
     self.YaraRule = YaraRule
     self.ida_proxy = IdaProxy()
     self.yrl = YaraRuleLoader()
     # fields
     self.idascope_config = idascope_config
     self.num_files_loaded = 0
     self._compiled_rules = []
     self._yara_rules = []
     self._results = []
     self.segment_offsets = []
示例#3
0
class YaraScanner():
    """
    A module to analyze and explore an IDB for semantics. For a set of API names, references to these
    are identified and used for creating context and allowing tagging of them.
    """

    def __init__(self, idascope_config):
        print ("[|] loading YaraScanner")
        self.os = os
        self.re = re
        self.traceback = traceback
        self.time = time
        self.yara = yara
        self.Misc = Misc
        self.StatusController = StatusController
        self.YaraRule = YaraRule
        self.ida_proxy = IdaProxy()
        self.yrl = YaraRuleLoader()
        # fields
        self.idascope_config = idascope_config
        self.num_files_loaded = 0
        self._compiled_rules = []
        self._yara_rules = []
        self._results = []
        self.segment_offsets = []

    def getResults(self):
        return self._results

    def load_rules(self):
        if not self.yara:
            return
        self.num_files_loaded = 0
        self._compiled_rules = []
        self._yara_rules = []
        for yara_path in self.idascope_config.yara_sig_folders:
            self._load_recursive(yara_path)

    def _load_recursive(self, yara_path):
        if self.os.path.isfile(yara_path):
            self._load_file(yara_path)
        elif self.os.path.isdir(yara_path):
            for dirpath, dirnames, filenames in self.os.walk(yara_path):
                for filename in sorted(filenames):
                    filepath = dirpath + self.os.sep + filename
                    self._load_file(filepath)

    def _load_file(self, filepath):
        try:
            rules_from_file = self.yrl.loadRulesFromFile(filepath)
            for rule in rules_from_file:
                rule.checkRule()
            self._yara_rules.extend(rules_from_file)
            rules = self.yara.compile(filepath)
            self._compiled_rules.append(rules)
            print("loading rules from file: %s (%d)" % (filepath, len(rules_from_file)))
            if rules:
                self.num_files_loaded += 1
        except Exception as exc:
            print("[!] Could not load yara rules from file: %s --- Exception: " % filepath)
            print(">" * 60)
            print(self.traceback.format_exc(exc))
            print("<" * 60)

    def scan(self):
        if not self.yara:
            print("[!] yara-python not available, please install it from (http://plusvic.github.io/yara/)")
            return
        memory, offsets = self._get_memory()
        self.segment_offsets = offsets
        self._results = []
        matches = []
        print("[!] Performing YARA scan...")
        for rule in self._compiled_rules:
            matches.append(rule.match(data=memory, callback=self._result_callback))
        if len(matches) == 0:
            print("  [-] no matches. :(")

    def _get_memory(self):
        result = ""
        segment_starts = [ea for ea in self.ida_proxy.Segments()]
        offsets = []
        start_len = 0
        for start in segment_starts:
            end = self.ida_proxy.SegEnd(start)
            for ea in self.Misc.lrange(start, end):
                result += chr(self.ida_proxy.Byte(ea))
            offsets.append((start, start_len, len(result)))
            start_len = len(result)
        return result, offsets

    def _result_callback(self, data):
        adjusted_offsets = []
        for string in data["strings"]:
            adjusted_offsets.append((self._translateMemOffsetToVirtualAddress(string[0]), string[1], string[2]))
        data["strings"] = adjusted_offsets
        if data["matches"]:
            print("  [+] YARA Match for signature: %s" % data["rule"])
        result_rule = None
        for rule in self._yara_rules:
            if rule.rule_name == data["rule"]:
                result_rule = rule
        if not result_rule:
            result_rule = self.YaraRule()
        result_rule.match_data = data
        self._results.append(result_rule)

        self.yara.CALLBACK_CONTINUE

    def _translateMemOffsetToVirtualAddress(self, offset):
        va_offset = 0
        for seg in self.segment_offsets:
            if seg[1] <= offset < seg[2]:
                va_offset = seg[0] + (offset - seg[1])
        return va_offset
示例#4
0
class YaraScanner:
    """
    A module to analyze and explore an IDB for semantics. For a set of API names, references to these
    are identified and used for creating context and allowing tagging of them.
    """

    def __init__(self, idascope_config):
        print ("[|] loading YaraScanner")
        self.os = os
        self.re = re
        self.time = time
        self.yara = yara
        self.YaraRule = YaraRule
        self.ida_proxy = IdaProxy()
        self.yrl = YaraRuleLoader()
        # fields
        self.idascope_config = idascope_config
        self.num_files_loaded = 0
        self._compiled_rules = []
        self._yara_rules = []
        self._results = []
        self.segment_offsets = []

    def getResults(self):
        return self._results

    def load_rules(self):
        if not self.yara:
            return
        self.num_files_loaded = 0
        self._compiled_rules = []
        self._yara_rules = []
        for yara_path in self.idascope_config.yara_sig_folders:
            self._load_recursive(yara_path)

    def _load_recursive(self, yara_path):
        if os.path.isfile(yara_path):
            self._load_file(yara_path)
        elif os.path.isdir(yara_path):
            for dirpath, dirnames, filenames in os.walk(yara_path):
                for filename in filenames:
                    filepath = dirpath + os.sep + filename
                    self._load_file(filepath)

    def _load_file(self, filepath):
        try:
            rules_from_file = self.yrl.loadRulesFromFile(filepath)
            for rule in rules_from_file:
                rule.checkRule()
            self._yara_rules.extend(rules_from_file)
            rules = yara.compile(filepath)
            self._compiled_rules.append(rules)
            print "loading rules from file: %s (%d)" % (filepath, len(rules_from_file))
            if rules:
                self.num_files_loaded += 1
        except:
            print "[!] Could not load yara rules from file: %s" % filepath

    def scan(self):
        if not self.yara:
            print "[!] yara-python not available, please install it from (http://plusvic.github.io/yara/)"
            return
        memory, offsets = self._get_memory()
        self.segment_offsets = offsets
        self._results = []
        matches = []
        print "[!] Performing YARA scan..."
        for rule in self._compiled_rules:
            matches.append(rule.match(data=memory, callback=self._result_callback))
        if len(matches) == 0:
            print "  [-] no matches. :("

    def _get_memory(self):
        result = ""
        segment_starts = [ea for ea in self.ida_proxy.Segments()]
        offsets = []
        start_len = 0
        for start in segment_starts:
            end = self.ida_proxy.SegEnd(start)
            for ea in Misc.lrange(start, end):
                result += chr(self.ida_proxy.Byte(ea))
            offsets.append((start, start_len, len(result)))
            start_len = len(result)
        return result, offsets

    def _result_callback(self, data):
        adjusted_offsets = []
        for string in data["strings"]:
            adjusted_offsets.append((self._translateMemOffsetToVirtualAddress(string[0]), string[1], string[2]))
        data["strings"] = adjusted_offsets
        if data["matches"]:
            print "  [+] YARA Match for signature: %s" % data["rule"]
        result_rule = None
        for rule in self._yara_rules:
            if rule.rule_name == data["rule"]:
                result_rule = rule
        if not result_rule:
            result_rule = self.YaraRule()
        result_rule.match_data = data
        self._results.append(result_rule)

        self.yara.CALLBACK_CONTINUE

    def _translateMemOffsetToVirtualAddress(self, offset):
        va_offset = 0
        for seg in self.segment_offsets:
            if seg[1] < offset < seg[2]:
                va_offset = seg[0] + (offset - seg[1])
        return va_offset