Skip to content

Draft: MSP430 support in Ghidra and PyGhidra#678

Open
paulnoalhyt wants to merge 12 commits into
masterfrom
disas/msp430
Open

Draft: MSP430 support in Ghidra and PyGhidra#678
paulnoalhyt wants to merge 12 commits into
masterfrom
disas/msp430

Conversation

@paulnoalhyt
Copy link
Copy Markdown
Collaborator

  • I have reviewed the OFRAK contributor guide and attest that this pull request is in accordance with it.
  • I have made or updated a changelog entry for the changes in this pull request.

One sentence summary of this PR (This should go in the CHANGELOG!)

Add support for MSP430 (and MSP430X: 32-bit variant) in Ghidra and PyGhidra.

This builds on top of #677, which should be merged first.

Link to Related Issue(s)

None.

Please describe the changes in your request.

Anyone you think should look at this, specifically?

@paulnoalhyt paulnoalhyt changed the title MSP430 support in Ghidra and PyGhidra Draft: MSP430 support in Ghidra and PyGhidra Dec 19, 2025
@paulnoalhyt
Copy link
Copy Markdown
Collaborator Author

Update on adding a test for MSP430 support in disassembler backends. I added a testcase for the CodeRegionUnpackAndVerifyPattern, which all backends will extend. For now it only works in PyGhidra.

I had to fix a bug in PyGhidra: the end address of a CodeRegion might not be in the Ghidra address space, so it was raise the following exception: ghidra.program.model.address.AddressFormatException: Offset must be between 0x0 and 0xffff, got 0x10000 instead!. Indeed, in a program where the last byte is at address 0xFFFF, it is impossible to get the end address of the code region which is 0x10000. So I fixed the code to use integers instead of Ghidra Address objects.

As of now, the MSP430 test fails with this exception when using the Ghidra backend:

E               ofrak_ghidra.ghidra_model.GhidraComponentException: OFRAK Ghidra server encountered the following exception for request to GetComplexBlocks with params __arg_0=0xf800,__arg_1=0xf85c:
E               java.lang.IllegalArgumentException: Address are in different spaces RAM != .comment

And this exception with the Angr backend:

../../venv/lib/python3.11/site-packages/cle/loader.py:1027: in _map_object
    base_addr = self._find_safe_rebase_addr(obj_size)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <Loaded from stream, maps [0x0:0xffff]>, size = 17412

    def _find_safe_rebase_addr(self, size):
        """
        Return a "safe" virtual address to map an object of size ``size``, i.e. one that won't
        overlap with anything already loaded.
        """
        # this assumes that self.main_object exists, which should... definitely be safe
        if self.main_object.arch.bits < 32 or self.main_object.max_addr >= 2 ** (self.main_object.arch.bits - 1):
            # HACK: On small arches, we should be more aggressive in packing stuff in.
            gap_start = 0
        else:
            gap_start = ALIGN_UP(self.main_object.max_addr + 1, self._rebase_granularity)
        for o in self.all_objects:
            if gap_start + size <= o.min_addr:
                break
            else:
                gap_start = ALIGN_UP(o.max_addr + 1, self._rebase_granularity)

        if gap_start + size > 2**self.main_object.arch.bits:
            # this may happen when loading an ELF core whose main object may occupy a large range of memory addresses
            # with large unoccupied holes left in the middle                                                                                           # we fall back to finding unoccupied holes
            for this_seg, next_seg in zip(self.main_object.segments.raw_list, self.main_object.segments.raw_list[1:]):
                gap_start = ALIGN_UP(this_seg.vaddr + this_seg.memsize, self._rebase_granularity)
                gap = next_seg.vaddr - gap_start
                if gap >= size:
                    break                                                                                                                              else:
>               raise CLEOperationError("Ran out of room in address space")
E               cle.errors.CLEOperationError: Ran out of room in address space

../../venv/lib/python3.11/site-packages/cle/loader.py:1088: CLEOperationError

To be further investigated...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants