我有一个下面的c代码(来自基准):
int main(int argc, char *argv[])
{
static char buf[10] = "";
/* OK */
buf[9] = 'A';
return 0;
}
我正在使用ghidra api从二进制文件中获取一些信息(使用标志-g
预编译)。我想获取在函数中定义的变量(或全局定义)。
function.getStackFrame().getStackVariables()
为我提供了在函数中定义的变量,但由于它定义为buf
,因此它无法检测到static
。从ghidra gui中,我可以看到变量是在名称空间下的“ main”中定义的。
有没有办法获得这些类型的变量(或一般来说是全局变量)?
如果使用gcc
进行编译,则在函数内定义的静态变量(例如,在您的情况下为变量buf
)表示为以相同名称开头并以编译器分配的数字结尾的全局变量后缀。这样的变量将在Ghidra中分配给“全局”名称空间,而不是函数的名称空间。
在Ghidra中,每个默认全局变量名称都以变量的地址结尾。每个默认的本地变量名称都以“ local_”开头,并以变量的堆栈偏移量结束。
我只使用过Java API。但是无论您使用Java还是Python,Ghidra类的层次结构都应该相同。这是一个Java脚本示例,它将列出当前程序中的所有非默认全局变量和局部变量:
// Lists non-default global and local variables in the current program.
//@category Example
import ghidra.app.script.GhidraScript;
import ghidra.program.database.ProgramDB;
import ghidra.program.database.symbol.NamespaceManager;
import ghidra.program.database.symbol.SymbolManager;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Variable;
import ghidra.program.model.symbol.Symbol;
import ghidra.program.model.symbol.SymbolType;
public class ListVariables extends GhidraScript {
@Override
public void run() throws Exception {
// List globals
SymbolManager smgr = (SymbolManager)currentProgram.getSymbolTable();
NamespaceManager nmgr =
((ProgramDB)currentProgram).getNamespaceManager();
for (Symbol sym : smgr.getSymbols(nmgr.getGlobalNamespace())) {
if (monitor.isCancelled()) return;
if (sym.getSymbolType() == SymbolType.LABEL) {
String sname = sym.getName();
if (!sname.endsWith(sym.getAddress().toString())) {
printf("global : %s\n", sname);
}
}
}
//List local variables
for (Function func :
currentProgram.getFunctionManager().getFunctions(true)) {
for (Variable var : func.getLocalVariables()) {
if (monitor.isCancelled()) return;
String vname = var.getName();
if (!vname.startsWith("local_")) {
printf("%s : %s\n", func.getName(), vname);
}
}
}
}
}
该脚本将其输出写入Ghidra控制台窗口。双击Ghidra控制台窗口中的函数或变量名称,列表将跳转到相应的函数/变量。