dod-cyber-crime-center / pyhidra

Pyhidra is a Python library that provides direct access to the Ghidra API within a native CPython interpreter using jpype.
Other
182 stars 16 forks source link

Question: scripting with multiple files #16

Closed lautalom closed 2 years ago

lautalom commented 2 years ago

I ran into difficulties scripting with multiple files. The main script can get the currentProgram object, as per the test examples, but that main script depends on other scripts that also need the currentProgram object and cannot get it from an if __name__ == __main__: clause.

To clarify, let me give an example. Supose in file A.py (main script) I go

if __name__ == '__main__':
    import B
    print(B.maxaddr()) #prints oops

And file B.py looks like

def maxaddr():
    if __name__ == '__main__':
        return currentProgram.maxAddress
    else:
        print("oops")

how should I go about it?

something I should point out is that return currentProgram.maxAddress without an if clause causes A to fail with an Exception: "currentProgram is not defined"

dc3-tsd commented 2 years ago

The if __name__ == "__main__": is a common technique in Python to determine if the current module is the first module that started execution. It is used to ensure the below code isn't executed unless executed explicitly instead of being imported. All imported modules will have their __name__ equal to the name of the module itself, which would explain why you are getting the "oops" printout instead.

That said, variables like currentProgram are only available in the local namespace of the first module. Therefore you will have to pass them along in function arguments to be used in other imported modules.

You may also pass __this__ as a function argument which provides access to the underlying GhidraScript instance.

Let us know if we didn't answer your question. If we don't hear back we will close this issue in two days.

lautalom commented 2 years ago

Great answer, thanks! I have a restriction that passing parameters is not an option for the particular problem I am working on, that's why I hoped there was a workaround without passing parameters, but I understand it is what it is. Thanks again!