接上一篇博客。这也是个很基础的需求,只不过我想简单记录一下:
下面以一个简单的C函数为例,假设我们想获得这个函数的low level和high level IR:
#include <stdio.h>
#include <stdlib.h>
int a=0;
char *p1;
void main(void)
{
int b;
char s[]="abc";
char *p2;
static int c=0;
p1=(char *)malloc(10);
p2=(char *)malloc(20);
printf("Global test!\n");
}
那应该怎么做呢,下面直接给出代码:
import java.util.Iterator;
import ghidra.app.decompiler.DecompInterface;
import ghidra.app.decompiler.DecompileOptions;
import ghidra.app.decompiler.DecompileResults;
import ghidra.app.script.GhidraScript;
import ghidra.framework.options.ToolOptions;
import ghidra.framework.plugintool.PluginTool;
import ghidra.framework.plugintool.util.OptionsService;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.FunctionIterator;
import ghidra.program.model.listing.Instruction;
import ghidra.program.model.listing.InstructionIterator;
import ghidra.program.model.listing.Program;
import ghidra.program.model.pcode.HighFunction;
import ghidra.program.model.pcode.PcodeOp;
import ghidra.program.model.pcode.PcodeOpAST;
public class PrintFuncIns extends GhidraScript {
private DecompInterface decomplib;
public void run() throws Exception {
decomplib = setUpDecompiler(currentProgram);
if (!decomplib.openProgram(currentProgram)) {
printf("Decompiler error: %s\n", decomplib.getLastMessage());
return;
}
FunctionIterator functionManager = this.currentProgram.getFunctionManager().getFunctions(true);
for (Function function : functionManager) {
if(function.getName().equals("main")) {
System.out.println("##########################################################");
InstructionIterator iter = currentProgram.getListing().getInstructions(function.getBody(), true);
for(Instruction ins : iter) {
System.out.println(ins.getMnemonicString());
int numOperands=ins.getNumOperands();
PcodeOp[] rawPcode = ins.getPcode();
for (PcodeOp pcodeOp : rawPcode) {
System.out.println(pcodeOp.toString());
}
}
System.out.println("##########################################################");
HighFunction hfunction = decompileFunction(function);
Iterator<PcodeOpAST> opIter=hfunction.getPcodeOps();
while (opIter.hasNext()) {
PcodeOpAST pcodeOp = opIter.next();
System.out.println(pcodeOp.toString());
}
System.out.println("##########################################################");
}
}
}
public HighFunction decompileFunction(Function f) {
HighFunction hfunction = null;
try {
DecompileResults dRes = decomplib.decompileFunction(f, decomplib.getOptions().getDefaultTimeout(),
getMonitor());
hfunction = dRes.getHighFunction();
} catch (Exception exc) {
printf("EXCEPTION IN DECOMPILATION!\n");
exc.printStackTrace();
}
return hfunction;
}
/*
* set up the decompiler
*/
private DecompInterface setUpDecompiler(Program program) {
DecompInterface decompInterface = new DecompInterface();
DecompileOptions options;
options = new DecompileOptions();
PluginTool tool = state.getTool();
if (tool != null) {
OptionsService service = tool.getService(OptionsService.class);
if (service != null) {
ToolOptions opt = service.getOptions("Decompiler");
options.grabFromToolAndProgram(null, opt, program);
}
}
decompInterface.setOptions(options);
decompInterface.toggleCCode(true);
decompInterface.toggleSyntaxTree(true);
decompInterface.setSimplificationStyle("decompile");
return decompInterface;
}
}
其实流程是很简单的,简单来说,low level IR就是汇编指令的直接翻译,而high level IR是decompiler处理之后的结果,具体可以参考这里:
得到的结果我这里也贴一下,相信大家一看就明白:
##########################################################
PUSH
(unique, 0xe780, 8) COPY (register, 0x28, 8)
(register, 0x20, 8) INT_SUB (register, 0x20, 8) , (const, 0x8, 8)
--- STORE (const, 0x1b1, 8) , (register, 0x20, 8) , (unique, 0xe780, 8)
MOV
(register, 0x28, 8) COPY (register, 0x20, 8)
SUB
(register, 0x200, 1) INT_LESS (register, 0x20, 8) , (const, 0x20, 8)
(register, 0x20b, 1) INT_SBORROW (register, 0x20, 8) , (const, 0x20, 8)
(register, 0x20, 8) INT_SUB (register, 0x20, 8) , (const, 0x20, 8)
(register, 0x207, 1) INT_SLESS (register, 0x20, 8) , (const, 0x0, 8)
(register, 0x206, 1) INT_EQUAL (register, 0x20, 8) , (const, 0x0, 8)
(unique, 0x12c00, 8) INT_AND (register, 0x20, 8) , (const, 0xff, 8)
(unique, 0x12c80, 1) POPCOUNT (unique, 0x12c00, 8)
(unique, 0x12d00, 1) INT_AND (unique, 0x12c80, 1) , (const, 0x1, 1)
(register, 0x202, 1) INT_EQUAL (unique, 0x12d00, 1) , (const, 0x0, 1)
MOV
(unique, 0x4f00, 8) INT_ADD (register, 0x110, 8) , (const, 0x28, 8)
(unique, 0xbd80, 8) LOAD (const, 0x1b1, 4) , (unique, 0x4f00, 8)
(register, 0x0, 8) COPY (unique, 0xbd80, 8)
MOV
(unique, 0x3100, 8) INT_ADD (register, 0x28, 8) , (const, 0xfffffffffffffff8, 8)
(unique, 0xbd80, 8) COPY (register, 0x0, 8)
--- STORE (const, 0x1b1, 4) , (unique, 0x3100, 8) , (unique, 0xbd80, 8)
XOR
(register, 0x200, 1) COPY (const, 0x0, 1)
(register, 0x20b, 1) COPY (const, 0x0, 1)
(register, 0x0, 4) INT_XOR (register, 0x0, 4) , (register, 0x0, 4)
(register, 0x0, 8) INT_ZEXT (register, 0x0, 4)
(register, 0x207, 1) INT_SLESS (register, 0x0, 4) , (const, 0x0, 4)
(register, 0x206, 1) INT_EQUAL (register, 0x0, 4) , (const, 0x0, 4)
(unique, 0x12c00, 4) INT_AND (register, 0x0, 4) , (const, 0xff, 4)
(unique, 0x12c80, 1) POPCOUNT (unique, 0x12c00, 4)
(unique, 0x12d00, 1) INT_AND (unique, 0x12c80, 1) , (const, 0x1, 1)
(register, 0x202, 1) INT_EQUAL (unique, 0x12d00, 1) , (const, 0x0, 1)
MOV
(unique, 0x3100, 8) INT_ADD (register, 0x28, 8) , (const, 0xfffffffffffffff4, 8)
(unique, 0xbd00, 4) COPY (const, 0x636261, 4)
--- STORE (const, 0x1b1, 4) , (unique, 0x3100, 8) , (unique, 0xbd00, 4)
MOV
(register, 0x38, 8) COPY (const, 0xa, 8)
CALL
(register, 0x20, 8) INT_SUB (register, 0x20, 8) , (const, 0x8, 8)
--- STORE (const, 0x1b1, 8) , (register, 0x20, 8) , (const, 0x1011a2, 8)
--- CALL (ram, 0x101050, 8)
MOV
(ram, 0x104020, 8) COPY (register, 0x0, 8)
MOV
(register, 0x38, 8) COPY (const, 0x14, 8)
CALL
(register, 0x20, 8) INT_SUB (register, 0x20, 8) , (const, 0x8, 8)
--- STORE (const, 0x1b1, 8) , (register, 0x20, 8) , (const, 0x1011b3, 8)
--- CALL (ram, 0x101050, 8)
MOV
(unique, 0x3100, 8) INT_ADD (register, 0x28, 8) , (const, 0xffffffffffffffe8, 8)
(unique, 0xbd80, 8) COPY (register, 0x0, 8)
--- STORE (const, 0x1b1, 4) , (unique, 0x3100, 8) , (unique, 0xbd80, 8)
LEA
(register, 0x38, 8) COPY (const, 0x102004, 8)
CALL
(register, 0x20, 8) INT_SUB (register, 0x20, 8) , (const, 0x8, 8)
--- STORE (const, 0x1b1, 8) , (register, 0x20, 8) , (const, 0x1011c3, 8)
--- CALL (ram, 0x101030, 8)
NOP
MOV
(unique, 0x3100, 8) INT_ADD (register, 0x28, 8) , (const, 0xfffffffffffffff8, 8)
(unique, 0xbd80, 8) LOAD (const, 0x1b1, 4) , (unique, 0x3100, 8)
(register, 0x0, 8) COPY (unique, 0xbd80, 8)
XOR
(unique, 0x4f00, 8) INT_ADD (register, 0x110, 8) , (const, 0x28, 8)
(register, 0x200, 1) COPY (const, 0x0, 1)
(register, 0x20b, 1) COPY (const, 0x0, 1)
(unique, 0xbd80, 8) LOAD (const, 0x1b1, 4) , (unique, 0x4f00, 8)
(register, 0x0, 8) INT_XOR (register, 0x0, 8) , (unique, 0xbd80, 8)
(register, 0x207, 1) INT_SLESS (register, 0x0, 8) , (const, 0x0, 8)
(register, 0x206, 1) INT_EQUAL (register, 0x0, 8) , (const, 0x0, 8)
(unique, 0x12c00, 8) INT_AND (register, 0x0, 8) , (const, 0xff, 8)
(unique, 0x12c80, 1) POPCOUNT (unique, 0x12c00, 8)
(unique, 0x12d00, 1) INT_AND (unique, 0x12c80, 1) , (const, 0x1, 1)
(register, 0x202, 1) INT_EQUAL (unique, 0x12d00, 1) , (const, 0x0, 1)
JZ
--- CBRANCH (ram, 0x1011d8, 8) , (register, 0x206, 1)
CALL
(register, 0x20, 8) INT_SUB (register, 0x20, 8) , (const, 0x8, 8)
--- STORE (const, 0x1b1, 8) , (register, 0x20, 8) , (const, 0x1011d8, 8)
--- CALL (ram, 0x101040, 8)
LEAVE
(register, 0x20, 8) COPY (register, 0x28, 8)
(register, 0x28, 8) LOAD (const, 0x1b1, 8) , (register, 0x20, 8)
(register, 0x20, 8) INT_ADD (register, 0x20, 8) , (const, 0x8, 8)
RET
(register, 0x288, 8) LOAD (const, 0x1b1, 8) , (register, 0x20, 8)
(register, 0x20, 8) INT_ADD (register, 0x20, 8) , (const, 0x8, 8)
--- RETURN (register, 0x288, 8)
##########################################################
(unique, 0x1000005d, 8) INT_ADD (register, 0x110, 8) , (const, 0x28, 8)
(unique, 0xbd80, 8) LOAD (const, 0x1b1, 4) , (unique, 0x4f00, 8)
(unique, 0x4f00, 8) CAST (unique, 0x1000005d, 8)
(unique, 0x10000065, 8) CALL (ram, 0x101050, 8) , (const, 0xa, 8)
(register, 0x110, 8) INDIRECT (register, 0x110, 8) , (const, 0x23, 4)
(ram, 0x104020, 8) INDIRECT (ram, 0x104020, 8) , (const, 0x23, 4)
(register, 0x0, 8) CAST (unique, 0x10000065, 8)
--- CALL (ram, 0x101050, 8) , (const, 0x14, 8)
(register, 0x110, 8) INDIRECT (register, 0x110, 8) , (const, 0x28, 4)
(ram, 0x104020, 8) INDIRECT (register, 0x0, 8) , (const, 0x28, 4)
--- CALL (ram, 0x101030, 8) , (unique, 0x10000055, 8)
(register, 0x110, 8) INDIRECT (register, 0x110, 8) , (const, 0x2f, 4)
(ram, 0x104020, 8) INDIRECT (ram, 0x104020, 8) , (const, 0x2f, 4)
(unique, 0x10000055, 8) COPY (const, 0x102004, 8)
(unique, 0x1000006d, 8) INT_ADD (register, 0x110, 8) , (const, 0x28, 8)
(unique, 0xbd80, 8) LOAD (const, 0x1b1, 4) , (unique, 0x4f00, 8)
(register, 0x206, 1) INT_NOTEQUAL (unique, 0xbd80, 8) , (unique, 0xbd80, 8)
(unique, 0x4f00, 8) CAST (unique, 0x1000006d, 8)
--- CBRANCH (ram, 0x1011d8, 1) , (register, 0x206, 1)
--- CALL (ram, 0x101040, 8)
--- RETURN (const, 0x1, 4)
(ram, 0x104020, 8) INDIRECT (ram, 0x104020, 8) , (const, 0x41, 4)
(ram, 0x104020, 8) COPY (ram, 0x104020, 8)
--- RETURN (const, 0x0, 8)
(ram, 0x104020, 8) COPY (ram, 0x104020, 8)
##########################################################