Exemple #1
0
def get(pe):
	try:
		for resource_type in pe.DIRECTORY_ENTRY_RESOURCE.entries:
			if resource_type.name is not None:
				name = "%s" % resource_type.name
			else:
				name = "%s" % pefile.RESOURCE_TYPE.get(resource_type.struct.Id)

			if name == None:
				name = "%d" % resource_type.struct.Id

			if hasattr(resource_type, 'directory'):
				for resource_id in resource_type.directory.entries:
					if hasattr(resource_id, 'directory'):
						for resource_lang in resource_id.directory.entries:
							try:
								data = pe.get_data(resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size)
							except:
								pass
							lang = pefile.LANG.get(resource_lang.data.lang, '*unknown*')
							sublang = pefile.get_sublang_name_for_lang( resource_lang.data.lang, resource_lang.data.sublang )

							data = filter(lambda x: x in string.printable, data)

			#print name, data, lang, sublang, hex(resource_lang.data.struct.OffsetToData), resource_lang.data.struct.Size
			res_array.append({"name": name, "data": data, "offset": hex(resource_lang.data.struct.OffsetToData), "size": resource_lang.data.struct.Size, "language": lang, "sublanguage": sublang})
	except:
		pass

	return res_array
Exemple #2
0
def check_rsrc(pe):
    ret = {}
    if hasattr(pe, 'DIRECTORY_ENTRY_RESOURCE'):
        i = 0
        for resource_type in pe.DIRECTORY_ENTRY_RESOURCE.entries:
            if resource_type.name is not None:
                name = "%s" % resource_type.name
            else:
                name = "%s" % pefile.RESOURCE_TYPE.get(resource_type.struct.Id)
            if name == None:
                name = "%d" % resource_type.struct.Id
            if hasattr(resource_type, 'directory'):
                for resource_id in resource_type.directory.entries:
                    if hasattr(resource_id, 'directory'):
                        for resource_lang in resource_id.directory.entries:
                            data = pe.get_data(resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size)
                            filetype = get_filetype_data(data)
                            lang = pefile.LANG.get(resource_lang.data.lang, '*unknown*')
                            sublang = pefile.get_sublang_name_for_lang( resource_lang.data.lang, resource_lang.data.sublang )
                            ret[i] = (name, resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size, filetype, lang, sublang)
                            #ret[i] = (name, resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size, lang, sublang)
                            i += 1
        if not ret:
            return None
        else:
            return ret
    else:
        return None
Exemple #3
0
def resource(level, r):
    """Recursive printing of resources"""
    if hasattr(r, "data"):
        # resource
        offset = r.data.struct.OffsetToData
        size = r.data.struct.Size
        data = pe.get_memory_mapped_image()[offset:offset+size]
        m = hashlib.md5()
        m.update(data)
        print("    "*level + "-%s\t%i\t%i\t%s\t%s\t%s" % (
                str(r.name),
                r.id,
                size,
                m.hexdigest(),
                pefile.LANG.get(r.data.lang, 'UNKNOWN'),
                pefile.get_sublang_name_for_lang(r.data.lang, r.data.sublang)
            )
        )
    else:
        # directory
        if r.name is None:
            print("    "*level + "-" + str(r.id))
        else:
            print("    "*level + "-" + str(r.name))
        for r2 in r.directory.entries:
            resource(level+1, r2)
Exemple #4
0
 def resource(self, pe, level, r, parents):
     """Recursive printing of resources"""
     if hasattr(r, "data"):
         # resource
         offset = r.data.struct.OffsetToData
         size = r.data.struct.Size
         data = pe.get_memory_mapped_image()[offset:offset+size]
         m = hashlib.md5()
         m.update(data)
         print("%-12s %-7s %-9s %-14s %-17s %-14s %-9s" % (
                 "-".join(parents + [str(r.id)]),
                 str(r.name),
                 "%i B" % size,
                 pefile.LANG.get(r.data.lang, 'UNKNOWN'),
                 pefile.get_sublang_name_for_lang(r.data.lang, r.data.sublang),
                 magic.from_buffer(data),
                 m.hexdigest()
             )
         )
     else:
         # directory
         parents = copy.copy(parents)
         if r.id is not None:
             parents.append(str(r.id))
         else:
             parents.append(r.name.string.decode('utf-8'))
         for r2 in r.directory.entries:
             self.resource(pe, level+1, r2, parents)
Exemple #5
0
        def get_resources(pe):
            resources = []
            if hasattr(pe, 'DIRECTORY_ENTRY_RESOURCE'):
                count = 1
                for resource_type in pe.DIRECTORY_ENTRY_RESOURCE.entries:
                    try:
                        resource = {}

                        if resource_type.name is not None:
                            name = str(resource_type.name)
                        else:
                            name = str(pefile.RESOURCE_TYPE.get(resource_type.struct.Id, "UNKNOWN"))

                        if name is None:
                            name = str(resource_type.struct.Id)

                        if hasattr(resource_type, 'directory'):
                            for resource_id in resource_type.directory.entries:
                                if hasattr(resource_id, 'directory'):
                                    for resource_lang in resource_id.directory.entries:
                                        data = pe.get_data(resource_lang.data.struct.OffsetToData,
                                                           resource_lang.data.struct.Size)
                                        entropy = get_entropy(data)
                                        filetype = get_type(data)
                                        md5 = get_md5(data)
                                        sha256 = get_sha256(data)
                                        language = pefile.LANG.get(resource_lang.data.lang, None)
                                        language_desc = LCID.get(resource_lang.id, 'unknown language')
                                        sublanguage = pefile.get_sublang_name_for_lang(
                                            resource_lang.data.lang, resource_lang.data.sublang)
                                        offset = ('%-8s' % hex(resource_lang.data.struct.OffsetToData)).strip()
                                        size = ('%-8s' % hex(resource_lang.data.struct.Size)).strip()

                                        resource = [
                                            count, name, offset, md5, sha256, size, filetype, entropy, language,
                                            sublanguage, language_desc
                                        ]

                                        # Dump resources if requested
                                        if self.dump and pe == self.pe:
                                            if self.dump:
                                                folder = self.dump
                                            else:
                                                folder = tempfile.mkdtemp()

                                            resource_path = path.join(folder, '{0}_{1}_{2}'.format(
                                                self.sha256, offset, name))
                                            resource.append(resource_path)

                                            with open(resource_path, 'wb') as resource_handle:
                                                resource_handle.write(data)

                                        resources.append(resource)

                                        count += 1
                    except Exception as e:
                        log.error(e)
                        continue

            return resources
Exemple #6
0
def get(pe):
	try:
		for resource_type in pe.DIRECTORY_ENTRY_RESOURCE.entries: #리소스 종류가 정의되있는 디렉토와 파일 비교.
			if resource_type.name is not None: #리소스 타입이 정의된 경우
				name = "%s" % resource_type.name #리소스의 타입을 정수로 받아 이름을 저장
			else:
				name = "%s" % pefile.RESOURCE_TYPE.get(resource_type.struct.Id) #리소스 이름을 resource_type.struct.Id 통해 받아옴

			if name == None: #두 경우가 아닌경우
				name = "%d" % resource_type.struct.Id #구조체의 이름을 리소스 이름으로 정의

			if hasattr(resource_type, 'directory'): # resource_type 에 directory 변수가 있는지 확인.
				for resource_id in resource_type.directory.entries: # 모든 디렉토리 검사.
					if hasattr(resource_id, 'directory'): # resource_id 에 directory 변수가 있는지 검사.
						for resource_lang in resource_id.directory.entries: # resource_id.directory.entries
							try:
								data = pe.get_data(resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size)
								#리소스의 구조가 정의되있고 사이즈가 같다면
							except:
								pass
							lang = pefile.LANG.get(resource_lang.data.lang, '*unknown*') #pefile.LANG.get 함수를 이용해 리소스 이름이 있다면 지정. 없다면 unknown으로 지정
							sublang = pefile.get_sublang_name_for_lang( resource_lang.data.lang, resource_lang.data.sublang )
							#언어 형식지정을 위한 sublang 사용 (pefile에 정의되있음)

							"""모든값은 16진수로 저장됨"""

							data = filter(lambda x: x in string.printable, data) #람다식을 이용해 16진수값을 출력가능한 값으로 변환

			#print 이름, 데이터, hex(resource_lang.data.struct.OffsetToData),리소스 사이즈 출력
			res_array.append({"name": name, "data": data, "offset": hex(resource_lang.data.struct.OffsetToData), "size": resource_lang.data.struct.Size, "language": lang, "sublanguage": sublang})
	except:
		pass

	return res_array
Exemple #7
0
	def get_resource_info(self):
		if hasattr(self._pe, 'DIRECTORY_ENTRY_RESOURCE'):
			for resource_type in self._pe.DIRECTORY_ENTRY_RESOURCE.entries:
				if resource_type.name is not None:
					name = "%s" % resource_type.name
				else:
					name = "%s" % pefile.RESOURCE_TYPE.get(resource_type.struct.Id)
				if name == None:
					name = "%d" % resource_type.struct.Id
				if hasattr(resource_type, 'directory'):
					for resource_id in resource_type.directory.entries:
						if hasattr(resource_id, 'directory'):
							for resource_lang in resource_id.directory.entries:
								data = self._pe.get_data(resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size)
								lang = pefile.LANG.get(resource_lang.data.lang, '*unknown*')
								sublang = pefile.get_sublang_name_for_lang( resource_lang.data.lang, resource_lang.data.sublang )
								resource_md5 = "hash2be"

								if self._hash_mode == "md5":
									resource_md5=hashlib.md5(data).hexdigest()
								elif self._hash_mode == "sha1":
									resource_md5=hashlib.sha1(data).hexdigest()
								elif self._hash_mode == "sha256":
									resource_md5=hashlib.sha256(data).hexdigest()

								if self._ssd:
									resource_ssdeep = ssdeep.hash(data)
								if self._dump_mode == True:
									resource_dump=open("ripPE-RESOURCE-" + self._md5 + "-" + name + "-" + resource_md5 + ".rsrc","wb+")
									resource_dump.write(data)
									resource_dump.close()
								self.output_handle("%s,%s,resource_md5,RESOURCE-%s,%s" % (self._filename,self._md5,name,resource_md5))
								if self._ssd:
									self.output_handle("%s,%s,resource_ssdeep,RESOURCE-%s,%s" % (self._filename,self._md5,name,resource_ssdeep))
Exemple #8
0
 def check_rsrc(self, pe):
     ret = {}
     if hasattr(pe, 'DIRECTORY_ENTRY_RESOURCE'):
         i = 0
         for resource_type in pe.DIRECTORY_ENTRY_RESOURCE.entries:
             if resource_type.name is not None:
                 name = "%s" % resource_type.name
             else:
                 name = "%s" % pefile.RESOURCE_TYPE.get(
                     resource_type.struct.Id)
             if name == None:
                 name = "%d" % resource_type.struct.Id
             if hasattr(resource_type, 'directory'):
                 for resource_id in resource_type.directory.entries:
                     if hasattr(resource_id, 'directory'):
                         for resource_lang in resource_id.directory.entries:
                             data = pe.get_data(
                                 resource_lang.data.struct.OffsetToData,
                                 resource_lang.data.struct.Size)
                             filetype = get_filetype(data)
                             lang = pefile.LANG.get(resource_lang.data.lang,
                                                    '*unknown*')
                             sublang = pefile.get_sublang_name_for_lang(
                                 resource_lang.data.lang,
                                 resource_lang.data.sublang)
                             ret[i] = (
                                 name,
                                 resource_lang.data.struct.OffsetToData,
                                 resource_lang.data.struct.Size, filetype,
                                 lang, sublang)
                             i += 1
     return ret
Exemple #9
0
 def check_rsrc(self, pe):
     ret = {}
     if hasattr(pe, 'DIRECTORY_ENTRY_RESOURCE'):
         i = 0
         for resource_type in pe.DIRECTORY_ENTRY_RESOURCE.entries:
             if resource_type.name is not None:
                 name = "%s" % resource_type.name
             else:
                 name = "%s" % pefile.RESOURCE_TYPE.get(resource_type.struct.Id)
             if name is None:
                 name = "%d" % resource_type.struct.Id
             if hasattr(resource_type, 'directory'):
                 for resource_id in resource_type.directory.entries:
                     if hasattr(resource_id, 'directory'):
                         for resource_lang in resource_id.directory.entries:
                             data = pe.get_data(resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size)
                             if 'magic' in sys.modules:
                                 if sys.version_info <= (2, 6):
                                     filetype = self.ms.buffer(data)
                                 else:
                                     # filetype = magic._buffer(data)
                                     filetype = "Magic Error"
                                 lang = pefile.LANG.get(resource_lang.data.lang, '*unknown*')
                                 sublang = pefile.get_sublang_name_for_lang(resource_lang.data.lang, resource_lang.data.sublang)
                             else:
                                 filetype = None
                             if filetype == None:
                                 filetype = ''
                             ret[i] = (name, resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size, filetype, lang, sublang)
                             i += 1
     return ret
Exemple #10
0
 def check_rsrc(self):
     """ Function needed to determine the compilation language """
     try:
         ret = {}
         if hasattr(self.pe, 'DIRECTORY_ENTRY_RESOURCE'):
             i = 0
             for resource_type in self.pe.DIRECTORY_ENTRY_RESOURCE.entries:
                 if resource_type.name is not None:
                     name = "%s" % resource_type.name
                 else:
                     name = "%s" % pefile.RESOURCE_TYPE.get(resource_type.struct.Id)
                 if name == None:
                     name = "%d" % resource_type.struct.Id
                 if hasattr(resource_type, 'directory'):
                     for resource_id in resource_type.directory.entries:
                         if hasattr(resource_id, 'directory'):
                             for resource_lang in resource_id.directory.entries:
                                 try:
                                     data = self.pe.get_data(resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size)
                                     filetype = magic.from_buffer(open(self.filename).read(1024)) 
                                     lang = pefile.LANG.get(resource_lang.data.lang, 'qq_*unknown*')
                                     sublang = pefile.get_sublang_name_for_lang( resource_lang.data.lang, resource_lang.data.sublang )
                                     ret[i] = (name, resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size, filetype, lang, sublang)
                                     i += 1
                                 except pefile.PEFormatError:
                                     pass
     except:
         ret = False 
         pass
     finally:
         return ret
Exemple #11
0
def resource(pe, level, r, parents):
    """Recursive printing of resources"""
    if hasattr(r, "data"):
        # resource
        offset = r.data.struct.OffsetToData
        size = r.data.struct.Size
        data = pe.get_memory_mapped_image()[offset:offset + size]
        m = hashlib.md5()
        m.update(data)
        result = ("-".join(parents + [str(r.id)]), str(r.name), "%i B" % size,
                  pefile.LANG.get(r.data.lang, 'UNKNOWN'),
                  pefile.get_sublang_name_for_lang(r.data.lang,
                                                   r.data.sublang),
                  m.hexdigest())

        res.append(result)
        # print tabulate(result, headers=['Id', 'Name', 'Size', 'Lang', 'Sublang', 'MD5'])

    else:
        # directory
        #try:
        parents = copy.copy(parents)
        if r.id:
            parents.append(str(r.id))
        elif r.name:

            parents.append(r.name.string.decode('utf-8'))

        for r2 in r.directory.entries:
            resource(pe, level + 1, r2, parents)
Exemple #12
0
    def resources(self):
        # TODO: Add Tests For Resources
        # TODO: Handle all cases + refactor.
        rv = {}
        # https://github.com/hiddenillusion/AnalyzePE/blob/9c76ecbc3ac417bc07439c244f2d5ed19af06578/pescanner.py#L190
        if hasattr(self.pe, 'DIRECTORY_ENTRY_RESOURCE'):
            for index, resource_entry in enumerate(
                    self.pe.DIRECTORY_ENTRY_RESOURCE.entries):  # pylint: disable=no-member
                rv[index] = {
                    "name": "",
                    "filetype": "",
                    "lang": "",
                    "sublang": ""
                }
                if resource_entry.name is not None:
                    rv[index]["name"] = resource_entry.name
                else:
                    rv[index]["name"] = pefile.RESOURCE_TYPE.get(
                        resource_entry.struct.Id, resource_entry.struct.Id)

                if hasattr(resource_entry, 'directory'):
                    for resource_id in resource_entry.directory.entries:
                        if hasattr(resource_id, 'directory'):
                            for entry in resource_id.directory.entries:
                                data = self.pe.get_data(
                                    entry.data.struct.OffsetToData,
                                    entry.data.struct.Size)
                                rv[index]["filetype"] = magic.from_buffer(data)
                                rv[index]["lang"] = pefile.LANG.get(
                                    entry.data.lang, '*unknown*')
                                rv[index][
                                    "sublang"] = pefile.get_sublang_name_for_lang(
                                        entry.data.lang, entry.data.sublang)

        return rv
Exemple #13
0
        def get_resources(pe):
            resources = []
            if hasattr(pe, 'DIRECTORY_ENTRY_RESOURCE'):
                count = 1
                for resource_type in pe.DIRECTORY_ENTRY_RESOURCE.entries:
                    try:
                        resource = {}

                        if resource_type.name is not None:
                            name = str(resource_type.name)
                        else:
                            name = str(pefile.RESOURCE_TYPE.get(resource_type.struct.Id))

                        if name is None:
                            name = str(resource_type.struct.Id)

                        if hasattr(resource_type, 'directory'):
                            for resource_id in resource_type.directory.entries:
                                if hasattr(resource_id, 'directory'):
                                    for resource_lang in resource_id.directory.entries:
                                        data = pe.get_data(resource_lang.data.struct.OffsetToData,
                                                           resource_lang.data.struct.Size)
                                        filetype = get_type(data)
                                        md5 = get_md5(data)
                                        language = pefile.LANG.get(resource_lang.data.lang, None)
                                        sublanguage = pefile.get_sublang_name_for_lang(
                                            resource_lang.data.lang, resource_lang.data.sublang)
                                        offset = ('%-8s' % hex(resource_lang.data.struct.OffsetToData)).strip()
                                        size = ('%-8s' % hex(resource_lang.data.struct.Size)).strip()

                                        resource = [count, name, offset, md5, size, filetype, language, sublanguage]

                                        # Dump resources if requested to and if the file currently being
                                        # processed is the opened session file.
                                        # This is to avoid that during a --scan all the resources being
                                        # scanned are dumped as well.
                                        if (self.args.open or self.args.dump) and pe == self.pe:
                                            if self.args.dump:
                                                folder = self.args.dump
                                            else:
                                                folder = tempfile.mkdtemp()

                                            resource_path = os.path.join(
                                                folder, '{0}_{1}_{2}'.format(__sessions__.current.file.md5, offset,
                                                                             name))
                                            resource.append(resource_path)

                                            with open(resource_path, 'wb') as resource_handle:
                                                resource_handle.write(data)

                                        resources.append(resource)

                                        count += 1
                    except Exception as e:
                        self.log('error', e)
                        continue

            return resources
Exemple #14
0
    def resources(self):
        resources = []
        if hasattr(self.pe, "DIRECTORY_ENTRY_RESOURCE"):
            for resource_type in self.pe.DIRECTORY_ENTRY_RESOURCE.entries:
                try:
                    if resource_type.name is not None:
                        name = str(resource_type.name)
                    else:
                        name = str(pefile.RESOURCE_TYPE.get(resource_type.struct.Id))
                    if name is None:
                        name = str(resource_type.struct.Id)

                    if hasattr(resource_type, "directory"):
                        for resource_id in resource_type.directory.entries:
                            if hasattr(resource_id, "directory"):
                                for resource_lang in resource_id.directory.entries:
                                    data = self.pe.get_data(
                                        resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size
                                    )
                                    filetype = self.__get_filetype(data)
                                    md5 = self.__md5(data)
                                    language = pefile.LANG.get(resource_lang.data.lang, None)
                                    sublanguage = pefile.get_sublang_name_for_lang(
                                        resource_lang.data.lang, resource_lang.data.sublang
                                    )
                                    offset = ("%-8s" % hex(resource_lang.data.struct.OffsetToData)).strip()
                                    size = ("%-8s" % hex(resource_lang.data.struct.Size)).strip()

                                    resource = {
                                        "name": name,
                                        "offset": offset,
                                        "md5": md5,
                                        "size": size,
                                        "filetype": filetype,
                                        "language": language.replace("LANG_", "").lower(),
                                        "sublanguage": sublanguage.replace("SUBLANG_", "").lower(),
                                    }

                                    # Dump resources if requested to and if the file currently being
                                    # processed is the opened session file.
                                    # This is to avoid that during a --scan all the resources being
                                    # scanned are dumped as well.
                                    # if dump_to and self.pe == self.pe:
                                    #     resource_path = os.path.join(dump_to,
                                    #                                  '{0}_{1}_{2}'.format(__session__.file.md5,
                                    #                                                       offset, name))
                                    #     resource.append(resource_path)
                                    #
                                    #     with open(resource_path, 'wb') as resource_handle:
                                    #         resource_handle.write(data)

                                    resources.append(resource)
                except Exception as e:
                    print_error(e)
                    continue

        return resources
    def get_resources_info(self):
        res_array = []
        printable = string.printable
        try:
            for resource_type in self.__pe.DIRECTORY_ENTRY_RESOURCE.entries:
                if resource_type.name is not None:
                    name = "%s" % resource_type.name
                else:
                    name = "%s" % pefile.RESOURCE_TYPE.get(
                        resource_type.struct.Id)

                if name == None:
                    name = "%d" % resource_type.struct.Id

                if hasattr(resource_type, 'directory'):
                    for resource_id in resource_type.directory.entries:
                        if hasattr(resource_id, 'directory'):
                            for resource_lang in resource_id.directory.entries:
                                try:
                                    data = self.__pe.get_data(
                                        resource_lang.data.struct.OffsetToData,
                                        resource_lang.data.struct.Size)
                                except:
                                    pass
                                lang = pefile.LANG.get(resource_lang.data.lang,
                                                       '*unknown*')
                                sublang = pefile.get_sublang_name_for_lang(
                                    resource_lang.data.lang,
                                    resource_lang.data.sublang)

                                result = ""

                                for each in data:
                                    if chr(each) in printable:
                                        result += chr(each)

                # print name, data, lang, sublang, hex(resource_lang.data.struct.OffsetToData), resource_lang.data.struct.Size
                res_array.append({
                    "name":
                    name,
                    "data":
                    result,
                    "offset":
                    hex(resource_lang.data.struct.OffsetToData),
                    "size":
                    resource_lang.data.struct.Size,
                    "language":
                    lang,
                    "sublanguage":
                    sublang
                })
        except:
            pass
        return res_array
Exemple #16
0
def _resources_data_entry(exe):
    data = list()
    data.append(exe.DIRECTORY_ENTRY_RESOURCE.struct.dump_dict())

    for resource_type in exe.DIRECTORY_ENTRY_RESOURCE.entries:
        resource_type_dict = dict()

        if resource_type.name is not None:
            resource_type_dict['Name'] = resource_type.name
        else:
            resource_type_dict['Id'] = (
                resource_type.struct.Id, pefile.RESOURCE_TYPE.get(resource_type.struct.Id, '-'))

        resource_type_dict.update(resource_type.struct.dump_dict())
        data.append(resource_type_dict)

        if hasattr(resource_type, 'directory'):
            directory_list = list()
            directory_list.append(resource_type.directory.struct.dump_dict())
            data.append(directory_list)

            for resource_id in resource_type.directory.entries:
                resource_id_dict = dict()

                if resource_id.name is not None:
                    resource_id_dict['Name'] = resource_id.name
                else:
                    resource_id_dict['Id'] = resource_id.struct.Id

                resource_id_dict.update(resource_id.struct.dump_dict())
                directory_list.append(resource_id_dict)

                if hasattr(resource_id, 'directory'):
                    resource_id_list = list()
                    resource_id_list.append(resource_id.directory.struct.dump_dict())
                    directory_list.append(resource_id_list)

                    for resource_lang in resource_id.directory.entries:
                        if hasattr(resource_lang, 'data'):
                            resource_lang_dict = dict()
                            resource_lang_dict['LANG'] = resource_lang.data.lang
                            resource_lang_dict['SUBLANG'] = resource_lang.data.sublang
                            resource_lang_dict['LANG_NAME'] = pefile.LANG.get(resource_lang.data.lang, '*unknown*')
                            resource_lang_dict['SUBLANG_NAME'] = pefile.get_sublang_name_for_lang(resource_lang.data.lang, resource_lang.data.sublang)
                            resource_lang_dict.update(resource_lang.struct.dump_dict())
                            resource_lang_dict.update(resource_lang.data.struct.dump_dict())
                            resource_id_list.append(resource_lang_dict)
                    if hasattr(resource_id.directory, 'strings') and resource_id.directory.strings:
                        for idx, res_string in list(resource_id.directory.strings.items()):
                            resource_id_list.append(res_string.encode(
                                    'unicode-escape',
                                    'backslashreplace').decode(
                                        'ascii'))       
    return data
Exemple #17
0
    def get_resources(self, depth=0, resource=None, file_details={}, resource_path=[]):
        if depth == 0:

            if hasattr(self.pe, 'DIRECTORY_ENTRY_RESOURCE'):
                for resource in self.pe.DIRECTORY_ENTRY_RESOURCE.entries:
                    file_details.update(self.get_resources(depth + 1, resource, file_details, []))
                return {'resources' : file_details}
        else:
            if hasattr(resource, 'data'):
                resource_data = self.pe.get_data(resource.data.struct.OffsetToData, resource.data.struct.Size)
                md5 = hashlib.md5()
                md5.update(resource_data)
                md5_hash = md5.hexdigest()
                id = None
                name = None
                if resource.id:
                    id = str(resource.id)
                if resource.name:
                    name = str(resource.name)
                else:
                    name = str(pefile.RESOURCE_TYPE.get(resource.struct.Id))
                if id is not None:
                    resource_path.append(id)
                if name is not None:
                    resource_path.append(name)

                file_details[':'.join(resource_path)] = {'md5' : md5_hash,
                                                         'lang' : pefile.LANG.get(resource.data.lang, 'none'),
                                                         'sub_lang' : pefile.get_sublang_name_for_lang(resource.data.lang, resource.data.lang),
                                                         'type' : utils.get_type(buffer=resource_data).get('file_type', 'unknown'),
                                                         'size' : resource.data.struct.Size,
                                                         'offset' : resource.data.struct.OffsetToData}
                return file_details
            else:
                # We're at a directory and need to recurse deeper
                id = None
                name = None
                if resource.id:
                    id = resource.id
                if resource.name:
                    name = resource.name.string.decode('utf-8')
                else:
                    name = pefile.RESOURCE_TYPE.get(resource.struct.Id)
                if id is not None:
                    resource_path.append(str(id))
                if name is not None:
                    resource_path.append(str(name))

                for child_resource in resource.directory.entries:
                    file_details.update(self.get_resources(depth+1, child_resource, file_details, resource_path))

                return file_details

        return file_details
Exemple #18
0
        def resource_info(pe, r, parents):
            """Recursive info of resources"""

            # resource
            if hasattr(r, "data"):

                # gather all the info
                offset = r.data.struct.OffsetToData
                size = r.data.struct.Size
                data = pe.get_memory_mapped_image()[offset:offset + size]
                parents_path = "/".join(parents) + "/"
                path = parents_path + str(
                    r.id) if not r.name else parents_path + r.name
                m = hashlib.md5()
                m.update(data)
                md5 = m.hexdigest()
                magic_type = magic.from_buffer(data)
                lang = pefile.LANG.get(r.data.lang, 'UNKNOWN')
                sublang = pefile.get_sublang_name_for_lang(
                    r.data.lang, r.data.sublang)

                # display it if we want
                cli_out(
                    "%-19s %-9s %-14s %-17s %-14s %-9s" %
                    (path, "%i B" % size, lang, sublang, magic_type, md5),
                    cli_mode)

                # return it in a dict
                return [{
                    "path": path,
                    "size": size,
                    "md5": md5,
                    "magic_type": magic_type,
                    "lang": lang,
                    "sublang": sublang
                }]

            # directory
            else:

                res = []

                # append this name or ID to the parents list
                parents = copy.copy(parents)
                if r.id is not None:
                    parents.append(str(r.id))
                else:
                    parents.append(r.name.string.decode('utf-8'))

                for r2 in r.directory.entries:
                    res += resource_info(pe, r2, parents)

                return res
Exemple #19
0
    def resources(self):
        resources = []
        if hasattr(self.pe, 'DIRECTORY_ENTRY_RESOURCE'):
            for resource_type in self.pe.DIRECTORY_ENTRY_RESOURCE.entries:
                try:
                    if resource_type.name is not None:
                        name = str(resource_type.name)
                    else:
                        name = str(pefile.RESOURCE_TYPE.get(resource_type.struct.Id))
                    if name is None:
                        name = str(resource_type.struct.Id)

                    if hasattr(resource_type, 'directory'):
                        for resource_id in resource_type.directory.entries:
                            if hasattr(resource_id, 'directory'):
                                for resource_lang in resource_id.directory.entries:
                                    data = self.pe.get_data(resource_lang.data.struct.OffsetToData,
                                                            resource_lang.data.struct.Size)
                                    filetype = self.__get_filetype(data)
                                    md5 = self.__md5(data)
                                    language = pefile.LANG.get(resource_lang.data.lang, None)
                                    sublanguage = pefile.get_sublang_name_for_lang(resource_lang.data.lang,
                                                                                   resource_lang.data.sublang)
                                    offset = ('%-8s' % hex(resource_lang.data.struct.OffsetToData)).strip()
                                    size = ('%-8s' % hex(resource_lang.data.struct.Size)).strip()

                                    resource = {'name': name,
                                                'offset': offset,
                                                'md5': md5,
                                                'size': size,
                                                'filetype': filetype,
                                                'language': language.replace('LANG_', '').lower(),
                                                'sublanguage': sublanguage.replace('SUBLANG_', '').lower()}

                                    # Dump resources if requested to and if the file currently being
                                    # processed is the opened session file.
                                    # This is to avoid that during a --scan all the resources being
                                    # scanned are dumped as well.
                                    # if dump_to and self.pe == self.pe:
                                    #     resource_path = os.path.join(dump_to,
                                    #                                  '{0}_{1}_{2}'.format(__session__.file.md5,
                                    #                                                       offset, name))
                                    #     resource.append(resource_path)
                                    #
                                    #     with open(resource_path, 'wb') as resource_handle:
                                    #         resource_handle.write(data)

                                    resources.append(resource)
                except Exception as e:
                    print_error(e)
                    continue

        return resources
Exemple #20
0
    def _get_resources(self):
        """Get resources.
        @return: resources dict or None.
        """
        if not self.pe:
            return None

        resources = []

        if hasattr(self.pe, "DIRECTORY_ENTRY_RESOURCE"):
            for resource_type in self.pe.DIRECTORY_ENTRY_RESOURCE.entries:
                try:
                    resource = {}

                    if resource_type.name is not None:
                        name = "%s" % resource_type.name
                    else:
                        name = "%s" % pefile.RESOURCE_TYPE.get(
                            resource_type.struct.Id)
                    if name == None:
                        name = "%d" % resource_type.struct.Id

                    if hasattr(resource_type, "directory"):
                        for resource_id in resource_type.directory.entries:
                            if hasattr(resource_id, "directory"):
                                for resource_lang in resource_id.directory.entries:
                                    data = self.pe.get_data(
                                        resource_lang.data.struct.OffsetToData,
                                        resource_lang.data.struct.Size)
                                    filetype = self._get_filetype(data)
                                    language = pefile.LANG.get(
                                        resource_lang.data.lang, None)
                                    sublanguage = pefile.get_sublang_name_for_lang(
                                        resource_lang.data.lang,
                                        resource_lang.data.sublang)

                                    resource["name"] = name
                                    resource["offset"] = ("%-8s" % hex(
                                        resource_lang.data.struct.OffsetToData)
                                                          ).strip()
                                    resource["size"] = (
                                        "%-8s" %
                                        hex(resource_lang.data.struct.Size)
                                    ).strip()
                                    resource["filetype"] = filetype
                                    resource["language"] = language
                                    resource["sublanguage"] = sublanguage
                                    resources.append(resource)
                except:
                    continue

        return resources
Exemple #21
0
        def get_resources(pe):
            resources = []
            if hasattr(pe, "DIRECTORY_ENTRY_RESOURCE"):
                for resource_type in pe.DIRECTORY_ENTRY_RESOURCE.entries:
                    try:
                        resource = {}

                        if resource_type.name is not None:
                            name = str(resource_type.name)
                        else:
                            name = str(pefile.RESOURCE_TYPE.get(resource_type.struct.Id))

                        if name == None:
                            name = str(resource_type.struct.Id)

                        if hasattr(resource_type, "directory"):
                            for resource_id in resource_type.directory.entries:
                                if hasattr(resource_id, "directory"):
                                    for resource_lang in resource_id.directory.entries:
                                        data = pe.get_data(
                                            resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size
                                        )
                                        filetype = self.__get_filetype(data)
                                        md5 = self.__get_md5(data)
                                        language = pefile.LANG.get(resource_lang.data.lang, None)
                                        sublanguage = pefile.get_sublang_name_for_lang(
                                            resource_lang.data.lang, resource_lang.data.sublang
                                        )
                                        offset = ("%-8s" % hex(resource_lang.data.struct.OffsetToData)).strip()
                                        size = ("%-8s" % hex(resource_lang.data.struct.Size)).strip()

                                        resource = [name, offset, md5, size, filetype, language, sublanguage]

                                        # Dump resources if requested to and if the file currently being
                                        # processed is the opened session file.
                                        # This is to avoid that during a --scan all the resources being
                                        # scanned are dumped as well.
                                        if arg_dump and pe == self.pe:
                                            resource_path = os.path.join(
                                                arg_dump, "{0}_{1}_{2}".format(__session__.file.md5, offset, name)
                                            )
                                            resource.append(resource_path)

                                            with open(resource_path, "wb") as resource_handle:
                                                resource_handle.write(data)

                                        resources.append(resource)
                    except Exception as e:
                        print_error(e)
                        continue

            return resources
Exemple #22
0
    def get_resources(self, pe: pefile.PE) -> List[Dict[str, str]]:
        """Get resources.
        @return: resources dict or None.
        """
        if not pe:
            return None

        resources = []

        if not hasattr(pe, "DIRECTORY_ENTRY_RESOURCE"):
            return resources

        for resource_type in pe.DIRECTORY_ENTRY_RESOURCE.entries:
            try:
                if resource_type.name is not None:
                    name = str(resource_type.name)
                else:
                    name = str(
                        pefile.RESOURCE_TYPE.get(resource_type.struct.Id))
                if hasattr(resource_type, "directory"):
                    for resource_id in resource_type.directory.entries:
                        if hasattr(resource_id, "directory"):
                            for resource_lang in resource_id.directory.entries:
                                data = pe.get_data(
                                    resource_lang.data.struct.OffsetToData,
                                    resource_lang.data.struct.Size)
                                resources.append({
                                    "name":
                                    name,
                                    "offset":
                                    f"0x{resource_lang.data.struct.OffsetToData:08x}",
                                    "size":
                                    f"0x{resource_lang.data.struct.Size:08x}",
                                    "filetype":
                                    self._get_filetype(data),
                                    "language":
                                    pefile.LANG.get(resource_lang.data.lang),
                                    "sublanguage":
                                    pefile.get_sublang_name_for_lang(
                                        resource_lang.data.lang,
                                        resource_lang.data.sublang),
                                    "entropy":
                                    f"{float(self.get_entropy(data)):.02f}",
                                })
            except pefile.PEFormatError as e:
                log.error("get_resources error: %s", str(e))
            except Exception as e:
                log.error(e, exc_info=True)
                continue

        return resources
Exemple #23
0
    def resources(self):
        resources = []
        if hasattr(self.pe, 'DIRECTORY_ENTRY_RESOURCE'):
            for resource_type in self.pe.DIRECTORY_ENTRY_RESOURCE.entries:
                try:
                    resource = {}

                    if resource_type.name is not None:
                        name = str(resource_type.name)
                    else:
                        name = str(pefile.RESOURCE_TYPE.get(resource_type.struct.Id))

                    if name == None:
                        name = str(resource_type.struct.Id)

                    if hasattr(resource_type, 'directory'):
                        for resource_id in resource_type.directory.entries:
                            if hasattr(resource_id, 'directory'):
                                for resource_lang in resource_id.directory.entries:
                                    data = self.pe.get_data(resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size)
                                    md5 = self.__get_md5(data)
                                    fs_id = ""
                                    if not self.artifact.database.fs.exists({"md5":md5}):
                                        fs_id = self.artifact.database.fs.put(data)
                                    else:
                                        grid_file = self.artifact.database.fs.get_version(md5=md5)
                                        fs_id = grid_file._id
                                    filetype = self.__get_filetype(data)

                                    language = pefile.LANG.get(resource_lang.data.lang, None)
                                    sublanguage = pefile.get_sublang_name_for_lang(resource_lang.data.lang, resource_lang.data.sublang)
                                    offset = ('%-8s' % hex(resource_lang.data.struct.OffsetToData)).strip()
                                    size = ('%-8s' % hex(resource_lang.data.struct.Size)).strip()
                                    resource = {
                                        "name": name,
                                        "filetype": filetype,
                                        "offset": offset,
                                        "size": size,
                                        "md5": md5,
                                        "language": language,
                                        "sublanguage": sublanguage,
                                        "fs_id": fs_id
                                    }

                                    resources.append(resource)
                except Exception as e:
                    logging.error(e)
                    continue

            self.data["sub"] = resources
    def process(self):
        pelib = self._getLibrary(PEFileModule().getName())
        if (pelib is None):
            return ""

        ret = []
        if hasattr(pelib, 'DIRECTORY_ENTRY_RESOURCE'):
            i = 0
            for resource_type in pelib.DIRECTORY_ENTRY_RESOURCE.entries:
                if resource_type.name is not None:
                    name = "%s" % resource_type.name
                else:
                    name = "%s" % pefile.RESOURCE_TYPE.get(
                        resource_type.struct.Id)
                if name is None:
                    name = "%d" % resource_type.struct.Id
                if hasattr(resource_type, 'directory'):
                    for resource_id in resource_type.directory.entries:
                        if hasattr(resource_id, 'directory'):
                            for resource_lang in resource_id.directory.entries:
                                try:
                                    data = pelib.get_data(
                                        resource_lang.data.struct.OffsetToData,
                                        resource_lang.data.struct.Size)
                                    # fd=open(name,'wb')
                                    # fd.write(data)
                                    # (data)
                                except pefile.PEFormatError:
                                    return "corrupt"
                                filetype = MIME_TYPE(data, False)
                                lang = pefile.LANG.get(resource_lang.data.lang,
                                                       'unknown')
                                sublang = pefile.get_sublang_name_for_lang(
                                    resource_lang.data.lang,
                                    resource_lang.data.sublang)
                                entry = {}
                                entry["name"] = self._normalize(name)
                                entry["rva"] = self._normalize(
                                    hex(resource_lang.data.struct.OffsetToData)
                                )
                                entry["size"] = self._normalize(
                                    hex(resource_lang.data.struct.Size))
                                entry["type"] = self._normalize(filetype)
                                entry["lang"] = self._normalize(lang)
                                entry["sublang"] = self._normalize(sublang)
                                entry["sha1"] = SHA1(data)
                                ret.append(entry)

        return ret
Exemple #25
0
    def analyze_dir(self, directory, prefix='', _type='', timedate=0):
        """ Analyze a resource directory and obtain all of its items."""
        log = logging.getLogger('Mastiff.Plugins.' + self.name + '.analyze')

        # save the timedate stamp
        timedate = directory.struct.TimeDateStamp

        for top_item in directory.entries:

            if hasattr(top_item, 'data'):
                # at the language level that contains all of our information
                resource = dict()
                resource['Id'] = prefix
                resource['Type'] = _type
                # store the offset as the offset within the file, not the RVA!
                try:
                    resource['Offset'] = self.pe.get_offset_from_rva(
                        top_item.data.struct.OffsetToData)
                    resource['Size'] = top_item.data.struct.Size
                    resource['Lang'] = [ pefile.LANG.get(top_item.data.lang, '*unknown*'), \
                                                            pefile.get_sublang_name_for_lang( top_item.data.lang, top_item.data.sublang ) ]
                    resource['TimeDate'] = timedate
                except pefile.PEFormatError, err:
                    log.error('Error grabbing resource \"%s\" info: %s' %
                              (prefix, err))
                    return False

                self.resources.append(resource)
                log.debug('Adding resource item %s' % resource['Id'])
            elif hasattr(top_item, 'directory'):
                if top_item.name is not None:
                    # in a name level
                    if len(prefix) == 0:
                        newprefix = prefix + str(top_item.name)
                    else:
                        newprefix = ', '.join([prefix, str(top_item.name)])
                else:
                    # if name is blank, we are in a Type level
                    if len(prefix) == 0:
                        newprefix = 'ID ' + str(top_item.id)
                        _type = pefile.RESOURCE_TYPE.get(top_item.id)
                    else:
                        newprefix = ', '.join(
                            [prefix, 'ID ' + str(top_item.id)])

                # we aren't at the end, recurse
                self.analyze_dir(top_item.directory,
                                 prefix=newprefix,
                                 _type=_type)
Exemple #26
0
def get(pe):
    try:
        for resource_type in pe.DIRECTORY_ENTRY_RESOURCE.entries:
            if resource_type.name is not None:
                name = "%s" % resource_type.name
            else:
                name = "%s" % pefile.RESOURCE_TYPE.get(resource_type.struct.Id)

            if name == None:
                name = "%d" % resource_type.struct.Id

            if hasattr(resource_type, 'directory'):
                for resource_id in resource_type.directory.entries:
                    if hasattr(resource_id, 'directory'):
                        for resource_lang in resource_id.directory.entries:
                            try:
                                data = pe.get_data(
                                    resource_lang.data.struct.OffsetToData,
                                    resource_lang.data.struct.Size)
                            except:
                                pass
                            lang = pefile.LANG.get(resource_lang.data.lang,
                                                   '*unknown*')
                            sublang = pefile.get_sublang_name_for_lang(
                                resource_lang.data.lang,
                                resource_lang.data.sublang)

                            data = filter(lambda x: x in string.printable,
                                          data)

            #print name, data, lang, sublang, hex(resource_lang.data.struct.OffsetToData), resource_lang.data.struct.Size
            res_array.append({
                "name":
                name,
                "data":
                data,
                "offset":
                hex(resource_lang.data.struct.OffsetToData),
                "size":
                resource_lang.data.struct.Size,
                "language":
                lang,
                "sublanguage":
                sublang
            })
    except:
        pass

    return res_array
Exemple #27
0
    def _get_resources(self):
        """Get resources.
        @return: resources dict or None.
        """
        if not self.pe:
            return None

        resources = []

        if hasattr(self.pe, "DIRECTORY_ENTRY_RESOURCE"):
            for resource_type in self.pe.DIRECTORY_ENTRY_RESOURCE.entries:
                try:
                    resource = {}

                    if resource_type.name is not None:
                        name = str(resource_type.name)
                    else:
                        name = str(
                            pefile.RESOURCE_TYPE.get(resource_type.struct.Id))

                    if hasattr(resource_type, "directory"):
                        for resource_id in resource_type.directory.entries:
                            if hasattr(resource_id, "directory"):
                                for resource_lang in resource_id.directory.entries:
                                    data = self.pe.get_data(
                                        resource_lang.data.struct.OffsetToData,
                                        resource_lang.data.struct.Size)
                                    filetype = _get_filetype(data)
                                    language = pefile.LANG.get(
                                        resource_lang.data.lang, None)
                                    sublanguage = pefile.get_sublang_name_for_lang(
                                        resource_lang.data.lang,
                                        resource_lang.data.sublang)
                                    resource["name"] = name
                                    resource["offset"] = "0x{0:08x}".format(
                                        resource_lang.data.struct.OffsetToData)
                                    resource["size"] = "0x{0:08x}".format(
                                        resource_lang.data.struct.Size)
                                    resource["filetype"] = filetype
                                    resource["language"] = language
                                    resource["sublanguage"] = sublanguage
                                    resource["entropy"] = "{0:.02f}".format(
                                        float(_get_entropy(data)))
                                    resources.append(resource)
                except:
                    continue

        return resources
Exemple #28
0
 def set_resources_info(self):
     res_array = []
     if hasattr(self.pe, 'DIRECTORY_ENTRY_RESOURCE'):
         for resource_type in self.pe.DIRECTORY_ENTRY_RESOURCE.entries:
             if resource_type.name is not None:
                 name = "%s" % resource_type.name
             else:
                 name = "%s" % pefile.RESOURCE_TYPE.get(
                     resource_type.struct.Id)
             if name == None:
                 name = "%d" % resource_type.struct.Id
             if hasattr(resource_type, 'directory'):
                 for resource_id in resource_type.directory.entries:
                     if hasattr(resource_id, 'directory'):
                         for resource_lang in resource_id.directory.entries:
                             raw_data = self.pe.get_data(
                                 resource_lang.data.struct.OffsetToData,
                                 resource_lang.data.struct.Size)
                             ent = self.__get_entropy(raw_data)
                             raw_data = [format(i, '02x') for i in raw_data]
                             lang = pefile.LANG.get(resource_lang.data.lang,
                                                    '*unknown*')
                             sublang = pefile.get_sublang_name_for_lang(
                                 resource_lang.data.lang,
                                 resource_lang.data.sublang)
                             file_ratio = self.__get_file_ratio(raw_data)
                             res_array.append({
                                 "name":
                                 name,
                                 "data":
                                 raw_data,
                                 "offset":
                                 hex(resource_lang.data.struct.OffsetToData
                                     ),
                                 "size":
                                 resource_lang.data.struct.Size,
                                 "file_ratio":
                                 file_ratio,
                                 "entropy":
                                 ent,
                                 "language":
                                 lang,
                                 "sublanguage":
                                 sublang
                             })
     if len(res_array) != 0:
         self.info['PE']['Resource'] = res_array
Exemple #29
0
    def _get_resources(self):
        if not self.pe:
            return None

        resources = []
        if not hasattr(self.pe, "DIRECTORY_ENTRY_RESOURCE"):
            return resources

        for resource_type in self.pe.DIRECTORY_ENTRY_RESOURCE.entries:
            try:
                resource = {}

                if resource_type.name is not None:
                    name = str(resource_type.name)
                else:
                    struct_id = resource_type.struct.Id
                    name = str(pefile.RESOURCE_TYPE.get(struct_id))

                if not hasattr(resource_type, "directory"):
                    continue

                for resource_id in resource_type.directory.entries:
                    if not hasattr(resource_id, "directory"):
                        continue
                    for resource_lang in resource_id.directory.entries:

                        offset = resource_lang.data.struct.OffsetToData
                        size = resource_lang.data.struct.Size
                        lang = resource_lang.data.lang
                        sublang = resource_lang.data.sublang
                        data = self.pe.get_data(offset, size)
                        filetype = self._get_filetype(data)
                        language = pefile.LANG.get(lang, None)
                        sublanguage = pefile.get_sublang_name_for_lang(
                            lang, sublang)
                        resource["name"] = name
                        resource["offset"] = "0x{0:08x}".format(offset)
                        resource["size"] = "0x{0:08x}".format(size)
                        resource["filetype"] = filetype
                        resource["language"] = language
                        resource["sublanguage"] = sublanguage
                        resources.append(resource)
            except:
                continue

        return resources
Exemple #30
0
    def _get_resources(self):
        if not self.pe:
            return None

        resources = []
        if not hasattr(self.pe, "DIRECTORY_ENTRY_RESOURCE"):
            return resources

        for resource_type in self.pe.DIRECTORY_ENTRY_RESOURCE.entries:
            try:
                resource = {}

                if resource_type.name is not None:
                    name = str(resource_type.name)
                else:
                    struct_id = resource_type.struct.Id
                    name = str(pefile.RESOURCE_TYPE.get(struct_id))

                if not hasattr(resource_type, "directory"):
                    continue

                for resource_id in resource_type.directory.entries:
                    if not hasattr(resource_id, "directory"):
                        continue
                    for resource_lang in resource_id.directory.entries:

                        offset = resource_lang.data.struct.OffsetToData
                        size = resource_lang.data.struct.Size
                        lang = resource_lang.data.lang
                        sublang = resource_lang.data.sublang
                        data = self.pe.get_data(offset, size)
                        filetype = self._get_filetype(data)
                        language = pefile.LANG.get(lang, None)
                        sublanguage = pefile.get_sublang_name_for_lang(lang,
                                                                       sublang)
                        resource["name"] = name
                        resource["offset"] = "0x{0:08x}".format(offset)
                        resource["size"] = "0x{0:08x}".format(size)
                        resource["filetype"] = filetype
                        resource["language"] = language
                        resource["sublanguage"] = sublanguage
                        resources.append(resource)
            except:
                continue

        return resources
    def process(self):
        pelib = self._getLibrary(PEFileModule().getName())
        if(pelib is None):
            return ""

        ret = []
        if hasattr(pelib, 'DIRECTORY_ENTRY_RESOURCE'):
            i = 0
            for resource_type in pelib.DIRECTORY_ENTRY_RESOURCE.entries:
                if resource_type.name is not None:
                    name = "%s" % resource_type.name
                else:
                    name = "%s" % pefile.RESOURCE_TYPE.get(
                        resource_type.struct.Id)
                if name is None:
                    name = "%d" % resource_type.struct.Id
                if hasattr(resource_type, 'directory'):
                    for resource_id in resource_type.directory.entries:
                        if hasattr(resource_id, 'directory'):
                            for resource_lang in resource_id.directory.entries:
                                try:
                                    data = pelib.get_data(
                                        resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size)
                                    # fd=open(name,'wb')
                                    # fd.write(data)
                                    # (data)
                                except pefile.PEFormatError:
                                    return "corrupt"
                                filetype = MIME_TYPE(data, False)
                                lang = pefile.LANG.get(
                                    resource_lang.data.lang, 'unknown')
                                sublang = pefile.get_sublang_name_for_lang(
                                    resource_lang.data.lang, resource_lang.data.sublang)
                                entry = {}
                                entry["name"] = self._normalize(name)
                                entry["rva"] = self._normalize(
                                    hex(resource_lang.data.struct.OffsetToData))
                                entry["size"] = self._normalize(
                                    hex(resource_lang.data.struct.Size))
                                entry["type"] = self._normalize(filetype)
                                entry["lang"] = self._normalize(lang)
                                entry["sublang"] = self._normalize(sublang)
                                entry["sha1"] = SHA1(data)
                                ret.append(entry)

        return ret
Exemple #32
0
    def analyze_dir(self, directory, prefix='', _type='', timedate=0):
        """ Analyze a resource directory and obtain all of its items."""
        log = logging.getLogger('Mastiff.Plugins.' + self.name + '.analyze')

        # save the timedate stamp
        timedate = directory.struct.TimeDateStamp

        for top_item in directory.entries:

            if hasattr(top_item, 'data'):
                # at the language level that contains all of our information
                resource = dict()
                resource['Id'] = prefix
                resource['Type'] = _type
                # store the offset as the offset within the file, not the RVA!
                try:
                    resource['Offset'] = self.pe.get_offset_from_rva(top_item.data.struct.OffsetToData)
                    resource['Size'] = top_item.data.struct.Size
                    resource['Lang'] = [ pefile.LANG.get(top_item.data.lang, '*unknown*'), \
                                                            pefile.get_sublang_name_for_lang( top_item.data.lang, top_item.data.sublang ) ]
                    resource['TimeDate'] = timedate
                except pefile.PEFormatError, err:
                    log.error('Error grabbing resource \"%s\" info: %s' %  (prefix, err))
                    return False

                self.resources.append(resource)
                log.debug('Adding resource item %s' % resource['Id'])
            elif hasattr(top_item, 'directory'):
                if top_item.name is not None:
                    # in a name level
                    if len(prefix) == 0:
                        newprefix = prefix + str(top_item.name)
                    else:
                        newprefix = ', '.join([prefix, str(top_item.name)])
                else:
                    # if name is blank, we are in a Type level
                    if len(prefix) == 0:
                        newprefix = 'ID ' + str(top_item.id)
                        _type = pefile.RESOURCE_TYPE.get(top_item.id)
                    else:
                        newprefix = ', '.join([prefix,  'ID ' + str(top_item.id)])

                # we aren't at the end, recurse
                self.analyze_dir(top_item.directory, prefix=newprefix, _type=_type)
Exemple #33
0
    def _get_resources(self):
        """Get resources.
        @return: resources dict or None.
        """
        if not self.pe:
            return None

        resources = []

        if hasattr(self.pe, "DIRECTORY_ENTRY_RESOURCE"):
            for resource_type in self.pe.DIRECTORY_ENTRY_RESOURCE.entries:
                try:
                    resource = {}

                    if resource_type.name is not None:
                        name = str(resource_type.name)
                    else:
                        name = str(pefile.RESOURCE_TYPE.get(resource_type.struct.Id))

                    if hasattr(resource_type, "directory"):
                        for resource_id in resource_type.directory.entries:
                            if hasattr(resource_id, "directory"):
                                for resource_lang in resource_id.directory.entries:
                                    data = self.pe.get_data(
                                        resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size
                                    )
                                    filetype = _get_filetype(data)
                                    language = pefile.LANG.get(resource_lang.data.lang, None)
                                    sublanguage = pefile.get_sublang_name_for_lang(
                                        resource_lang.data.lang, resource_lang.data.sublang
                                    )
                                    resource["name"] = name
                                    resource["offset"] = "0x{0:08x}".format(resource_lang.data.struct.OffsetToData)
                                    resource["size"] = "0x{0:08x}".format(resource_lang.data.struct.Size)
                                    resource["filetype"] = filetype
                                    resource["language"] = language
                                    resource["sublanguage"] = sublanguage
                                    resource["entropy"] = "{0:.02f}".format(float(_get_entropy(data)))
                                    resources.append(resource)
                except:
                    continue

        return resources
Exemple #34
0
def get_resource_data(pe):
    resources = []
    if hasattr(pe, "DIRECTORY_ENTRY_RESOURCE"):
        for resource_type in pe.DIRECTORY_ENTRY_RESOURCE.entries:
            resource = {}

            try:
                if resource_type.name is not None:
                    name = str(resource_type.name)
                else:
                    name = str(
                        pefile.RESOURCE_TYPE.get(resource_type.struct.Id))
            except TypeError:
                name = 'unknown'

            if hasattr(resource_type, "directory"):
                for resource_id in resource_type.directory.entries:
                    if hasattr(resource_id, "directory"):
                        for resource_lang in resource_id.directory.entries:
                            data = pe.get_data(
                                resource_lang.data.struct.OffsetToData,
                                resource_lang.data.struct.Size)
                            language = pefile.LANG.get(resource_lang.data.lang,
                                                       None)
                            sub_language = pefile.get_sublang_name_for_lang(
                                resource_lang.data.lang,
                                resource_lang.data.sublang)
                            resource["name"] = name
                            resource["offset"] = "0x{0:08x}".format(
                                resource_lang.data.struct.OffsetToData)
                            resource["size"] = "0x{0:08x}".format(
                                resource_lang.data.struct.Size)
                            resource["language"] = language
                            resource["sublanguage"] = sub_language
                            resource['filetype'] = magic.from_buffer(
                                pe.get_memory_mapped_image()
                                [resource_lang.data.struct.OffsetToData:
                                 resource_lang.data.struct.OffsetToData +
                                 1024])
                            resources.append(resource)

    return resources
 def _parse_resource(self, type: str, entry, pe) -> Tuple[Dict, bytes]:
     sublang = pefile.get_sublang_name_for_lang(entry.data.lang, entry.data.sublang)
     rva = entry.data.struct.OffsetToData
     size = entry.data.struct.Size
     raw_data = pe.get_data(rva, size)
     metadata = {
         'type': type,
         'resource_id': entry.id,
         'resource_type': entry.data.struct.name,
         'address': rva,
         'offset': pe.get_offset_from_rva(rva),
         'sha256': hashlib.sha256(raw_data).hexdigest(),
         'sha1': hashlib.sha1(raw_data).hexdigest(),
         'md5': hashlib.md5(raw_data).hexdigest(),
         'language': pefile.LANG.get(entry.data.lang, 'unknown'),
         'sub_language': sublang,
         'size': size,
         'name': f'resource_{type}_{entry.id}',
     }
     return (metadata, raw_data)
Exemple #36
0
    def _get_resources(self):
        """Get resources.
        @return: resources dict or None.
        """
        if not self.pe:
            return None

        resources = []

        if hasattr(self.pe, "DIRECTORY_ENTRY_RESOURCE"):
            for resource_type in self.pe.DIRECTORY_ENTRY_RESOURCE.entries:
                try:
                    resource = {}

                    if resource_type.name is not None:
                        name = "%s" % resource_type.name
                    else:
                        name = "%s" % pefile.RESOURCE_TYPE.get(resource_type.struct.Id)
                    if name == None:
                        name = "%d" % resource_type.struct.Id

                    if hasattr(resource_type, "directory"):
                        for resource_id in resource_type.directory.entries:
                            if hasattr(resource_id, "directory"):
                                for resource_lang in resource_id.directory.entries:
                                    data = self.pe.get_data(resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size)
                                    filetype = self._get_filetype(data)
                                    language = pefile.LANG.get(resource_lang.data.lang, None)
                                    sublanguage = pefile.get_sublang_name_for_lang(resource_lang.data.lang, resource_lang.data.sublang)

                                    resource["name"] = name
                                    resource["offset"] = ("%-8s" % hex(resource_lang.data.struct.OffsetToData)).strip()
                                    resource["size"] = ("%-8s" % hex(resource_lang.data.struct.Size)).strip()
                                    resource["filetype"] = filetype
                                    resource["language"] = language
                                    resource["sublanguage"] = sublanguage
                                    resources.append(resource)
                except:
                    continue

        return resources
Exemple #37
0
def resource(level, r):
    """Recursive printing of resources"""
    if hasattr(r, "data"):
        # resource
        offset = r.data.struct.OffsetToData
        size = r.data.struct.Size
        data = pe.get_memory_mapped_image()[offset:offset + size]
        m = hashlib.md5()
        m.update(data)
        print("    " * level + "-%s\t%i\t%i\t%s\t%s\t%s" %
              (str(r.name), r.id, size, m.hexdigest(),
               pefile.LANG.get(r.data.lang, 'UNKNOWN'),
               pefile.get_sublang_name_for_lang(r.data.lang, r.data.sublang)))
    else:
        # directory
        if r.name is None:
            print("    " * level + "-" + str(r.id))
        else:
            print("    " * level + "-" + str(r.name))
        for r2 in r.directory.entries:
            resource(level + 1, r2)
Exemple #38
0
 def _parse_resource(self, type: str, entry, pe) -> Tuple[Dict, bytes]:
     sublang = pefile.get_sublang_name_for_lang(entry.data.lang,
                                                entry.data.sublang)
     rva = entry.data.struct.OffsetToData
     size = entry.data.struct.Size
     raw_data = pe.get_data(rva, size)
     metadata = {
         "type": type,
         "resource_id": entry.id,
         "resource_type": entry.data.struct.name,
         "address": rva,
         "offset": pe.get_offset_from_rva(rva),
         "sha256": hashlib.sha256(raw_data).hexdigest(),
         "sha1": hashlib.sha1(raw_data).hexdigest(),
         "md5": hashlib.md5(raw_data).hexdigest(),
         "language": pefile.LANG.get(entry.data.lang, "unknown"),
         "sub_language": sublang,
         "size": size,
         "name": f"resource_{type}_{entry.id}",
     }
     return (metadata, raw_data)
Exemple #39
0
def lang_bools(pe):
    """Scours the resource directory of a PE32 file for language information.
    Returns four booleans that Yonts argued might make good malware indicators.
    The booleans are: Language=0, Language>127, SubLanguage=0, SubLanguage=2"""

    ret = [0, 0, 0, 0]

    # Getting to the language attributes requires a lot of digging
    if hasattr(pe, 'DIRECTORY_ENTRY_RESOURCE'):
        for resource_type in pe.DIRECTORY_ENTRY_RESOURCE.entries:
            if hasattr(resource_type, 'directory'):
                for resource_id in resource_type.directory.entries:
                    if hasattr(resource_id, 'directory'):
                        for resource_lang in resource_id.directory.entries:
                            lang = pefile.LANG.get(resource_lang.data.lang, \
                            '*unknown*')
                            sublang = pefile.get_sublang_name_for_lang( \
                            resource_lang.data.lang, resource_lang.data.sublang)

                            # Here we check if we need to set any bools to true
                            try:
                                if (pefile.LANG[lang] == 0):
                                    ret[0] = 1
                                if (pefile.LANG[lang] > 127):
                                    ret[1] = 1
                            except KeyError:
                                print 'KeyError!'
                                ret[0] = -1
                                ret[1] = -1
                            try:
                                if (pefile.SUBLANG[sublang] == 0):
                                    ret[2] = 1
                                if (pefile.SUBLANG[sublang] == 2):
                                    ret[3] = 1
                            except KeyError:
                                print 'KeyError!'
                                ret[2] = -1
                                ret[3] = -1
    return ret
Exemple #40
0
def lang_bools(pe):
    """Scours the resource directory of a PE32 file for language information.
    Returns four booleans that Yonts argued might make good malware indicators.
    The booleans are: Language=0, Language>127, SubLanguage=0, SubLanguage=2"""

    ret = [0, 0, 0, 0]

    # Getting to the language attributes requires a lot of digging
    if hasattr(pe, 'DIRECTORY_ENTRY_RESOURCE'):
        for resource_type in pe.DIRECTORY_ENTRY_RESOURCE.entries:
            if hasattr(resource_type, 'directory'):
                for resource_id in resource_type.directory.entries:
                    if hasattr(resource_id, 'directory'):
                        for resource_lang in resource_id.directory.entries:
                            lang = pefile.LANG.get(resource_lang.data.lang, \
                            '*unknown*')
                            sublang = pefile.get_sublang_name_for_lang( \
                            resource_lang.data.lang, resource_lang.data.sublang)

                            # Here we check if we need to set any bools to true
                            try:
                                if(pefile.LANG[lang] == 0):
                                    ret[0] = 1
                                if(pefile.LANG[lang] > 127):
                                    ret[1] = 1
                            except KeyError:
                                print 'KeyError!'
                                ret[0] = -1
                                ret[1] = -1
                            try:
                                if(pefile.SUBLANG[sublang] == 0):
                                    ret[2] = 1
                                if(pefile.SUBLANG[sublang] == 2):
                                    ret[3] = 1
                            except KeyError:
                                print 'KeyError!'
                                ret[2] = -1
                                ret[3] = -1
    return ret                            
Exemple #41
0
def getPEResource(f):
    try:
        pe = pefile.PE(data=f)
        resourcesList = []
        if hasattr(pe, "DIRECTORY_ENTRY_RESOURCE"):
            for entry in pe.DIRECTORY_ENTRY_RESOURCE.entries:
                type = pefile.RESOURCE_TYPE.get(entry.id, 'NA')
                for e in entry.directory.entries:
                    for m in e.directory.entries:
                        lang = pefile.LANG.get(m.data.lang, '*unknown*')
                        sublang = pefile.get_sublang_name_for_lang(
                            m.data.lang, m.data.sublang)
                        rva = m.data.struct.OffsetToData
                        size = m.data.struct.Size
                        data = pe.get_data(rva, size)
                        name = entry.name
                        resources = (type, hashlib.sha256(data).hexdigest(),
                                     hashlib.md5(data).hexdigest(), lang,
                                     sublang, size)
                        resourcesList.append(resources)
            return resourcesList
    except:
        return
Exemple #42
0
def get_resources(pe):
	res_array = []
	try:
		'''
		# resource types					# description
		RT_CURSOR = 1						# Hardware-dependent cursor resource.
		RT_BITMAP = 2						# Bitmap resource.
		RT_ICON = 3							# Hardware-dependent icon resource.
		RT_MENU = 4							# Menu resource.
		RT_DIALOG = 5						# Dialog box.
		RT_STRING = 6						# String-table entry.
		RT_FONTDIR = 7						# Font directory resource.
		RT_FONT = 8							# Font resource.
		RT_ACCELERATOR = 9					# Accelerator table.
		RT_RCDATA = 10						# Application-defined resource (raw data.)
		RT_MESSAGETABLE = 11				# Message-table entry.
		RT_VERSION = 16						# Version resource.
		RT_DLGINCLUDE = 17					# Allows a resource editing tool to associate a string with an .rc file.
		RT_PLUGPLAY = 19					# Plug and Play resource.
		RT_VXD = 20							# VXD.
		RT_ANICURSOR = 21					# Animated cursor.
		RT_ANIICON = 22						# Animated icon.
		RT_HTML = 23						# HTML resource.
		RT_MANIFEST = 24					# Side-by-Side Assembly Manifest.

		RT_GROUP_CURSOR = RT_CURSOR + 11	# Hardware-independent cursor resource.
		RT_GROUP_ICON = RT_ICON + 11		# Hardware-independent icon resource.
		'''
		for resource_type in pe.DIRECTORY_ENTRY_RESOURCE.entries:
			if resource_type.name is not None:
				name = "%s" % resource_type.name
			else:
				name = "%s" % pefile.RESOURCE_TYPE.get(resource_type.struct.Id)
			if name == None:
				name = "%d" % resource_type.struct.Id

			if hasattr(resource_type, 'directory'):
				i = 0
				for resource_id in resource_type.directory.entries:
					if len(resource_type.directory.entries) > 1:
						i = i+1
						newname = name+'_'+str(i)
					else:
						newname = name

					for resource_lang in resource_id.directory.entries:
						data_byte = pe.get_data(resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size)[:50]
						is_pe = False
						if magic_check(data_byte)[:8]:
							is_pe = True
						lang = pefile.LANG.get(resource_lang.data.lang, '*unknown*')
						sublang = pefile.get_sublang_name_for_lang(resource_lang.data.lang, resource_lang.data.sublang)

						res_array.append({
							"name": newname,
							"data": str(data_byte),
							"executable": is_pe,
							"offset": resource_lang.data.struct.OffsetToData,
							"size": resource_lang.data.struct.Size, 
							"language": lang, 
							"sublanguage": sublang
							})
	except:
		pass

	return res_array
def startAnalyses():
    version()

    try:
        opts, args = getopt.getopt(sys.argv[1:], "hf:", ["help", "file="])

    except getopt.GetoptError:
        help()
        sys.exit(2)

    for opt, arg in opts:

        if opt in ("-h", "--help"):
            help()
            sys.exit()

        elif opt in ("-f", "--file"):
            filePath = arg

            f = open(filePath)

            html = createFile(filePath)

            pe = pefile.PE(filePath)

            # get the filetype by calling the external program file
            filetype = subprocess.check_output(["file", "-b", filePath])

            html.write("File Size: %s<br>\nFile Type: %s<br>\n" % (os.path.getsize(filePath), filetype))
            html.write(
                "Compilation timestamp: %s<br>\n" % (datetime.datetime.fromtimestamp(pe.FILE_HEADER.TimeDateStamp)))

            insertSeperator(html)

            html.write("<br><b><a id='version'>File Version Info:</a></b>\n<br>\n")

            # from Ero Carrera's blog
            for fileinfo in pe.FileInfo:
                if fileinfo.Key == 'StringFileInfo':
                    for st in fileinfo.StringTable:
                        for entry in st.entries.items():
                            html.write("%s: %s<br>\n" % (entry[0], entry[1]))

                if fileinfo.Key == 'VarFileInfo':
                    for var in fileinfo.Var:
                        html.write("%s: %s<br>\n" % var.entry.items()[0])

            insertSeperator(html)

            # calculate some Checksums
            md5, sha1, sha256, sha512 = calcChecksum(f)
            html.write(
                "<br><b><a id='checksums'>File Checksums:</a></b>\n<br>\nMD5:    %s<br>\nSHA1:   %s<br>\nSHA256: %s<br>\nSHA512: %s<br>\n" % (
                md5, sha1, sha256, sha512))

            insertSeperator(html)

            # create Virustotal Analysis Link
            vtlink = vtanalysisurl + sha256 + "/analysis"

            # request Results from Virustotal
            try:
                response_dict = queryVT(md5)
                html.write("<br><b><a id='virus'>VirusTotal Results:</a></b><br>%s / %s<br><br><a href='%s' target='_blank'>VirusTotal Analysis Link</a><br>\n" % (
                response_dict.get("positives"), response_dict.get("total"), vtlink))
            except:
                html.write("<br><b><a id='virus'>VirusTotal Results:</a></b><br>Error!<br>\n")

            insertSeperator(html)

            html.write("<br><b><a id='sections'>Sections:</a></b><br>\n")
            html.write("Entrypoint: %s<br>Number of Sections: %i<br><br>\n" % (
            hex(pe.OPTIONAL_HEADER.AddressOfEntryPoint), len(pe.sections)))
            html.write("<table><tr><th>Name</th> <th>Virtual address</th> <th>Virtual size</th> <th>Raw size</th> <th>Entropy</th></tr>\n")
            for section in pe.sections:
                e = getEntropy(section.get_data())
                if e < 6.0:
                    a = "Not packed"
                elif e < 7.0:
                    a = "Maybe packed"
                else:  # 7.0 .. 8.0
                    a = "Packed"
                html.write("<tr><td>%s</td> <td>%s</td> <td>%s</td> <td>%s</td> <td>%.2f (%s)</td></tr>\n" % (
                section.Name, hex(section.VirtualAddress), hex(section.Misc_VirtualSize), section.SizeOfRawData, e, a))

            html.write("</table>\n")

            insertSeperator(html)

            susp_api = []

            apis = getList(BASE_DIR + "/api.txt")

            pe.parse_data_directories()

            html.write("<br><b><a id='imports'>Imports:</a></b><br>\n")

            for entry in pe.DIRECTORY_ENTRY_IMPORT:
                html.write("<b>%s</b><br>\n" % entry.dll)
                for imp in entry.imports:
                    html.write("%s %s<br>\n" % (hex(imp.address), imp.name))
                    if (imp.name != None) and (imp.name != ""):
                        for api in apis:
                            if imp.name.startswith(api):
                                susp_api.append(imp)

            insertSeperator(html)

            html.write("<br><b><a id='suspicious'>Suspicious APIs:</a></b><br>\n")

            for imp in susp_api:
                html.write("%s %s<br>\n" % (hex(imp.address), imp.name))

            insertSeperator(html)

            html.write("<br><b><a id='exports'>Exports:</a></b><br>\n")
            try:
                for exp in pe.DIRECTORY_ENTRY_EXPORT.symbols:
                    html.write("%s %s<br>\n" % (hex(pe.OPTIONAL_HEADER.ImageBase + exp.address), exp.name))
            except:
                html.write("No Exports found!<br>\n")

            insertSeperator(html)

            html.write("<br><b><a id='resources'>Resources:</a></b><br>\n")
            html.write("<table><tr><th>Name</th> <th>Virtual address</th> <th>Virtual size</th> <th>Raw size</th> <th>Entropy</th></tr>\n")

            for resource_type in pe.DIRECTORY_ENTRY_RESOURCE.entries:
                if resource_type.name is not None:
                    name = "%s" % resource_type.name
                    print name
                else:
                    name = "%s" % pefile.RESOURCE_TYPE.get(resource_type.struct.Id)
                if name == None:
                    name = "%d" % resource_type.struct.Id
                for resource_id in resource_type.directory.entries:
                    if hasattr(resource_type, 'directory'):
                        for resource_id in resource_type.directory.entries:
                            if hasattr(resource_id, 'directory'):
                                for resource_lang in resource_id.directory.entries:
                                    data = pe.get_data(resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size)
                                    lang = pefile.LANG.get(resource_lang.data.lang)
                                    sublang = pefile.get_sublang_name_for_lang(resource_lang.data.lang, resource_lang.data.sublang)
                                    html.write("<tr><td>%s</td> <td>%s</td> <td>%s</td> <td>%s</td> <td>%s</td></tr>\n" % (name, hex(resource_lang.data.struct.OffsetToData), hex(resource_lang.data.struct.Size), lang, sublang))

            html.write("</table>\n")

            insertSeperator(html)

            # get printable strings in the binary file by calling the external program strings
            strings = subprocess.check_output(["strings", filePath])

            html.write("<br><b><a id='strings'>Strings:</a></b><br>\n")
            html.write("<br>\n".join(strings.split()))
Exemple #44
0
def _resources_data_entry(exe):
    data = list()
    data.append(exe.DIRECTORY_ENTRY_RESOURCE.struct.dump_dict())

    for resource_type in exe.DIRECTORY_ENTRY_RESOURCE.entries:
        resource_type_dict = dict()

        if resource_type.name is not None:
            resource_type_dict['Name'] = resource_type.name
        else:
            resource_type_dict['Id'] = (resource_type.struct.Id,
                                        pefile.RESOURCE_TYPE.get(
                                            resource_type.struct.Id, '-'))

        resource_type_dict.update(resource_type.struct.dump_dict())
        data.append(resource_type_dict)

        if hasattr(resource_type, 'directory'):
            directory_list = list()
            directory_list.append(resource_type.directory.struct.dump_dict())
            data.append(directory_list)

            for resource_id in resource_type.directory.entries:
                resource_id_dict = dict()

                if resource_id.name is not None:
                    resource_id_dict['Name'] = resource_id.name
                else:
                    resource_id_dict['Id'] = resource_id.struct.Id

                resource_id_dict.update(resource_id.struct.dump_dict())
                directory_list.append(resource_id_dict)

                if hasattr(resource_id, 'directory'):
                    resource_id_list = list()
                    resource_id_list.append(
                        resource_id.directory.struct.dump_dict())
                    directory_list.append(resource_id_list)

                    for resource_lang in resource_id.directory.entries:
                        if hasattr(resource_lang, 'data'):
                            resource_lang_dict = dict()
                            resource_lang_dict[
                                'LANG'] = resource_lang.data.lang
                            resource_lang_dict[
                                'SUBLANG'] = resource_lang.data.sublang
                            resource_lang_dict['LANG_NAME'] = pefile.LANG.get(
                                resource_lang.data.lang, '*unknown*')
                            resource_lang_dict[
                                'SUBLANG_NAME'] = pefile.get_sublang_name_for_lang(
                                    resource_lang.data.lang,
                                    resource_lang.data.sublang)
                            resource_lang_dict.update(
                                resource_lang.struct.dump_dict())
                            resource_lang_dict.update(
                                resource_lang.data.struct.dump_dict())
                            resource_id_list.append(resource_lang_dict)
                    if hasattr(resource_id.directory,
                               'strings') and resource_id.directory.strings:
                        for idx, res_string in list(
                                resource_id.directory.strings.items()):
                            resource_id_list.append(
                                res_string.encode(
                                    'unicode-escape',
                                    'backslashreplace').decode('ascii'))
    return data
Exemple #45
0
    def resources(self):
        if not self.pe:
            return

        def usage():
            print("usage: pe resources [-d=folder]")

        def help():
            usage()
            print("")
            print("Options:")
            print("\t--help (-h)\tShow this help message")
            print("\t--dump (-d)\tDestination directory to store resource files in")
            print("")

        try:
            opts, argv = getopt.getopt(self.args[1:], 'hd:', ['help', 'dump='])
        except getopt.GetoptError as e:
            print(e)
            usage()
            return

        dump_to = None

        for opt, value in opts:
            if opt in ('-h', '--help'):
                help()
                return
            elif opt in ('-d', '--dump'):
                dump_to = value

        resources = []

        if hasattr(self.pe, 'DIRECTORY_ENTRY_RESOURCE'):
            for resource_type in self.pe.DIRECTORY_ENTRY_RESOURCE.entries:
                try:
                    resource = {}

                    if resource_type.name is not None:
                        name = str(resource_type.name)
                    else:
                        name = str(pefile.RESOURCE_TYPE.get(resource_type.struct.Id))

                    if name == None:
                        name = str(resource_type.struct.Id)

                    if hasattr(resource_type, 'directory'):
                        for resource_id in resource_type.directory.entries:
                            if hasattr(resource_id, 'directory'):
                                for resource_lang in resource_id.directory.entries:
                                    data = self.pe.get_data(resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size)
                                    filetype = self.__get_filetype(data)
                                    language = pefile.LANG.get(resource_lang.data.lang, None)
                                    sublanguage = pefile.get_sublang_name_for_lang(resource_lang.data.lang, resource_lang.data.sublang)
                                    offset = ('%-8s' % hex(resource_lang.data.struct.OffsetToData)).strip()
                                    size = ('%-8s' % hex(resource_lang.data.struct.Size)).strip()

                                    resource = [name, offset, size, filetype, language, sublanguage]

                                    if dump_to:
                                        resource_path = os.path.join(dump_to, '{0}_{1}_{2}'.format(__session__.file.md5, offset, name))
                                        resource.append(resource_path)

                                        with open(resource_path, 'wb') as resource_handle:
                                            resource_handle.write(data)

                                    resources.append(resource)
                except Exception as e:
                    print_error(e)
                    continue

        headers = ['Name', 'Offset', 'Size', 'File Type', 'Language', 'Sublanguage']
        if dump_to:
            headers.append('Dumped To')

        print table(headers, resources)
Exemple #46
0
    def _run(self, scanObject, result, depth, args):
        moduleResult = []
        imports = {}
        sections = {}
        exports = []

        try:
            pe = pefile.PE(data=scanObject.buffer)
            dump_dict = pe.dump_dict()

            # Parse sections
            for section in dump_dict.get("PE Sections", []):
                secName = section.get("Name", {}).get("Value", "").strip("\0")
                ptr = section.get("PointerToRawData", {}).get("Value")
                virtAddress = section.get("VirtualAddress", {}).get("Value")
                virtSize = section.get("Misc_VirtualSize", {}).get("Value")
                size = section.get("SizeOfRawData", {}).get("Value")
                secData = pe.get_data(ptr, size)
                secInfo = {
                    "Virtual Address": "0x%08X" % virtAddress,
                    "Virtual Size": virtSize,
                    "Raw Size": size,
                    "MD5": section.get("MD5", ""),
                    "SHA1": section.get("SHA1", ""),
                    "SHA256": section.get("SHA256", ""),
                    "Entropy": section.get("Entropy", ""),
                    "Section Characteristics": section.get("Flags", []),
                    "Structure": section.get("Structure", ""),
                }
                if secInfo["MD5"] != scanObject.objectHash:
                    moduleResult.append(ModuleObject(buffer=secData, externalVars=ExternalVars(filename=secName)))
                sections[secName] = secInfo
            sections["Total"] = pe.FILE_HEADER.NumberOfSections
            scanObject.addMetadata(self.module_name, "Sections", sections)

            # Parse imports and exports
            try:
                for exp in pe.DIRECTORY_ENTRY_EXPORT.symbols:
                    exports.append(exp.name)
                scanObject.addMetadata(self.module_name, "Exports", exports)
            except ScanError:
                raise
            except:
                logging.debug("No export entries")

            for imp_symbol in dump_dict.get("Imported symbols", []):
                for imp in imp_symbol:
                    if imp.get("DLL"):
                        dll = imp.get("DLL")
                        imports.setdefault(dll, [])
                        # Imports can be identified by ordinal or name
                        if imp.get("Ordinal"):
                            ordinal = imp.get("Ordinal")
                            imports[dll].append(ordinal)
                        if imp.get("Name"):
                            name = imp.get("Name")
                            imports[dll].append(name)
            scanObject.addMetadata(self.module_name, "Imports", imports)

            # Parse resources
            try:
                for resource in pe.DIRECTORY_ENTRY_RESOURCE.entries:
                    res_type = pefile.RESOURCE_TYPE.get(resource.id, "Unknown")
                    for entry in resource.directory.entries:
                        for e_entry in entry.directory.entries:
                            sublang = pefile.get_sublang_name_for_lang(e_entry.data.lang, e_entry.data.sublang)
                            offset = e_entry.data.struct.OffsetToData
                            size = e_entry.data.struct.Size
                            r_data = pe.get_data(offset, size)
                            language = pefile.LANG.get(e_entry.data.lang, "Unknown")
                            data = {
                                "Type": res_type,
                                "Id": e_entry.id,
                                "Name": e_entry.data.struct.name,
                                "Offset": offset,
                                "Size": size,
                                "SHA256": hashlib.sha256(r_data).hexdigest(),
                                "SHA1": hashlib.sha1(r_data).hexdigest(),
                                "MD5": hashlib.md5(r_data).hexdigest(),
                                "Language": language,
                                "Sub Language": sublang,
                            }
                            scanObject.addMetadata(self.module_name, "Resources", data)
            except ScanError:
                raise
            except:
                logging.debug("No resources")

            # Gather miscellaneous stuff
            try:
                scanObject.addMetadata(self.module_name, "Imphash", pe.get_imphash())
            except ScanError:
                raise
            except:
                logging.debug("Unable to identify imphash")

            imgChars = dump_dict.get("Flags", [])
            scanObject.addMetadata(self.module_name, "Image Characteristics", imgChars)
            # Make a pretty date format
            date = datetime.fromtimestamp(pe.FILE_HEADER.TimeDateStamp)
            isoDate = date.isoformat()
            scanObject.addMetadata(self.module_name, "Date", isoDate)
            scanObject.addMetadata(self.module_name, "Timestamp", pe.FILE_HEADER.TimeDateStamp)

            machine = pe.FILE_HEADER.Machine
            machineData = {"Id": machine, "Type": pefile.MACHINE_TYPE.get(machine)}
            scanObject.addMetadata(self.module_name, "Machine Type", machineData)

            # Reference: http://msdn.microsoft.com/en-us/library/windows/desktop/ms680339%28v=vs.85%29.aspx
            scanObject.addMetadata(
                self.module_name, "Image Magic", IMAGE_MAGIC_LOOKUP.get(pe.OPTIONAL_HEADER.Magic, "Unknown")
            )

            dllChars = dump_dict.get("DllCharacteristics", [])
            scanObject.addMetadata(self.module_name, "DLL Characteristics", dllChars)

            subsystem = pe.OPTIONAL_HEADER.Subsystem
            subName = pefile.SUBSYSTEM_TYPE.get(subsystem)
            scanObject.addMetadata(self.module_name, "Subsystem", subName)

            # Reference: http://msdn.microsoft.com/en-us/library/windows/desktop/ms648009%28v=vs.85%29.aspx

            scanObject.addMetadata(self.module_name, "Stack Reserve Size", pe.OPTIONAL_HEADER.SizeOfStackReserve)
            scanObject.addMetadata(self.module_name, "Stack Commit Size", pe.OPTIONAL_HEADER.SizeOfStackCommit)
            scanObject.addMetadata(self.module_name, "Heap Reserve Size", pe.OPTIONAL_HEADER.SizeOfHeapReserve)
            scanObject.addMetadata(self.module_name, "Heap Commit Size", pe.OPTIONAL_HEADER.SizeOfHeapCommit)
            scanObject.addMetadata(self.module_name, "EntryPoint", hex(pe.OPTIONAL_HEADER.AddressOfEntryPoint))
            scanObject.addMetadata(self.module_name, "ImageBase", hex(pe.OPTIONAL_HEADER.ImageBase))

            # Parse RSDS & Rich
            scanObject.addMetadata(self.module_name, "Rich Header", self.parseRich(pe))

            if hasattr(pe, "DIRECTORY_ENTRY_DEBUG"):
                debug = dict()
                for e in pe.DIRECTORY_ENTRY_DEBUG:
                    rawData = pe.get_data(e.struct.AddressOfRawData, e.struct.SizeOfData)
                    if rawData.find("RSDS") != -1 and len(rawData) > 24:
                        pdb = rawData[rawData.find("RSDS") :]
                        debug["guid"] = "%s-%s-%s-%s" % (
                            binascii.hexlify(pdb[4:8]),
                            binascii.hexlify(pdb[8:10]),
                            binascii.hexlify(pdb[10:12]),
                            binascii.hexlify(pdb[12:20]),
                        )
                        debug["age"] = struct.unpack("<L", pdb[20:24])[0]
                        debug["pdb"] = pdb[24:].rstrip("\x00")
                        scanObject.addMetadata(self.module_name, "RSDS", debug)
                    elif rawData.find("NB10") != -1 and len(rawData) > 16:
                        pdb = rawData[rawData.find("NB10") + 8 :]
                        debug["created"] = datetime.fromtimestamp(struct.unpack("<L", pdb[0:4])[0]).isoformat()
                        debug["age"] = struct.unpack("<L", pdb[4:8])[0]
                        debug["pdb"] = pdb[8:].rstrip("\x00")
                        scanObject.addMetadata(self.module_name, "NB10", debug)

        except pefile.PEFormatError:
            logging.debug("Invalid PE format")
        return moduleResult
Exemple #47
0
    def scan(self, data, file, options, expire_at):
        try:
            pe = pefile.PE(data=data)
        except pefile.PEFormatError:
            self.flags.append('pe_format_error')
            return

        cert_dict = parse_certificates(data)
        if cert_dict:
            self.event['security'] = cert_dict

        self.event['total'] = {
            'libraries': 0,
            'resources': 0,
            'sections': len(pe.sections),
            'symbols': 0,
        }
        self.event['summary'] = {}

        if hasattr(pe, 'DIRECTORY_ENTRY_DEBUG'):
            for d in pe.DIRECTORY_ENTRY_DEBUG:
                data = pe.get_data(d.struct.AddressOfRawData,
                                   d.struct.SizeOfData)
                if data.find(b'RSDS') != -1 and len(data) > 24:
                    pdb = data[data.find(b'RSDS'):]
                    self.event['debug'] = {
                        'type':
                        'rsds',
                        'guid':
                        b'%s-%s-%s-%s' % (
                            binascii.hexlify(pdb[4:8]),
                            binascii.hexlify(pdb[8:10]),
                            binascii.hexlify(pdb[10:12]),
                            binascii.hexlify(pdb[12:20]),
                        ),
                        'age':
                        struct.unpack('<L', pdb[20:24])[0],
                        'pdb':
                        pdb[24:].rstrip(b'\x00')
                    }
                elif data.find(b'NB10') != -1 and len(data) > 16:
                    pdb = data[data.find(b'NB10') + 8:]
                    self.event['debug'] = {
                        'type': 'nb10',
                        'created': struct.unpack('<L', pdb[0:4])[0],
                        'age': struct.unpack('<L', pdb[4:8])[0],
                        'pdb': pdb[8:].rstrip(b'\x00'),
                    }

        self.event['file_info'] = {
            'fixed': {},
            'string': [],
            'var': {},
        }

        # https://github.com/erocarrera/pefile/blob/master/pefile.py#L3553
        if hasattr(pe, 'FileInfo'):
            fi = pe.FileInfo[0]  # contains a single element
            for i in fi:
                if i.Key == b'StringFileInfo':
                    for st in i.StringTable:
                        for k, v in st.entries.items():
                            if k.decode() in COMMON_FILE_INFO_NAMES:
                                self.event['file_info'][COMMON_FILE_INFO_NAMES[
                                    k.decode()]] = v.decode()
                            else:
                                self.event['file_info']['string'].append({
                                    'name':
                                    k.decode(),
                                    'value':
                                    v.decode(),
                                })
                elif i.Key == b'VarFileInfo':
                    for v in i.Var:
                        translation = v.entry.get(b'Translation')
                        (lang, char) = (translation.split())
                        self.event['file_info']['var'] = {
                            'language':
                            VAR_FILE_INFO_LANGS.get(int(lang, 16)),
                            'character_set':
                            VAR_FILE_INFO_CHARS.get(int(char, 16)),
                        }

        if hasattr(pe, 'VS_FIXEDFILEINFO'):
            vs_ffi = pe.VS_FIXEDFILEINFO[0]  # contains a single element
            self.event['file_info']['fixed'] = {
                'flags': [],
                'operating_systems': [],
                'type': {
                    'primary':
                    FIXED_FILE_INFO_TYPE.get(vs_ffi.FileType),
                    'sub':
                    FIXED_FILE_INFO_SUBTYPE.get(
                        (vs_ffi.FileType, vs_ffi.FileSubtype), ''),
                }
            }

            # http://www.jasinskionline.com/windowsapi/ref/v/vs_fixedfileinfo.html
            ff_flags = vs_ffi.FileFlagsMask & vs_ffi.FileFlags
            for f in FIXED_FILE_INFO_FLAGS:
                if ff_flags & f:
                    self.event['file_info']['fixed']['flags'].append(
                        FIXED_FILE_INFO_FLAGS[f])
            for o in FIXED_FILE_INFO_OS:
                if vs_ffi.FileOS & o:
                    self.event['file_info']['fixed'][
                        'operating_systems'].append(FIXED_FILE_INFO_OS[o])

        self.event['header'] = {
            'machine': {
                'id':
                pe.FILE_HEADER.Machine,
                'type':
                pefile.MACHINE_TYPE.get(pe.FILE_HEADER.Machine).replace(
                    'IMAGE_FILE_MACHINE_', ''),
            },
            'magic': {
                'dos': MAGIC_DOS.get(pe.DOS_HEADER.e_magic, ''),
                'image': MAGIC_IMAGE.get(pe.OPTIONAL_HEADER.Magic, ''),
            },
            'subsystem':
            pefile.SUBSYSTEM_TYPE.get(pe.OPTIONAL_HEADER.Subsystem).replace(
                'IMAGE_SUBSYSTEM_', ''),
        }

        self.event['base_of_code'] = pe.OPTIONAL_HEADER.BaseOfCode
        self.event[
            'address_of_entry_point'] = pe.OPTIONAL_HEADER.AddressOfEntryPoint
        self.event['image_base'] = pe.OPTIONAL_HEADER.ImageBase
        self.event['size_of_code'] = pe.OPTIONAL_HEADER.SizeOfCode
        self.event[
            'size_of_initialized_data'] = pe.OPTIONAL_HEADER.SizeOfInitializedData
        self.event['size_of_headers'] = pe.OPTIONAL_HEADER.SizeOfHeaders
        self.event[
            'size_of_heap_reserve'] = pe.OPTIONAL_HEADER.SizeOfHeapReserve
        self.event['size_of_image'] = pe.OPTIONAL_HEADER.SizeOfImage
        self.event[
            'size_of_stack_commit'] = pe.OPTIONAL_HEADER.SizeOfStackCommit
        self.event[
            'size_of_stack_reserve'] = pe.OPTIONAL_HEADER.SizeOfStackReserve
        self.event['size_of_heap_commit'] = pe.OPTIONAL_HEADER.SizeOfHeapCommit
        self.event[
            'size_of_uninitalized_data'] = pe.OPTIONAL_HEADER.SizeOfUninitializedData
        self.event['file_alignment'] = pe.OPTIONAL_HEADER.FileAlignment
        self.event['section_alignment'] = pe.OPTIONAL_HEADER.SectionAlignment
        self.event['checksum'] = pe.OPTIONAL_HEADER.CheckSum

        self.event[
            'major_image_version'] = pe.OPTIONAL_HEADER.MajorImageVersion
        self.event[
            'minor_image_version'] = pe.OPTIONAL_HEADER.MinorImageVersion
        self.event[
            'major_linker_version'] = pe.OPTIONAL_HEADER.MajorLinkerVersion
        self.event[
            'minor_linker_version'] = pe.OPTIONAL_HEADER.MinorLinkerVersion
        self.event[
            'major_operating_system_version'] = pe.OPTIONAL_HEADER.MajorOperatingSystemVersion
        self.event[
            'minor_operating_system_version'] = pe.OPTIONAL_HEADER.MinorOperatingSystemVersion
        self.event[
            'major_subsystem_version'] = pe.OPTIONAL_HEADER.MajorSubsystemVersion
        self.event[
            'minor_subsystem_version'] = pe.OPTIONAL_HEADER.MinorSubsystemVersion
        self.event['image_version'] = float(
            f'{pe.OPTIONAL_HEADER.MajorImageVersion}.{pe.OPTIONAL_HEADER.MinorImageVersion}'
        )
        self.event['linker_version'] = float(
            f'{pe.OPTIONAL_HEADER.MajorLinkerVersion}.{pe.OPTIONAL_HEADER.MinorLinkerVersion}'
        )
        self.event['operating_system_version'] = float(
            f'{pe.OPTIONAL_HEADER.MajorOperatingSystemVersion}.{pe.OPTIONAL_HEADER.MinorOperatingSystemVersion}'
        )
        self.event['subsystem_version'] = float(
            f'{pe.OPTIONAL_HEADER.MajorSubsystemVersion}.{pe.OPTIONAL_HEADER.MinorSubsystemVersion}'
        )

        try:
            self.event['compile_time'] = datetime.datetime.utcfromtimestamp(
                pe.FILE_HEADER.TimeDateStamp).isoformat()
        except OverflowError:
            logging.info("invalid compile time caused an overflow error")

        if hasattr(pe.OPTIONAL_HEADER, 'BaseOfData'):
            self.event['base_of_data'] = pe.OPTIONAL_HEADER.BaseOfData

        dll_characteristics = []
        for o in CHARACTERISTICS_DLL:
            if pe.OPTIONAL_HEADER.DllCharacteristics & o:
                dll_characteristics.append(CHARACTERISTICS_DLL[o])

        if dll_characteristics:
            self.event['dll_characteristics'] = dll_characteristics

        image_characteristics = []
        for o in CHARACTERISTICS_IMAGE:
            if pe.FILE_HEADER.Characteristics & o:
                image_characteristics.append(CHARACTERISTICS_IMAGE[o])

        if image_characteristics:
            self.event['image_characteristics'] = image_characteristics

        self.event['resources'] = []
        if hasattr(pe, 'DIRECTORY_ENTRY_RESOURCE'):
            resource_md5_set = set()
            resource_sha1_set = set()
            resource_sha256_set = set()

            for res0 in pe.DIRECTORY_ENTRY_RESOURCE.entries:
                for res1 in res0.directory.entries:
                    for res2 in res1.directory.entries:
                        lang = res2.data.lang
                        sub = res2.data.sublang
                        sub = pefile.get_sublang_name_for_lang(lang, sub)
                        data = pe.get_data(res2.data.struct.OffsetToData,
                                           res2.data.struct.Size)

                        resource_md5 = hashlib.md5(data).hexdigest()
                        resource_sha1 = hashlib.sha1(data).hexdigest()
                        resource_sha256 = hashlib.sha256(data).hexdigest()
                        resource_md5_set.add(resource_md5)
                        resource_sha1_set.add(resource_sha1)
                        resource_sha256_set.add(resource_sha256)

                        resource_dict = {
                            'id':
                            res1.id,
                            'language': {
                                'sub': sub.replace('SUBLANG_', '')
                            },
                            'type':
                            pefile.RESOURCE_TYPE.get(res0.id,
                                                     '').replace('RT_', ''),
                            'md5':
                            resource_md5,
                            'sha1':
                            resource_sha1,
                            'sha256':
                            resource_sha256,
                        }

                        if lang in pefile.LANG:
                            resource_dict['language']['primary'] = pefile.LANG[
                                lang].replace('LANG_', '')

                        if res1.name:
                            resource_dict['name'] = str(res1.name)

                        self.event['resources'].append(resource_dict)

            self.event['summary']['resource_md5'] = list(resource_md5_set)
            self.event['summary']['resource_sha1'] = list(resource_sha1_set)
            self.event['summary']['resource_sha256'] = list(
                resource_sha256_set)

        self.event['total']['resources'] = len(self.event['resources'])

        self.event['sections'] = []
        section_md5_set = set()
        section_sha1_set = set()
        section_sha256_set = set()

        for sec in pe.sections:
            try:
                name = sec.Name.rstrip(b'\x00').decode()
                section_md5 = sec.get_hash_md5()
                section_sha1 = sec.get_hash_sha1()
                section_sha256 = sec.get_hash_sha256()

                section_md5_set.add(section_md5)
                section_sha1_set.add(section_sha1)
                section_sha256_set.add(section_sha256)
                row = {
                    'address': {
                        'physical': sec.Misc_PhysicalAddress,
                        'virtual': sec.VirtualAddress,
                    },
                    'characteristics': [],
                    'entropy': sec.get_entropy(),
                    'name': name,
                    'size': sec.SizeOfRawData,
                    'md5': section_md5,
                    'sha1': section_sha1,
                    'sha256': section_sha256,
                }
                for o in CHARACTERISTICS_SECTION:
                    if sec.Characteristics & o:
                        row['characteristics'].append(
                            CHARACTERISTICS_SECTION[o])

                self.event['sections'].append(row)
                self.event['summary']['section_md5'] = list(section_md5_set)
                self.event['summary']['section_sha1'] = list(section_sha1_set)
                self.event['summary']['section_sha256'] = list(
                    section_sha256_set)
            except Exception as e:
                logging.warning(f"exception thrown when parsing section's {e}")

        self.event['symbols'] = {
            'exported': [],
            'imported': [],
            'libraries': [],
            'table': [],
        }

        if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):
            self.event['imphash'] = pe.get_imphash()

            for imp in pe.DIRECTORY_ENTRY_IMPORT:
                lib = imp.dll.decode()
                if lib not in self.event['symbols']['libraries']:
                    self.event['symbols']['libraries'].append(lib)

                row = {
                    'library': lib,
                    'symbols': [],
                    'type': 'import',
                }
                for e in imp.imports:
                    if not e.name:
                        name = f'ord{e.ordinal}'
                    else:
                        name = e.name.decode()
                    self.event['symbols']['imported'].append(name)
                    row['symbols'].append(name)
                self.event['symbols']['table'].append(row)

        if hasattr(pe, 'DIRECTORY_ENTRY_EXPORT'):
            for exp in pe.DIRECTORY_ENTRY_EXPORT.symbols:
                if not exp.name:
                    name = f'ord{exp.ordinal}'
                else:
                    name = exp.name
                self.event['symbols']['exported'].append(name)
                self.event['symbols']['table'].append({
                    'address': exp.address,
                    'symbol': name,
                    'type': 'export',
                })

        self.event['total']['libraries'] = len(
            self.event['symbols']['libraries'])
        self.event['total']['symbols'] = len(self.event['symbols']['table'])
Exemple #48
0
    def _run(self, scanObject, result, depth, args):
        moduleResult = []
        imports = {}
        sections = {}
        exports = []

        try:
            pe = pefile.PE(data=scanObject.buffer)
            dump_dict = pe.dump_dict()

            # Parse sections
            for section in dump_dict.get('PE Sections', []):
                secName = section.get('Name', {}).get('Value', '').strip('\0')
                ptr = section.get('PointerToRawData', {}).get('Value')
                virtAddress = section.get('VirtualAddress', {}).get('Value')
                virtSize = section.get('Misc_VirtualSize', {}).get('Value')
                size = section.get('SizeOfRawData', {}).get('Value')
                secData = pe.get_data(ptr, size)
                secInfo = {
                    'Virtual Address': '0x%08X' % virtAddress,
                    'Virtual Size': virtSize,
                    'Raw Size': size,
                    'MD5': section.get('MD5', ''),
                    'SHA1': section.get('SHA1', ''),
                    'SHA256': section.get('SHA256', ''),
                    'Entropy': section.get('Entropy', ''),
                    'Section Characteristics': section.get('Flags', []),
                    'Structure': section.get('Structure', ''),
                }
                if secInfo['MD5'] != scanObject.objectHash:
                    moduleResult.append(ModuleObject(
                        buffer=secData,
                        externalVars=ExternalVars(filename=secName)))
                sections[secName] = secInfo
            sections['Total'] = pe.FILE_HEADER.NumberOfSections
            scanObject.addMetadata(self.module_name, 'Sections', sections)

            # Parse imports and exports
            try:
                for exp in pe.DIRECTORY_ENTRY_EXPORT.symbols:
                    exports.append(exp.name)
                scanObject.addMetadata(self.module_name, 'Exports', exports)
            except ScanError:
                raise
            except:
                logging.debug('No export entries')

            for imp_symbol in dump_dict['Imported symbols']:
                for imp in imp_symbol:
                    if imp.get('DLL'):
                        dll = imp.get('DLL')
                        imports.setdefault(dll, [])
                        # Imports can be identified by ordinal or name
                        if imp.get('Ordinal'):
                            ordinal = imp.get('Ordinal')
                            imports[dll].append(ordinal)
                        if imp.get('Name'):
                            name = imp.get('Name')
                            imports[dll].append(name)
            scanObject.addMetadata(self.module_name, 'Imports', imports)

            # Parse resources
            try:
                for resource in pe.DIRECTORY_ENTRY_RESOURCE.entries:
                    res_type = pefile.RESOURCE_TYPE.get(resource.id, 'Unknown')
                    for entry in resource.directory.entries:
                        for e_entry in entry.directory.entries:
                            sublang = pefile.get_sublang_name_for_lang(
                                e_entry.data.lang,
                                e_entry.data.sublang,
                            )
                            offset = e_entry.data.struct.OffsetToData
                            size = e_entry.data.struct.Size
                            r_data = pe.get_data(offset, size)
                            language = pefile.LANG.get(
                                e_entry.data.lang, 'Unknown')
                            data = {
                                'Type': res_type,
                                'Id': e_entry.id,
                                'Name': e_entry.data.struct.name,
                                'Offset': offset,
                                'Size': size,
                                'SHA256': hashlib.sha256(r_data).hexdigest(),
                                'SHA1': hashlib.sha1(r_data).hexdigest(),
                                'MD5': hashlib.md5(r_data).hexdigest(),
                                'Language': language,
                                'Sub Language': sublang,
                            }
                            scanObject.addMetadata(
                                self.module_name, 'Resources', data)
            except ScanError:
                raise
            except:
                logging.debug('No resources')

            # Gather miscellaneous stuff
            try:
                scanObject.addMetadata(self.module_name,
                                       'Imphash', pe.get_imphash())
            except ScanError:
                raise
            except:
                logging.debug('Unable to identify imphash')

            imgChars = dump_dict.get('Flags', [])
            scanObject.addMetadata(
                self.module_name, 'Image Characteristics', imgChars)
            # Make a pretty date format
            date = datetime.fromtimestamp(pe.FILE_HEADER.TimeDateStamp)
            isoDate = date.isoformat()
            scanObject.addMetadata(self.module_name, 'Date', isoDate)
            scanObject.addMetadata(
                self.module_name, 'Timestamp', pe.FILE_HEADER.TimeDateStamp)

            machine = pe.FILE_HEADER.Machine
            machineData = {
                'Id': machine,
                'Type': pefile.MACHINE_TYPE.get(machine)
            }
            scanObject.addMetadata(
                self.module_name, 'Machine Type', machineData)

            # Reference: http://msdn.microsoft.com/en-us/library/windows/desktop/ms680339%28v=vs.85%29.aspx
            scanObject.addMetadata(
                self.module_name,
                'Image Magic',
                IMAGE_MAGIC_LOOKUP.get(pe.OPTIONAL_HEADER.Magic, 'Unknown'))

            dllChars = dump_dict.get('DllCharacteristics', [])
            scanObject.addMetadata(
                self.module_name, 'DLL Characteristics', dllChars)

            subsystem = pe.OPTIONAL_HEADER.Subsystem
            subName = pefile.SUBSYSTEM_TYPE.get(subsystem)
            scanObject.addMetadata(self.module_name, 'Subsystem', subName)

            # Reference: http://msdn.microsoft.com/en-us/library/windows/desktop/ms648009%28v=vs.85%29.aspx

            scanObject.addMetadata(
                self.module_name,
                'Stack Reserve Size',
                pe.OPTIONAL_HEADER.SizeOfStackReserve)
            scanObject.addMetadata(
                self.module_name,
                'Stack Commit Size',
                pe.OPTIONAL_HEADER.SizeOfStackCommit)
            scanObject.addMetadata(
                self.module_name,
                'Heap Reserve Size',
                pe.OPTIONAL_HEADER.SizeOfHeapReserve)
            scanObject.addMetadata(
                self.module_name,
                'Heap Commit Size',
                pe.OPTIONAL_HEADER.SizeOfHeapCommit)
            scanObject.addMetadata(
                self.module_name,
                'EntryPoint',
                hex(pe.OPTIONAL_HEADER.AddressOfEntryPoint))
            scanObject.addMetadata(
                self.module_name,
                'ImageBase',
                hex(pe.OPTIONAL_HEADER.ImageBase))

            # Parse RSDS & Rich
            scanObject.addMetadata(
                self.module_name, 'Rich Header', self.parseRich(pe))

            if hasattr(pe, 'DIRECTORY_ENTRY_DEBUG'):
                debug = dict()
                for e in pe.DIRECTORY_ENTRY_DEBUG:
                    rawData = pe.get_data(e.struct.AddressOfRawData, e.struct.SizeOfData)
                    if rawData.find('RSDS') != -1 and len(rawData) > 24:
                        pdb = rawData[rawData.find('RSDS'):]
                        debug["guid"] = "%s-%s-%s-%s" % (
                            binascii.hexlify(pdb[4:8]),
                            binascii.hexlify(pdb[8:10]),
                            binascii.hexlify(pdb[10:12]),
                            binascii.hexlify(pdb[12:20]))
                        debug["age"] = struct.unpack('<L', pdb[20:24])[0]
                        debug["pdb"] = pdb[24:].rstrip('\x00')
                        scanObject.addMetadata(self.module_name, 'RSDS', debug)
                    elif rawData.find('NB10') != -1 and len(rawData) > 16:
                        pdb = rawData[rawData.find('NB10')+8:]
                        debug["created"] = datetime.fromtimestamp(struct.unpack('<L', pdb[0:4])[0]).isoformat()
                        debug["age"] = struct.unpack('<L', pdb[4:8])[0]
                        debug["pdb"] = pdb[8:].rstrip('\x00')
                        scanObject.addMetadata(self.module_name, 'NB10', debug)

        except pefile.PEFormatError:
            logging.debug("Invalid PE format")
        return moduleResult