NationalSecurityAgency / ghidra

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

FlatProgramAPI.createFunction doesn't support namespace #6840

Open mumbel opened 1 month ago

mumbel commented 1 month ago

Describe the bug Would expect createFunction to document global only namespace like other things in FlatProgramAPI, or support NAMESPACE_DELIMITER names.

To Reproduce Steps to reproduce the behavior:

  1. goto a code w/o a function defined (this is my case at least)
  2. createFunction(toAddr(0xdeadbeef), "thing::foo")
  3. function is created but with the name "thing::foo", not function "foo" in namespace "thing"
  4. using GUI, changing the label (press l and immediately press enter it converts to namespaced function)

Expected behavior be able to script creating functions in namespaces

Environment (please complete the following information): Ghidra Version: 11.1.2 Ghidra Release: PUBLIC Ghidra Build Date: 2024-Jul-09 1157 EDT Ghidra Revision: 68cad06ddfae2b92c03054357c67c32f2d0553a8 Ghidra Development Mode: false OS Name: Linux OS Arch: amd64 OS Version: 6.8.0-40-generic OS Pretty Name: Ubuntu 22.04.4 LTS Java Vendor: Ubuntu Java Version: 21.0.4

mumbel commented 1 month ago

did i miss something, is there a more straight forward approach?

name = "thing::foo"
addr = toAddr(0xdeadbeef)

st = currentProgram.getSymbolTable()
st.createLabel(toAddr(addr),
    name.split("::")[1],
    st.getOrCreateNameSpace(currentProgram.getGlobalNamespace(),
        name.split("::")[0],
        SourceType.USER_DEFINED),
    SourceType.USER_DEFINED)
createFunction(addr, None)    
dragonmacher commented 1 month ago

This seems unintuitive to me. Poking around, our internal APIs to seem to be symbol oriented. Creating a function seems to really be unrelated to how the symbol is named and parented. As an example, the demangler will create the function first. Then, it will manipulate the symbol, creating the namespace as needed. Last, it will make that new symbol primary.

This feels like a convoluted flow. I suppose the CreateFunctionCmd could be smart enough to do all of this for the client. My feeling is that we typically are creating default functions that will later get renamed by the user or some other API, which may explain how we ended up here.

I think we could update that script method to handle parsing and applying the namespace.

Nemoumbra commented 3 weeks ago

@dragonmacher Do you intend to make sure the createFunction automatically creates the new namespaces and applies them to the function or to introduce an option for the user to enable this behavior? I've recently made a script that renames a few functions in the program and it just so happened that some of them were in the form namespace_name::func_name. I'm very happy the functions ended up in the global namespace with the name equal to the whole string, because the namespaces are not displayed in the Function View.

dragonmacher commented 3 weeks ago

We haven't yet discussed the best way to fix this.

Regarding the 'Functions View', if you are referring to the Functions table, then you should be able to add a Namespace column to the table.