Exemple #1
0
def importldsymbols(bv,filename):
    """Janky parser to import a GNU LD symbols file to Binary Ninja."""
    f=open(filename,"r");
    for l in f:
        words=l.strip().split();

        try:
            name=words[0];
            adrstr=words[2];
            adr=int(adrstr.strip(";"),16);

            #Function symbols are odd address in Flash.
            if adr&0xF8000001==0x08000001:
                bv.define_auto_symbol(Symbol(SymbolType.FunctionSymbol, adr&~1, name));
                bv.add_function(adr&~1);
                print("Imported function symbol %s at 0x%x"%(name,adr));

            #Data symbols are in SRAM or TCRAM with unpredictable alignment.
            elif adr&0xC0000000==0:
                bv.define_auto_symbol(Symbol(SymbolType.DataSymbol, adr, name));
                print("Imported data symbol %s at 0x%x"%(name,adr));
            else:
                print "Uncategorized adr=0x%08x."%adr;
        except:
            # Print warnings when our janky parser goes awry.
            if len(words)>0 and words[0]!="/*" and words[0]!="*/":
                print("#Warning in: %s\n"%words);
                log_error(traceback.format_exc())
	def _destroy_instance(self, ctxt):
		try:
			if self in self.__class__._registered_instances:
				self.__class__._registered_instances.remove(self)
			self.perform_destroy_instance()
		except:
			log.log_error(traceback.format_exc())
	def _get_current_view(self, ctxt):
		try:
			view = self.get_current_view()
		except:
			log.log_error(traceback.format_exc())
			view = ""
		return core.BNAllocString(view)
			def perform_request(self, url):
				try:
					proxy_setting = Settings().get_string('downloadClient.httpsProxy')
					if proxy_setting:
						proxies = {"https": proxy_setting}
					else:
						proxies = None

					r = requests.get(pyNativeStr(url), proxies=proxies)
					if not r.ok:
						core.BNSetErrorForDownloadInstance(self.handle, "Received error from server")
						return -1
					data = r.content
					if len(data) == 0:
						core.BNSetErrorForDownloadInstance(self.handle, "No data received from server!")
						return -1
					raw_bytes = (ctypes.c_ubyte * len(data)).from_buffer_copy(data)
					bytes_wrote = core.BNWriteDataForDownloadInstance(self.handle, raw_bytes, len(raw_bytes))
					if bytes_wrote != len(raw_bytes):
						core.BNSetErrorForDownloadInstance(self.handle, "Bytes written mismatch!")
						return -1
					continue_download = core.BNNotifyProgressForDownloadInstance(self.handle, bytes_wrote, bytes_wrote)
					if continue_download is False:
						core.BNSetErrorForDownloadInstance(self.handle, "Download aborted!")
						return -1
				except requests.RequestException as e:
					core.BNSetErrorForDownloadInstance(self.handle, e.__class__.__name__)
					return -1
				except:
					core.BNSetErrorForDownloadInstance(self.handle, "Unknown Exception!")
					log.log_error(traceback.format_exc())
					return -1

				return 0
	def _free_parameters(self, params, count):
		try:
			buf = ctypes.cast(params, ctypes.c_void_p)
			if buf.value not in self._pending_param_lists:
				raise ValueError("freeing parameter list that wasn't allocated")
			del self._pending_param_lists[buf.value]
		except:
			log.log_error(traceback.format_exc())
	def _show_html_report(self, ctxt, view, title, contents, plaintext):
		try:
			if view:
				view = binaryview.BinaryView(handle = core.BNNewViewReference(view))
			else:
				view = None
			self.show_html_report(view, title, contents, plaintext)
		except:
			log.log_error(traceback.format_exc())
	def _show_graph_report(self, ctxt, view, title, graph):
		try:
			if view:
				view = binaryview.BinaryView(handle = core.BNNewViewReference(view))
			else:
				view = None
			self.show_graph_report(view, title, flowgraph.CoreFlowGraph(core.BNNewFlowGraphReference(graph)))
		except:
			log.log_error(traceback.format_exc())
	def _get_int_input(self, ctxt, result, prompt, title):
		try:
			value = self.get_int_input(prompt, title)
			if value is None:
				return False
			result[0] = value
			return True
		except:
			log.log_error(traceback.format_exc())
	def _create_instance(self, ctxt):
		try:
			result = self.__class__.instance_class(self)
			if result is None:
				return None
			return ctypes.cast(core.BNNewDownloadInstanceReference(result.handle), ctypes.c_void_p).value
		except:
			log.log_error(traceback.format_exc())
			return None
	def _get_directory_name_input(self, ctxt, result, prompt, default_name):
		try:
			value = self.get_directory_name_input(prompt, default_name)
			if value is None:
				return False
			result[0] = core.BNAllocString(str(value))
			return True
		except:
			log.log_error(traceback.format_exc())
	def _update(self, ctxt):
		try:
			graph = self.update()
			if graph is None:
				return None
			return core.BNNewFlowGraphReference(graph.handle)
		except:
			log.log_error(traceback.format_exc())
			return None
	def _recognize_medium_level_il(self, ctxt, data, func, il):
		try:
			file_metadata = filemetadata.FileMetadata(handle = core.BNGetFileForView(data))
			view = binaryview.BinaryView(file_metadata = file_metadata, handle = core.BNNewViewReference(data))
			func = function.Function(view, handle = core.BNNewFunctionReference(func))
			il = mediumlevelil.MediumLevelILFunction(func.arch, handle = core.BNNewMediumLevelILFunctionReference(il))
			return self.recognize_medium_level_il(view, func, il)
		except:
			log.log_error(traceback.format_exc())
			return False
	def _get_choice_input(self, ctxt, result, prompt, title, choice_buf, count):
		try:
			choices = []
			for i in range(0, count):
				choices.append(choice_buf[i])
			value = self.get_choice_input(prompt, title, choices)
			if value is None:
				return False
			result[0] = value
			return True
		except:
			log.log_error(traceback.format_exc())
	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
	def _get_address_input(self, ctxt, result, prompt, title, view, current_address):
		try:
			if view:
				view = binaryview.BinaryView(handle = core.BNNewViewReference(view))
			else:
				view = None
			value = self.get_address_input(prompt, title, view, current_address)
			if value is None:
				return False
			result[0] = value
			return True
		except:
			log.log_error(traceback.format_exc())
Exemple #16
0
 def init_arm7(self):
     try:
         self.init_common()
         self.arm7_offset = struct.unpack("<L", self.hdr[0x30:0x34])[0]
         self.arm_entry_addr = struct.unpack("<L", self.hdr[0x34:0x38])[0]
         self.arm7_load_addr = struct.unpack("<L", self.hdr[0x38:0x3C])[0]
         self.arm7_size = struct.unpack("<L", self.hdr[0x3C:0x40])[0]
         self.add_auto_segment(self.arm7_load_addr, self.arm7_size, self.arm7_offset, self.arm7_size,
             SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)
         self.add_entry_point(Architecture['armv7'].standalone_platform, self.arm_entry_addr)
         return True
     except:
         log_error(traceback.format_exc())
         return False
	def _get_parameters(self, ctxt, count):
		try:
			count[0] = len(self.parameters)
			param_buf = (core.BNTransformParameterInfo * len(self.parameters))()
			for i in range(0, len(self.parameters)):
				param_buf[i].name = self.parameters[i].name
				param_buf[i].longName = self.parameters[i].long_name
				param_buf[i].fixedLength = self.parameters[i].fixed_length
			result = ctypes.cast(param_buf, ctypes.c_void_p)
			self._pending_param_lists[result.value] = (result, param_buf)
			return result.value
		except:
			log.log_error(traceback.format_exc())
			count[0] = 0
			return None
	def _encode(self, ctxt, input_buf, output_buf, params, count):
		try:
			input_obj = databuffer.DataBuffer(handle = core.BNDuplicateDataBuffer(input_buf))
			param_map = {}
			for i in range(0, count):
				data = databuffer.DataBuffer(handle = core.BNDuplicateDataBuffer(params[i].value))
				param_map[params[i].name] = str(data)
			result = self.perform_encode(str(input_obj), param_map)
			if result is None:
				return False
			result = str(result)
			core.BNSetDataBufferContents(output_buf, result, len(result))
			return True
		except:
			log.log_error(traceback.format_exc())
			return False
	def _get_lines_for_data(self, ctxt, view, addr, type, prefix, prefixCount, width, count, typeCtx, 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))

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

			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, HighlightStandardColor) and not isinstance(color, highlight.HighlightColor):
					raise ValueError("Specified color is not one of HighlightStandardColor, highlight.HighlightColor")
				if isinstance(color, 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 = InstructionTextToken.get_instruction_lines(line.tokens)

			return ctypes.cast(line_buf, ctypes.c_void_p).value
		except:
			log_error(traceback.format_exc())
			return None
Exemple #20
0
    def init_thumb2(self, adr=0x08000000):
        try:
            self.init_common()
            self.thumb2_offset = 0
            self.arm_entry_addr = struct.unpack("<L", self.hdr[0x4:0x8])[0]
            self.thumb2_load_addr = adr #struct.unpack("<L", self.hdr[0x38:0x3C])[0]
            self.thumb2_size = len(self.hdr);

            # Add segment for SRAM, not backed by file contents
	    self.add_auto_segment(0x20000000, 0x20000, #128K at address 0x20000000.
                                  0, 0,
                                  SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable | SegmentFlag.SegmentExecutable)
            # Add segment for TCRAM, not backed by file contents
	    self.add_auto_segment(0x10000000, 0x10000, #64K at address 0x10000000.
                                  0, 0,
                                  SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable)
            
            #Add a segment for this Flash application.
            self.add_auto_segment(self.thumb2_load_addr, self.thumb2_size,
                                  self.thumb2_offset, self.thumb2_size,
            SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)

            #Define the RESET vector entry point.
            self.define_auto_symbol(Symbol(SymbolType.FunctionSymbol,
                                           self.arm_entry_addr&~1, "RESET"))
            self.add_entry_point(self.arm_entry_addr&~1)

            #Define other entries of the Interrupt Vector Table (IVT)
            for ivtindex in range(8,0x184+4,4):
                ivector=struct.unpack("<L", self.hdr[ivtindex:ivtindex+4])[0]
                if ivector>0:
                    #Create the symbol, then the entry point.
                    self.define_auto_symbol(Symbol(SymbolType.FunctionSymbol,
                                                   ivector&~1, "vec_%x"%ivector))
                    self.add_function(ivector&~1);
            return True
        except:
            log_error(traceback.format_exc())
            return False
def write_breakpoint(view, start, length):
	"""Sample function to show registering a plugin menu item for a range of bytes. Also possible:
		register
		register_for_address
		register_for_function
	"""
	bkpt_str = {
		"x86": "int3",
		"x86_64": "int3",
		"armv7": "bkpt",
		"aarch64": "brk #0",
		"mips32": "break"}

	if view.arch.name not in bkpt_str:
		log_error("Architecture %s not supported" % view.arch.name)
		return

	bkpt, err = view.arch.assemble(bkpt_str[view.arch.name])
	if bkpt is None:
		log_error(err)
		return
	view.write(start, bkpt * length // len(bkpt))
	def _get_form_input(self, ctxt, fields, count, title):
		try:
			field_objs = []
			for i in range(0, count):
				if fields[i].type == FormInputFieldType.LabelFormField:
					field_objs.append(LabelField(fields[i].prompt))
				elif fields[i].type == FormInputFieldType.SeparatorFormField:
					field_objs.append(SeparatorField())
				elif fields[i].type == FormInputFieldType.TextLineFormField:
					field_objs.append(TextLineField(fields[i].prompt))
				elif fields[i].type == FormInputFieldType.MultilineTextFormField:
					field_objs.append(MultilineTextField(fields[i].prompt))
				elif fields[i].type == FormInputFieldType.IntegerFormField:
					field_objs.append(IntegerField(fields[i].prompt))
				elif fields[i].type == FormInputFieldType.AddressFormField:
					view = None
					if fields[i].view:
						view = binaryview.BinaryView(handle = core.BNNewViewReference(fields[i].view))
					field_objs.append(AddressField(fields[i].prompt, view, fields[i].currentAddress))
				elif fields[i].type == FormInputFieldType.ChoiceFormField:
					choices = []
					for j in range(0, fields[i].count):
						choices.append(fields[i].choices[j])
					field_objs.append(ChoiceField(fields[i].prompt, choices))
				elif fields[i].type == FormInputFieldType.OpenFileNameFormField:
					field_objs.append(OpenFileNameField(fields[i].prompt, fields[i].ext))
				elif fields[i].type == FormInputFieldType.SaveFileNameFormField:
					field_objs.append(SaveFileNameField(fields[i].prompt, fields[i].ext, fields[i].defaultName))
				elif fields[i].type == FormInputFieldType.DirectoryNameFormField:
					field_objs.append(DirectoryNameField(fields[i].prompt, fields[i].defaultName))
				else:
					field_objs.append(LabelField(fields[i].prompt))
			if not self.get_form_input(field_objs, title):
				return False
			for i in range(0, count):
				field_objs[i]._fill_core_result(fields[i])
			return True
		except:
			log.log_error(traceback.format_exc())
		def perform_request(self, url):
			try:
				proxy_setting = Settings().get_string('downloadClient.httpsProxy')
				if proxy_setting:
					opener = build_opener(ProxyHandler({'https': proxy_setting}))
					install_opener(opener)

				r = urlopen(pyNativeStr(url))
				total_size = int(r.headers.get('content-length', 0))
				bytes_sent = 0
				while True:
					data = r.read(4096)
					if not data:
						break
					raw_bytes = (ctypes.c_ubyte * len(data)).from_buffer_copy(data)
					bytes_wrote = core.BNWriteDataForDownloadInstance(self.handle, raw_bytes, len(raw_bytes))
					if bytes_wrote != len(raw_bytes):
						core.BNSetErrorForDownloadInstance(self.handle, "Bytes written mismatch!")
						return -1
					bytes_sent = bytes_sent + bytes_wrote
					continue_download = core.BNNotifyProgressForDownloadInstance(self.handle, bytes_sent, total_size)
					if continue_download is False:
						core.BNSetErrorForDownloadInstance(self.handle, "Download aborted!")
						return -1

				if not bytes_sent:
					core.BNSetErrorForDownloadInstance(self.handle, "Received no data!")
					return -1

			except URLError as e:
				core.BNSetErrorForDownloadInstance(self.handle, e.__class__.__name__)
				return -1
			except:
				core.BNSetErrorForDownloadInstance(self.handle, "Unknown Exception!")
				log.log_error(traceback.format_exc())
				return -1

			return 0
 def _set_current_selection(self, ctxt, begin, end):
     try:
         self.perform_set_current_selection(begin, end)
     except:
         log.log_error(traceback.format_exc())
Exemple #25
0
    def run(self) -> None:
        try:
            df = DexFile(self.bv.raw.read(0, self.bv.raw.end))
        except Exception:
            log_error("caught error, writing json anyway")
            raise
        finally:
            # TODO add gui button to do this
            # TODO make this depend on filename
            # FIXME this is a file write -> code exec vuln with the right
            # timing
            background_task = JsonWriter(df, "/tmp/out.json")
            background_task.start()

        data_size = df._parse_uint(self.bv.hdr[104:108])
        data_off = df._parse_uint(self.bv.hdr[108:112])
        self.bv.add_auto_segment(
            data_off,
            data_size,
            data_off,
            data_size,
            SegmentFlag.SegmentReadable
            | SegmentFlag.SegmentContainsData
            | SegmentFlag.SegmentContainsCode,
        )

        # Process code blocks
        # For each code block, add
        # - binja section
        # - binja function
        # - binja symbol
        # - comments for tries and catches
        self.progress = self.progress_title + ": processing code blocks"
        defined_functions: Set[str] = set()
        for class_def in df.class_defs:
            if not class_def.class_data:
                continue
            for method in (class_def.class_data.direct_methods +
                           class_def.class_data.virtual_methods):
                if method.code:
                    off = method.code._insns_off
                    # Add section
                    self.bv.add_auto_section(
                        f"code_{hex(off)}",
                        method.code._insns_off,
                        2 * method.code.insns_size,
                        SectionSemantics.ReadOnlyCodeSectionSemantics,
                    )
                    # Add function and symbol
                    function_name = f"{method.access_flags}{method.method.class_}->{method.method.name}("
                    for param in method.method.proto.parameters:
                        function_name += param
                    function_name += ")" + method.method.proto.return_type
                    if function_name in defined_functions:
                        log_error(f"Duplicate function name {function_name}")
                    defined_functions.add(function_name)
                    self.bv.define_auto_symbol(
                        Symbol(SymbolType.FunctionSymbol, off, function_name))
                    self.bv.add_function(off)

                    # Add tries and catches as comments
                    if method.code.tries_size:
                        for try_item in method.code.tries:
                            self.bv.set_comment_at(
                                off + try_item.start_addr * 2,
                                f":try_start_{try_item.start_addr:x}",
                            )
                            self.bv.set_comment_at(
                                off + try_item.start_addr * 2 +
                                try_item.insn_count * 2,
                                f":try_end_{try_item.start_addr+try_item.insn_count:x}",
                            )
                            self.bv.set_comment_at(
                                off + try_item.start_addr * 2 +
                                try_item.insn_count * 2,
                                f"{try_item.handler}",
                            )
	def _show_report_collection(self, ctxt, title, reports):
		try:
			self.show_report_collection(title, ReportCollection(core.BNNewReportCollectionReference(reports)))
		except:
			log.log_error(traceback.format_exc())
Exemple #27
0
 def _prepare_for_layout(self, ctxt):
     try:
         self.prepare_for_layout()
     except:
         log.log_error(traceback.format_exc())
Exemple #28
0
 def _external_ref_released(self, ctxt):
     try:
         self.__class__._registered_instances.remove(self)
     except:
         log.log_error(traceback.format_exc())
Exemple #29
0
 def _external_ref_taken(self, ctxt):
     try:
         self.__class__._registered_instances.append(self)
     except:
         log.log_error(traceback.format_exc())
 def _execute_script_input(self, ctxt, text):
     try:
         return self.perform_execute_script_input(text)
     except:
         log.log_error(traceback.format_exc())
         return ScriptingProviderExecuteResult.InvalidScriptInput
Exemple #31
0
 def _get_int_return_reg(self, ctxt):
     try:
         return self.arch.regs[self.__class__.int_return_reg].index
     except:
         log.log_error(traceback.format_exc())
         return False
	def _populate_nodes(self, ctxt):
		try:
			self.populate_nodes()
		except:
			log.log_error(traceback.format_exc())
Exemple #33
0
 def log(self, msg, error=False):
     msg = f'[Switch-Binja-Loader] {msg}'
     if not error:
         log_info(msg)
     else:
         log_error(msg)
	def _complete(self, ctxt):
		try:
			if self.on_complete is not None:
				self.on_complete()
		except:
			log.log_error(traceback.format_exc())
 def _input_ready_state_changed(self, ctxt, state):
     try:
         self.notify_input_ready_state_changed(state)
     except:
         log.log_error(traceback.format_exc())
 def _error(self, ctxt, text):
     try:
         self.notify_error(text)
     except:
         log.log_error(traceback.format_exc())
Exemple #37
0
    def init(self):
        try:
            hdr = self.parent_view.read(0, 128)
            self.version = struct.unpack("B", hdr[5])[0]
            self.song_count = struct.unpack("B", hdr[6])[0]
            self.starting_song = struct.unpack("B", hdr[7])[0]
            self.load_address = struct.unpack("<H", hdr[8:10])[0]
            self.init_address = struct.unpack("<H", hdr[10:12])[0]
            self.play_address = struct.unpack("<H", hdr[12:14])[0]
            self.song_name = hdr[15].split('\0')[0]
            self.artist_name = hdr[46].split('\0')[0]
            self.copyright_name = hdr[78].split('\0')[0]
            self.play_speed_ntsc = struct.unpack("<H", hdr[110:112])[0]
            self.bank_switching = hdr[112:120]
            self.play_speed_pal = struct.unpack("<H", hdr[120:122])[0]
            self.pal_ntsc_bits = struct.unpack("B", hdr[122])[0]
            self.pal = True if (self.pal_ntsc_bits & 1) == 1 else False
            self.ntsc = not self.pal
            if self.pal_ntsc_bits & 2 == 2:
                self.pal = True
                self.ntsc = True
            self.extra_sound_bits = struct.unpack("B", hdr[123])[0]

            if self.bank_switching == "\0" * 8:
                # no bank switching
                self.load_address & 0xFFF
                self.rom_offset = 128

            else:
                # bank switching not implemented
                log_info("Bank switching not implemented in this loader.")

            # Add mapping for RAM and hardware registers, not backed by file contents
            self.add_auto_segment(
                0, 0x8000, 0, 0, SegmentFlag.SegmentReadable
                | SegmentFlag.SegmentWritable | SegmentFlag.SegmentExecutable)

            # Add ROM mappings
            self.add_auto_segment(
                0x8000, 0x4000, self.rom_offset, 0x4000,
                SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)

            self.define_auto_symbol(
                Symbol(SymbolType.FunctionSymbol, self.play_address, "_play"))
            self.define_auto_symbol(
                Symbol(SymbolType.FunctionSymbol, self.init_address, "_init"))
            self.add_entry_point(self.init_address)
            self.add_function(self.play_address)

            # Hardware registers
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x2000, "PPUCTRL"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x2001, "PPUMASK"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x2002, "PPUSTATUS"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x2003, "OAMADDR"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x2004, "OAMDATA"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x2005, "PPUSCROLL"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x2006, "PPUADDR"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x2007, "PPUDATA"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4000, "SQ1_VOL"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4001, "SQ1_SWEEP"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4002, "SQ1_LO"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4003, "SQ1_HI"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4004, "SQ2_VOL"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4005, "SQ2_SWEEP"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4006, "SQ2_LO"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4007, "SQ2_HI"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4008, "TRI_LINEAR"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x400a, "TRI_LO"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x400b, "TRI_HI"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x400c, "NOISE_VOL"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x400e, "NOISE_LO"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x400f, "NOISE_HI"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4010, "DMC_FREQ"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4011, "DMC_RAW"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4012, "DMC_START"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4013, "DMC_LEN"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4014, "OAMDMA"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4015, "SND_CHN"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4016, "JOY1"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4017, "JOY2"))

            return True
        except:
            log_error(traceback.format_exc())
            return False
            def perform_custom_request(self, method, url, headers, data):
                result = None
                try:
                    proxy_setting = settings.Settings().get_string(
                        'network.httpsProxy')
                    if proxy_setting:
                        opener = build_opener(
                            ProxyHandler({'https': proxy_setting}))
                        install_opener(opener)

                    if b"Content-Length" in headers:
                        del headers[b"Content-Length"]

                    req = PythonDownloadInstance.CustomRequest(
                        pyNativeStr(url),
                        data=data,
                        headers=headers,
                        method=pyNativeStr(method))
                    result = urlopen(req)
                except HTTPError as he:
                    result = he
                except URLError as e:
                    core.BNSetErrorForDownloadInstance(self.handle,
                                                       e.__class__.__name__)
                    log.log_error(str(e))
                    return None
                except:
                    core.BNSetErrorForDownloadInstance(self.handle,
                                                       "Unknown Exception!")
                    log.log_error(traceback.format_exc())
                    return None

                total_size = int(result.headers.get('content-length', 0))
                bytes_sent = 0
                while True:
                    data = result.read(4096)
                    if not data:
                        break
                    raw_bytes = (ctypes.c_ubyte *
                                 len(data)).from_buffer_copy(data)
                    bytes_wrote = core.BNWriteDataForDownloadInstance(
                        self.handle, raw_bytes, len(raw_bytes))
                    if bytes_wrote != len(raw_bytes):
                        core.BNSetErrorForDownloadInstance(
                            self.handle, "Bytes written mismatch!")
                        return None
                    bytes_sent = bytes_sent + bytes_wrote
                    continue_download = core.BNNotifyProgressForDownloadInstance(
                        self.handle, bytes_sent, total_size)
                    if continue_download is False:
                        core.BNSetErrorForDownloadInstance(
                            self.handle, "Download aborted!")
                        return None

                if not bytes_sent:
                    core.BNSetErrorForDownloadInstance(self.handle,
                                                       "Received no data!")
                    return None

                return DownloadInstance.Response(result.getcode(),
                                                 result.headers, None)
Exemple #39
0
    def init(self):
        try:
            hdr = self.parent_view.read(0, 0x800)
            # Remember, Pythons indexer is retarded: from:(to+1)
            self.init_pc = struct.unpack("<L", hdr[0x10:0x14])[0]
            self.text_start = struct.unpack("<L", hdr[0x18:0x1c])[0]
            self.text_size = struct.unpack("<L", hdr[0x1c:0x20])[0]
            self.init_sp = struct.unpack("<L", hdr[0x30:0x34])[0]
            self.info = hdr[0x4c:self.HDR_SIZE]
            # log_debug("/info: %r" % self.info)
            log_debug("/info size: %s" % format(len(self.info), '#010x'))

            log_info("PC:   %s" % format(self.init_pc, '#010x'))
            log_info("TEXT: %s" % format(self.text_start, '#010x'))
            log_info("SIZE: %s" % format(self.text_size, '#010x'))
            log_info("SP:   %s" % format(self.init_sp, '#010x'))
            log_info("info: %s" % self.info)

            # PSX came with 2M, but the BIOS supports 8
            # for dev machines. Supposed be multiple if
            # 2048, but that is not required for the
            # method used to sideload homebrew. (FIXME: Is
            # it enforced by the BIOS? Can't remember...)

            # FIXME: this is just a sanity check. Make it
            # check if text_start + text_size would run
            # outside address space.
            if (self.text_size > 0x800000):
                log_warn("size > 8M: %d", self.text_size)
            if (self.text_size % 2048 != 0):
                log_warn("size not divisable by 2k")

            text = self.parent_view.read(self.HDR_SIZE, self.text_size)
            log_info("Actual size of aquired TEXT: %s" %
                     format(len(text), '#010x'))
            if (len(text) != self.text_size):
                log_error(
                    "Size of aquired data is not same as header-prescribed TEXT size. Truncated file?"
                )

# add_auto_segment(start, length,
#                  data_offset, data_length, flags)

            r__ = SegmentFlag.SegmentReadable
            rw_ = (SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable)
            rwx = (SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable
                   | SegmentFlag.SegmentExecutable)
            r_x = (SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)
            r_xc = (SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable
                    | SegmentFlag.SegmentContainsCode)

            # Scratchpad RAM 1k
            self.add_auto_segment(0x9F800000, 1024, 0, 0, rwx)
            self.add_auto_section("Scratchpad", 0x9F800000, 1024)

            # FIXME: I seem to remember most IO access as
            # in the KSEG1 region. This wont cover that.

            # IO Ports 8k
            self.add_auto_segment(0x9F801000, 8 * 1024, 0, 0, rwx)
            self.add_auto_section("IO Ports", 0x9F801000, 8 * 1024)
            # Expansion 2 (IO Ports) 8k
            self.add_auto_segment(0x9F802000, 8 * 1024, 0, 0, rwx)
            self.add_auto_section("Expansion region 2 (IO Ports)", 0x9F802000,
                                  8 * 1024)
            # Expansion 3 2M
            self.add_auto_segment(0x9FA00000, 0x200000, 0, 0, rwx)
            self.add_auto_section("Expansion region 3", 0x9FA00000, 0x200000)
            # BIOS ROM 512k
            self.add_auto_segment(0x9FC00000, 512 * 1024, 0, 0, r_x)
            self.add_auto_section("BIOS", 0x9FC00000, 512 * 1024)

            # RAM (cached address space) 2M
            # Dividing this into pre-EXE and post-EXE
            # space since it's the only way I've found to
            # not have the exe zeroed out

            # FIXME: The areas definitions overlap by one
            # byte: Getting one missing byte in the
            # viewer if I don't. Is BN using the wierd
            # python semantics of ranges?
            ramsize = 0x200000
            prestart = 0x80000000
            presize = (self.text_start - 0) - 0x80000000
            if (presize > 0):
                log_info("pre-RAM: %s - %s, size: %s" %
                         (format(prestart,
                                 '#010x'), format(prestart + presize, '#010x'),
                          format(presize, '#010x')))
                self.add_auto_segment(prestart, presize, 0, 0, rwx)
                self.add_auto_section("RAM (pre EXE)", 0x80000000, presize)

# Area for the actual executable. Will overlap
# with RAM if it's a correct PSX-EXE
            self.add_auto_segment(self.text_start, self.text_size,
                                  self.HDR_SIZE, self.text_size, r_xc)
            self.add_auto_section("PS-X EXE", self.text_start, self.text_size)
            # semantics = SectionSemantics.ReadOnlyCodeSectionSemantics)

            # RAM (cached address space) 2M
            poststart = self.text_start + self.text_size
            postsize = (prestart + ramsize) - (self.text_start +
                                               self.text_size)
            if (postsize > 0):
                log_info("post-RAM: %s - %s, size: %s" %
                         (format(poststart, '#010x'),
                          format(poststart + postsize,
                                 '#010x'), format(postsize, '#010x')))
                self.add_auto_segment(poststart, postsize, 0, 0, rwx)
                self.add_auto_section("RAM (post EXE)", poststart, postsize)

            self.define_auto_symbol(
                Symbol(SymbolType.FunctionSymbol, self.init_pc, "_start"))
            self.define_auto_symbol(
                Symbol(SymbolType.FunctionSymbol, self.init_sp,
                       "_stack"))  # default: 0x801ffff0
            self.add_entry_point(self.init_pc)

            # The iomapped control of devices in a PSX is
            # high up that every time those values are
            # used you can be pretty sure we are talking
            # about the control registers and not some
            # random loop counter.
            #
            # FIXME: With the exception of a0, b0 and
            # c0-calls, those should be lifted in some
            # other manner but are useful enough that they
            # are hardcoded right now.
            for addr, symbol in psx_memmap_constants.iteritems():
                self.define_auto_symbol(
                    Symbol(SymbolType.DataSymbol, addr, symbol))

# Uncomment this and remove the hook if you want to run
# function BIOS calls manually.

#PluginCommand.register('Find PSX BIOS calls',
#                       'Find PSX BIOS calls and rename them.',
#                       find_bios_calls_run)

# Run PSX BIOS function finder after analysis
            self.add_analysis_completion_event(
                lambda _: find_bios_calls_run(self))

            return True
        except:
            log_error(traceback.format_exc())
            return False
 def _perform_request(self, ctxt, url):
     try:
         return self.perform_request(url)
     except:
         log.log_error(traceback.format_exc())
         return -1
Exemple #41
0
 def _stack_adjusted_on_return(self, ctxt):
     try:
         return self.__class__.stack_adjusted_on_return
     except:
         log.log_error(traceback.format_exc())
         return False
 def _destroy_instance(self, ctxt):
     try:
         self.perform_destroy_instance()
     except:
         log.log_error(traceback.format_exc())
Exemple #43
0
 def _stack_reserved_for_arg_regs(self, ctxt):
     try:
         return self.__class__.stack_reserved_for_arg_regs
     except:
         log.log_error(traceback.format_exc())
         return False
	def _show_message_box(self, ctxt, title, text, buttons, icon):
		try:
			return self.show_message_box(title, text, buttons, icon)
		except:
			log.log_error(traceback.format_exc())
Exemple #45
0
 def _complete_layout(self, ctxt):
     try:
         self.complete_layout()
     except:
         log.log_error(traceback.format_exc())
Exemple #46
0
 def _arg_regs_share_index(self, ctxt):
     try:
         return self.__class__.arg_regs_share_index
     except:
         log.log_error(traceback.format_exc())
         return False
Exemple #47
0
 def _populate_nodes(self, ctxt):
     try:
         self.populate_nodes()
     except:
         log.log_error(traceback.format_exc())
Exemple #48
0
    def get_instruction_text(self, data, addr):
        tokens = []

        if self.vtil == None:
            try:
                self.vtil = VTILParser.from_file(get_filename())
            except Exception as ex:
                log_error(str(ex))
                tokens.append(
                    InstructionTextToken(InstructionTextTokenType.TextToken,
                                         "ERROR"))
                return tokens, 1

        next_vip, sp_index, sp_reset, sp_offset, code = find_instruction(
            addr, self.vtil)
        if code == None:
            tokens.append(
                InstructionTextToken(InstructionTextTokenType.TextToken,
                                     "ERROR"))
            return tokens, 1

        if sp_index > 0:
            tokens.append(
                InstructionTextToken(InstructionTextTokenType.TextToken, "["))
            tokens.append(
                InstructionTextToken(InstructionTextTokenType.IntegerToken,
                                     str(sp_index),
                                     value=sp_index,
                                     size=64))
            tokens.append(
                InstructionTextToken(InstructionTextTokenType.TextToken, "] "))
        else:
            tokens.append(
                InstructionTextToken(InstructionTextTokenType.TextToken,
                                     "    "))

        prefix = "-"
        if sp_offset >= 0: prefix = "+"
        sp_offset = abs(sp_offset)

        if sp_reset > 0:
            txt = f">{prefix}{hex(sp_offset)}"
            txt = f"{txt:<6}"
            tokens.append(
                InstructionTextToken(InstructionTextTokenType.TextToken, txt))
        else:
            txt = f"{prefix}{hex(sp_offset)}"
            txt = f"{txt:<6}"
            tokens.append(
                InstructionTextToken(InstructionTextTokenType.TextToken, txt))
        tokens.append(
            InstructionTextToken(InstructionTextTokenType.TextToken, " "))

        if " " in code:
            instr, operands = code.split(" ", 1)

            if " " in operands:
                operands = operands.split(" ")
            else:
                operands = [operands]

            if instr in self.instructions.keys():
                token_set = self.instructions[instr]["tokens"]

                for index in self.instructions[instr]["operands"]:
                    operand = operands.pop(0)

                    if "0x" in operand:
                        if instr == "js":
                            token_set[index] = InstructionTextToken(
                                InstructionTextTokenType.GotoLabelToken,
                                f"vip_{operand[2:]}")
                        elif instr == "jmp":
                            token_set[index] = InstructionTextToken(
                                InstructionTextTokenType.GotoLabelToken,
                                f"vip_{hex(next_vip[0])[2:]}")
                        else:
                            token_set[index] = InstructionTextToken(
                                InstructionTextTokenType.IntegerToken,
                                operand,
                                value=int(operand, 16),
                                size=64)
                    else:
                        token_set[index] = InstructionTextToken(
                            InstructionTextTokenType.RegisterToken, operand)

                tokens.extend(token_set)
            else:
                # fallback
                tokens.append(
                    InstructionTextToken(
                        InstructionTextTokenType.InstructionToken, instr))
                tokens.append(
                    InstructionTextToken(
                        InstructionTextTokenType.OperandSeparatorToken, " "))

                for operand in operands:
                    if "0x" in operand:
                        if instr == "jmp":
                            tokens.append(
                                InstructionTextToken(
                                    InstructionTextTokenType.GotoLabelToken,
                                    f"vip_{hex(next_vip[0])[2:]}"))
                        else:
                            tokens.append(
                                InstructionTextToken(
                                    InstructionTextTokenType.IntegerToken,
                                    operand,
                                    value=int(operand, 16),
                                    size=64))
                    else:
                        tokens.append(
                            InstructionTextToken(
                                InstructionTextTokenType.RegisterToken,
                                operand))
                    tokens.append(
                        InstructionTextToken(
                            InstructionTextTokenType.OperandSeparatorToken,
                            ", "))

                tokens.pop()
        else:
            tokens.append(
                InstructionTextToken(InstructionTextTokenType.InstructionToken,
                                     code))

        return tokens, 1
Exemple #49
0
    {
        "title" : "Indentation Syntax highlighting for snippets",
        "type" : "string",
        "default" : "    ",
        "description" : "String to use for indentation in snippets (tip: to use a tab, copy/paste a tab from another text field and paste here)",
        "ignore" : ["SettingsProjectScope", "SettingsResourceScope"]
    }
    """)

snippetPath = os.path.realpath(
    os.path.join(user_plugin_path(), "..", "snippets"))
try:
    if not os.path.exists(snippetPath):
        os.mkdir(snippetPath)
except IOError:
    log_error("Unable to create %s" % snippetPath)


def includeWalk(dir, includeExt):
    filePaths = []
    for (root, dirs, files) in os.walk(dir):
        for f in files:
            if os.path.splitext(f)[1] in includeExt:
                filePaths.append(os.path.join(root, f))
    return filePaths


def loadSnippetFromFile(snippetPath):
    try:
        with codecs.open(snippetPath, 'r', 'utf-8') as snippetFile:
            snippetText = snippetFile.readlines()
 def _set_current_address(self, ctxt, addr):
     try:
         self.perform_set_current_address(addr)
     except:
         log.log_error(traceback.format_exc())
Exemple #51
0
	def _show_report_collection(self, ctxt, title, reports):
		try:
			self.show_report_collection(title, ReportCollection(core.BNNewReportCollectionReference(reports)))
		except:
			log.log_error(traceback.format_exc())
Exemple #52
0
	def _show_message_box(self, ctxt, title, text, buttons, icon):
		try:
			return self.show_message_box(title, text, buttons, icon)
		except:
			log.log_error(traceback.format_exc())
Exemple #53
0
    def init(self):
        try:
            hdr = self.parent_view.read(0, 16)
            self.rom_banks = struct.unpack("B", hdr[4:5])[0]
            self.vrom_banks = struct.unpack("B", hdr[5:6])[0]
            self.rom_flags = struct.unpack("B", hdr[6:7])[0]
            self.mapper_index = struct.unpack(
                "B", hdr[7:8])[0] | (self.rom_flags >> 4)
            self.ram_banks = struct.unpack("B", hdr[8:9])[0]
            self.rom_offset = 16
            if self.rom_flags & 4:
                self.rom_offset += 512
            self.rom_length = self.rom_banks * 0x4000

            # Add mapping for RAM and hardware registers, not backed by file contents
            self.add_auto_segment(
                0, 0x8000, 0, 0, SegmentFlag.SegmentReadable
                | SegmentFlag.SegmentWritable | SegmentFlag.SegmentExecutable)

            # Add ROM mappings
            self.add_auto_segment(
                0x8000, 0x4000,
                self.rom_offset + (self.__class__.bank * 0x4000), 0x4000,
                SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)
            self.add_auto_segment(
                0xc000, 0x4000, self.rom_offset + self.rom_length - 0x4000,
                0x4000,
                SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)

            nmi = struct.unpack("<H", self.read(0xfffa, 2))[0]
            start = struct.unpack("<H", self.read(0xfffc, 2))[0]
            irq = struct.unpack("<H", self.read(0xfffe, 2))[0]
            self.define_auto_symbol(
                Symbol(SymbolType.FunctionSymbol, nmi, "_nmi"))
            self.define_auto_symbol(
                Symbol(SymbolType.FunctionSymbol, start, "_start"))
            self.define_auto_symbol(
                Symbol(SymbolType.FunctionSymbol, irq, "_irq"))
            self.add_function(nmi)
            self.add_function(irq)
            self.add_entry_point(start)

            # Hardware registers
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x2000, "PPUCTRL"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x2001, "PPUMASK"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x2002, "PPUSTATUS"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x2003, "OAMADDR"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x2004, "OAMDATA"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x2005, "PPUSCROLL"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x2006, "PPUADDR"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x2007, "PPUDATA"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4000, "SQ1_VOL"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4001, "SQ1_SWEEP"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4002, "SQ1_LO"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4003, "SQ1_HI"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4004, "SQ2_VOL"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4005, "SQ2_SWEEP"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4006, "SQ2_LO"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4007, "SQ2_HI"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4008, "TRI_LINEAR"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x400a, "TRI_LO"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x400b, "TRI_HI"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x400c, "NOISE_VOL"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x400e, "NOISE_LO"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x400f, "NOISE_HI"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4010, "DMC_FREQ"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4011, "DMC_RAW"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4012, "DMC_START"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4013, "DMC_LEN"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4014, "OAMDMA"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4015, "SND_CHN"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4016, "JOY1"))
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, 0x4017, "JOY2"))

            sym_files = [
                self.file.filename + ".%x.nl" % self.__class__.bank,
                self.file.filename + ".ram.nl",
                self.file.filename + ".%x.nl" % (self.rom_banks - 1)
            ]
            for f in sym_files:
                if os.path.exists(f):
                    with open(f, "r") as f:
                        lines = f.readlines()
                    for line in lines:
                        line = line.strip()
                        sym = line.split('#')
                        if len(sym) < 3:
                            break
                        addr = int(sym[0][1:], 16)
                        name = sym[1]
                        self.define_auto_symbol(
                            Symbol(SymbolType.FunctionSymbol, addr, name))
                        if addr >= 0x8000:
                            self.add_function(addr)

            return True
        except:
            log_error(traceback.format_exc())
            return False
Exemple #54
0
def decompile(view, function):
    try:
        retdec = RetDec(view, function)
        retdec.decompile_function()
    except Exception as e:
        log_error('failed to decompile function\n{}'.format(e.message))
	def _prepare_for_layout(self, ctxt):
		try:
			self.prepare_for_layout()
		except:
			log.log_error(traceback.format_exc())
Exemple #56
0
 def _get_current_offset(self, ctxt):
     try:
         return self.get_current_offset()
     except:
         log.log_error(traceback.format_exc())
         return 0
	def _complete_layout(self, ctxt):
		try:
			self.complete_layout()
		except:
			log.log_error(traceback.format_exc())
Exemple #58
0
 def _navigate(self, ctxt, view, offset):
     try:
         return self.navigate(view, offset)
     except:
         log.log_error(traceback.format_exc())
         return False
Exemple #59
0
	def init(self):
		try:
			hdr = self.parent_view.read(0, 128)
			self.version = struct.unpack("B", hdr[5])[0]
			self.song_count = struct.unpack("B", hdr[6])[0]
			self.starting_song = struct.unpack("B", hdr[7])[0]
			self.load_address = struct.unpack("<H", hdr[8:10])[0]
			self.init_address = struct.unpack("<H", hdr[10:12])[0]
			self.play_address = struct.unpack("<H", hdr[12:14])[0]
			self.song_name = hdr[15].split('\0')[0]
			self.artist_name = hdr[46].split('\0')[0]
			self.copyright_name = hdr[78].split('\0')[0]
			self.play_speed_ntsc = struct.unpack("<H", hdr[110:112])[0]
			self.bank_switching = hdr[112:120]
			self.play_speed_pal = struct.unpack("<H", hdr[120:122])[0]
			self.pal_ntsc_bits = struct.unpack("B", hdr[122])[0]
			self.pal = True if (self.pal_ntsc_bits & 1) == 1 else False
			self.ntsc = not self.pal
			if self.pal_ntsc_bits & 2 == 2:
				self.pal = True
				self.ntsc = True
			self.extra_sound_bits = struct.unpack("B", hdr[123])[0]

			if self.bank_switching == "\0" * 8:
				# no bank switching
				self.load_address & 0xFFF
				self.rom_offset = 128

			else:
				# bank switching not implemented
				log_info("Bank switching not implemented in this loader.")

			# Add mapping for RAM and hardware registers, not backed by file contents
			self.add_auto_segment(0, 0x8000, 0, 0, SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable | SegmentFlag.SegmentExecutable)

			# Add ROM mappings
			self.add_auto_segment(0x8000, 0x4000, self.rom_offset, 0x4000,
				SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)

			self.define_auto_symbol(Symbol(SymbolType.FunctionSymbol, self.play_address, "_play"))
			self.define_auto_symbol(Symbol(SymbolType.FunctionSymbol, self.init_address, "_init"))
			self.add_entry_point(self.init_address)
			self.add_function(self.play_address)

			# Hardware registers
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x2000, "PPUCTRL"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x2001, "PPUMASK"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x2002, "PPUSTATUS"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x2003, "OAMADDR"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x2004, "OAMDATA"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x2005, "PPUSCROLL"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x2006, "PPUADDR"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x2007, "PPUDATA"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4000, "SQ1_VOL"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4001, "SQ1_SWEEP"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4002, "SQ1_LO"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4003, "SQ1_HI"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4004, "SQ2_VOL"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4005, "SQ2_SWEEP"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4006, "SQ2_LO"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4007, "SQ2_HI"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4008, "TRI_LINEAR"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x400a, "TRI_LO"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x400b, "TRI_HI"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x400c, "NOISE_VOL"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x400e, "NOISE_LO"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x400f, "NOISE_HI"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4010, "DMC_FREQ"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4011, "DMC_RAW"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4012, "DMC_START"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4013, "DMC_LEN"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4014, "OAMDMA"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4015, "SND_CHN"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4016, "JOY1"))
			self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4017, "JOY2"))

			return True
		except:
			log_error(traceback.format_exc())
			return False
                return DownloadInstance.Response(result.getcode(),
                                                 result.headers, None)

        class PythonDownloadProvider(DownloadProvider):
            name = "PythonDownloadProvider"
            instance_class = PythonDownloadInstance

        PythonDownloadProvider().register()
        _loaded = True
    except ImportError:
        pass

if not _loaded:
    if sys.platform == "win32":
        log.log_error(
            "The pip requests package is required for network connectivity!")
        log.log_error(
            "Please install the requests package into the selected Python environment:"
        )
        log.log_error("  python -m pip install requests")
    else:
        log.log_error(
            "On Python versions below 2.7.9, the pip requests[security] package is required for network connectivity!"
        )
        log.log_error(
            "On an Ubuntu 14.04 install, the following three commands are sufficient to enable networking for the current user:"******"  sudo apt install python-pip")
        log.log_error("  python -m pip install pip --upgrade --user")
        log.log_error(
            "  python -m pip install requests[security] --upgrade --user")