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

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

View File

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

View File

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

View File

@ -362,7 +362,9 @@ public class NeLoader extends AbstractLibrarySupportLoader {
buf.append("Handle: " + Conv.toHexString(resource.getHandle()) + "\n");
buf.append("Usage: " + Conv.toHexString(resource.getUsage()) + "\n");
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,
//then go and create the strings...
@ -435,7 +437,8 @@ public class NeLoader extends AbstractLibrarySupportLoader {
Function refFunction = null;
try {
ExternalLocation loc;
loc = externalManager.addExtFunction(moduleName, callname, null, SourceType.IMPORTED);
loc = externalManager.addExtFunction(moduleName, callname, null,
SourceType.IMPORTED);
refFunction = loc.getFunction();
}
catch (DuplicateNameException e) {