Skip to content

ROP should also use __setattr__ to automatically set register values with setRegisters #1636

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

Closed
heapcrash opened this issue Jul 10, 2020 · 6 comments
Labels
feature rop Return Oriented Programming manipulation routines

Comments

@heapcrash
Copy link
Collaborator

Currently, if you have a ROP gadget that has a pop eax; ret gadget, you can access ROP.eax and get the gadget information.

This should work in the other direction, so that setting e.g. rop.rax = 0xdeadbeef adds the correct data to the stack.

@heapcrash heapcrash added feature rop Return Oriented Programming manipulation routines labels Jul 10, 2020
@mariuszskon
Copy link
Contributor

Hi,
I am interested in working on this.
The only thing I am unsure of at the moment is how we would handle setting multiple registers "at once" i.e. with the minimum number of rop chains. I see that we are using _ delimited registers in __getattr__:

        #
        # Check for a '_'-delimited list of registers
        #
        x86_suffixes = ['ax', 'bx', 'cx', 'dx', 'bp', 'sp', 'di', 'si',
                        'r8', 'r9', '10', '11', '12', '13', '14', '15']

        if all(map(lambda x: x[-2:] in x86_suffixes, attr.split('_'))):
            return self.search(regs=attr.split('_'), order='regs')

But what should go on the right hand side of the assignment? A tuple? e.g.

rop.rax_rdi_rsi = (0xdead, 0xbeef, 0xcafe)

This looks a bit ugly to me, but I'm not sure what else we can do.
Ideally something like this would work, but would require each __setattr__ call to check previous ones:

rop.rax = 0xdead
rop.rdi = 0xbeef
rop.rsi = 0xcafe
rop.chain()  # minimum rop chain for setting all of the above, not three separate chains (if possible)

Thanks,
Mariusz

@Arusekk
Copy link
Member

Arusekk commented Sep 26, 2020

Yes, this is a good option, but I don't think this would be required. Most will actually use it with a single register name.

A pretty pretty option would be to allow something like this:

rop = ROP(context.binary)
rop(rax=0xdead, rdi=0xbeef, rsi=0xcafe)

@mariuszskon
Copy link
Contributor

Indeed the __call__ interface @Arusekk proposes appears quite pleasant. Any other opinions?

@zachriggle
Copy link
Member

zachriggle commented Sep 28, 2020 via email

@Arusekk
Copy link
Member

Arusekk commented Sep 28, 2020

See #1681

@mariuszskon
Copy link
Contributor

Please see my PR #1688

@Arusekk Arusekk closed this as completed in bcb6e06 Oct 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature rop Return Oriented Programming manipulation routines
Projects
None yet
Development

No branches or pull requests

4 participants