Beispiel #1
0
	def read_from_file(input, address, reference):
		input.seek(anal.addr_to_offset(address))
		code = anal.read_int(input, 4)

		size = reference.get_code_size(code, input)

		input.seek(anal.addr_to_offset(address + 4))
		args = [anal.read_int(input, 4) for _ in range(size - 1)]

		return SceneIns(code, size, args)
Beispiel #2
0
def main(args):
	def show_exception_and_exit(exc_type, exc_value, tb):
		import traceback

		traceback.print_exception(exc_type, exc_value, tb)
		sys.exit(-1)

	sys.excepthook = show_exception_and_exit

	if (len(args) == 0):
		sys.exit(":(")

	sceneInsReference = ev6anal.InsReference(ev6anal.FE6_SCENE_INS_REFERENCE_ADDR)

	analyser = anal.RomAnalyser()

	analyser.set_analysis_handler(ev6anal.ANAL_KEY_SCENE, lambda a, i, d, n: ev6anal.analyse_scene(a, i, d, n, sceneInsReference))
	analyser.set_analysis_handler(ev6anal.ANAL_KEY_MOMA, ev6anal.analyse_moma)
	analyser.set_analysis_handler(ev6anal.ANAL_KEY_UNITS, ev6anal.analyse_units)
	analyser.set_analysis_handler(ev6anal.ANAL_KEY_ITEMS, ev6anal.analyse_items)
	analyser.set_analysis_handler(ev6anal.ANAL_KEY_EVLIST, ev6anal.analyse_event_list)
	analyser.set_analysis_handler(ev6anal.ANAL_KEY_PTRLIST, ev6anal.analyse_chapter_events)

	with open(args[0], 'rb') as f:
		CHAPTER_TABLE_ADDR = 0x086637A4
		CHAPTER_ASSET_ADDR = 0x08664398

		for i in range(45):
			f.seek(anal.addr_to_offset(CHAPTER_TABLE_ADDR + 0x44*i + 0x3A))
			assetId = anal.read_int(f, 1)

			if assetId != 0:
				f.seek(anal.addr_to_offset(CHAPTER_ASSET_ADDR + 4*assetId))
				analyser.enqueue_analysis(anal.read_int(f, 4), ev6anal.ANAL_KEY_PTRLIST, "chapter{}".format(i))

		analyser.analyse_queued(f)

	printer = anal.AnalysisPrinter()

	printer.set_printer(ev6anal.ANAL_KEY_SCENE, lambda a: ScenePrinter.print_scene(a, sceneInsReference))

	for line in printer.iter_print_list(analyser.get_analysed_sorted()):
		sys.stdout.write(line)
Beispiel #3
0
def analyse_moma(analyser, input, address, name):
	"""
	Analysis handler for movement scripts ("MOMAs").
	"""

	input.seek(anal.addr_to_offset(address))
	start = address

	while True:
		cmd = anal.read_int(input, 1, True)
		address = address + 1

		if (cmd == 12):
			anal.read_int(input, 1) # void speed
			address = address + 1

		elif (cmd == -1) | (cmd == 4):
			break

	return anal.AnalysedObject(
		start, address - start, ANAL_KEY_MOMA, anal.read_data_at(input, start, address - start), name)
Beispiel #4
0
	def get_code_size(self, code, input = None):
		if code in self.sizeCache:
			return self.sizeCache[code]

		elif input:
			input.seek(anal.addr_to_offset(self.referenceAddr + code*8 + 4))
			size = anal.read_int(input, 4)

			self.sizeCache[code] = size
			return size

		raise Exception("uncached code size with no available input")
Beispiel #5
0
def main(args):
	def show_exception_and_exit(exc_type, exc_value, tb):
		import traceback

		traceback.print_exception(exc_type, exc_value, tb)
		sys.exit(-1)

	sys.excepthook = show_exception_and_exit

	if (len(args) == 0):
		sys.exit(":(")

	analyser = anal.RomAnalyser()

	analyser.set_analysis_handler(ANAL_KEY_SCENE, analyse_scene)
	analyser.set_analysis_handler(ANAL_KEY_MOMA, analyse_moma)
	analyser.set_analysis_handler(ANAL_KEY_UNITS, analyse_units)
	analyser.set_analysis_handler(ANAL_KEY_ITEMS, analyse_items)
	analyser.set_analysis_handler(ANAL_KEY_EVLIST, analyse_event_list)
	analyser.set_analysis_handler(ANAL_KEY_PTRLIST, analyse_chapter_events)

	with open(args[0], 'rb') as f:
		CHAPTER_TABLE_ADDR = 0x086637A4
		CHAPTER_ASSET_ADDR = 0x08664398

		for i in range(45):
			f.seek(anal.addr_to_offset(CHAPTER_TABLE_ADDR + 0x44*i + 0x3A))
			assetId = anal.read_int(f, 1)

			if assetId != 0:
				f.seek(anal.addr_to_offset(CHAPTER_ASSET_ADDR + 4*assetId))
				analyser.enqueue_analysis(anal.read_int(f, 4), ANAL_KEY_PTRLIST, "chapter{}".format(i))

		analyser.analyse_queued(f)

	for line in analyser.iter_pretty_summary():
		print(line)
Beispiel #6
0
def analyse_items(analyser, input, address, name):
	"""
	Analysis handler for shop item lists.
	"""

	input.seek(anal.addr_to_offset(address))
	start = address

	while True:
		item = anal.read_int(input, 2)
		address = address + 2

		if item == 0:
			break

	return anal.AnalysedObject(
		start, address - start, ANAL_KEY_ITEMS, anal.read_data_at(input, start, address - start), name)
Beispiel #7
0
def analyse_units(analyser, input, address, name):
	"""
	Analysis handler for unit groups.
	"""

	start = address

	while True:
		input.seek(anal.addr_to_offset(address))
		charId = anal.read_int(input, 1)

		address = address + 0x10

		if charId == 0:
			break

	return anal.AnalysedObject(
		start, address - start, ANAL_KEY_UNITS, anal.read_data_at(input, start, address - start), name)
Beispiel #8
0
def analyse_chapter_events(analyser, input, address, name):
	"""
	Analysis handler for chapter events root ("pointer arrays").
	"""

	input.seek(anal.addr_to_offset(address))

	analyser.enqueue_analysis(anal.read_int(input, 4), ANAL_KEY_EVLIST, name + ".turn") # turn events
	analyser.enqueue_analysis(anal.read_int(input, 4), ANAL_KEY_EVLIST, name + ".char") # character events
	analyser.enqueue_analysis(anal.read_int(input, 4), ANAL_KEY_EVLIST, name + ".loca") # location events
	analyser.enqueue_analysis(anal.read_int(input, 4), ANAL_KEY_EVLIST, name + ".action") # misc events

	analyser.enqueue_analysis(anal.read_int(input, 4), ANAL_KEY_UNITS, name + ".blue") # initial blue units
	analyser.enqueue_analysis(anal.read_int(input, 4), ANAL_KEY_UNITS, name + ".red") # initial red units

	analyser.enqueue_analysis(anal.read_int(input, 4), ANAL_KEY_SCENE, name + ".ending") # ending scene

	return anal.AnalysedObject(
		address, 0x1C, ANAL_KEY_PTRLIST, anal.read_data_at(input, address, 0x1C), name)