Closed pieceofsummer closed 2 years ago
Thank you for the report @pieceofsummer ! We will do some digging here to see if we can pinpoint the issue, or upstream if Jep-specific. In the meantime, the following workaround should resolve the exception:
isinstance(dt, type(FunctionDefinitionDB))
Hi.
Unfortunately, the proposed workaround won't work. Of course, it doesn't throw errors anymore, but the result is absolutely wrong:
>>> dm = currentProgram.getDataTypeManager()
>>> dt = next(x for x in dm.getAllDataTypes() if x.getName() == 'CreateProcessW')
>>> type(dt)
<class 'ghidra.program.database.data.FunctionDefinitionDB'>
>>> isinstance(dt, type(FunctionDefinitionDB))
False
>>> type(FunctionDefinitionDB)
<class 'jep.PyJClass'>
The only workaround I've found for this, is 'FunctionDefinitionDB' in str(type(dt))
. Obviously something one won't expect to see in good code, but at least it works )
Nice catch - apologies for that. I did some more digging and Jep exposes the underlying Python type through __pytype__
e.g.:
isinstance(dt, FunctionDefinitionDB.__pytype__)
that in my testing worked with isinstance
:
_____ _ _ _ _ _
/ ____| | (_) | | | | | |
| | __| |__ _ __| |_ __ __ _| |_| |__ ___ _ __
| | |_ | '_ \| |/ _` | '__/ _` | __| '_ \ / _ \| '_ \
| |__| | | | | | (_| | | | (_| | |_| | | | (_) | | | |
\_____|_| |_|_|\__,_|_| \__,_|\__|_| |_|\___/|_| |_|
Python 3.11.0 Interpreter for Ghidra. Developed by FLARE.
>>> from ghidra.program.model.data import *
>>> dt = next(x for x in currentProgram.getDataTypeManager().getAllDataTypes() if x.getName() == "uint")
>>> dt
<ghidra.program.model.data.UnsignedIntegerDataType object at 0x000001BFD2CAB500>
>>> type(UnsignedIntegerDataType)
<class 'jep.PyJClass'>
>>> isinstance(dt, UnsignedIntegerDataType.__pytype__)
True
>>> isinstance(int, UnsignedIntegerDataType.__pytype__)
False
We want to see isinstance
used without a workaround and we'll work to improve this.
Yep, that works. Thanks for your effort!
@pieceofsummer I sent this issue upstream and the Jep developers came up with a fix (see https://github.com/ninia/jep/pull/440). Unfortunately it may be some time before the fix makes it in a Jep release. For now, we've added a workaround (see https://github.com/mandiant/Ghidrathon/commit/fdf6c4590ba346f884e0c61087205ea532cce013) that will be included in the Ghidrathon 2.0.0 release, likely dropping later today. I'll open a separate issue to remind us to remove the workaround when the Jep fix is released.
_____ _ _ _ _ _
/ ____| | (_) | | | | | |
| | __| |__ _ __| |_ __ __ _| |_| |__ ___ _ __
| | |_ | '_ \| |/ _` | '__/ _` | __| '_ \ / _ \| '_ \
| |__| | | | | | (_| | | | (_| | |_| | | | (_) | | | |
\_____|_| |_|_|\__,_|_| \__,_|\__|_| |_|\___/|_| |_|
Python 3.11.0 Interpreter for Ghidra 10.2. Developed by FLARE.
>>> from ghidra.program.database import ProgramDB
>>> type(currentProgram)
<class 'ghidra.program.database.ProgramDB'>
>>> type(ProgramDB)
<class 'jep.PyJClass'>
>>> isinstance(currentProgram, ProgramDB)
True
>>> isinstance(currentProgram, str)
False
Seems like
isinstance()
is broken for Ghidra types: