An ISA definition for Kingdom Hearts 2 AI https://govanify.com/post/kh2ai/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

65 lines
2.0KB

  1. # This script imports a Kh2Ai file into Ghidra
  2. #@author Gauvain "GovanifY" Roussel-Tarbouriech
  3. #@category Import
  4. #@keybinding
  5. #@menupath
  6. #@toolbar
  7. import struct
  8. import sys
  9. import os.path
  10. # import the file into ghidra db
  11. file = askFile("Select AI object (*.ai) to import", "Import")
  12. lang = getDefaultLanguage(ghidra.program.model.lang.Processor.findOrPossiblyCreateProcessor("kh2ai"))
  13. comp = lang.getDefaultCompilerSpec()
  14. program = importFileAsBinary(file, lang, comp)
  15. ai = open(file.toString(), "rb")
  16. flat = ghidra.program.flatapi.FlatProgramAPI(program)
  17. txn = program.startTransaction("Import program")
  18. mem = program.getMemory()
  19. start = mem.getMinAddress()
  20. # read header
  21. entry=[]
  22. ai_name = ai.read(0x10).decode('utf-8')
  23. unk1, unk2, unk3 = struct.unpack("<3L", ai.read(0xc))
  24. print("ai: %s, header: %s %s %s" % (ai_name, hex(unk1), hex(unk2), hex(unk3)))
  25. # document header (very important!!11!)
  26. flat.createLabel(start, "header", True)
  27. flat.createAsciiString(start, 0x10)
  28. for i in range(0, 3):
  29. flat.createDWord(start.add(0x10+i*4))
  30. # read out all entrypoints and callbacks
  31. while True:
  32. callback, offset = struct.unpack("<2L", ai.read(0x8))
  33. if(callback == 0 and offset == 0):
  34. flat.createLabel(start.add(0x1c+len(entry)*8), "header_end", True)
  35. flat.createDWord(start.add(0x1c+len(entry)*8))
  36. flat.createDWord(start.add(0x1c+4+len(entry)*8))
  37. break
  38. print("entry%s: %s" % (callback, hex(0x10+offset*2)))
  39. flat.createLabel(start.add(0x1c+len(entry)*8), "entry"+str(callback), True)
  40. flat.createDWord(start.add(0x1c+len(entry)*8))
  41. flat.createDWord(start.add(0x1c+4+len(entry)*8))
  42. entry.append([callback, 0x10+offset*2])
  43. print(entry)
  44. ai.close()
  45. for i in entry:
  46. label="entry"+str(i[0])
  47. flat = ghidra.program.flatapi.FlatProgramAPI(program)
  48. flat.createLabel(start.add(i[1]), label, True)
  49. flat.addEntryPoint(start.add(i[1]))
  50. flat.disassemble(start.add(i[1]))
  51. # Open for user to see and to start analyzing
  52. program.endTransaction(txn, True)
  53. openProgram(program)