Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from idaapi import *
- from idc import *
- import idaapi as ida
- import idc
- def dump_image(start_ptr, end_ptr, name):
- h = "7F 45 4C 46 01 02 01 00 00 00 00 00 00 00 00 00 00 02 00 17 00 00 00 01 00 00 00 00 00 00 00 34 00 00 00 00 00 00 00 00 00 34 00 20 00 01 00 00 00 00 00 00 00 00 00 01 00 00 00 54 00 00 00 00 00 00 00 00 00 04 00 00 00 04 00 00 00 00 00 07 00 00 00 00"
- size = end_ptr - start_ptr
- filename = ask_file(1, name + ".elf", "Output file name")
- with open(filename, "wb") as out:
- # Images are raw, so lets add elf header for easier loading,
- # and to mitigate ida 7.3+ bug to set SPU to LE if raw image is loaded.
- header = bytearray.fromhex(h)
- data = get_bytes(start_ptr, size, False)
- out.write(header)
- out.seek(0x54, 0)
- out.write(data)
- def find_addresses(pattern, name):
- address = 0
- address = idaapi.find_binary(address, ida_idaapi.BADADDR, pattern, 0x10, SEARCH_DOWN)
- if address == BADADDR:
- print("Pattern " + name + " not found!")
- return 1
- print("Found " + name + " pattern at: " + hex(address))
- ptr = idaapi.find_binary(0, ida_idaapi.BADADDR, hex(address), 0x10, SEARCH_DOWN)
- if ptr == BADADDR:
- print("False positive, skipping...")
- return 1
- ptr -= 1
- print("Program name pointer at: " + hex(ptr))
- start_ptr = get_wide_dword(ptr + 8)
- end_ptr = get_wide_dword(ptr + 16)
- if start_ptr > end_ptr:
- print("Error: dump start addr > dump end addr")
- return 1
- print(name + " start offset: " + hex(start_ptr))
- print(name + " end offset: " + hex(end_ptr))
- if pattern == "66 65 00 00":
- # Try to dump "be" which seems to be always after fe.
- # "be" pattern is tricky because multi xrefs.
- be_start_ptr = get_wide_dword(ptr + 32)
- be_end_ptr = get_wide_dword(ptr + 40)
- print("Dumping spu_be")
- print("Start offset" + be_start_ptr)
- print("End offset" + be_end_ptr)
- dump_image(be_start_ptr, be_end_ptr, "spu_be")
- dump_image(start_ptr, end_ptr, name)
- def start():
- spu_eedma_pattern = "73 70 75 5F 65 65 64 6D 61 00"
- spu_iop_pattern = "73 70 75 5F 69 6F 70 00"
- spu_ipu_pattern = "73 70 75 5F 69 70 75 00"
- spu_spu2_pattern = "73 70 75 5F 73 70 75 32 00"
- spu_vu1_pattern = "73 70 75 5F 76 75 31 00"
- spu_gse_pattern = "73 70 75 5F 67 73 65 00"
- spu_gsegif_pattern = "73 70 75 5F 67 73 65 67 69 66 00"
- spu_gsgif_pattern = "73 70 75 5F 67 73 67 69 66 00"
- spu_fe_pattern = "66 65 00 00" # Tricky, can give false possitives
- #spu_be_pattern = "62 65 00 00" # Of course...
- find_addresses(spu_eedma_pattern, "spu_eedma")
- find_addresses(spu_iop_pattern, "spu_iop")
- find_addresses(spu_ipu_pattern, "spu_ipu")
- find_addresses(spu_spu2_pattern, "spu_spu2")
- find_addresses(spu_vu1_pattern, "spu_vu1")
- find_addresses(spu_gse_pattern, "spu_gse")
- find_addresses(spu_gsegif_pattern, "spu_gsegif")
- find_addresses(spu_gsgif_pattern, "spu_gsgif")
- find_addresses(spu_fe_pattern, "spu_fe")
- address = 0
- # Search for function responsible for starting SPE cores.
- # Function take (LS base, start_addr) as arguments.
- # LS base is 40000000 for SPE0, 40080000 for SPE1, 40100000 for SPE2,
- # 40180000 for SPE3, 40200000 for SPE4, 40280000 for SPE5, and 40300000 for SPE6.
- # Todo: Make this automatic, grab function vars, and add start address to elf header, and resolve 40xx0000 xref.
- start_spe_pattern = "3D 43 00 04 7C 08 02 A6 F8 21 FF 91 F8 01 00 80 80 0A 40 24 54 00 07 FE 2F 80 00 00"
- address = idaapi.find_binary(address, ida_idaapi.BADADDR, start_spe_pattern, 0x10, SEARCH_DOWN)
- if address == BADADDR:
- print("BADADDR in find_start")
- return 1
- set_name(address, "start_spe", 0)
- print("Found start_spe function at: " + hex(address))
- print("Second arg (r4) to that function is entry point in matching elf.")
- start()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement