I want to create a simple tool (with C) which can do this tiny subset of gdb
s features:
- Attach to an already running program (with PID)
- Inject instructions into it like this:
dup2(open("/tmp/my_stdout", 1089, 0777), 1)
GDB can do this without issues, but it has a massive source.
What Im looking for is some kind of starting point of guidance.
There are tons of information on Google but all of them are 10ish years old, and I need to make this work on aarch64 arch which was not existed by that time.
Really, any help is greatly appreciated.
I tried to strace gdb while it is attaching to a process, but my terminal blowed up literally.
CodePudding user response:
Im looking for is some kind of starting point of guidance.
Take a look at the unwind-pid example here. It uses ptrace to unwind the stack of an alien process, identified by PID.
Note: you could ignore all the unw_*
calls. The "attach to pid" part is rather trivial:
pid_t pid = atoi(argv[1]);
if (ptrace(PTRACE_ATTACH, pid, 0, 0) != 0)
die("ERROR: cannot attach to %d\n", pid);
...
(void) ptrace(PTRACE_DETACH, pid, 0, 0);
Inject instructions into it like this:
dup2(open("/tmp/my_stdout", 1089, 0777), 1)
Search for "Linux inject code into running process". Here is one example.
Update:
That will not work, I think. I don't want to dup2 the tracer's stdout. I want to dup2 the tracee's stdout!
Yes you do, and yes it will.
Well, maybe not quite (you could do it with code injection, but you don't have to).
What you want to do is construct (on the stack and in registers) the state of the tracee as if it just called open("/tmp/my_stdout", ...)
itself. Then set a breakpoint after open
returns, set IP
to open
and resume the tracee. The tracee will run until the breakpoint, at which point you will have an open fd
in the results register. Now repeat the same process for dup2
, and you are done.