1

I need to run another process that needs to ptrace() its inferior. But also gdb needs to ptrace() the same inferior as well, so this will lead to chaos.

The first and obvious solution that came to my mind was to detach the gdb whenever the other process needs to access the inferior and then attach again. However, this is also problematic when the inferior is stopped for debugging.

Then I tried to launch the other process from gdb using gdb's shell command thinking maybe it can work if gdb executes the other process as its child. But even when gdb executes it as a child, they'll have different PIDs, so the problem still continues.

Is it possible to make gdb and the other process look like they share the same PID so they can attach to the same inferior?

2
  • Linux prohibits two processes from invoking ptrace on the same target. What are you trying to accomplish, exactly? Commented Feb 17, 2016 at 14:23
  • I want to run scanmem along with gdb to do some basic memory searching. I also tried to use gdb's find command to do it but it's too slow. Commented Feb 17, 2016 at 14:32

3 Answers 3

3

No, there's no way to do this.

Your best bet is to add new code to gdb to do what you want.

Sign up to request clarification or add additional context in comments.

1 Comment

I see, this was the comment I was afraid of getting. Welp, it seems like I have no option left other than hacking into the gdb. Time to learn something brand new(and scary).
2

It is not completely impossible. Just very very very difficult. Probably more difficult than it's worth (i.e. - than hacking gdb). It is, however, what fakeroot-ng does in order to allow strace to work.

The idea is that, if you run both your target process and gdb traced by the same debugger, you can emulate the ptrace calls done by gdb, and perform them yourself. The result is that gdb thinks it is tracing your child process, but you are, in fact, the one tracing it in practice.

Like I said above, this apprach is, in no way, simpler than hacking gdb to just do what you want.

Comments

0

Solution 1: do not use ptrace

In recent versions of Linux (since 3.2), a process can read/write another process memory without ptracing it first:

  • either by open/read/write-ing /proc/$pid/mem (before Linux 3.2, it was only possible to read from this file when the target process was stopped but since Linux 3.2 you do not need to stop the target process);

  • or using the new system calls process_vm_readv() and process_vm_write().

scanmem could be adapted to avoid ptracing the target process and use those methods instead. As scanmem only uses PTRACE_ATTACH, PTRACE_DETACH, PTRACE_PEEKDATA and and PTRACE_POKEDATA, it should be possible to simply write a ptrace-less version.

Solution 2: GDB server

Summary:

[GDB] ----------> [ tracer ] ---> [ traced ] GDB protocol ptrace 

You have three processes:

  • the GDB process;

  • the (other) tracer process;

  • the traced process.

The idea is that GDB does not ptrace the traced process itself.

Instead, you want to modify the tracer in order to expose a gdbserver-like interface to GDB using the GDB protocol. Instead of tracing the traced process, GDB connects to the tracer which can do the operations on the tracer on behalf of GDB.

This means that the tracer must manage its ptrace operations in order to do both the GDB stuff and its own stuff which is probably not an easy task.

This second solution is way too complex/overkill for what you cant to achieve however.

7 Comments

It seems that scanmem uses ptrace. Can you point to how to get access to another process' memory without ptrace at all?
A simple example, is this program (github.com/randomstuff/unjit) I wrote which reads JIT-compiled code from another process without ptrace-ing it and disassemble it (github.com/randomstuff/unjit/blob/…).
Is there a reason you don't simply point to the syscall/proc file/whatever that was added in Linux version 3.2 that allows to do it? From reading your code, all i can see is that you use libelf to load the ELF file a given process uses, which would, of course, allow you to disassemble it, but that's not reading another process' address space.
The second link points to a call to process_vm_readv which is the system call we are talking about :)
Updated the answer.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.