mirror of
https://github.com/encounter/ghidra-cli.git
synced 2026-07-10 03:18:56 -07:00
fix: bump version to 0.1.7 and update command filters in Ghidra CLI
This commit is contained in:
Generated
+1
-1
@@ -739,7 +739,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ghidra-cli"
|
||||
version = "0.1.6"
|
||||
version = "0.1.7"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"assert_cmd",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ghidra-cli"
|
||||
version = "0.1.6"
|
||||
version = "0.1.7"
|
||||
edition = "2021"
|
||||
authors = ["Alexander Kiselev"]
|
||||
description = "Rust CLI to run Ghidra headless for reverse engineering with Claude Code and other agents"
|
||||
|
||||
@@ -217,7 +217,7 @@ public class GhidraCliBridge extends GhidraScript {
|
||||
case "type_create": return handleTypeCreate(args);
|
||||
case "type_apply": return handleTypeApply(args);
|
||||
// Comment commands
|
||||
case "comment_list": return handleCommentList();
|
||||
case "comment_list": return handleCommentList(args);
|
||||
case "comment_get": return handleCommentGet(args);
|
||||
case "comment_set": return handleCommentSet(args);
|
||||
case "comment_delete": return handleCommentDelete(args);
|
||||
@@ -519,6 +519,7 @@ public class GhidraCliBridge extends GhidraScript {
|
||||
}
|
||||
|
||||
int limit = getArgInt(args, "limit", 0);
|
||||
String nameFilter = getArgString(args, "filter");
|
||||
|
||||
JsonArray strings = new JsonArray();
|
||||
Listing listing = currentProgram.getListing();
|
||||
@@ -532,6 +533,11 @@ public class GhidraCliBridge extends GhidraScript {
|
||||
if (data.hasStringValue()) {
|
||||
try {
|
||||
String val = data.getValue().toString();
|
||||
|
||||
if (nameFilter != null && !val.toLowerCase().contains(nameFilter.toLowerCase())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
JsonObject strData = new JsonObject();
|
||||
strData.addProperty("address", data.getAddress().toString());
|
||||
strData.addProperty("value", val);
|
||||
@@ -1435,13 +1441,17 @@ public class GhidraCliBridge extends GhidraScript {
|
||||
private JsonObject handleSymbolList(JsonObject args) {
|
||||
if (currentProgram == null) return errorResult("No program loaded");
|
||||
|
||||
int limit = getArgInt(args, "limit", 0);
|
||||
String nameFilter = getArgString(args, "filter");
|
||||
|
||||
SymbolTable symbolTable = currentProgram.getSymbolTable();
|
||||
JsonArray symbols = new JsonArray();
|
||||
int count = 0;
|
||||
|
||||
SymbolIterator symIter = symbolTable.getAllSymbols(true);
|
||||
while (symIter.hasNext()) {
|
||||
if (limit > 0 && count >= limit) break;
|
||||
|
||||
Symbol symbol = symIter.next();
|
||||
String name = symbol.getName();
|
||||
|
||||
@@ -1456,6 +1466,7 @@ public class GhidraCliBridge extends GhidraScript {
|
||||
symData.addProperty("source", symbol.getSource().toString());
|
||||
symData.addProperty("is_primary", symbol.isPrimary());
|
||||
symbols.add(symData);
|
||||
count++;
|
||||
}
|
||||
|
||||
JsonObject result = new JsonObject();
|
||||
@@ -1645,6 +1656,7 @@ public class GhidraCliBridge extends GhidraScript {
|
||||
if (currentProgram == null) return errorResult("No program loaded");
|
||||
|
||||
int limit = getArgInt(args, "limit", 0);
|
||||
String nameFilter = getArgString(args, "filter");
|
||||
DataTypeManager dtm = currentProgram.getDataTypeManager();
|
||||
JsonArray types = new JsonArray();
|
||||
|
||||
@@ -1653,6 +1665,11 @@ public class GhidraCliBridge extends GhidraScript {
|
||||
while (dtIter.hasNext()) {
|
||||
DataType dt = dtIter.next();
|
||||
if (limit > 0 && count >= limit) break;
|
||||
|
||||
if (nameFilter != null && !dt.getName().toLowerCase().contains(nameFilter.toLowerCase())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
JsonObject typeData = new JsonObject();
|
||||
typeData.addProperty("name", dt.getName());
|
||||
typeData.addProperty("path", dt.getPathName());
|
||||
@@ -1818,12 +1835,16 @@ public class GhidraCliBridge extends GhidraScript {
|
||||
}
|
||||
}
|
||||
|
||||
private JsonObject handleCommentList() {
|
||||
private JsonObject handleCommentList(JsonObject args) {
|
||||
if (currentProgram == null) return errorResult("No program loaded");
|
||||
|
||||
int limit = getArgInt(args, "limit", 0);
|
||||
String nameFilter = getArgString(args, "filter");
|
||||
|
||||
Listing listing = currentProgram.getListing();
|
||||
Memory memory = currentProgram.getMemory();
|
||||
JsonArray comments = new JsonArray();
|
||||
int count = 0;
|
||||
|
||||
int[][] commentTypes = {
|
||||
{CodeUnit.EOL_COMMENT},
|
||||
@@ -1834,6 +1855,8 @@ public class GhidraCliBridge extends GhidraScript {
|
||||
String[] commentNames = {"EOL", "PRE", "POST", "PLATE"};
|
||||
|
||||
for (MemoryBlock block : memory.getBlocks()) {
|
||||
if (limit > 0 && count >= limit) break;
|
||||
|
||||
ghidra.program.model.address.AddressSet addrSet =
|
||||
new ghidra.program.model.address.AddressSet(block.getStart(), block.getEnd());
|
||||
|
||||
@@ -1841,18 +1864,27 @@ public class GhidraCliBridge extends GhidraScript {
|
||||
listing.getCommentAddressIterator(addrSet, true);
|
||||
|
||||
while (addrIter.hasNext()) {
|
||||
if (limit > 0 && count >= limit) break;
|
||||
|
||||
Address addr = addrIter.next();
|
||||
CodeUnit cu = listing.getCodeUnitAt(addr);
|
||||
if (cu == null) continue;
|
||||
|
||||
for (int i = 0; i < commentNames.length; i++) {
|
||||
if (limit > 0 && count >= limit) break;
|
||||
|
||||
String text = cu.getComment(commentTypes[i][0]);
|
||||
if (text != null) {
|
||||
if (nameFilter != null && !text.toLowerCase().contains(nameFilter.toLowerCase())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
JsonObject commentObj = new JsonObject();
|
||||
commentObj.addProperty("address", addr.toString());
|
||||
commentObj.addProperty("type", commentNames[i]);
|
||||
commentObj.addProperty("text", text);
|
||||
comments.add(commentObj);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+8
-8
@@ -121,8 +121,8 @@ impl BridgeClient {
|
||||
}
|
||||
|
||||
/// List strings.
|
||||
pub fn list_strings(&self, limit: Option<usize>) -> Result<serde_json::Value> {
|
||||
self.send_command("list_strings", Some(json!({"limit": limit})))
|
||||
pub fn list_strings(&self, limit: Option<usize>, filter: Option<String>) -> Result<serde_json::Value> {
|
||||
self.send_command("list_strings", Some(json!({"limit": limit, "filter": filter})))
|
||||
}
|
||||
|
||||
/// List imports.
|
||||
@@ -184,8 +184,8 @@ impl BridgeClient {
|
||||
|
||||
// === Extended commands (symbols, types, comments, etc.) ===
|
||||
|
||||
pub fn symbol_list(&self, filter: Option<&str>) -> Result<serde_json::Value> {
|
||||
self.send_command("symbol_list", Some(json!({"filter": filter})))
|
||||
pub fn symbol_list(&self, limit: Option<usize>, filter: Option<&str>) -> Result<serde_json::Value> {
|
||||
self.send_command("symbol_list", Some(json!({"limit": limit, "filter": filter})))
|
||||
}
|
||||
|
||||
pub fn symbol_get(&self, name: &str) -> Result<serde_json::Value> {
|
||||
@@ -210,8 +210,8 @@ impl BridgeClient {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn type_list(&self, limit: Option<usize>) -> Result<serde_json::Value> {
|
||||
self.send_command("type_list", Some(json!({"limit": limit})))
|
||||
pub fn type_list(&self, limit: Option<usize>, filter: Option<&str>) -> Result<serde_json::Value> {
|
||||
self.send_command("type_list", Some(json!({"limit": limit, "filter": filter})))
|
||||
}
|
||||
|
||||
pub fn type_get(&self, name: &str) -> Result<serde_json::Value> {
|
||||
@@ -229,8 +229,8 @@ impl BridgeClient {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn comment_list(&self) -> Result<serde_json::Value> {
|
||||
self.send_command("comment_list", None)
|
||||
pub fn comment_list(&self, limit: Option<usize>, filter: Option<&str>) -> Result<serde_json::Value> {
|
||||
self.send_command("comment_list", Some(json!({"limit": limit, "filter": filter})))
|
||||
}
|
||||
|
||||
pub fn comment_get(&self, address: &str) -> Result<serde_json::Value> {
|
||||
|
||||
+9
-9
@@ -621,8 +621,8 @@ fn execute_via_bridge(
|
||||
}))
|
||||
}
|
||||
Commands::Query(args) => match args.data_type.as_str() {
|
||||
"functions" => client.list_functions(args.limit.or(default_limit), None),
|
||||
"strings" => client.list_strings(args.limit.or(default_limit)),
|
||||
"functions" => client.list_functions(args.limit.or(default_limit), args.filter.clone()),
|
||||
"strings" => client.list_strings(args.limit.or(default_limit), args.filter.clone()),
|
||||
"imports" => client.list_imports(),
|
||||
"exports" => client.list_exports(),
|
||||
"memory" => client.memory_map(),
|
||||
@@ -633,7 +633,7 @@ fn execute_via_bridge(
|
||||
use cli::FunctionCommands;
|
||||
match cmd {
|
||||
FunctionCommands::List(opts) => {
|
||||
client.list_functions(opts.limit.or(default_limit), None)
|
||||
client.list_functions(opts.limit.or(default_limit), opts.filter.clone())
|
||||
}
|
||||
FunctionCommands::Decompile(args) => client.decompile(args.target.clone()),
|
||||
FunctionCommands::Get(args) => {
|
||||
@@ -667,7 +667,7 @@ fn execute_via_bridge(
|
||||
Commands::Strings(cmd) => {
|
||||
use cli::StringsCommands;
|
||||
match cmd {
|
||||
StringsCommands::List(opts) => client.list_strings(opts.limit.or(default_limit)),
|
||||
StringsCommands::List(opts) => client.list_strings(opts.limit.or(default_limit), opts.filter.clone()),
|
||||
StringsCommands::Refs(args) => client.xrefs_to(args.string.clone()),
|
||||
}
|
||||
}
|
||||
@@ -703,9 +703,9 @@ fn execute_via_bridge(
|
||||
DumpCommands::Imports(_) => client.list_imports(),
|
||||
DumpCommands::Exports(_) => client.list_exports(),
|
||||
DumpCommands::Functions(opts) => {
|
||||
client.list_functions(opts.limit.or(default_limit), None)
|
||||
client.list_functions(opts.limit.or(default_limit), opts.filter.clone())
|
||||
}
|
||||
DumpCommands::Strings(opts) => client.list_strings(opts.limit.or(default_limit)),
|
||||
DumpCommands::Strings(opts) => client.list_strings(opts.limit.or(default_limit), opts.filter.clone()),
|
||||
}
|
||||
}
|
||||
Commands::Summary(_) => client.program_info(),
|
||||
@@ -744,7 +744,7 @@ fn execute_via_bridge(
|
||||
Commands::Symbol(cmd) => {
|
||||
use cli::SymbolCommands;
|
||||
match cmd {
|
||||
SymbolCommands::List(_) => client.symbol_list(None),
|
||||
SymbolCommands::List(opts) => client.symbol_list(opts.limit.or(default_limit), opts.filter.as_deref()),
|
||||
SymbolCommands::Get(args) => client.symbol_get(&args.name),
|
||||
SymbolCommands::Create(args) => client.symbol_create(&args.address, &args.name),
|
||||
SymbolCommands::Delete(args) => client.symbol_delete(&args.name),
|
||||
@@ -756,7 +756,7 @@ fn execute_via_bridge(
|
||||
Commands::Type(cmd) => {
|
||||
use cli::TypeCommands;
|
||||
match cmd {
|
||||
TypeCommands::List(opts) => client.type_list(opts.limit.or(default_limit)),
|
||||
TypeCommands::List(opts) => client.type_list(opts.limit.or(default_limit), opts.filter.as_deref()),
|
||||
TypeCommands::Get(args) => client.type_get(&args.name),
|
||||
TypeCommands::Create(args) => client.type_create(&args.definition),
|
||||
TypeCommands::Apply(args) => client.type_apply(&args.address, &args.type_name),
|
||||
@@ -765,7 +765,7 @@ fn execute_via_bridge(
|
||||
Commands::Comment(cmd) => {
|
||||
use cli::CommentCommands;
|
||||
match cmd {
|
||||
CommentCommands::List(_) => client.comment_list(),
|
||||
CommentCommands::List(opts) => client.comment_list(opts.limit.or(default_limit), opts.filter.as_deref()),
|
||||
CommentCommands::Get(args) => client.comment_get(&args.address),
|
||||
CommentCommands::Set(args) => {
|
||||
client.comment_set(&args.address, &args.text, args.comment_type.as_deref())
|
||||
|
||||
Reference in New Issue
Block a user