new_contents: # Copyright (c) 2015-2020 Vector 35 Inc
  #
  # Permission is hereby granted, free of charge, to any person obtaining a copy
  # of this software and associated documentation files (the "Software"), to
  # deal in the Software without restriction, including without limitation the
  # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  # sell copies of the Software, and to permit persons to whom the Software is
  # furnished to do so, subject to the following conditions:
  #
  # The above copyright notice and this permission notice shall be included in
  # all copies or substantial portions of the Software.
  #
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  # IN THE SOFTWARE.
  
  # This is an example BinaryView plugin which demonstrates how to specify
  # and generate a load settings spec. Load settings can subsequently be presented
  # by the UI in the Open With Options dialog or headless when opening a
  # file with options.
  
  from binaryninja import log
  from binaryninja import _binaryninjacore as core
  from binaryninja.architecture import Architecture
  from binaryninja.binaryview import BinaryView
  from binaryninja.binaryview import BinaryViewType
  from binaryninja.enums import SegmentFlag
  from binaryninja import Settings
  import json
  
  use_default_loader_settings = True
  
  class MappedView(BinaryView):
  	name = "Mapped (Python)"
  	long_name = "Mapped (Python)"
  	load_address = 0x100000
  
  	def __init__(self, data):
  		BinaryView.__init__(self, parent_view = data, file_metadata = data.file)
  
  	@classmethod
  	def is_valid_for_data(cls, data):
  		# Insert code that looks for a magic identifier and return True if this BinaryViewType can handle/parse the binary
  		return True
  
  	@classmethod
  	def get_load_settings_for_data(cls, data):
  		# This method is optional. If provided this is where the Load Settings for a BinaryViewType are specified. Binary Ninja provides
  		# some default read-only load settings which are:
  		#		["loader.architecture", "loader.platform", "loader.entryPoint", "loader.imageBase", "loader.segments", "loader.sections"]
  		# The default load settings are provided for consistency and convenience.
  		# The default load settings are always generated with a read-only indication which is respected by the UI.
  		# The read-only indication is a property that consists of a JSON name/value pair ("readOnly" : true).
  		load_settings = None
  		if not use_default_loader_settings:
  			# Create a new named Settings container for the load settings.
  			Settings("mapped_load_settings")
  		else:
  			# Optionally, perform light-weight parsing of the 'Raw' BinaryView to extract required information for load settings generation.
  			# This allows finer control of the settings provided as well as their default values.
  			# For example, the view.relocatable property could be used to control the read-only attribute of "loader.imageBase"
  			view = cls.registered_view_type.parse(data)
  
  			# Populate settings container with default load settings
  			# Note: `get_default_load_settings_for_data` automatically tries to parse the input if the `data` BinaryViewType name does not match the
  			# cls BinaryViewType name. In this case a parsed view is already being passed.
  			load_settings = cls.registered_view_type.get_default_load_settings_for_data(view)
  
  			# Specify default load settings that can be overridden (from the UI).
  			overrides = ["loader.architecture", "loader.platform", "loader.entryPoint", "loader.imageBase", "loader.segments", "loader.sections"]
  			for override in overrides:
  				if load_settings.contains(override):
  					load_settings.update_property(override, json.dumps({'readOnly': False}))
  
  			# Override the default setting values.
  			load_settings.update_property("loader.imageBase", json.dumps({'default': 0}))
  			load_settings.update_property("loader.entryPoint", json.dumps({'default': 0}))
  
  		# Specify additional custom settings.
  		load_settings.register_setting("loader.my_custom_arch.customLoadSetting",
  			'{"title" : "My Custom Load Setting",\
  			"type" : "boolean",\
  			"default" : false,\
  			"description" : "My custom load setting description."}')
  
  		return load_settings
  
  	def init(self):
  		if self.parse_only is True:
  			# Perform light-weight parsing to extract required information for load settings generation.
  			# A light-weight parsed view does not get finalized.
  			print("Mapped (Python): init(): perform light-weight parsing")
  		else:
  			# Perform normal BinaryView initialization
  			print("Mapped (Python): init(): perform normal BinaryView initialization")
  
  		# Finish BinaryView initialization using the load settings, if they exist
  		try:
  			load_settings = self.get_load_settings(self.name)
  			if load_settings is None:
  				self.arch = Architecture['x86']
  				self.platform = Architecture['x86'].standalone_platform
  				self.add_auto_segment(0, len(self.parent_view), 0, len(self.parent_view), SegmentFlag.SegmentReadable)
  				return True
  			arch = load_settings.get_string("loader.architecture", self)
  			self.arch = Architecture[arch]
  			self.platform = Architecture[arch].standalone_platform
  			self.load_address = load_settings.get_integer("loader.imageBase", self)
  			entry_point = load_settings.get_integer("loader.entryPoint", self)
  			self.add_entry_point(self.load_address + entry_point)
  			self.add_auto_segment(self.load_address, len(self.parent_view), 0, len(self.parent_view), SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)
  			return True
  		except:
  			log_error(traceback.format_exc())
  			return False
  
  	def perform_get_entry_point(self):
  		return self.load_address
  
  	def perform_is_executable(self):
  		return True
  
  	def perform_is_relocatable(self):
  		return True
  
  	def perform_get_address_size(self):
  		return self.arch.address_size
  
  MappedView.register()
  
subject: Add example binary view plugin which demonstrates the load settings system.