<commit_before>import re
import hashlib
import pefile
import io
import yara

from malwareconfig.yarascanner import YaraScanner

from zipfile import ZipFile

# this is a file parser class it will expose the resources, strings and some otheer things about a file.


class FileParser:
    def __init__(self, file_path=None, rawdata=None):
        if file_path:
            file_object = open(file_path, 'rb')
        else:
            file_object = io.BytesIO(rawdata)
            file_object.name = "DummyFile.ext"
        self.file_name = file_object.name
        self.file_data = file_object.read()
        self.file_size = len(self.file_data)
        self.malware_name = ''
        self.yarascan()
        file_object.close()

    def yarascan(self):
        print("  [-] Scanning File")
        scanner = YaraScanner()
        scanner.yara_scan(self.file_data)
        if len(scanner.rule_list) > 0:
            self.malware_name = scanner.rule_list[0]

    def file_hash(self, hash_type="sha256"):
        filehash = ''
        if hash_type == "sha256":
            filehash = hashlib.sha256(self.file_data).hexdigest()
        return filehash

    def pe_resource_names(self):
        """
        Read PE Resources and return a list of resource names
        :return: list
        """
        resource_names = []
        pe = pefile.PE(data=self.file_data)
        for rsrc in pe.DIRECTORY_ENTRY_RESOURCE.entries:
            for entry in rsrc.directory.entries:
                if entry.name is not None:
                    resource_names.append(entry.name.decode('utf-8'))
        return resource_names

    def pe_resource_by_name(self, resource_name):
        """
        Extract a PE Resource from a binary by name
        :param resource_name: str
        :return: byte array
        """
        offset = 0x00
        size = 0x00

        pe = pefile.PE(data=self.file_data)
        for rsrc in pe.DIRECTORY_ENTRY_RESOURCE.entries:
            for entry in rsrc.directory.entries:
                if entry.name is not None:
                    if entry.name.__str__() == resource_name:
                        offset = entry.directory.entries[0].data.struct.OffsetToData
                        size = entry.directory.entries[0].data.struct.Size

        return pe.get_memory_mapped_image()[offset:offset + size]

    def dotnet_resource(self, resource_name):
        """
        Extract a .NET Resource by name
        :param resource_name:
        :return:
        """
        rules = yara.compile(source='import "dotnet" rule a { condition: false }')

        def modules_callback(data):
            for i, resource in enumerate(data.get('resources', [])):
                offset = resource['offset']
                length = resource['length']
                print(dir(resource))
                resource_data = self.file_data[offset:offset + length]
                print(resource_data[:4])

            return yara.CALLBACK_CONTINUE

        rules.match(data=self.file_data, modules_callback=modules_callback)

    def dotnet_guids(self):
        """
        Exrtract GUIDS from a .NET Binary
        :return: list of guids
        """
        rules = yara.compile(source='import "dotnet" rule a { condition: false }')
        guid_list = []

        def modules_callback(data):
            for i, guid in enumerate(data.get('guids', [])):
                guid_list.append(guid.decode('utf-8'))
            return yara.CALLBACK_CONTINUE<commit_msg>get pe resource by name and list of resource names<commit_after>import re
import hashlib
import pefile
import io
import yara

from malwareconfig.yarascanner import YaraScanner

from zipfile import ZipFile

# this is a file parser class it will expose the resources, strings and some otheer things about a file.


class FileParser:
    def __init__(self, file_path=None, rawdata=None):
        if file_path:
            file_object = open(file_path, 'rb')
        else:
            file_object = io.BytesIO(rawdata)
            file_object.name = "DummyFile.ext"
        self.file_name = file_object.name
        self.file_data = file_object.read()
        self.file_size = len(self.file_data)
        self.malware_name = ''
        self.yarascan()
        file_object.close()

    def yarascan(self):
        print("  [-] Scanning File")
        scanner = YaraScanner()
        scanner.yara_scan(self.file_data)
        if len(scanner.rule_list) > 0:
            self.malware_name = scanner.rule_list[0]

    def file_hash(self, hash_type="sha256"):
        filehash = ''
        if hash_type == "sha256":
            filehash = hashlib.sha256(self.file_data).hexdigest()
        return filehash

    def pe_resource_names(self):
        """
        Read PE Resources and return a list of resource names
        :return: list
        """
        resource_names = []
        pe = pefile.PE(data=self.file_data)
        for rsrc in pe.DIRECTORY_ENTRY_RESOURCE.entries:
            for entry in rsrc.directory.entries:
                if entry.name is not None:
                    resource_names.append(entry.name.decode('utf-8'))
        return resource_names

    def pe_resource_by_name(self, resource_name):
        """
        Extract a PE Resource from a binary by name
        :param resource_name: str
        :return: byte array
        """
        offset = 0x00
        size = 0x00

        pe = pefile.PE(data=self.file_data)
        for rsrc in pe.DIRECTORY_ENTRY_RESOURCE.entries:
            print(rsrc.name, "====")
            for entry in rsrc.directory.entries:
                if entry.name is not None:
                    if entry.name.__str__() == resource_name:
                        offset = entry.directory.entries[0].data.struct.OffsetToData
                        size = entry.directory.entries[0].data.struct.Size

        return pe.get_memory_mapped_image()[offset:offset + size]


    def dotnet_resource_names(self):
        """
        Read .NET Resources and return a list of resource names
        :return: list
        """
        rules = yara.compile(source='import "dotnet" rule a { condition: false }')
        resource_list = []

        def modules_callback(data):
            for i, resource in enumerate(data.get('resources', [])):
                resource_list.append(resource['name'])
            return yara.CALLBACK_CONTINUE

        rules.match(data=self.file_data, modules_callback=modules_callback)
        return resource_list

    def dotnet_resource_by_name(self, resource_name):
        """
        Extract a .NET Resource by name
        :param resource_name:
        :return:
        """
        rules = yara.compile(source='import "dotnet" rule a { condition: false }')

        def modules_callback(data):
            for i, resource in enumerate(data.get('resources', [])):
                if resource['name'] == resource_name:
                    offset = resource['offset']
                    length = resource['length']
                    self.res_data = self.file_data[offset:offset + length]
                    print(self.res_data[:4])


            return yara.CALLBACK_CONTINUE

        rules.match(data=self.file_data, modules_callback=modules_callback)
        return self.res_data

    def dotnet_guids(self):
        """
        Exrtract GUIDS from a .NET Binary
        :return: list of guids
        """
        rules = yara.compile(source='import "dotnet" rule a { condition: false }')
        guid_list = []

        def modules_callback(data):
            for i, guid in enumerate(data.get('guids', [])):
                guid_list.append(guid.decode('utf-8'))
            return yara.CALLBACK_CONTINUE
{'fraction_non_alphanumeric': 0.09587965990843689, 'fraction_numerical': 0.0057553956834532375, 'mean_word_length': 2.0743868114193806, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7191819', 'n_tokens_mistral': 2239, 'n_tokens_neox': 2149, 'n_words': 519}