Esempio n. 1
0
    def _get_type_tokens_after_name(self, ctxt, type, platform,
                                    base_confidence, parent_type, escaping,
                                    result, result_count):
        try:
            platform_py = None
            if platform:
                platform_py = _platform.Platform(
                    handle=core.BNNewPlatformReference(platform))
            parent_type_py = None
            if parent_type:
                parent_type_py = types.Type(
                    handle=core.BNNewTypeReference(parent_type))
            result_py = self.get_type_tokens_after_name(
                types.Type(handle=core.BNNewTypeReference(type)), platform_py,
                base_confidence, parent_type_py, escaping)

            TypePrinter._cached_tokens = _function.InstructionTextToken._get_core_struct(
                result_py)
            result[0] = TypePrinter._cached_tokens
            result_count[0] = len(result_py)

            return True
        except:
            log_error(traceback.format_exc())
            return False
Esempio n. 2
0
    def parse_types_from_source(self,
                                source,
                                filename=None,
                                include_dirs=[],
                                auto_type_source=None):
        """
		``parse_types_from_source`` parses the source string and any needed headers searching for them in
		the optional list of directories provided in ``include_dirs``.

		:param str source: source string to be parsed
		:param str filename: optional source filename
		:param list(str) include_dirs: optional list of string filename include directories
		:param str auto_type_source: optional source of types if used for automatically generated types
		:return: :py:class:`TypeParserResult` (a SyntaxError is thrown on parse error)
		:rtype: TypeParserResult
		:Example:

			>>> platform.parse_types_from_source('int foo;\\nint bar(int x);\\nstruct bas{int x,y;};\\n')
			({types: {'bas': <type: struct bas>}, variables: {'foo': <type: int32_t>}, functions:{'bar':
			<type: int32_t(int32_t x)>}}, '')
			>>>
		"""

        if filename is None:
            filename = "input"
        dir_buf = (ctypes.c_char_p * len(include_dirs))()
        for i in range(0, len(include_dirs)):
            dir_buf[i] = include_dirs[i].encode('charmap')
        parse = core.BNTypeParserResult()
        errors = ctypes.c_char_p()
        result = core.BNParseTypesFromSource(self.handle, source, filename,
                                             parse, errors, dir_buf,
                                             len(include_dirs),
                                             auto_type_source)
        error_str = errors.value
        core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte)))
        if not result:
            raise SyntaxError(error_str)
        type_dict = {}
        variables = {}
        functions = {}
        for i in range(0, parse.typeCount):
            name = types.QualifiedName._from_core_struct(parse.types[i].name)
            type_dict[name] = types.Type(core.BNNewTypeReference(
                parse.types[i].type),
                                         platform=self)
        for i in range(0, parse.variableCount):
            name = types.QualifiedName._from_core_struct(
                parse.variables[i].name)
            variables[name] = types.Type(core.BNNewTypeReference(
                parse.variables[i].type),
                                         platform=self)
        for i in range(0, parse.functionCount):
            name = types.QualifiedName._from_core_struct(
                parse.functions[i].name)
            functions[name] = types.Type(core.BNNewTypeReference(
                parse.functions[i].type),
                                         platform=self)
        core.BNFreeTypeParserResult(parse)
        return types.TypeParserResult(type_dict, variables, functions)
Esempio n. 3
0
    def _get_lines_for_data(self, ctxt, view, addr, type, prefix, prefixCount,
                            width, count, typeCtx, ctxCount):
        try:
            file_metadata = filemetadata.FileMetadata(
                handle=core.BNGetFileForView(view))
            view = binaryview.BinaryView(file_metadata=file_metadata,
                                         handle=core.BNNewViewReference(view))
            type = types.Type(handle=core.BNNewTypeReference(type))

            prefixTokens = function.InstructionTextToken.get_instruction_lines(
                prefix, prefixCount)
            pycontext = []
            for i in range(ctxCount):
                pycontext.append(
                    TypeContext(
                        types.Type(core.BNNewTypeReference(typeCtx[i].type)),
                        typeCtx[i].offset))

            result = self.perform_get_lines_for_data(ctxt, view, addr, type,
                                                     prefixTokens, width,
                                                     pycontext)

            count[0] = len(result)
            line_buf = (core.BNDisassemblyTextLine * len(result))()
            for i in range(len(result)):
                line = result[i]
                color = line.highlight
                if not isinstance(
                        color,
                        enums.HighlightStandardColor) and not isinstance(
                            color, highlight.HighlightColor):
                    raise ValueError(
                        "Specified color is not one of HighlightStandardColor, highlight.HighlightColor"
                    )
                if isinstance(color, enums.HighlightStandardColor):
                    color = highlight.HighlightColor(color)
                line_buf[i].highlight = color._get_core_struct()
                if line.address is None:
                    if len(line.tokens) > 0:
                        line_buf[i].addr = line.tokens[0].address
                    else:
                        line_buf[i].addr = 0
                else:
                    line_buf[i].addr = line.address
                if line.il_instruction is not None:
                    line_buf[i].instrIndex = line.il_instruction.instr_index
                else:
                    line_buf[i].instrIndex = 0xffffffffffffffff

                line_buf[i].count = len(line.tokens)
                line_buf[
                    i].tokens = function.InstructionTextToken.get_instruction_lines(
                        line.tokens)

            return ctypes.cast(line_buf, ctypes.c_void_p).value
        except:
            log.log_error(traceback.format_exc())
            return None
Esempio n. 4
0
	def _is_valid_for_data(self, ctxt, view, addr, type, context, ctxCount):
		try:
			file_metadata = FileMetadata(handle=core.BNGetFileForView(view))
			view = BinaryView(file_metadata=file_metadata, handle=core.BNNewViewReference(view))
			type = Type(handle=core.BNNewTypeReference(type))
			pycontext = []
			for i in range(0, ctxCount):
				pycontext.append(Type(core.BNNewTypeReference(context[i])))
			return self.perform_is_valid_for_data(ctxt, view, addr, type, pycontext)
		except:
			log_error(traceback.format_exc())
			return False
Esempio n. 5
0
	def parse_types_from_source_file(self, filename, include_dirs=[], auto_type_source=None):
		"""
		``parse_types_from_source_file`` parses the source file ``filename`` and any needed headers searching for them in
		the optional list of directories provided in ``include_dirs``.

		:param str filename: filename of file to be parsed
		:param include_dirs: optional list of string filename include directories
		:type include_dirs: list(str)
		:param str auto_type_source: optional source of types if used for automatically generated types
		:return: :py:class:`TypeParserResult` (a SyntaxError is thrown on parse error)
		:rtype: TypeParserResult
		:Example:

			>>> file = "/Users/binja/tmp.c"
			>>> open(file).read()
			'int foo;\\nint bar(int x);\\nstruct bas{int x,y;};\\n'
			>>> platform.parse_types_from_source_file(file)
			({types: {'bas': <type: struct bas>}, variables: {'foo': <type: int32_t>}, functions:
			{'bar': <type: int32_t(int32_t x)>}}, '')
			>>>
		"""
		if not (isinstance(filename, str) and os.path.isfile(filename) and os.access(filename, os.R_OK)):
			 raise AttributeError("File {} doesn't exist or isn't readable".format(filename))
		dir_buf = (ctypes.c_char_p * len(include_dirs))()
		for i in range(0, len(include_dirs)):
			dir_buf[i] = include_dirs[i].encode('charmap')
		parse = core.BNTypeParserResult()
		errors = ctypes.c_char_p()
		result = core.BNParseTypesFromSourceFile(self.handle, filename, parse, errors, dir_buf,
			len(include_dirs), auto_type_source)
		error_str = errors.value.decode("utf-8")
		core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte)))
		if not result:
			raise SyntaxError(error_str)
		type_dict = {}
		variables = {}
		functions = {}
		for i in range(0, parse.typeCount):
			name = types.QualifiedName._from_core_struct(parse.types[i].name)
			type_dict[name] = types.Type(core.BNNewTypeReference(parse.types[i].type), platform = self)
		for i in range(0, parse.variableCount):
			name = types.QualifiedName._from_core_struct(parse.variables[i].name)
			variables[name] = types.Type(core.BNNewTypeReference(parse.variables[i].type), platform = self)
		for i in range(0, parse.functionCount):
			name = types.QualifiedName._from_core_struct(parse.functions[i].name)
			functions[name] = types.Type(core.BNNewTypeReference(parse.functions[i].type), platform = self)
		core.BNFreeTypeParserResult(parse)
		return types.TypeParserResult(type_dict, variables, functions)
Esempio n. 6
0
 def parameters(self):
     """Type parameters list (read-only)"""
     count = ctypes.c_ulonglong()
     params = core.BNGetTypeParameters(self.handle, count)
     result = []
     for i in range(0, count.value):
         param_type = Type(core.BNNewTypeReference(params[i].type),
                           platform=self.platform,
                           confidence=params[i].typeConfidence)
         if params[i].defaultLocation:
             param_location = None
         else:
             name = params[i].name
             if (params[i].location.type
                     == VariableSourceType.RegisterVariableSourceType) and (
                         self.platform is not None):
                 name = self.platform.arch.get_reg_name(
                     params[i].location.storage)
             elif params[
                     i].location.type == VariableSourceType.StackVariableSourceType:
                 name = "arg_%x" % params[i].location.storage
             param_location = binaryninja.function.Variable(
                 None, params[i].location.type, params[i].location.index,
                 params[i].location.storage, name, param_type)
         result.append(
             FunctionParameter(param_type, params[i].name, param_location))
     core.BNFreeTypeParameterList(params, count.value)
     return result
Esempio n. 7
0
	def __getitem__(self, name):
		try:
			member = core.BNGetStructureMemberByName(self.handle, name)
			return StructureMember(Type(core.BNNewTypeReference(member.contents.type), confidence=member.contents.typeConfidence),
					member.contents.name, member.contents.offset)
		finally:
			core.BNFreeStructureMember(member)
Esempio n. 8
0
	def functions(self):
		"""List of platform-specific function definitions (read-only)"""
		count = ctypes.c_ulonglong(0)
		type_list = core.BNGetPlatformFunctions(self.handle, count)
		result = {}
		for i in range(0, count.value):
			name = types.QualifiedName._from_core_struct(type_list[i].name)
			result[name] = types.Type(core.BNNewTypeReference(type_list[i].type), platform = self)
		core.BNFreeTypeList(type_list, count.value)
		return result
Esempio n. 9
0
	def members(self):
		"""Structure member list (read-only)"""
		count = ctypes.c_ulonglong()
		members = core.BNGetStructureMembers(self.handle, count)
		result = []
		for i in range(0, count.value):
			result.append(StructureMember(Type(core.BNNewTypeReference(members[i].type), confidence = members[i].typeConfidence),
				members[i].name, members[i].offset))
		core.BNFreeStructureMemberList(members, count.value)
		return result
Esempio n. 10
0
	def member_at_offset(self, offset):
		try:
			if self._mutable:
				member = core.BNGetStructureBuilderMemberAtOffset(self._handle, offset, None)
			else:
				member = core.BNGetStructureMemberAtOffset(self._handle, offset, None)
			return StructureMember(Type(core.BNNewTypeReference(member.contents.type), confidence=member.contents.typeConfidence),
					member.contents.name, member.contents.offset)
		finally:
			core.BNFreeStructureMember(member)
Esempio n. 11
0
	def system_calls(self):
		"""List of system calls for this platform (read-only)"""
		count = ctypes.c_ulonglong(0)
		call_list = core.BNGetPlatformSystemCalls(self.handle, count)
		result = {}
		for i in range(0, count.value):
			name = types.QualifiedName._from_core_struct(call_list[i].name)
			t = types.Type(core.BNNewTypeReference(call_list[i].type), platform = self)
			result[call_list[i].number] = (name, t)
		core.BNFreeSystemCallList(call_list, count.value)
		return result
Esempio n. 12
0
	def named_types(self):
		"""
		A dict containing all named types provided by a type library (read-only)
		"""
		count = ctypes.c_ulonglong(0)
		result = {}
		named_types = core.BNGetTypeLibraryNamedTypes(self.handle, count)
		for i in range(0, count.value):
			name = types.QualifiedName._from_core_struct(named_types[i].name)
			result[name] = types.Type(core.BNNewTypeReference(named_types[i].type))
		core.BNFreeQualifiedNameAndTypeArray(named_types, count.value)
		return result
Esempio n. 13
0
 def get_type_lines(
     self,
     type: types.Type,
     data: binaryview.BinaryView,
     name: types.QualifiedNameType,
     line_width=80,
     collapsed=False,
     escaping: TokenEscapingType = TokenEscapingType.
     BackticksTokenEscapingType
 ) -> List[types.TypeDefinitionLine]:
     if not isinstance(name, types.QualifiedName):
         name = types.QualifiedName(name)
     count = ctypes.c_ulonglong()
     core_lines = ctypes.POINTER(core.BNTypeDefinitionLine)()
     if not core.BNGetTypePrinterTypeLines(
             self.handle, type.handle, data.handle,
             name._to_core_struct(), line_width, collapsed,
             ctypes.c_int(escaping), core_lines, count):
         raise RuntimeError("BNGetTypePrinterTypeLines returned False")
     lines = []
     for i in range(count.value):
         tokens = _function.InstructionTextToken._from_core_struct(
             core_lines[i].tokens, core_lines[i].count)
         type_ = types.Type.create(handle=core.BNNewTypeReference(
             core_lines[i].type),
                                   platform=data.platform)
         root_type = types.Type.create(handle=core.BNNewTypeReference(
             core_lines[i].rootType),
                                       platform=data.platform)
         root_type_name = core.pyNativeStr(core_lines[i].rootTypeName)
         line = types.TypeDefinitionLine(core_lines[i].lineType, tokens,
                                         type_, root_type, root_type_name,
                                         core_lines[i].offset,
                                         core_lines[i].fieldIndex)
         lines.append(line)
     core.BNFreeTypeDefinitionLineList(core_lines, count.value)
     return lines
Esempio n. 14
0
    def _get_type_string(self, ctxt, type, platform, name, escaping, result):
        try:
            platform_py = None
            if platform:
                platform_py = _platform.Platform(
                    handle=core.BNNewPlatformReference(platform))
            result_py = self.get_type_string(
                types.Type(handle=core.BNNewTypeReference(type)), platform_py,
                types.QualifiedName._from_core_struct(name.contents), escaping)

            TypePrinter._cached_string = core.cstr(result_py)
            result[0] = TypePrinter._cached_string
            return True
        except:
            log_error(traceback.format_exc())
            return False
Esempio n. 15
0
    def _get_type_lines(self, ctxt, type, data, name, line_width, collapsed,
                        escaping, result, result_count):
        try:
            result_py = self.get_type_lines(
                types.Type(handle=core.BNNewTypeReference(type)),
                binaryview.BinaryView(handle=core.BNNewViewReference(data)),
                types.QualifiedName._from_core_struct(name.contents),
                line_width, collapsed, escaping)

            TypePrinter._cached_lines = (core.BNTypeDefinitionLine *
                                         len(result_py))()
            for (i, line) in enumerate(result_py):
                TypePrinter._cached_lines[i] = line._to_core_struct()
            result[0] = TypePrinter._cached_lines
            result_count[0] = len(result_py)

            return True
        except:
            log_error(traceback.format_exc())
            return False
Esempio n. 16
0
    def parse_type_string(
        self,
        source: str,
        platform: 'platform.Platform',
        existing_types: Optional[List[QualifiedNameTypeAndId]] = None
    ) -> Tuple[Optional[Tuple['types.QualifiedNameType', 'types.Type']],
               List[TypeParserError]]:
        if existing_types is None:
            existing_types = []
        existing_types_cpp = (core.BNQualifiedNameTypeAndId *
                              len(existing_types))()
        for (i, qnatid) in enumerate(existing_types):
            existing_types_cpp[i] = qnatid._to_core_struct()

        result_cpp = core.BNQualifiedNameAndType()
        errors_cpp = ctypes.POINTER(core.BNTypeParserError)()
        error_count = ctypes.c_size_t()

        success = core.BNTypeParserParseTypeString(self.handle, source,
                                                   platform.handle,
                                                   existing_types_cpp,
                                                   len(existing_types),
                                                   result_cpp, errors_cpp,
                                                   error_count)

        if success:
            result = (types.QualifiedName._from_core_struct(result_cpp.name),
                      types.Type.create(
                          handle=core.BNNewTypeReference(result_cpp.type)))
            core.BNFreeQualifiedNameAndType(result_cpp)
        else:
            result = None

        errors = []
        for i in range(error_count.value):
            errors.append(TypeParserError._from_core_struct(errors_cpp[i]))
        core.BNFreeTypeParserErrors(errors_cpp, error_count.value)

        return result, errors
Esempio n. 17
0
    def _parse_type_string(self, ctxt, source, platform_, existingTypes,
                           existingTypeCount, result, errors,
                           errorCount) -> bool:
        try:
            source_py = core.pyNativeStr(source)
            platform_py = platform.Platform(
                handle=core.BNNewPlatformReference(platform_))

            existing_types_py = []
            for i in range(existingTypeCount):
                existing_types_py.append(
                    QualifiedNameTypeAndId._from_core_struct(existingTypes[i]))

            (result_py,
             errors_py) = self.parse_type_string(source_py, platform_py,
                                                 existing_types_py)

            if result_py is not None and result is not None:
                result[0].name = types.QualifiedName(
                    result_py[0])._to_core_struct()
                result[0].type = core.BNNewTypeReference(result_py[1].handle)

            if errorCount is not None:
                errorCount[0] = len(errors_py)
            if errors is not None:
                errors_out = (core.BNTypeParserError * len(errors_py))()
                for i in range(len(errors_py)):
                    errors_out[i] = errors_py[i]._to_core_struct()
                TypeParser._cached_error = errors_out
                errors[0] = errors_out

            return result_py is not None
        except:
            errorCount[0] = 0
            log_error(traceback.format_exc())
            return False
Esempio n. 18
0
 def with_confidence(self, confidence):
     return Type(handle=core.BNNewTypeReference(self.handle),
                 platform=self.platform,
                 confidence=confidence)
Esempio n. 19
0
 def _to_core_struct(self) -> core.BNQualifiedNameTypeAndId:
     result = core.BNQualifiedNameTypeAndId()
     result.name = types.QualifiedName(self.name)._to_core_struct()
     result.type = core.BNNewTypeReference(self.type.handle)
     result.id = self.id
     return result
Esempio n. 20
0
 def _from_core_struct(
         cls,
         struct: core.BNQualifiedNameTypeAndId) -> 'QualifiedNameTypeAndId':
     name = types.QualifiedName._from_core_struct(struct.name)
     type = types.Type.create(handle=core.BNNewTypeReference(struct.type))
     return QualifiedNameTypeAndId(name, struct.id, type)
Esempio n. 21
0
 def _to_core_struct(self) -> core.BNParsedType:
     result = core.BNParsedType()
     result.name = types.QualifiedName(self.name)._to_core_struct()
     result.type = core.BNNewTypeReference(self.type.handle)
     result.isUser = self.is_user
     return result
Esempio n. 22
0
 def _from_core_struct(cls, struct: core.BNParsedType) -> 'ParsedType':
     name = types.QualifiedName._from_core_struct(struct.name)
     type = types.Type.create(handle=core.BNNewTypeReference(struct.type))
     return ParsedType(name, type, struct.isUser)