Merge remote-tracking branch 'origin/GP-182_emteere_UnknownResourcesFix'

This commit is contained in:
ghidra1
2020-09-18 17:19:45 -04:00
3 changed files with 140 additions and 107 deletions

View File

@@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -16,11 +15,11 @@
*/ */
package ghidra.app.util.bin.format.ne; package ghidra.app.util.bin.format.ne;
import ghidra.app.util.bin.format.*;
import ghidra.util.Conv;
import java.io.IOException; import java.io.IOException;
import ghidra.app.util.bin.format.FactoryBundledWithBinaryReader;
import ghidra.util.Conv;
/** /**
* An implementation of the new-executable TNAMEINFO structure. * An implementation of the new-executable TNAMEINFO structure.
* *
@@ -61,6 +60,7 @@ public class Resource {
public short getFileOffset() { public short getFileOffset() {
return fileOffset; return fileOffset;
} }
/** /**
* Returns the file length of this resource. * Returns the file length of this resource.
* @return the file length of this resource * @return the file length of this resource
@@ -68,6 +68,7 @@ public class Resource {
public short getFileLength() { public short getFileLength() {
return fileLength; return fileLength;
} }
/** /**
* Returns the flag word of this resource. * Returns the flag word of this resource.
* @return the flag word of this resource * @return the flag word of this resource
@@ -75,6 +76,7 @@ public class Resource {
public short getFlagword() { public short getFlagword() {
return flagword; return flagword;
} }
/** /**
* Returns the resource ID of this resource. * Returns the resource ID of this resource.
* @return the resource ID of this resource * @return the resource ID of this resource
@@ -82,6 +84,7 @@ public class Resource {
public short getResourceID() { public short getResourceID() {
return resourceID; return resourceID;
} }
/** /**
* Returns the handle of this resource. * Returns the handle of this resource.
* @return the handle of this resource * @return the handle of this resource
@@ -89,6 +92,7 @@ public class Resource {
public short getHandle() { public short getHandle() {
return handle; return handle;
} }
/** /**
* Returns the usage of this resource. * Returns the usage of this resource.
* @return the usage of this resource * @return the usage of this resource
@@ -96,6 +100,7 @@ public class Resource {
public short getUsage() { public short getUsage() {
return usage; return usage;
} }
/** /**
* Returns true if this resource is moveable. * Returns true if this resource is moveable.
* @return true if this resource is moveable * @return true if this resource is moveable
@@ -103,6 +108,7 @@ public class Resource {
public boolean isMoveable() { public boolean isMoveable() {
return (flagword & FLAG_MOVEABLE) != 0; return (flagword & FLAG_MOVEABLE) != 0;
} }
/** /**
* Returns true if this resource is pure. * Returns true if this resource is pure.
* @return true if this resource is pure * @return true if this resource is pure
@@ -110,13 +116,15 @@ public class Resource {
public boolean isPure() { public boolean isPure() {
return (flagword & FLAG_PURE) != 0; return (flagword & FLAG_PURE) != 0;
} }
/** /**
* Returns true if this resource is preloaded. * Returns true if this resource is preloaded.
* @return true if this resource is preloaded * @return true if this resource is preloaded
*/ */
public boolean isPreload() { public boolean isPreload() {
return (flagword & FLAG_PRELOAD) != 0; return (flagword & FLAG_PRELOAD) != 0;
} }
/** /**
* Returns the shifted file offset of this resource. * Returns the shifted file offset of this resource.
* <code>this.getFileOffset() &lt;&lt; ResourceTable.getAlignmentShiftCount()</code> * <code>this.getFileOffset() &lt;&lt; ResourceTable.getAlignmentShiftCount()</code>
@@ -127,6 +135,7 @@ public class Resource {
int offset_int = Conv.shortToInt(fileOffset); int offset_int = Conv.shortToInt(fileOffset);
return offset_int << shift_int; return offset_int << shift_int;
} }
/** /**
* Returns the shifted file length of this resource. * Returns the shifted file length of this resource.
* <code>this.getFileLength() &lt;&lt; ResourceTable.getAlignmentShiftCount()</code> * <code>this.getFileLength() &lt;&lt; ResourceTable.getAlignmentShiftCount()</code>
@@ -137,20 +146,20 @@ public class Resource {
int length_int = Conv.shortToInt(fileLength); int length_int = Conv.shortToInt(fileLength);
return length_int << shift_int; return length_int << shift_int;
} }
/** /**
* Returns the actual bytes for this resource. * Returns the actual bytes for this resource.
* @return the actual bytes for this resource * @return the actual bytes for this resource
*/ */
public byte[] getBytes() throws IOException { public byte[] getBytes() throws IOException {
return reader.readByteArray( return reader.readByteArray(getFileOffsetShifted(), getFileLengthShifted());
getFileOffsetShifted(),
getFileLengthShifted());
} }
/** /**
* @see java.lang.Object#toString() * @see java.lang.Object#toString()
*/ */
@Override @Override
public String toString() { public String toString() {
//if MSB is set, then resourceID is a unique id of this resource... //if MSB is set, then resourceID is a unique id of this resource...
if ((resourceID & 0x8000) != 0) { if ((resourceID & 0x8000) != 0) {
return "" + (resourceID & 0x7fff); return "" + (resourceID & 0x7fff);
@@ -159,12 +168,14 @@ public class Resource {
//index to a resource name relative to the //index to a resource name relative to the
//beginning of the resource table... //beginning of the resource table...
ResourceName[] names = rt.getResourceNames(); ResourceName[] names = rt.getResourceNames();
for (int i = 0; i < names.length; ++i) { for (ResourceName name : names) {
if (resourceID == names[i].getIndex() - rt.getIndex()) { if (resourceID == name.getIndex() - rt.getIndex()) {
return names[i].getName(); return name.getName();
} }
} }
throw new RuntimeException( if (resourceID >= 0 && resourceID < names.length) {
"NE - Resource - unknown id - " + Conv.toHexString(resourceID)); return names[resourceID].getName();
}
return ("NE - Resource - unknown id - " + Conv.toHexString(resourceID));
} }
} }

View File

@@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -16,12 +15,12 @@
*/ */
package ghidra.app.util.bin.format.ne; package ghidra.app.util.bin.format.ne;
import ghidra.app.util.bin.format.*;
import ghidra.util.Conv;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import ghidra.app.util.bin.format.FactoryBundledWithBinaryReader;
import ghidra.util.Conv;
/** /**
* An implementation of the TTYPEINFO structure. * An implementation of the TTYPEINFO structure.
* *
@@ -30,123 +29,143 @@ import java.util.ArrayList;
public class ResourceType { public class ResourceType {
//0x00 is not defined...? //0x00 is not defined...?
/**Constant indicating cursor resource type.*/ /**Constant indicating cursor resource type.*/
public final static short RT_CURSOR = 0x01; public final static short RT_CURSOR = 0x01;
/**Constant indicating bitmap resource type.*/ /**Constant indicating bitmap resource type.*/
public final static short RT_BITMAP = 0x02; public final static short RT_BITMAP = 0x02;
/**Constant indicating icon resource type.*/ /**Constant indicating icon resource type.*/
public final static short RT_ICON = 0x03; public final static short RT_ICON = 0x03;
/**Constant indicating menu resource type.*/ /**Constant indicating menu resource type.*/
public final static short RT_MENU = 0x04; public final static short RT_MENU = 0x04;
/**Constant indicating dialog resource type.*/ /**Constant indicating dialog resource type.*/
public final static short RT_DIALOG = 0x05; public final static short RT_DIALOG = 0x05;
/**Constant indicating string resource type.*/ /**Constant indicating string resource type.*/
public final static short RT_STRING = 0x06; public final static short RT_STRING = 0x06;
/**Constant indicating font directory resource type.*/ /**Constant indicating font directory resource type.*/
public final static short RT_FONTDIR = 0x07; public final static short RT_FONTDIR = 0x07;
/**Constant indicating font resource type.*/ /**Constant indicating font resource type.*/
public final static short RT_FONT = 0x08; public final static short RT_FONT = 0x08;
/**Constant indicating an accelerator resource type.*/ /**Constant indicating an accelerator resource type.*/
public final static short RT_ACCELERATOR = 0x09; public final static short RT_ACCELERATOR = 0x09;
/**Constant indicating RC data resource type.*/ /**Constant indicating RC data resource type.*/
public final static short RT_RCDATA = 0x0a; public final static short RT_RCDATA = 0x0a;
/**Constant indicating message table resource type.*/ /**Constant indicating message table resource type.*/
public final static short RT_MESSAGETABLE = 0x0b; public final static short RT_MESSAGETABLE = 0x0b;
/**Constant indicating cursor group resource type.*/ /**Constant indicating cursor group resource type.*/
public final static short RT_GROUP_CURSOR = 0x0c; public final static short RT_GROUP_CURSOR = 0x0c;
//0x0d is not defined...? //0x0d is not defined...?
/**Constant indicating icon group resource type.*/ /**Constant indicating icon group resource type.*/
public final static short RT_GROUP_ICON = 0x0e; public final static short RT_GROUP_ICON = 0x0e;
//0x0f is not defined...? //0x0f is not defined...?
/**Constant indicating version resource type.*/ /**Constant indicating version resource type.*/
public final static byte RT_VERSION = 0x10; public final static byte RT_VERSION = 0x10;
private short typeID; //if >= 0x8000, then private short typeID; //if >= 0x8000, then
private short count; //number of resources of this type private short count; //number of resources of this type
private int reserved; //reserved...for what? private int reserved; //reserved...for what?
private Resource [] resources; private Resource[] resources;
/** /**
* Constructs a new resource type. * Constructs a new resource type.
* @param reader the binary reader * @param reader the binary reader
* @param rt the resource table * @param rt the resource table
*/ */
ResourceType(FactoryBundledWithBinaryReader reader, ResourceTable rt) throws IOException { ResourceType(FactoryBundledWithBinaryReader reader, ResourceTable rt) throws IOException {
typeID = reader.readNextShort(); typeID = reader.readNextShort();
if (typeID == 0) return; //not a valid resource type... if (typeID == 0) {
return; //not a valid resource type...
}
count = reader.readNextShort(); count = reader.readNextShort();
reserved = reader.readNextInt(); reserved = reader.readNextInt();
ArrayList<Resource> list = new ArrayList<Resource>(); ArrayList<Resource> list = new ArrayList<Resource>();
int count_int = Conv.shortToInt(count); int count_int = Conv.shortToInt(count);
for (int i = 0 ; i < count_int ; ++i) { for (int i = 0; i < count_int; ++i) {
if ((short)(typeID&0x7fff) == RT_STRING) { if ((short) (typeID & 0x7fff) == RT_STRING) {
list.add(new ResourceStringTable(reader, rt)); list.add(new ResourceStringTable(reader, rt));
} }
else { else {
list.add(new Resource(reader, rt)); list.add(new Resource(reader, rt));
} }
} }
resources = new Resource[list.size()]; resources = new Resource[list.size()];
list.toArray(resources); list.toArray(resources);
} }
/** /**
* Returns the resource type ID. * Returns the resource type ID.
* @return the resource type ID * @return the resource type ID
*/ */
public short getTypeID() { public short getTypeID() {
return typeID; return typeID;
} }
/**
* Returns the number of resources of this type. /**
* @return the number of resources of this type * Returns the number of resources of this type.
*/ * @return the number of resources of this type
public short getCount() { */
return count; public short getCount() {
} return count;
/** }
* Returns the reserved value (purpose is unknown).
* @return the reserved value /**
*/ * Returns the reserved value (purpose is unknown).
public int getReserved() { * @return the reserved value
return reserved; */
} public int getReserved() {
/** return reserved;
* Returns the array of resources of this type. }
* @return the array of resources of this type
*/ /**
public Resource [] getResources() { * Returns the array of resources of this type.
return resources; * @return the array of resources of this type
} */
public Resource[] getResources() {
return resources;
}
/** /**
* @see java.lang.Object#toString() * @see java.lang.Object#toString()
*/ */
@Override @Override
public String toString() { public String toString() {
if ((typeID & 0x8000) == 0) { if ((typeID & 0x8000) == 0) {
throw new RuntimeException("NE - ResourceType - name lookup required - "+typeID); return "UnknownResourceType_" + typeID;
} }
int idx = typeID&0x7fff; int idx = typeID & 0x7fff;
switch (idx) { switch (idx) {
case RT_CURSOR: return "Cursor"; case RT_CURSOR:
case RT_BITMAP: return "Bitmap"; return "Cursor";
case RT_ICON: return "Icon"; case RT_BITMAP:
case RT_MENU: return "Menu"; return "Bitmap";
case RT_DIALOG: return "Dialog Box"; case RT_ICON:
case RT_STRING: return "String Table"; return "Icon";
case RT_FONTDIR: return "Font Directory"; case RT_MENU:
case RT_FONT: return "Font"; return "Menu";
case RT_ACCELERATOR: return "Accelerator Table"; case RT_DIALOG:
case RT_RCDATA: return "Resource Data"; return "Dialog Box";
case RT_MESSAGETABLE: return "Message Table"; case RT_STRING:
case RT_GROUP_CURSOR: return "Cursor Directory"; return "String Table";
case RT_GROUP_ICON: return "Icon Directory"; case RT_FONTDIR:
case RT_VERSION: return "Version Information"; return "Font Directory";
case RT_FONT:
return "Font";
case RT_ACCELERATOR:
return "Accelerator Table";
case RT_RCDATA:
return "Resource Data";
case RT_MESSAGETABLE:
return "Message Table";
case RT_GROUP_CURSOR:
return "Cursor Directory";
case RT_GROUP_ICON:
return "Icon Directory";
case RT_VERSION:
return "Version Information";
default: default:
return "Unknown_"+idx; return "Unknown_" + idx;
} }
} }
} }

View File

@@ -362,7 +362,9 @@ public class NeLoader extends AbstractLibrarySupportLoader {
buf.append("Handle: " + Conv.toHexString(resource.getHandle()) + "\n"); buf.append("Handle: " + Conv.toHexString(resource.getHandle()) + "\n");
buf.append("Usage: " + Conv.toHexString(resource.getUsage()) + "\n"); buf.append("Usage: " + Conv.toHexString(resource.getUsage()) + "\n");
CodeUnit cu = listing.getCodeUnitAt(addr); CodeUnit cu = listing.getCodeUnitAt(addr);
cu.setComment(CodeUnit.PRE_COMMENT, buf.toString()); if (cu != null) {
cu.setComment(CodeUnit.PRE_COMMENT, buf.toString());
}
//if this resource is a string table, //if this resource is a string table,
//then go and create the strings... //then go and create the strings...
@@ -435,7 +437,8 @@ public class NeLoader extends AbstractLibrarySupportLoader {
Function refFunction = null; Function refFunction = null;
try { try {
ExternalLocation loc; ExternalLocation loc;
loc = externalManager.addExtFunction(moduleName, callname, null, SourceType.IMPORTED); loc = externalManager.addExtFunction(moduleName, callname, null,
SourceType.IMPORTED);
refFunction = loc.getFunction(); refFunction = loc.getFunction();
} }
catch (DuplicateNameException e) { catch (DuplicateNameException e) {