hugsy / gef

GEF (GDB Enhanced Features) - a modern experience for GDB with advanced debugging capabilities for exploit devs & reverse engineers on Linux
https://hugsy.github.io/gef
MIT License
6.94k stars 730 forks source link

[Bug] 'gef-remote' failed to execute properly, reason: [Errno 17] File exists #1128

Open Cnly opened 1 month ago

Cnly commented 1 month ago

GEF+GDB version

GEF: (Standalone)
Blob Hash(/home/parallels/.gef-2024.06.py): 88981e223320723f9df39bd8714ea2d56da4dbee
SHA256(/home/parallels/.gef-2024.06.py): 764738509912bea65f67927691d5fa0421444d1969678208095733fdbf0dd83d
GDB: 15.1
GDB-Python: 3.12

Operating System

Kali Linux

Describe the issue you encountered

When I try to use gef-remote --qemu-user --qemu-binary ~/Desktop/<executable> localhost 1234, the command fails with the error

[!] Command 'gef-remote' failed to execute properly, reason: [Errno 17] File exists: '/tmp/tmp_k7juwvp/home/parallels/Desktop'

which seems to be a result of this exist_ok=False flag: https://github.com/hugsy/gef/blob/1b6f46a0054eb2600919ffde4d930319452d9fe4/gef.py#L11481

I also tested with the main branch (674c74d) and the problem still exists. Setting the flag to True solves the problem. If this is the correct fix, I'm happy to open a PR from my fork.

Do you read the docs and look at previously closed issues/PRs for similar cases?

Yes

Architecture impacted

Describe your issue. Without a proper reproduction step-by-step, your issue will be ignored.

  1. Compile the minimalist test case.
  2. Run it with qemu-arm64 -g 1234 a.out
  3. gdb-multiarch -ex 'gef-remote --qemu-user --qemu-binary /path/to/a.out localhost 1234'

Minimalist test case

// compile with gcc -fPIE -fpic a.c
int main(){ return 0; }

Additional context?

No response

ValekoZ commented 1 month ago

Why does this directory already exists? If it's a correct behavior to mkdir this directory multiple times, then I guess your fix should be good :)

Cnly commented 3 weeks ago

@ValekoZ So I spent some more time digging around and found this line

https://github.com/hugsy/gef/blob/1b6f46a0054eb2600919ffde4d930319452d9fe4/gef.py#L6247

where session.connect() sets up a remote_objfile_event_handler which self.sync()s the remote file to local on gdb.events.NewObjFileEvent. This creates the directory in question. Later, session.setup() calls self.__setup_qemu() which contains code to copy the executable to the same location, causing the error.

It seems to me a better fix would be to replace these lines

https://github.com/hugsy/gef/blob/1b6f46a0054eb2600919ffde4d930319452d9fe4/gef.py#L11480-L11482

with a simple self.sync() call. Is this doable? Is there any reason / specific case where we would need the copy2() instead of the remote get gdb command as used in sync()?

ValekoZ commented 3 weeks ago

In this case, in your command you specify a qemu-binary manually, so we want to copy it instead of just syncing using gdb remote get, so as far as I understand this code, it is fine like it is currently so that if we can't sync using gdb's features we can do it manually, but then we should accept that the directory already exists so your fix should be fine imo. @hugsy maybe I'm wrong, could you double check? I never really checked how the qemu part works :sweat_smile:

Cnly commented 3 weeks ago

Hmmm, just to add some info here, the docs instruct users to

Use --qemu-user and --qemu-binary /bin/ls when starting gef-remote

And if the binary is not manually specified, it seems it's still automatically set by the code:

https://github.com/hugsy/gef/blob/1b6f46a0054eb2600919ffde4d930319452d9fe4/gef.py#L6232