diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/ResourceDataDirectory.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/ResourceDataDirectory.java index b3c7230393..f4efe7dcd3 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/ResourceDataDirectory.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/ResourceDataDirectory.java @@ -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 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(); + } + } + } } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/MenuResourceDataType.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/MenuResourceDataType.java index d764344ff5..588b0cb76d 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/MenuResourceDataType.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/MenuResourceDataType.java @@ -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 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 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; } } }