|
| 1 | +""" |
| 2 | +# Improved version of "export_to_redux.py" script by Nicolas |
| 3 | +# that supports overlays filtering with GUI component |
| 4 | +# Usage: |
| 5 | +# 1. Run the script. |
| 6 | +# 2. Paste the main function address. |
| 7 | +# 3. Select PCSX-Redux Folder. |
| 8 | +# 4. Select the overlays you need, the only selected overlays symbols will be exported. |
| 9 | +""" |
| 10 | +#@author Nicolas "Pixel" Noble |
| 11 | +#@author acemon33 |
| 12 | + |
| 13 | +import os |
| 14 | +from ghidra.program.model.data import DataType, Pointer, Structure |
| 15 | + |
| 16 | + |
| 17 | +selected_overlays = [] |
| 18 | +memory_block_list = [] |
| 19 | +filter_list = [] |
| 20 | + |
| 21 | + |
| 22 | +def find_overlays(): |
| 23 | + for mem in currentProgram.getMemory().getBlocks(): |
| 24 | + if mem.isOverlay(): |
| 25 | + memory_block_list.append(mem.getName()) |
| 26 | + |
| 27 | + |
| 28 | +def filter_memory_block(): |
| 29 | + for memory_block_name in selected_overlays: |
| 30 | + filter_list.append(memory_block_name + '::') |
| 31 | + |
| 32 | + |
| 33 | +def print_overlays(): |
| 34 | + for i in range(0, len(memory_block_list)): |
| 35 | + print(i + 1, memory_block_list[i]) |
| 36 | + |
| 37 | + |
| 38 | +main_address = int(str(askAddress("Enter the main Address", "Address")), 16) |
| 39 | +root_dir = askDirectory("Select PCSX-Redux Directory", "Select") |
| 40 | +fm = currentProgram.getFunctionManager() |
| 41 | +dtm = currentProgram.getDataTypeManager() |
| 42 | + |
| 43 | +find_overlays() |
| 44 | +selected_overlays = askChoices("Title", "Message", memory_block_list); |
| 45 | + |
| 46 | +filter_memory_block() |
| 47 | +print('main: ', hex(main_address)) |
| 48 | +print('Selected Modules : ', selected_overlays) |
| 49 | + |
| 50 | +filename = os.path.join(str(root_dir), 'redux_data_types.txt') |
| 51 | +with open(filename, 'w') as f: |
| 52 | + # @todo: enums, typedefs, etc. |
| 53 | + for data_type in dtm.getAllStructures(): |
| 54 | + dt_info = data_type.getName() + ';' |
| 55 | + for component in data_type.getComponents(): |
| 56 | + type_name = component.getDataType().getName() |
| 57 | + field_name = component.getFieldName() |
| 58 | + if field_name == None: |
| 59 | + field_name = 'None' |
| 60 | + field_length = str(component.getLength()) |
| 61 | + dt_info += type_name + ',' + field_name + ',' + field_length + ';' |
| 62 | + f.write(dt_info + '\n') |
| 63 | + |
| 64 | +filename = os.path.join(str(root_dir), 'redux_funcs.txt') |
| 65 | +with open(filename, 'w') as f: |
| 66 | + for func in fm.getFunctions(toAddr(main_address), True): |
| 67 | + entry_point = func.getEntryPoint().toString() |
| 68 | + in_overlay = entry_point.find('::') |
| 69 | + if (in_overlay == -1) or (entry_point[:in_overlay+2] in filter_list): |
| 70 | + num_addr = int(entry_point.split(':')[-1], 16) |
| 71 | + func_info = entry_point.split(':')[-1] + ';' + func.getName() + ';' |
| 72 | + for param in func.getParameters(): |
| 73 | + data_type_name = param.getDataType().getName() |
| 74 | + if data_type_name.__contains__('undefined'): |
| 75 | + data_type_name = 'int' |
| 76 | + func_info += data_type_name + ',' + param.getName() + ',' + str(param.getLength()) + ';' |
| 77 | + f.write(func_info + '\n') |
| 78 | + |
| 79 | +popup('Finish') |
0 commit comments