Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NullPointerException ghidra.program.model.data.DataTypeManager.getUniversalID() #4578

Closed
FlashHit opened this issue Sep 5, 2022 · 34 comments
Assignees

Comments

@FlashHit
Copy link

FlashHit commented Sep 5, 2022

Cannot invoke "ghidra.program.model.data.DataTypeManager.getUniversalID()" because the return value of "ghidra.program.model.data.DataType.getDataTypeManager()" is null
java.lang.NullPointerException: Cannot invoke "ghidra.program.model.data.DataTypeManager.getUniversalID()" because the return value of "ghidra.program.model.data.DataType.getDataTypeManager()" is null
	at ghidra.app.plugin.core.datamgr.tree.DataTypeNode.getCurrentDisplayText(DataTypeNode.java:269)
	at ghidra.app.plugin.core.datamgr.tree.DataTypeNode.<init>(DataTypeNode.java:48)
	at ghidra.app.plugin.core.datamgr.tree.CategoryNode.generateChildren(CategoryNode.java:63)
	at docking.widgets.tree.CoreGTreeNode.children(CoreGTreeNode.java:114)
	at docking.widgets.tree.GTreeNode.getChildCount(GTreeNode.java:171)
	at docking.widgets.tree.internal.GTreeModel.getChildCount(GTreeModel.java:97)
	at java.desktop/javax.swing.tree.VariableHeightLayoutCache$TreeStateNode.expand(VariableHeightLayoutCache.java:1457)
	at java.desktop/javax.swing.tree.VariableHeightLayoutCache$TreeStateNode.expand(VariableHeightLayoutCache.java:1272)
	at java.desktop/javax.swing.tree.VariableHeightLayoutCache.ensurePathIsExpanded(VariableHeightLayoutCache.java:967)
	at java.desktop/javax.swing.tree.VariableHeightLayoutCache.setExpandedState(VariableHeightLayoutCache.java:181)
	at java.desktop/javax.swing.plaf.basic.BasicTreeUI.updateExpandedDescendants(BasicTreeUI.java:2003)
	at java.desktop/javax.swing.plaf.basic.BasicTreeUI$Handler.treeExpanded(BasicTreeUI.java:4295)
	at java.desktop/javax.swing.JTree.fireTreeExpanded(JTree.java:2853)
	at java.desktop/javax.swing.JTree.setExpandedState(JTree.java:3766)
	at java.desktop/javax.swing.JTree.expandPath(JTree.java:2296)
	at java.desktop/javax.swing.plaf.basic.BasicTreeUI.toggleExpandState(BasicTreeUI.java:2644)
	at java.desktop/javax.swing.plaf.basic.BasicTreeUI.handleExpandControlClick(BasicTreeUI.java:2629)
	at java.desktop/javax.swing.plaf.basic.BasicTreeUI.checkForClickInExpandControl(BasicTreeUI.java:2577)
	at java.desktop/javax.swing.plaf.basic.BasicTreeUI$Handler.handleSelection(BasicTreeUI.java:4090)
	at java.desktop/javax.swing.plaf.basic.BasicTreeUI$Handler.mousePressed(BasicTreeUI.java:4038)
	at docking.widgets.JTreeMouseListenerDelegate.fireMousePressed(JTreeMouseListenerDelegate.java:125)
	at docking.widgets.JTreeMouseListenerDelegate.mousePressed(JTreeMouseListenerDelegate.java:97)
	at java.desktop/java.awt.Component.processMouseEvent(Component.java:6623)
	at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3389)
	at java.desktop/java.awt.Component.processEvent(Component.java:6391)
	at java.desktop/java.awt.Container.processEvent(Container.java:2266)
	at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5001)
	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
	at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948)
	at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4572)
	at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4516)
	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310)
	at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)
	at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:746)
	at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:744)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:743)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

---------------------------------------------------
Build Date: 2022-Jul-26 1543 EDT
Ghidra Version: 10.1.5
Java Home: C:\Program Files\Eclipse Adoptium\jdk-17.0.4.8-hotspot
JVM Version: Eclipse Adoptium 17.0.4
OS: Windows 11 10.0 amd64
Workstation: REVISION-PC
@dragonmacher
Copy link
Collaborator

This should not be possible in the normal work flow. The implication is that a Data Type Manager was closed off of the Swing thread or that the JTree did not get notified that the manager was closed.

Do you recall what you were doing when this happened?

@FlashHit
Copy link
Author

FlashHit commented Sep 6, 2022

@dragonmacher I added new things to the Data Type Manager, where I had 2 folders and both contained a struct called TypeInfoData then one had a pointer to the other one and the other one had a pointer to itself. Something like that.

But it is still happening. Basically I can't use the Data Type Manager at all rn. Whenever I try to access anything from it, it will throw this error.

@dragonmacher
Copy link
Collaborator

I see. It seems like it is in a bad state. Does the issue go away if you restart Ghidra?

@FlashHit
Copy link
Author

FlashHit commented Sep 6, 2022

@dragonmacher no, this issue doesn't go away.
The error message changes slightly depending on what I do but the issue is the same.

Cannot invoke "ghidra.program.model.data.DataTypeManager.getName()" because the return value of "ghidra.program.model.data.DataType.getDataTypeManager()" is null
java.lang.NullPointerException: Cannot invoke "ghidra.program.model.data.DataTypeManager.getName()" because the return value of "ghidra.program.model.data.DataType.getDataTypeManager()" is null
	at ghidra.app.plugin.core.datamgr.util.DataTypeComparator.compare(DataTypeComparator.java:40)
	at ghidra.app.plugin.core.datamgr.util.DataTypeComparator.compare(DataTypeComparator.java:23)
	at java.base/java.util.TimSort.binarySort(TimSort.java:296)
	at java.base/java.util.TimSort.sort(TimSort.java:239)
	at java.base/java.util.Arrays.sort(Arrays.java:1307)
	at java.base/java.util.ArrayList.sort(ArrayList.java:1721)
	at java.base/java.util.Collections.sort(Collections.java:179)
	at ghidra.app.plugin.core.datamgr.archive.DataTypeIndexer$IndexerTask.run(DataTypeIndexer.java:140)
	at ghidra.util.task.Task.monitoredRun(Task.java:134)
	at ghidra.util.task.TaskRunner.lambda$startTaskThread$0(TaskRunner.java:106)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.lang.Thread.run(Thread.java:833)

---------------------------------------------------
Build Date: 2022-Jul-26 1543 EDT
Ghidra Version: 10.1.5
Java Home: C:\Program Files\Eclipse Adoptium\jdk-17.0.4.8-hotspot
JVM Version: Eclipse Adoptium 17.0.4
OS: Windows 11 10.0 amd64
Workstation: REVISION-PC

@FlashHit
Copy link
Author

FlashHit commented Sep 6, 2022

The struct types in the functions are still labelled correct and still show all the fields btw.
I can also modify these structs but I can't point to any other structs besides the default windows ones.

@dragonmacher
Copy link
Collaborator

When you added the types mentioned above, did you do so via a script or through the UI? Are you manipulating types via a script?

@FlashHit
Copy link
Author

FlashHit commented Sep 6, 2022

Edit: I can modify these structs and point to other structs except the ones that I added when it broke, but the suggestions are missing thats why I thought only the default windows ones work.

@FlashHit
Copy link
Author

FlashHit commented Sep 6, 2022

When you added the types mentioned above, did you do so via a script or through the UI? Are you manipulating types via a script?

No, I didn't use a script. I did it through the UI. I actually never used scripts with Ghidra.

@dragonmacher
Copy link
Collaborator

We would like to examine your binary. Will you export your program as a .gzf file and then post it here?

@FlashHit
Copy link
Author

FlashHit commented Sep 6, 2022

Any way to share this file not in public?

@ryanmkurtz ryanmkurtz added the Status: Triage Information is being gathered label Sep 7, 2022
@dragonmacher
Copy link
Collaborator

This is the only forum we are currently using for sharing.

You can try to isolate the offending type(s). First, make a copy of your binary in the front end so that you can freely make changes, reverting back to the original as desired. In the copy, start removing the types you believe caused the issue.

If there is only one or a few offending types, then finding them should be relatively easy. Hopefully, once those types are removed, the issue will go away. At that point, we would like you to re-create the types to see if the issue returns. Being able to isolate the characteristics of that type should allow us to reproduce the issue by following the steps you used to create the type. Once we understand the issue, we may be able to offer guidance on how to fix those types in the original version of your binary.

@FlashHit
Copy link
Author

FlashHit commented Sep 7, 2022

Okay but how can I remove the types? I cannot expand the folder in Data Type Manager UI.

@dragonmacher
Copy link
Collaborator

I see. Scripting may be the only way to do this then. You can try creating this new script via the Script Manager window.

Press the new script button on the toolbar. Create a Java scirpt. Name it 'FindBadTypesScript.java' and then paste these contents in the editor:

import java.util.Iterator;

import ghidra.app.script.GhidraScript;
import ghidra.program.model.data.DataType;
import ghidra.program.model.data.DataTypeManager;

public class FindBadTypesScript extends GhidraScript {

	@Override
	protected void run() throws Exception {

		DataTypeManager dtm = currentProgram.getDataTypeManager();
		Iterator<DataType> types = dtm.getAllDataTypes();
		while (types.hasNext()) {
			DataType dt = types.next();
			if (dt.getDataTypeManager() == null) { 
				println("found bad type: " + dt.getDataTypePath());
			}
		}

	}
}

Let us know if the script produces any output when you run it.

@FlashHit
Copy link
Author

FlashHit commented Sep 7, 2022

Output:

FindBadTypesScript.java> Running...
FindBadTypesScript.java> found bad type: /TypeInfo
FindBadTypesScript.java> Finished!

@dragonmacher
Copy link
Collaborator

Now replace the contents of the run() method with this code and run the script again:

        DataTypeManager dtm = currentProgram.getDataTypeManager();
	DataType dt = dtm.getDataType("/TypeInfo");
	boolean success = dtm.remove(dt, TaskMonitor.DUMMY);
	println("removed dt?: " + success);

@FlashHit
Copy link
Author

FlashHit commented Sep 7, 2022

FindBadTypesScript.java:14: error: cannot find symbol
		boolean success = dtm.remove(dt, TaskMonitor.DUMMY);
		                                 ^
  symbol:   variable TaskMonitor
  location: class FindBadTypesScript
skipping C:\Users\Admin\ghidra_scripts\FindBadTypesScript.java
> Unable to locate script class: FindBadTypesScript.java

@FlashHit
Copy link
Author

FlashHit commented Sep 7, 2022

added
import ghidra.util.task.TaskMonitor;

now the output is:

FindBadTypesScript.java> Running...
FindBadTypesScript.java> removed dt?: false
FindBadTypesScript.java> Finished!

@dragonmacher
Copy link
Collaborator

My mistake. Try overwriting the complete contents with this:


import ghidra.app.script.GhidraScript;
import ghidra.program.model.data.DataType;
import ghidra.program.model.data.DataTypeManager;
import ghidra.util.task.TaskMonitor;

public class FindBadTypesScript extends GhidraScript {

	@Override
	protected void run() throws Exception {

		DataTypeManager dtm = currentProgram.getDataTypeManager();
		DataType dt = dtm.getDataType("/TypeInfo");
		boolean success = dtm.remove(dt, TaskMonitor.DUMMY);
		println("removed dt?: " + success);

	}
}

@FlashHit
Copy link
Author

FlashHit commented Sep 7, 2022

Output is still:

FindBadTypesScript.java> Running...
FindBadTypesScript.java> removed dt?: false
FindBadTypesScript.java> Finished!

@dragonmacher
Copy link
Collaborator

Try this:

import ghidra.app.script.GhidraScript;
import ghidra.program.model.data.DataType;
import ghidra.program.model.data.DataTypeManager;

public class FindBadTypesScript extends GhidraScript {

	@Override
	protected void run() throws Exception {

		DataTypeManager dtm = currentProgram.getDataTypeManager();
		DataType dt = dtm.getDataType("/TypeInfo");
		if (dt == null) {
			println("could not retrieve dt");
			return;
		}

		println("dt: " + dt);
		println("id: " + dt.getUniversalID());
		println("manager: " + dt.getDataTypeManager());

	}
}

@FlashHit
Copy link
Author

FlashHit commented Sep 7, 2022

Output:

FindBadTypesScript.java> Running...
FindBadTypesScript.java> dt: TypeInfo
FindBadTypesScript.java> id: null
FindBadTypesScript.java> manager: null
FindBadTypesScript.java> Finished!

@dragonmacher
Copy link
Collaborator

Try this:

import ghidra.app.script.GhidraScript;
import ghidra.program.model.data.DataType;
import ghidra.program.model.data.DataTypeManager;

public class FindBadTypesScript extends GhidraScript {

	@Override
	protected void run() throws Exception {

		DataTypeManager dtm = currentProgram.getDataTypeManager();
		DataType dt = dtm.getDataType("/TypeInfo");
		if (dt == null) {
			println("could not retrieve dt");
			return;
		}

		println("dt class: " + dt.getClass());

	}
}

@FlashHit
Copy link
Author

FlashHit commented Sep 7, 2022

Output:

FindBadTypesScript.java> Running...
FindBadTypesScript.java> dt class: class ghidra.app.cmd.data.rtti.gcc.factory.TypeInfoFactoryDataType
FindBadTypesScript.java> Finished!

@FlashHit
Copy link
Author

FlashHit commented Sep 7, 2022

Okay I know how I created this error.
I made a struct called TypeInfo and in there I wanted a pointer to itself, but instead I added a pointer to TypeInfoFactoryDataType which results in this error.

@dragonmacher
Copy link
Collaborator

So, that is the problem. Is TypeInfoFactoryDataType a type that you created yourself? If not, where did you find this type?

@FlashHit
Copy link
Author

FlashHit commented Sep 7, 2022

No I just typed TypeInfo * and pressed enter and then it chose that. I guess this is sth that comes along with Ghidra itself?

@dragonmacher
Copy link
Collaborator

This is not a type that we provide. It appears as though it is from this repo:
https://github.com/astrelsky/Ghidra-Cpp-Class-Analyzer/tree/master/src/main/java/ghidra/app/cmd/data/rtti/gcc/factory

Do you have this extension? Or any other extension to Ghidra that may be using this?

@FlashHit
Copy link
Author

FlashHit commented Sep 7, 2022

Yes I have this extension. It is literally the only thing that I have and I didn't even use this ever.

@FlashHit
Copy link
Author

FlashHit commented Sep 7, 2022

Okay everything works fine if I disable this extension.

@dragonmacher
Copy link
Collaborator

dragonmacher commented Sep 7, 2022

Edit: I just saw your message. Good to see you were able to work around the issue.

Otherwise, this should have worked for you:

  1. Close the Code Browser tool and your program
  2. From the Front End tool, remove this extension
  3. Open the Code Browser tool by clicking the green dragon icon, but do NOT open your program
  4. Replace the script contents with what is below this list
  5. Run the script
  6. Reopen your program and see if it works.
import ghidra.app.script.GhidraScript;
import ghidra.util.classfinder.ClassTranslator;

public class FindBadTypesScript extends GhidraScript {

	@Override
	protected void run() throws Exception {

		ClassTranslator.put("ghidra.app.cmd.data.rtti.gcc.factory.TypeInfoFactoryDataType",
			"ghidra.program.model.data.DWordDataType");

	}
}

@FlashHit
Copy link
Author

FlashHit commented Sep 7, 2022

Thanks for your help!

@astrelsky
Copy link
Contributor

astrelsky commented Sep 7, 2022

It's all my fault, what else is new 😅. Sorry about that.

I remember seeing this yesterday and just thinking, wth this should be impossible.

@dragonmacher
Copy link
Collaborator

It's all my fault, what else is new sweat_smile. Sorry about that.

Perhaps you can think of this as helping to bring the community together?

@astrelsky
Copy link
Contributor

It's all my fault, what else is new sweat_smile. Sorry about that.

Perhaps you can think of this as helping to bring the community together?

🤔 Well when you put it that way, I wonder what else I can break.

@ryanmkurtz ryanmkurtz removed the Status: Triage Information is being gathered label Nov 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants