有没有办法从命令行运行 ghidra?
GUI界面很重。
我想要的只是获取函数列表并在 c 中反编译它们。
谢谢
有没有办法从命令行运行 ghidra?
GUI界面很重。
我想要的只是获取函数列表并在 c 中反编译它们。
谢谢
在这里检查我的答案。
您所要做的就是使用./analyzeHeadless
ghidra 附带的脚本:
./analyzeHeadless ghidra-project-directory -import binary-file -postscript yourpythonscript
您可以使用java
或python 2.7
。你可以在这里查看 ghidra api 。
您可以通过以下方式编写脚本(在 python 中):
from ghidra.app.decompiler import DecompInterface
from ghidra.util.task import ConsoleTaskMonitor
# get the current program
# here currentProgram is predefined
program = currentProgram
decompinterface = DecompInterface()
decompinterface.openProgram(program);
functions = program.getFunctionManager().getFunctions(True)
for function in list(functions):
print(function)
# decompile each function
tokengrp = decompinterface.decompileFunction(function, 0, ConsoleTaskMonitor())
print(tokengrp.getDecompiledFunction().getC())
Ghidra 反编译器被集成到radare2 中,它是一个命令行反汇编器(除其他外)。
您需要安装r2ghidra-dec软件包。然后,您可以使用该afl
命令打印函数列表,并使用该pdg
命令显示 Ghidra 对给定函数的反编译输出。
例如:
[0x080484d0]> afl
0x080484d0 1 50 entry0
0x08048503 1 4 fcn.08048503
0x08048480 1 6 sym.imp.__libc_start_main
0x08048530 4 50 -> 41 sym.deregister_tm_clones
0x08048570 4 58 -> 54 sym.register_tm_clones
0x080485b0 3 34 -> 31 entry.fini0
0x080485e0 1 6 entry.init0
0x08048780 1 2 sym.__libc_csu_fini
0x08048520 1 4 sym.__x86.get_pc_thunk.bx
0x0804865f 1 63 sym.vuln
0x08048430 1 6 sym.imp.gets
0x08048714 1 4 loc.get_return_address
0x08048420 1 6 sym.imp.printf
0x08048784 1 20 sym._fini
0x08048720 4 93 sym.__libc_csu_init
0x08048510 1 2 sym._dl_relocate_static_pie
0x0804869e 1 118 main
0x08048490 1 6 sym.imp.setvbuf
0x08048450 1 6 sym.imp.getegid
0x080484b0 1 6 sym.imp.setresgid
0x08048460 1 6 sym.imp.puts
0x080485e6 3 121 sym.flag
0x080484a0 1 6 sym.imp.fopen
0x08048470 1 6 sym.imp.exit
0x08048440 1 6 sym.imp.fgets
0x080483e8 3 35 sym._init
[0x080484d0]> pdg @ sym.vuln
// WARNING: Variable defined which should be unmapped: var_4h
// WARNING: [r2ghidra] Removing arg arg_4h because it doesn't fit into ProtoModel
void sym.vuln(void)
{
undefined4 uVar1;
int32_t unaff_EBX;
char *s;
int32_t var_4h;
sym.__x86.get_pc_thunk.bx();
sym.imp.gets(&s);
uVar1 = loc.get_return_address();
sym.imp.printf(unaff_EBX + 0x19c, uVar1);
return;
}
一种方法是使用Ghidra的CppExporter扩展Java类中类GhidraScript类。Ghidra 的源代码包含一些示例代码,可以在以下链接中找到:反编译器示例。我拿了其中一个并对代码进行了一些改进。
必须将下面的代码复制到一个名为Decompile.java的文件中, 然后,您必须运行 Ghidra 的analyzeHeadless二进制工具。
<ghidra_root>/support/analyzeHeadless <ghidra_project_dir> <project_name> \
-import <path_to_binary> -postscript <your_path>/Decompile.java <out_C_file_path>
命令示例:
./analyzeHeadless MyProjDir MyProj -import libX.so -postscript Decompile.java libX_dec.c
注意:如果项目目录不存在,您可能需要创建它。
反编译.java示例:
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import ghidra.app.plugin.core.script.Ingredient;
import ghidra.app.plugin.core.script.IngredientDescription;
import ghidra.app.script.GatherParamPanel;
import ghidra.app.script.GhidraScript;
import ghidra.app.util.Option;
import ghidra.app.util.OptionException;
import ghidra.app.util.exporter.CppExporter;
import ghidra.app.util.exporter.ExporterException;
public class Decompile extends GhidraScript implements Ingredient {
private static Logger log;
public Decompile() {
log = LogManager.getLogger(Decompile.class);
}
public void export(String filename) {
File outputFile = new File(filename);
CppExporter cppExporter = new CppExporter();
cppExporter.setExporterServiceProvider(state.getTool());
List<Option> options = new ArrayList<Option>();
Option cppExportHeaderOption =
new Option(CppExporter.CREATE_HEADER_FILE, new Boolean(false));
options.add(cppExportOption);
try {
cppExporter.setOptions(options);
} catch (OptionException e) {
log.error("Unable to set cppExporter options", e);
return;
}
try {
cppExporter.export(outputFile, currentProgram, null, monitor);
} catch (IOException e) {
log.error("Failed writing decompiled code as output", e);
} catch (ExporterException e) {
log.error("Failed to export with cppExporter", e);
}
}
@Override
public void run() throws Exception {
IngredientDescription[] ingredients = getIngredientDescriptions();
for (IngredientDescription ingredient : ingredients) {
state.addParameter(ingredient.getID(), ingredient.getLabel(),
ingredient.getType(), ingredient.getDefaultValue());
}
String[] args = getScriptArgs();
export(args[0]);
}
@Override
public IngredientDescription[] getIngredientDescriptions() {
IngredientDescription[] retVal = new IngredientDescription[] {
new IngredientDescription(
"COutputFile", "Output C File", GatherParamPanel.FILE, "")};
return retVal;
}
}
我编写了这个脚本,它接收一个二进制文件并将 C 源代码输出到一个文件中。只需要稍微修改 ghidra 的 Ghidra/Features/Decompiler/ghidra_scripts/Decompile.java 脚本。