NationalSecurityAgency / ghidra

Ghidra is a software reverse engineering (SRE) framework
https://www.nsa.gov/ghidra
Apache License 2.0
50.61k stars 5.78k forks source link

Renamed decompiler function parameter doesn't show with ghidra_script #3685

Open 6r0k3d opened 2 years ago

6r0k3d commented 2 years ago

Is there a way to see a renamed parameter from decompiler view in a ghidra script?

In the decompiler window, when I edit the function signature, the renamed parameter shows throughout the rest of the function. For example, editing the function sig results in the function calls using the new variable name:

uint IOCTL_Handler(longlong param_1,PIRP pIRP){
...
uVar6 = FUN_140001788(unknown,(longlong)pIRP);
...
uVar5 = FUN_140002a14(param_1,(longlong)pIRP,(longlong)CurrentStackLocation);
}

When I try and check for the new name via ghidra_script though, the name doesn't show:

Script:

public class helloGhidra extends GhidraScript {
    @Override
    public void run() throws Exception {
        Address addr = currentAddress;
        Function fn = getFunctionContaining(addr);
        Set callees = fn.getCalledFunctions(null);
        Iterator itr = callees.iterator();
        while (itr.hasNext()) {
            Function temp = (Function) itr.next();
            Parameter[] params = temp.getParameters();
            println(String.valueOf(temp) + " " + Arrays.toString(params));
        }
}

Output:

FUN_140001788 [[undefined8 param_1@RCX:8], [longlong param_2@RDX:8]]
FUN_140002a14 [[longlong param_1@RCX:8], [longlong param_2@RDX:8], [longlong param_3@R8:8]]

I'm expecting param_2@RDX:8 to show as pIRP@RDX:8. I've tried Commit Params/Return and Commit Local Names, and running my script after either option still doesn't output what I'm expecting.

Wall-AF commented 2 years ago

Here's what I used to output my function definitions:

    private static String getDescription(Function f) {
        StringBuilder s = new StringBuilder();
        String szSep = " (";
        s.append(f.getReturnType().getName()).append(' ').append(f.getName());
        for (int i = 0; i < f.getParameters().length; i++) {
            Parameter p = f.getParameter(i);
            s.append(szSep).append(p.getFormalDataType().getName()).append(' ').append(p.getName());
            //s.append("[").append(p.getLastStorageVarnode().toString()).append("]");
            szSep = ", ";
        }
        s.append(')');
        return s.toString();
    }

The commented line adds the storage (if you need that).

Hope this helps.

If you require the calling convention, add something like .append(' ').append(f.getCallingConventionName() in the appropriate place.

6r0k3d commented 2 years ago

Oh thats neat! Having the same issue though, getParameters doesn't return the same thing as what's shown in the decompiler window. I know pictures are frowned on, but I figure the text in the original question is searchable enough. I'm expecting the results of getParameters to return the same as whats shown in the decompiler / listing windows, and it doesnt.

image

Wall-AF commented 2 years ago

My code example only takes the parameter names that have been specified in the function definitions. What you're showing in your image is the names you've updated in the calling function. Sorry, my code doesn't go that far!!!

6r0k3d commented 2 years ago

When I change the calling function signature in the decompiler window, the updated variable name propagates out everywhere its used. But when I call getParams, it just says param_2. Clearly the decompiler window is able to show the updated variable names. What do I have to do to have the updated names made available in the script? I've tried Commit Params and Commit Locals in the decompiler and listing views, and neither have helped.

ghidra1 commented 2 years ago

@6r0k3d When you assign a variable/parameter name within a function it is not pushed or propagated to other functions. Your script is looking at the sub-function declaration which is completely independent of any naming at it point of use. The callee has its own naming of variables which may be passed - just like in normal source code.

6r0k3d commented 2 years ago

Interesting. What I'm finding confusing is the decompiler view shows the renamed variable being sent to the called functions. Is there a way to programmatically access what's being show in the decompiler view from a ghidra script? I figured if its in the display window, there must be some way to access what it's showing, I just don't know how

ghidra1 commented 2 years ago

I suspect so, although it may be quite complicated. I would examine some of the GUI action implementation code to see how to navigate tokens and such within the decompiler results (e.g., ForwardSliceAction.java) which make use of the DecompilerUtils.