Skip to content

Add new ROP feature: relative stack offset #2583

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: dev
Choose a base branch
from

Conversation

CsomePro
Copy link

Add new ROP feature: relative stack offset

Sometimes, the ROP needs to be set using the relative offset position on the stack.

This is a temporary solution.

rop = ROP(elf)
rop.rbp = len(rop.chain()) + 8 + offset

But sometimes errors occur.

rop = ROP(elf)
rop.call("open", [b"file", 0])
rop.rbp = len(rop.chain()) + 8 + offset

Because of the existence of AppendedArgument, arguments will be placed at the end of the stack.

len(rop.chain()) will not be the correct offset from base to the current slot.

Therefore, I added a class StackRelative and added the processing logic for StackRelative in the ROP.build function

class StackRelative(Unresolved):
    def __init__(self, offset):
        self.offset = offset
    
    def resolve(self, base):
        return base + self.offset
        ...
        elif isinstance(slot, StackRelative):
            address = slot.resolve(slot_address)
            stack[i] = address
            stack.describe(self.describe(address), slot_address)
        ...

At this point we can use this to solve the above example.

rop = ROP(elf)
rop.call("open", [b"file", 0])
rop.rbp = StackRelative(offset)

@peace-maker
Copy link
Member

Nice, can you please add a test to the ROP class itself or the module at the top which verifies this works as expected? You can look at the other tests which use ELF.from_assembly to setup a test binary with required gadgets manually. That way other users can learn about the existence of this new feature too.

@CsomePro
Copy link
Author

I added the StackRelative test at the top of rop.py. And this test error seems to be a problem with the libcdb module.

@peace-maker
Copy link
Member

This reminds me of labels for flat as proposed in #1026 #1063 but the ROP class is a different space. I don't think that label concept is really applicable for rop chains?

@CsomePro
Copy link
Author

CsomePro commented May 31, 2025

This reminds me of labels for flat as proposed in #1026 #1063 but the ROP class is a different space. I don't think that label concept is really applicable for rop chains?

I am also thinking about this question. If I want to set an address precisely to the front or back of a gadget or data during ROP writing, due to the encapsulation of some ROP layouts, how should I do this? Since the length of the data after the gadget is uncertain, it seems difficult to achieve this requirement.

@CsomePro CsomePro requested a review from peace-maker June 6, 2025 16:00
@CsomePro
Copy link
Author

The document is complete and can be reviewed.

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