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

Use a "universal" ARM+Thumb breakpoint #592

Open
10110111 opened this Issue Aug 24, 2017 · 4 comments

Comments

Projects
None yet
2 participants
@10110111
Contributor

10110111 commented Aug 24, 2017

I'm not too happy with current separation of breakpoints to ARM and Thumb: when we're not sure what type of code we have (and in general we aren't), it's better to have some universal breakpoint instruction. Fortunately, there does exist one: F0 DE F0 E7. It works as UDF 0x0de0 in ARM mode and as a sequence of UDF 0xf0; B .-28 in Thumb mode. Might be even better to use F0 DE FE E7, so that the branch after UDF is B . — the infinite loop (for some safety).
One disadvantage of this instruction sequence is that it results in SIGILL, unlike our current breakpoints, which are hooked by the kernel to result in SIGTRAP. So we first have to implement some code which handles this difference in breakpoint behavior.
Ideally I'd put this into the code generating the debug event, so that Debugger::handle_event didn't have to deal with these differences.

@10110111

This comment has been minimized.

Show comment
Hide comment
@10110111

10110111 Aug 24, 2017

Contributor

BTW, GDB in this situation just sets the wrong breakpoint — the one for ARM. Tested on a ARM-glibc + Thumb-app, stripped, when trying to set a breakpoint at the address of main. The result is that the breakpoint is missed, and the app segfaults after having run many instructions after it.

Contributor

10110111 commented Aug 24, 2017

BTW, GDB in this situation just sets the wrong breakpoint — the one for ARM. Tested on a ARM-glibc + Thumb-app, stripped, when trying to set a breakpoint at the address of main. The result is that the breakpoint is missed, and the app segfaults after having run many instructions after it.

@eteran

This comment has been minimized.

Show comment
Hide comment
@eteran

eteran Aug 24, 2017

Owner

I like the idea of a universal breakpoint. However, we do need to be careful with using a 4 byte breakpoint in thumb mode, because I think it gets messy when dealing with adjacent breakpoints. Think 2 instructions immediately after each other, and we want to set a breakpoint on each...

Owner

eteran commented Aug 24, 2017

I like the idea of a universal breakpoint. However, we do need to be careful with using a 4 byte breakpoint in thumb mode, because I think it gets messy when dealing with adjacent breakpoints. Think 2 instructions immediately after each other, and we want to set a breakpoint on each...

@10110111

This comment has been minimized.

Show comment
Hide comment
@10110111

10110111 Aug 24, 2017

Contributor

This actually is important in the more general case of overlapping multibyte breakpoints (think UD2 on x86).

For ARM though, I think it's more or less solvable with the following rules:

  • For breakpoints on 4-byte-aligned addresses use universal breakpoint, and in particular F0 DE FD E7
  • If we have to add a breakpoint on a 2-byte-aligned address:
    • Before universal breakpoint: just add a 2-byte breakpoint, there's no way it'll interfere with the universal BP following it
    • In the middle of universal breakpoint: don't change any bytes, make note of this fact. Then FD E7 will be treated as a jump to previous instruction (i.e. b .-2), which is already a Thumb breakpoint. We'll have a hard time distinguishing these two though.

In any case I think universal breakpoints should only be used when we don't know type of code (e.g. without analysis and debug information), and in the cases of potential problems warn the user.

Also, single-steppers should employ only mode-specific breakpoints, since they know their context exactly.

Contributor

10110111 commented Aug 24, 2017

This actually is important in the more general case of overlapping multibyte breakpoints (think UD2 on x86).

For ARM though, I think it's more or less solvable with the following rules:

  • For breakpoints on 4-byte-aligned addresses use universal breakpoint, and in particular F0 DE FD E7
  • If we have to add a breakpoint on a 2-byte-aligned address:
    • Before universal breakpoint: just add a 2-byte breakpoint, there's no way it'll interfere with the universal BP following it
    • In the middle of universal breakpoint: don't change any bytes, make note of this fact. Then FD E7 will be treated as a jump to previous instruction (i.e. b .-2), which is already a Thumb breakpoint. We'll have a hard time distinguishing these two though.

In any case I think universal breakpoints should only be used when we don't know type of code (e.g. without analysis and debug information), and in the cases of potential problems warn the user.

Also, single-steppers should employ only mode-specific breakpoints, since they know their context exactly.

@10110111

This comment has been minimized.

Show comment
Hide comment
@10110111

10110111 Sep 5, 2017

Contributor

I've come across a problem with this type of breakpoint: when it's put on a non-4-byte-aligned address, it results in the situation where ARM two bytes further simply is messed up without actually breaking. This leads to unpredictable effects, normally resulting in a subsequent segfault. So at least, this type of breakpoints shouldn't be used on "obviously-Thumb" addresses.
I suppose this type of breakpoints actually should never be used by EDB by its own initiative — only when the user told EDB to do so.

Contributor

10110111 commented Sep 5, 2017

I've come across a problem with this type of breakpoint: when it's put on a non-4-byte-aligned address, it results in the situation where ARM two bytes further simply is messed up without actually breaking. This leads to unpredictable effects, normally resulting in a subsequent segfault. So at least, this type of breakpoints shouldn't be used on "obviously-Thumb" addresses.
I suppose this type of breakpoints actually should never be used by EDB by its own initiative — only when the user told EDB to do so.

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