Гидра: как получить статические переменные, используя Python API Гидра?

У меня есть следующий код 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, Из GUID гидратов я смог увидеть, что переменные определены в "main" в пространствах имен.

Есть ли способ получить эти типы переменных (или глобальные переменные в целом)?

0 ответов

Если вы компилируете с gcc, статическая переменная, определенная в функции (например, переменная buf, в вашем случае) представлена ​​как глобальная переменная, которая начинается с того же имени и заканчивается присвоенным компилятором числовым суффиксом. Такая переменная будет назначена в Ghidra "глобальному" пространству имен, а не пространству имен функции.

В Ghidra каждое имя глобальной переменной по умолчанию заканчивается адресом переменной. Каждое имя локальной переменной по умолчанию начинается с "local_" и заканчивается смещением стека переменной.

Я использовал только Java API. Но иерархия классов Ghidra должна быть одинаковой, независимо от того, используете ли вы Java или Python. Вот пример сценария 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 переместит листинг к соответствующей функции / переменной.

Другие вопросы по тегам