1

I have a following c code (from a benchmark):

int main(int argc, char *argv[])
{
  static   char buf[10] = "";


  /*  OK  */
  buf[9] = 'A';


  return 0;
}

I am using ghidra api to get some information out of the binary (precompiled using flag -g). I want to get the variables defined in the function (or globally).

function.getStackFrame().getStackVariables()

gives me variables defined within the function, but it doesn't detect buf, as it is defined as static. From ghidra gui I was able to see that the variables is defined in the "main" under namespaces.

Is there way to get these type of variables (or global variables in general)?

Seki
  • 11,135
  • 7
  • 46
  • 70
R4444
  • 2,016
  • 2
  • 19
  • 30

1 Answers1

2

If you compile with gcc, a static variable defined within a function (e.g., the variable buf, in your case) is represented as a global variable that starts with the same name and ends with a compiler-assigned numeric suffix. Such a variable will be assigned within Ghidra to the "global" namespace, rather than the function's namespace.

In Ghidra, each default global variable name ends with the variable's address. Each default local variable name starts with "local_" and ends with the variable's stack offset.

I've only used the Java API. But the Ghidra class hierarchy should be the same, regardless of whether you use Java or Python. Here is an example Java script that will list all non-default global and local variables in the current program:

// 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);
            }
         }
      }
   }
}

The script writes its output to the Ghidra console window. Double-clicking a function or variable name in the Ghidra console window will jump the listing to the corresponding function/variable.

j-ratz
  • 21
  • 2