-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCROLink.java
More file actions
94 lines (87 loc) · 3.91 KB
/
CROLink.java
File metadata and controls
94 lines (87 loc) · 3.91 KB
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
// Links ALL .cro modules with themselves, and with the static binary (using .crs)
// @category 3DS
import java.io.*;
import java.util.*;
import ghidra.app.script.GhidraScript;
import ghidra.app.services.ProgramManager;
import ghidra.app.util.demangler.*;
import ghidra.framework.model.*;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.*;
import ghidra.program.model.symbol.*;
import ghidra.util.exception.TimeoutException;
import util.CRXLibrary;
import util.RTTIUtil;
import util.RenameVTableFunctions;
public class CROLink extends GhidraScript {
private final List<CRXLibrary> crxLibraries = new ArrayList<>();
@Override
protected void run() throws Exception {
// This script will link all .cro files and the static.crs file together.
// Get pertinent files, and form .crx into proper CRXLibrary objects
DomainFile codeFile = askDomainFile("Select the static module (code.bin / .code)");
File crsFile = askFile("Select static.crs","OK");
DomainFolder croFolder = askProjectFolder("Select the cro directory");
ProgramManager pman = getState().getTool().getService(ProgramManager.class);
crxLibraries.add(new CRXLibrary(codeFile, crsFile, pman, monitor));
for (DomainFile cro : croFolder.getFiles()) {
CRXLibrary temp = new CRXLibrary(cro, pman, monitor);
if (temp.isValidCRO0()) {
crxLibraries.add(temp);
}
}
for (var crx : crxLibraries) {
crx.importModules(crxLibraries);
}
// Iterate through the list, linking each module to its imports
for (var crx : crxLibraries) {
crx.link(crxLibraries);
}
CRXLibrary codebin = crxLibraries.getFirst();
Symbol[] syms = codebin.program.getSymbolTable().getSymbols(codebin.getBaseAddr());
for (int i=0; i<syms.length; i++) {
if (i==0) syms[i].setName("Entry",SourceType.USER_DEFINED);
else syms[i].delete();
}
// Analyze the VTables (starting with static)
RTTIUtil rtti = new RTTIUtil(this);
RenameVTableFunctions renamer = new RenameVTableFunctions(this);
List<Map<Long, Long>> AllVtableRttiSlots = new ArrayList<>();
List<Set<Long>> AllTypeinfoAddresses = new ArrayList<>();
for (var crx : crxLibraries) {
int txId = crx.program.startTransaction("RTTI Discovery Pipeline");
try {
rtti.run(crx.program);
AllVtableRttiSlots.add(new HashMap<>(rtti.getVtableRttiSlots()));
AllTypeinfoAddresses.add(new HashSet<>(rtti.getTypeinfoAddresses()));
} finally {
crx.program.endTransaction(txId, true);
}
}
for (int i=0; i<crxLibraries.size(); i++) {
var crx = crxLibraries.get(i);
int txId = crx.program.startTransaction("RTTI Discovery Pipeline");
try {
Map<Long, Long> vtableRttiSlots = AllVtableRttiSlots.get(i);
Set<Long> typeinfoAddresses = AllTypeinfoAddresses.get(i);
if (vtableRttiSlots.isEmpty()) continue;
renamer.run(crx.program, vtableRttiSlots, typeinfoAddresses);
} finally {
crx.program.endTransaction(txId, true);
}
}
// Save or forget progress
boolean shouldSave = askYesNo("Save?",
String.format("%d modules linked successfully!\nDo you want to save? " +
"If not, progress in external libraries will be lost, and this script must be ran again.",
crxLibraries.size()));
for (CRXLibrary crx : crxLibraries) {
if (crx.program == currentProgram) continue;
try {
crx.cleanup(shouldSave);
} catch (TimeoutException e) {
closeProgram(crx.program);
}
}
}
}