1

Basically I'm extending the CreateStructure.java plugin so it iterates all functions and tries to automatically create structures on all variables.

It looks something like this:

public class CreateStructure extends GhidraScript {

    @Override
    public void run() throws Exception {
        FunctionIterator funcs = currentProgram.getFunctionManager().getFunctions(true);
        DecompInterface decomp = setUpDecompiler(currentProgram);
        for (Function fn : funcs) {
            Variable[] allvars = fn.getAllVariables();
            for(Variable var : allvars) {
                /*DecompileResults res = decomp.decompileFunction(fn, 10000, monitor);
                ClangNode nodres = null;
                ClangTokenGroup ccode = res.getCCodeMarkup();
                println("Decompiled " + fn.getName());
                ClangToken tokeres = new ClangToken((ClangNode) var.getVariableStorage().getFirstVarnode());
                */
                //DecompilerLocation loc = new DecompilerLocation(currentProgram, var.getFirstStorageVarnode().getAddress(), fn.getEntryPoint(), res, tokeres,0,0);
                setCurrentLocation(var.getMinAddress());
                FillOutStructureCmd fillCmd =
                        new FillOutStructureCmd(currentProgram, currentLocation, state.getTool());
                fillCmd.applyTo(currentProgram, this.monitor);
            }
        }
    }
    
    private DecompInterface setUpDecompiler(Program program) {
        DecompInterface decompInterface = new DecompInterface();

        // call it to get results
        if (!decompInterface.openProgram(currentProgram)) {
            println("Decompile Error: " + decompInterface.getLastMessage());
            return null;
        }

        DecompileOptions options;
        options = new DecompileOptions();
        OptionsService service = state.getTool().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;
    }
}

But it only iterates through the functions variables without creating structures - unlike when I position my cursor on a parameter and execute there.

What am I missing?

(You can also see my attempt to retrieve the DecompilerLocation which also doesn't work)

1 Answer 1

1

I figure it out something like this does it:

public class CreateStructure extends GhidraScript {

    @Override
    public void run() throws Exception {
        /*println("" + currentLocation.toString());
        FillOutStructureCmd fillCmd =
                new FillOutStructureCmd(currentProgram, currentLocation, state.getTool());
        fillCmd.applyTo(currentProgram, this.monitor);*/
        FunctionIterator funcs = currentProgram.getFunctionManager().getFunctions(true);
        DecompInterface decomp = setUpDecompiler(currentProgram);
        for (Function fn : funcs) {
            Variable[] allvars = fn.getAllVariables();
            for(Variable var : allvars) {
                /*DecompileResults res = decomp.decompileFunction(fn, 10000, monitor);
                ClangNode nodres = null;
                ClangTokenGroup ccode = res.getCCodeMarkup();
                println("Decompiled " + fn.getName());
                ClangToken tokeres = new ClangToken((ClangNode) var.getVariableStorage().getFirstVarnode());
                */
                DataType dattyp = var.getDataType();
                String datatypstring = dattyp.getDisplayName();
                println(datatypstring = datatypstring.replaceAll("\\[|\\]|\\*|\\s", ""));
                DecompileResults res = decomp.decompileFunction(fn, 10000, monitor);
                
                ClangTokenGroup tokengrp = res.getCCodeMarkup();
                
                if(tokengrp == null) continue;
                
                ClangToken tokeres = null;
                
                println("searching for " + datatypstring);
                
                mainloop:
                for(ClangNode  token : tokengrp) {
                    if(token instanceof ClangFuncProto) {
                        for(ClangNode  outter : ((ClangFuncProto)token)) {
                            if(outter instanceof ClangVariableDecl)
                            for(ClangNode inner2 : ((ClangVariableDecl)outter)) {
                                if(inner2 instanceof ClangToken) {
                                    if(((ClangToken)inner2).getText().equals(datatypstring)) {
                                        tokeres = (ClangToken)inner2;
                                        println(inner2.getClass().toString());
                                        break mainloop;
                                    }
                                    else {
                                        println("" + ((ClangToken)inner2).getText());
                                    }
                                }
                                else {
                                    println(inner2.getClass().toString());
                                }
                            }
                    }
                }
                }
                if(tokeres == null) continue;
                println("found");
                
                //ClangToken tokeres = new ClangToken(null, datatypstring);
                DecompilerLocation loc = new DecompilerLocation(currentProgram, fn.getEntryPoint(), fn.getEntryPoint(), res, tokeres,1,1);
                println("" + loc);
                FillOutStructureCmd fillCmd =
                        new FillOutStructureCmd(currentProgram, loc, state.getTool());
                fillCmd.applyTo(currentProgram, this.monitor);
            }
        }
    }
    
    private DecompInterface setUpDecompiler(Program program) {
        DecompInterface decompInterface = new DecompInterface();

        // call it to get results
        if (!decompInterface.openProgram(currentProgram)) {
            println("Decompile Error: " + decompInterface.getLastMessage());
            return null;
        }

        DecompileOptions options;
        options = new DecompileOptions();
        OptionsService service = state.getTool().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;
    }
}

Now I only need to seed out the non structure types because currently it's creating structure for everything.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.