122 lines
3.1 KiB
Java
122 lines
3.1 KiB
Java
// CSV format per line:
|
|
// 0x401000,<count>
|
|
//
|
|
// Creates NOTE bookmarks in category: FAIL_MARKER
|
|
|
|
import ghidra.app.script.GhidraScript;
|
|
import ghidra.program.model.address.Address;
|
|
import ghidra.program.model.listing.BookmarkManager;
|
|
import java.io.BufferedReader;
|
|
import java.io.File;
|
|
import java.io.FileReader;
|
|
|
|
public class ImportMarkersAsBookmarks extends GhidraScript {
|
|
|
|
private static final String BOOKMARK_TYPE = "NOTE";
|
|
private static final String BOOKMARK_CATEGORY = "FAIL_MARKER";
|
|
|
|
@Override
|
|
public void run() throws Exception {
|
|
File input = askFile("Select CSV file", "Import");
|
|
BookmarkManager bm = currentProgram.getBookmarkManager();
|
|
|
|
int imported = 0;
|
|
int skipped = 0;
|
|
int lineNo = 0;
|
|
|
|
try (BufferedReader br = new BufferedReader(new FileReader(input))) {
|
|
String line;
|
|
while ((line = br.readLine()) != null) {
|
|
lineNo++;
|
|
|
|
if (monitor.isCancelled()) {
|
|
println("Cancelled.");
|
|
break;
|
|
}
|
|
|
|
line = line.trim();
|
|
if (line.isEmpty() || line.startsWith("#")) {
|
|
continue;
|
|
}
|
|
|
|
String[] parts = splitCsvLine(line);
|
|
if (parts.length < 1) {
|
|
skipped++;
|
|
printerr("Line " + lineNo + ": missing address");
|
|
continue;
|
|
}
|
|
|
|
String addrText = parts[0].trim();
|
|
String description = parts.length >= 2 ? parts[1].trim() : "";
|
|
|
|
if (addrText.isEmpty()) {
|
|
skipped++;
|
|
printerr("Line " + lineNo + ": empty address");
|
|
continue;
|
|
}
|
|
|
|
Address addr = parseAddress(addrText);
|
|
if (addr == null) {
|
|
skipped++;
|
|
printerr("Line " + lineNo + ": invalid address: " + addrText);
|
|
continue;
|
|
}
|
|
|
|
println("Adding bookmark at " + addr + " with description " + description);
|
|
bm.setBookmark(addr, BOOKMARK_TYPE, BOOKMARK_CATEGORY, description);
|
|
imported++;
|
|
}
|
|
}
|
|
|
|
println("Imported " + imported + " bookmarks.");
|
|
if (skipped > 0) {
|
|
println("Skipped " + skipped + " lines.");
|
|
}
|
|
}
|
|
|
|
public Address parseAddress(String text) {
|
|
text = text.trim();
|
|
|
|
if (text.startsWith("\"") && text.endsWith("\"") && text.length() >= 2) {
|
|
text = text.substring(1, text.length() - 1).trim();
|
|
}
|
|
|
|
if (text.startsWith("0x") || text.startsWith("0X")) {
|
|
text = text.substring(2);
|
|
}
|
|
|
|
try {
|
|
return toAddr(text);
|
|
} catch (Exception e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private String[] splitCsvLine(String line) {
|
|
java.util.ArrayList<String> fields = new java.util.ArrayList<>();
|
|
StringBuilder current = new StringBuilder();
|
|
boolean inQuotes = false;
|
|
|
|
for (int i = 0; i < line.length(); i++) {
|
|
char c = line.charAt(i);
|
|
|
|
if (c == '"') {
|
|
if (inQuotes && i + 1 < line.length() && line.charAt(i + 1) == '"') {
|
|
current.append('"');
|
|
i++;
|
|
} else {
|
|
inQuotes = !inQuotes;
|
|
}
|
|
} else if (c == ',' && !inQuotes) {
|
|
fields.add(current.toString());
|
|
current.setLength(0);
|
|
} else {
|
|
current.append(c);
|
|
}
|
|
}
|
|
|
|
fields.add(current.toString());
|
|
return fields.toArray(new String[0]);
|
|
}
|
|
}
|