Skip to content
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

Command namebreak seems to be broken #707

Closed
4 tasks done
Kileak opened this issue Sep 4, 2021 · 3 comments · Fixed by #710
Closed
4 tasks done

Command namebreak seems to be broken #707

Kileak opened this issue Sep 4, 2021 · 3 comments · Fixed by #710
Labels

Comments

@Kileak
Copy link
Contributor

Kileak commented Sep 4, 2021

  • Did you use the latest version of GEF from dev branch?
  • Is your bug specific to GEF (not GDB)? - Try to reproduce it running gdb -nx
  • Did you read the documentation first?
  • Did you check issues (including
    the closed ones) - and the PR?

Step 1: Describe your environment

  • Operating System / Distribution: Ubuntu 20.10
  • Architecture: amd64
  • GEF version (including the Python library version) run version in GEF.
GEF: rev:169e6e6dad57fe1325b1cabafbaf405cd5705cb7 (Git - clean)
SHA1(/home/kileak/Tools/gef/gef.py): cd2793e58829c5b047204f8b73cb53d2c8835015
GDB: 9.2
GDB-Python: 3.8

Step 2: Describe your problem

namebreakisn't working anymore as expected. namebreak supported adding breakpoints on direct addresses as for symbols or current ip.

Examples:

nb test *main+120
nb test2 *0x400650
nb test3

All those commands now result in an error message in current gef (see Observed results)

Reason for this seems to be, that the parsing of the user argument for the breakpoint address has been changed from:

location = argv[1] if len(argv) > 1 else "*{}".format(hex(current_arch.pc))

to a new parsing style:

location = parse_address(args.address)
NamedBreakpoint(location, args.name)

The output of parse_address though doesn't seem to play well with the Breakpoint class.

After changing it back to something more like the old version (using $pc variable also didn't work for me):

location = "*{}".format(current_arch.pc) if args.address == "$pc" else args.address
NamedBreakpoint(location, args.name)

namebreak worked again, as it used to (with direct addresses, symbols and current pc).

Though I assume, you tried to achieve something else with the new parsing attributes there, so I didn't create a pull request, since this fix doesn't seem to fit into the attribute based parsing, so maybe you can come up with a better solution (but at least this fixed it for me again).

Steps to reproduce

  1. Start gef with any binary
  2. Try to add a named breakpoint like nb test *main+10

Observed Results

  • What happened? This could be a description, log output, etc.
─────────────────────────────── Exception raised ───────────────────────────────
TypeError: argument 1 must be str, not int
───────────────────────────── Detailed stacktrace ──────────────────────────────
↳ File "~/Tools/gef_dev/gef/gef.py", line 4209, in __init__()
    →             super().__init__(spec=location, type=gdb.BP_BREAKPOINT, internal=False, temporary=False)
↳ File "~/Tools/gef_dev/gef/gef.py", line 7766, in do_invoke()
    →             NamedBreakpoint(location, args.name)
↳ File "~/Tools/gef_dev/gef/gef.py", line 2705, in wrapper()
    →                 return f(*args, **kwargs)
↳ File "~/Tools/gef_dev/gef/gef.py", line 243, in wrapper()
    →                 rv = f(*args, **kwargs)
↳ File "~/Tools/gef_dev/gef/gef.py", line 4281, in invoke()
    →                 bufferize(self.do_invoke)(argv)
─────────────────────────────────── Version ────────────────────────────────────
GEF: rev:169e6e6dad57fe1325b1cabafbaf405cd5705cb7 (Git - clean)
SHA1(/home/kileak/Tools/gef_dev/gef/gef.py): cd2793e58829c5b047204f8b73cb53d2c8835015
GDB: 9.2
GDB-Python: 3.8
Loaded commands: $, aliases, aliases add, aliases ls, aliases rm, aslr, canary, capstone-disassemble, checksec, context, dereference, edit-flags, elf-info, entry-break, format-string-helper, functions, gef-remoteh
───────────────────────────── Last 10 GDB commands ─────────────────────────────
    1  nb test3 *read+24
───────────────────────────── Runtime environment ──────────────────────────────
* GDB: 9.2
* Python: 3.8.10 - final
* OS: Linux - 5.8.0-63-generic (x86_64)
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 20.10
Release:	20.10
Codename:	groovy
────────────────────────────────────────────────────────────────────────────────

Expected results

  • What did you expect to happen?
gef➤  nb test *read+24
Breakpoint 2 at 0x7ffff7ebde88: file ../sysdeps/unix/sysv/linux/read.c, line 26.
@Kileak Kileak added the triage label Sep 4, 2021
theguy147 added a commit to theguy147/gef that referenced this issue Sep 4, 2021
@Grazfather
Copy link
Collaborator

Fixed on dev by #708. Could you please verify?

@Kileak
Copy link
Contributor Author

Kileak commented Sep 5, 2021

No, this doesn't fix the issue completely.

nb should accept breakpoint definition in the same way b does.

gef➤  b *0x7ffff7ebe33d
Breakpoint 7 at 0x7ffff7ebe33d: file ../sysdeps/unix/sysv/linux/connect.c, line 26.
gef➤  b *connect+31
Breakpoint 8 at 0x7ffff7ebe33f: file ../sysdeps/unix/sysv/linux/connect.c, line 26.
gef➤  b
Breakpoint 9 at 0x7ffff7ebe337: file ../sysdeps/unix/sysv/linux/connect.c, line 26.
gef➤  b 0x7ffff7ebe33d
Function "0x7ffff7ebe33d" not defined.
gef➤  nb t1 *0x7ffff7ebe33d
Breakpoint 14 at 0x48c35177   <-- Wrong breakpoint (address got derefed)
gef➤  nb t2 *connect+31
Breakpoint 15 at 0x7ffff7ebe33f: file ../sysdeps/unix/sysv/linux/connect.c, line 26.  
^-- Ok, but it did a breakpoint on **connect+31
gef➤  nb t3
Breakpoint 16 at 0x7ffff7ebe337: file ../sysdeps/unix/sysv/linux/connect.c, line 26.  <-- Correct
gef➤  nb t4 0x7ffff7ebe33d   <-- This should not result in a breakpoint but an error message
Breakpoint 17 at 0x7ffff7ebe33d: file ../sysdeps/unix/sysv/linux/connect.c, line 26. 

So, for direct addresses, it will still create a wrong breakpoint (addresses have to be passed with a * and the fix makes it to a **), because it will dereference the address before passing it to Breakpoint.

And for breakpoints on symbols this only works, because you can put as many *s before connect+31 as you want, it will always result in the same breakpoint. But it's not really accurate program logic wise, since it will forward a b **conect+31 instead of b *connect+31, which just coincidentially results in the same breakpoint).

I don't see the need of calling parse_address here, other than resolving $pc. In all other cases, the user will already have given the correct argument to be passed to Breakpoint, which shouldn't be altered.

Changing the fix to:

address = "*{}".format(parse_address(location)) if location=="$pc" else location

results in almost same behaviour for all three cases like normal b

gef➤  nb t1 *0x7ffff7ebe33d
Breakpoint 1 at 0x7ffff7ebe33d: file ../sysdeps/unix/sysv/linux/connect.c, line 26.
gef➤  nb t2 *connect+31
Breakpoint 2 at 0x7ffff7ebe33f: file ../sysdeps/unix/sysv/linux/connect.c, line 26.
gef➤   nb t3
Breakpoint 3 at 0x7ffff7ebe337: file ../sysdeps/unix/sysv/linux/connect.c, line 26.
gef➤  nb t4 0x7ffff7ebe33d
Function "0x7ffff7ebe33d" not defined.
Breakpoint 4 (0x7ffff7ebe33d) pending.

Default b would not create a pending breakpoint in the last example, but that's negligible.

@Kileak
Copy link
Contributor Author

Kileak commented Sep 5, 2021

After checking the code a bit more, it's even easier to fix it properly, by just setting the default value for address if none is given to *$pc instead of $pc.

Then, no parsing would be needed at all, and we can just pass the user input forward. Looks like the cleanest solution to me for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants