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

Reorder reset_arch: param forced, elf header, gdb conf #1004

Merged
merged 1 commit into from
Nov 29, 2023

Conversation

josx
Copy link
Contributor

@josx josx commented Sep 2, 2023

Description

Reorder how on reset_architecture fn is going to find arch. Now:

  • Param forced
  • Elf header
  • gdb conf

It is based on chat on #947 with @Grazfather

This change is needed because if first check for gdb conf if some has another language active would raise an exception making gef not work at all (some code match only english sentences).

This pattch would help non englihs users of gdb to not have many problems to use gef.

Checklist

  • My code follows the code style of this project.
  • My change includes a change to the documentation, if required.
  • If my change adds new code, adequate tests have been added.
  • I have read and agree to the CONTRIBUTING document.

@github-actions
Copy link

github-actions bot commented Sep 2, 2023

🤖 Coverage Update

  • Commit: 6a6e2a0
  • Current Coverage: 71.6614%
  • New Coverage: 71.6614%
  • Diff: 0.0

To this point, this PR:

  • does not include changes to tests
  • does not include changes to documentation
  • does not include forbidden words

@hugsy
Copy link
Owner

hugsy commented Sep 12, 2023

Hi @josx

First thanks for your PR but to be honest I'm not big on merging this: it doesn't fix the problem, just moves it as a last case hoping the first 2 conditions will be met.

Like I mentioned in the thread, the correct approach is to entirely remove the obsolete function get_arch by changing the only one spot it is still used, and where it parses the output string - expecting an english version of the error message.

Considering we only support ELF in GEF, having a valid gef.binary.e_machine should not be a big ask and that logic would make things a bit easier if/when we decide to finalize supporting PE/MachO.

@josx
Copy link
Contributor Author

josx commented Sep 12, 2023

Sorry but i dont get very well, what do you want to do?
get rid of get_arch and just returning param set or e_machine?

@hugsy
Copy link
Owner

hugsy commented Sep 12, 2023

Sorry but i dont get very well, what do you want to do?
get rid of get_arch and just returning param set or e_machine?

The function get_arch() is an old function designed to abstract how GEF determines the architecture to use. Originally it was only using the show arch native GDB command and parsing the output string (where your problem originates).

Over time, other methods were added to determine the architecture to use. Currently the most reliable is through the parsing of the ELF file itself. So get_arch() which used to be used everywhere, is now only used in 1 location - in reset_architecture where you tried to apply your change.

gef/gef.py

Lines 3682 to 3695 in 5927df4

gdb_arch = get_arch()
preciser_arch = next((a for a in arches.values() if a.supports_gdb_arch(gdb_arch)), None)
if preciser_arch:
gef.arch = preciser_arch()
return
# last resort, use the info from elf header to find it from the known architectures
try:
arch_name = gef.binary.e_machine if gef.binary else gdb_arch
gef.arch = arches[arch_name]()
except KeyError:
raise OSError(f"CPU type is currently not supported: {get_arch()}")
return

So what I'm suggesting is to re-work the logic so we don't need get_arch altogether, making the issue you're having nil.

There are currently (AFAIK) 2 ways to determine the architecture from the Python API, and both require the ELF to be loaded.

  1. either using gdb.selected_frame().architecture() if the bin is running
  2. either using the ELF header is not (gef.binary.e_machine)

So the only thing is in reset_architecture, we need is to make sure we match the architecture names for both cases so that doing gef.arch = arches[arch_name]() on L3692 (almost) never fails.

It is a bit more work but worth it, as we'll be also improving the perf (gdb.execute is very slow).

Hope this clarifies my point.

@josx
Copy link
Contributor Author

josx commented Sep 12, 2023

Ok this clarify me a little more, something like this would work for you (BTW i get rid of get_arch):

def reset_architecture(arch: Optional[str] = None) -> None:
    """Sets the current architecture.
    If an architecture is explicitly specified by parameter, try to use that one. If this fails, an `OSError`
    exception will occur.
    If no architecture is specified, then GEF will attempt to determine automatically based on the current
    ELF target. If this fails, an `OSError` exception will occur.
    """
    global gef
    arches = __registered_architectures__

    # check if the architecture is forced by parameter
    if arch:
        try:
            gef.arch = arches[arch]()
        except KeyError:
            raise OSError(f"Specified arch {arch.upper()} is not supported")
        return

    # check for bin running
    if is_alive():
        try:
            arch = gdb.selected_frame().architecture()
            gef.arch = arches[arch.name()]()
        except KeyError:
            raise OSError(f"Running Binary arch {arch.name().upper()} is not supported")
        return

    # check for elf header architecture
    if gef.binary.e_machine:
        try:
            gef.arch = arches[gef.binary.e_machine]()
        except KeyError:
            raise OSError(f"CPU type is currently not supported: {gef.binary.e_machine}")
        return

    # Unknown, we throw an exception to be safe
    raise RuntimeError(f"Unknown architecture: {arch_str}")

@hugsy
Copy link
Owner

hugsy commented Sep 12, 2023

Yes, this is much closer to what I had in mind.

@josx
Copy link
Contributor Author

josx commented Sep 12, 2023

Let me update de PR

@josx josx force-pushed the reorder_reset_arch branch from c49ea4f to 53d0aa5 Compare September 12, 2023 21:41
@github-actions
Copy link

🤖 Coverage Update

  • Commit: 5927df4
  • Current Coverage: 71.6387%
  • New Coverage: 71.6387%
  • Diff: 0.0

To this point, this PR:

  • does not include changes to tests
  • does not include changes to documentation
  • does not include forbidden words

Copy link
Owner

@hugsy hugsy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems all good, just minor changes

gef.py Show resolved Hide resolved
gef.py Outdated Show resolved Hide resolved
gef.py Outdated Show resolved Hide resolved
gef.py Outdated Show resolved Hide resolved
@hugsy
Copy link
Owner

hugsy commented Sep 13, 2023

By the way @josx do you confirm this PR solves your problem?

@josx josx force-pushed the reorder_reset_arch branch from 53d0aa5 to 7042208 Compare September 14, 2023 13:03
@github-actions
Copy link

🤖 Coverage Update

  • Commit: 5927df4
  • Current Coverage: 71.6387%
  • New Coverage: 71.6387%
  • Diff: 0.0

To this point, this PR:

  • does not include changes to tests
  • does not include changes to documentation
  • does not include forbidden words

@josx
Copy link
Contributor Author

josx commented Sep 14, 2023

By the way @josx do you confirm this PR solves your problem?

Yes, solves my problem.

@josx
Copy link
Contributor Author

josx commented Sep 14, 2023

Updated with your comments.

Copy link
Owner

@hugsy hugsy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

supports_gdb_arch was removed, it should not be as it is an important part of the logic to let users enforce their own gdb arch with gef. It should be restored

gef.py Outdated Show resolved Hide resolved
gef.py Show resolved Hide resolved
@josx josx force-pushed the reorder_reset_arch branch from 7042208 to c34bda9 Compare September 14, 2023 18:48
@github-actions
Copy link

🤖 Coverage Update

  • Commit: 5927df4
  • Current Coverage: 71.6387%
  • New Coverage: 71.6387%
  • Diff: 0.0

To this point, this PR:

  • does not include changes to tests
  • does not include changes to documentation
  • does not include forbidden words

@josx josx requested a review from hugsy October 2, 2023 12:56
@hugsy
Copy link
Owner

hugsy commented Nov 1, 2023

Sorry for the delay I was on long holiday. I'll review this PR asap

@josx
Copy link
Contributor Author

josx commented Nov 2, 2023

No problem. Every one deserves a long vacation :)

Copy link
Owner

@hugsy hugsy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@hugsy hugsy merged commit 295cbf7 into hugsy:main Nov 29, 2023
@hugsy
Copy link
Owner

hugsy commented Nov 29, 2023

Quick local tests went ok so merging.
Thanks @josx 🙌 apologies for the (extreme) delay on this

@hugsy hugsy added this to the 2024.01 milestone Dec 22, 2023
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