Skip to content

Annotations, Symbols, and Changes Owned by BinaryView not Individual Memory Regions or Segments #7558

@utkonos

Description

@utkonos

Version and Platform (required):

  • Binary Ninja Version: 5.2.8539-dev Ultimate, 84a0243d
  • OS: macos
  • OS Version: 15.6
  • CPU Architecture: arm64

What is the feature you'd like to have?
I am working on a packer with two stages of packing. The outer packer is custom. It allocates memory and then writes the unpacked data to the allocated memory. During the packing process, the PE header is stripped off the next stage image. The next stage is packed with UPX. The first stage writes the sections of the UPX packer in place as if it were loaded in memory normally. The first stage either calls or jumps to the UPX stage's OEP depending on which variant I'm looking at. The outer custom packer resolves API addresses that both the UPX stage needs as well as the final payload. It then overwrites the imports where the UPX image expects them and then stomps the rest of the resolved addresses after the UPX imports. This is how the APIs the final stage needs are resolved. I am dumping the allocated memory before the UPX unpacking has occurred and writing it to a new memory segment using the Memory Map. The addresses I'm using match up with what I am observing in x64dbg. With the header-less image located in memory, I'm starting with a predictable UPX PE header for the version of UPX this is. I'm then using binja API to calculate the rest of the fields in the PE header that are not predictable (DLL or not, section virtual and raw sizes etc etc). This works once doing it manually and I'm writing the steps into a plugin. The resulting binary unpacks cleanly using UPX unpacking methods and can be used to analyze the payload. However, because of the API stomping, those API addresses don't "just work". My solution was to disable the new segment to "save state" before the UPX unpacking happens. Then in the debugger let the UPX unpacking run until it would jump to the final payload's OEP. Then dump the same memory region, and use memory map to make a new segment in the exact same address space as the disabled one. I can then analyze the final payload with everything lining up as it is in the debugger including the extra API addresses.

If the annotations and symbols were "owned" by the memory segment/region rather than the binaryview, I can go back and forth between the states by toggling them enabled/disabled.

Is your feature request related to a problem?
The problem I've encountered is that if I want to go back and look at the previous state in Memory Map, all the symbols and annotations are still there no matter which segment is enabled or disabled. The annotations from the unpacked state are all over the place in the pre-unpacking state in locations where they don't make sense.

Are any alternative solutions acceptable?
Not sure if this is directly related, but what I'm asking for above is approximately like this feature, but for Memory Map:
#3614

Additional Information:
If it helps to see what I'm talking about, here is a database where I have added both states in the same memory map:
prism apex splits creatively. You can toggle them with bv.memory_map.set_memory_region_enabled. One is called payload the other unpacked.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Component: CoreIssue needs changes to the coreEffort: HighIssues require > 1 month of workImpact: LowIssue is a papercut or has a good, supported workaround

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions