forked from wiiu-wasteland/ghidra_scripts
/
GhidraWiiSyscallUDF.java
109 lines (93 loc) · 3.59 KB
/
GhidraWiiSyscallUDF.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
//Find Wii IOS syscalls via undefined instruction
//@author rw, GaryOderNichts
//@category ARM
//@keybinding
//@menupath
//@toolbar
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.HashMap;
import java.util.Vector;
import ghidra.app.script.GhidraScript;
import ghidra.app.cmd.function.ApplyFunctionSignatureCmd;
import ghidra.app.util.parser.FunctionSignatureParser;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Function;
import ghidra.program.model.data.DataTypeConflictHandler;
import ghidra.program.model.data.FunctionDefinitionDataType;
import ghidra.program.model.listing.FunctionIterator;
import ghidra.program.model.symbol.Symbol;
import ghidra.program.model.symbol.SymbolIterator;
import ghidra.program.model.symbol.SymbolTable;
import ghidra.program.model.mem.Memory;
import ghidra.program.model.symbol.SourceType;
public class GhidraWiiSyscallUDF extends GhidraScript {
private HashMap<Integer, FunctionDefinitionDataType> Syscalls = new HashMap<Integer, FunctionDefinitionDataType>();
protected final FunctionDefinitionDataType parseSignature(String signature) {
FunctionSignatureParser parser = new FunctionSignatureParser(currentProgram.getDataTypeManager(), null);
try {
return parser.parse(null, signature);
} catch (Exception e) {
println("Failed to parse " + signature);
}
return null;
}
protected void applyFunctionDefinition(Function fn, FunctionDefinitionDataType definition) {
ApplyFunctionSignatureCmd cmd = new ApplyFunctionSignatureCmd(fn.getEntryPoint(), definition,
SourceType.USER_DEFINED, true, true);
runCommand(cmd);
}
@Override
protected void run() throws Exception {
File file = askFile("Please specify a syscall definition file", "Select syscalls definition");
println("Using " + file.getName() + " as syscalls description file");
BufferedReader br = new BufferedReader(new FileReader(file));
for (String line = br.readLine(); line != null; line = br.readLine()) {
String[] fields = line.split(":");
Syscalls.put(Integer.decode(fields[0]), parseSignature(fields[1]));
}
Memory memory = currentProgram.getMemory();
SymbolIterator iter = currentProgram.getSymbolTable().getAllSymbols(true);
while (iter.hasNext()) {
Symbol symbol = iter.next();
if (monitor.isCancelled()) {
break;
}
Address instrAddr = symbol.getAddress();
try {
int instrVal = memory.getInt(instrAddr, true);
int instr = instrVal & 0xffffe01f;
if (instr != 0xe6000010) {
continue;
}
int sysnum = (instrVal >>> 5) & 0xff;
if (!Syscalls.containsKey(sysnum)) {
continue;
}
FunctionDefinitionDataType definition = Syscalls.get(sysnum);
if (definition == null) {
continue;
}
String fnname = definition.getName();
Function fn = currentProgram.getFunctionManager().getFunctionAt(instrAddr);
if (fn != null) {
println("Applying signature to: " + fn.getName() + " -> " + fnname);
applyFunctionDefinition(fn, definition);
} else {
println("Renaming: " + symbol.getName() + " -> " + fnname);
symbol.setName(fnname, SourceType.USER_DEFINED);
}
// try to also rename thunks for thumb
if (symbol.hasReferences()) {
Address fnAddress = symbol.getReferences()[0].getFromAddress();
fn = currentProgram.getFunctionManager().getFunctionAt(fnAddress);
if (fn != null) {
println("Applying signature to: " + fn.getName() + " -> " + fnname);
applyFunctionDefinition(fn, definition);
}
}
} catch(Exception e) {}
}
}
}