ghidra: NeLoader and supporting classes fail to recognise referenced API names (16-bit Windows)

Describe the bug When loading a Windows 16-bit “NE” file to analyse, the external references to functions in dependent libraries (like KERNEL, USER etc.) don’t reflect thier API names and instead appear as “Ordinal_xxx”.

(Also, it appears that the compilers of those days didn’t store the file extension of dependent librares either (so to find the “USER.DLL”, I had to create a copy called “USER”!)

To Reproduce Steps to reproduce the behavior:

  1. Load a Windows 16-bit “NE” file into a Ghidra project to analyse
  2. Go to the Decompile Tool
  3. Look at the Thunks in the “Listings: …” view and/or look into the “Imports” section of the “Symbol Tree” view
  4. See the names imported!

Expected behavior To see the correct API name, and therefore be able to analyse better. (Those old Microsoft libraries only seem to hold the exported API names in capital letters, so some additional lookup is required.)

Screenshots image

Attachments See screenshot.

Environment (please complete the following information):

  • OS: Windows 10 (2004)
  • Java Version: [e.g. 11.0.2
  • Ghidra Version: 9.1.2 and current Master branch (9.2-DEV) commit c1095fe9383b153fffdfa7453679512124a60d87

Additional context My solution is to modify the method “private void processModuleReferenceTable” in class “/Features Base/src/main/java/ghidra/app/util/opinion/NeLoader.java” to add the following:

  1. the reference below: ReferenceManager refManager = program.getReferenceManager();

  2. and within the “for loop” after the call to “functionManager.createThunkFunction(…);” add the following:

					refManager.addExternalReference(addr, moduleName,
							callname, null, SourceType.IMPORTED, 0, RefType.DATA);

PS, other simple issues include:

  1. registers now are in capitals, so in method “private void setRegisterDS(…)”: Register ds = context.getRegister("ds"); becomes Register ds = context.getRegister("DS");

  2. I believe library names should be case insensitive. Therefore the below needs adding to the same class:

	@Override
	protected boolean isCaseInsensitiveLibraryFilenames() {
		return true;
	}
  1. when loading dependent libraries (like “USER.DLL”) the “.export” files produced seem to contain multiple exports that are for the same ordinal value (so far I’ve noticed they all refer to ones named “Ordinal_xxx” apart from 1)! We need a way to pick up that one. The current implementation of class “/Features Base/src/main/java/ghidra/app/util/opinion/LibrarySymbolTable.java” uses “org.jdom." which cannot sort the “Element” objects. Maybe Ghidra need updating to use "org.jdom2.”, a bigger job than I wanted!

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 1
  • Comments: 30 (2 by maintainers)

Commits related to this issue

Most upvoted comments

Thanks i’ve used to to generate .exports files that we can include in the release.

AFAIK the extensions aren’t used in this situation.