update PE resource parser to track menu depth

This commit is contained in:
Ben Stone 2022-02-22 14:40:56 +11:00
parent 3e245c6f80
commit c684fbb958
2 changed files with 42 additions and 26 deletions

View File

@ -638,17 +638,18 @@ public class ResourceDataDirectory extends DataDirectory {
private String setExtraCommentForMenuResource(Data data) throws MemoryAccessException {
short MF_POPUP = 0x0010;
short LAST = 0x0090;
short MF_END = 0x0080;
DumbMemBufferImpl buffer = new DumbMemBufferImpl(data.getMemory(), data.getAddress());
StringBuilder comment = new StringBuilder();
if (data.getBaseDataType().getName().equals("MenuResource")) {
//get first structure
short menuItemOption = 0;
Stack<Short> parentItemOptions = new Stack<>();
parentItemOptions.push((short)0);
int numComponents = data.getNumComponents();
boolean topLevel = false;
for (int i = 0; i < numComponents; i++) {
DataType dt = data.getComponent(i).getBaseDataType();
int offset = data.getComponent(i).getRootOffset();
@ -667,26 +668,19 @@ public class ResourceDataDirectory extends DataDirectory {
}
if (dt.getName().equals("word")) {
short option = buffer.getShort(offset);
menuItemOption = buffer.getShort(offset);
if (option == MF_POPUP) {
topLevel = true; //this type has no mtID to skip
}
else if (option == LAST) {
topLevel = true;
i++; //skip the mtID
}
else {
topLevel = false;
if ((menuItemOption & MF_POPUP) == 0) {
i++; //skip the mtID
}
}
if (dt.getName().equals("unicode")) {
if (topLevel) {
int depth = parentItemOptions.size() - 1;
if (depth == 0) {
comment.append("\n");
}
else {
comment.append(" ");
} else {
comment.append(" ".repeat(2 * depth));
}
String menuString = fixupStringRepForDisplay(
@ -698,6 +692,18 @@ public class ResourceDataDirectory extends DataDirectory {
else {
comment.append(menuString + "\n");
}
if ((menuItemOption & MF_POPUP) == MF_POPUP) {
// Increase the current depth
parentItemOptions.push(menuItemOption);
} else if ((menuItemOption & MF_END) == MF_END) {
// Decrease the current depth until we have found a parent menu item that isn't the last item in its parent
short parentOptions = parentItemOptions.pop();
while ((parentOptions & MF_END) == MF_END) {
parentOptions = parentItemOptions.pop();
}
}
}
}

View File

@ -17,6 +17,7 @@ package ghidra.program.model.data;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import ghidra.docking.settings.Settings;
import ghidra.program.model.address.Address;
@ -30,7 +31,6 @@ public class MenuResourceDataType extends DynamicDataType {
private static short MF_POPUP = 0x0010;
private static short MF_END = 0x0080;
private static short LAST = 0x0090;
static {
ClassTranslator.put("ghidra.app.plugin.prototype.data.MenuResourceDataType",
@ -68,7 +68,6 @@ public class MenuResourceDataType extends DynamicDataType {
protected DataTypeComponent[] getAllComponents(MemBuffer mbIn) {
List<DataTypeComponent> comps = new ArrayList<>();
int tempOffset = 0;
boolean lastMenuItem = false;
MemBuffer memBuffer = mbIn;
short option;
@ -81,18 +80,29 @@ public class MenuResourceDataType extends DynamicDataType {
//loop through menu items and add them
boolean lastItem = false;
// keep options from parent popup menu items
Stack<Short> parentItemOptions = new Stack<>();
parentItemOptions.push((short) 0);
while (!lastItem) {
option = memBuffer.getShort(tempOffset);
tempOffset = addMenuItemTemplate(memBuffer, comps, tempOffset, option);
//last item in a menu
if (option == MF_END) {
if (lastMenuItem == true) {
lastItem = true;
if ((option & MF_POPUP) == MF_POPUP) {
// Increase the depth
parentItemOptions.push(option);
} else if ((option & MF_END) == MF_END) {
// Decrease the depth until we have found a parent menu item that isn't also the last item
short parentOptions = parentItemOptions.pop();
while ((parentOptions & MF_END) == MF_END) {
parentOptions = parentItemOptions.pop();
}
}
//last menu
if (option == LAST) {
lastMenuItem = true;
// We have finished when there are no more parent menu items
if (parentItemOptions.size() == 0) {
lastItem = true;
}
}
}