implement attaching and detaching to process threads
This commit is contained in:
parent
57c74b1abb
commit
0196d39a4b
3 changed files with 70 additions and 3 deletions
|
|
@ -55,4 +55,10 @@ int find_active_thread(process_status_t* list, size_t count, process_status_t**
|
||||||
// check if this process has any capability or is ran as root to be able to ptrace attach
|
// check if this process has any capability or is ran as root to be able to ptrace attach
|
||||||
int check_ptrace_permissions();
|
int check_ptrace_permissions();
|
||||||
|
|
||||||
|
// attach to all threads of the process. on error returns 1 and detaches from already attached
|
||||||
|
int process_attach_all(process_status_t* threads, size_t thread_count);
|
||||||
|
|
||||||
|
// detaches from all threads
|
||||||
|
void process_detach_all(process_status_t* threads, size_t thread_count);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
24
src/main.c
24
src/main.c
|
|
@ -1,7 +1,9 @@
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include "process.h"
|
#include "process.h"
|
||||||
|
|
||||||
void print_process(process_status_t* proc)
|
void print_process(process_status_t* proc)
|
||||||
|
|
@ -69,15 +71,31 @@ int main(int argc, char** argv)
|
||||||
puts("Active thread:");
|
puts("Active thread:");
|
||||||
print_process(active);
|
print_process(active);
|
||||||
|
|
||||||
free(threads);
|
|
||||||
free(list);
|
|
||||||
|
|
||||||
if (!check_ptrace_permissions())
|
if (!check_ptrace_permissions())
|
||||||
{
|
{
|
||||||
fputs("this process doesn't have permission to ptrace.\n", stderr);
|
fputs("this process doesn't have permission to ptrace.\n", stderr);
|
||||||
fputs("either run as root or set caps.\n", stderr);
|
fputs("either run as root or set caps.\n", stderr);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// attach
|
||||||
|
if (process_attach_all(threads, thread_count))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "failed to attach: %s\n", strerror(errno));
|
||||||
|
|
||||||
|
free(threads);
|
||||||
|
free(list);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
puts("attached to all threads. press any key");
|
||||||
|
getc(stdin);
|
||||||
|
|
||||||
|
process_detach_all(threads, thread_count);
|
||||||
|
|
||||||
|
free(threads);
|
||||||
|
free(list);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
#include "process.h"
|
#include "process.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include <sys/capability.h>
|
#include <sys/capability.h>
|
||||||
|
#include <sys/ptrace.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
|
@ -235,4 +237,45 @@ int check_ptrace_permissions()
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int process_attach_all(process_status_t* threads, size_t thread_count)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < thread_count; i++)
|
||||||
|
{
|
||||||
|
pid_t pid = threads[i].pid;
|
||||||
|
if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0)
|
||||||
|
{
|
||||||
|
// we've encountered error. now we must detach from attached and return 1
|
||||||
|
process_detach_all(threads, i+1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// now wait for thread to be stopped
|
||||||
|
int wstatus;
|
||||||
|
do {
|
||||||
|
waitpid(pid, &wstatus, 0);
|
||||||
|
#if DEBUG
|
||||||
|
if (WIFEXITED(wstatus)) {
|
||||||
|
TRACE("exited, status=%d\n", WEXITSTATUS(wstatus));
|
||||||
|
} else if (WIFSIGNALED(wstatus)) {
|
||||||
|
TRACE("killed by signal %d\n", WTERMSIG(wstatus));
|
||||||
|
} else if (WIFSTOPPED(wstatus)) {
|
||||||
|
TRACE("stopped by signal %d\n", WSTOPSIG(wstatus));
|
||||||
|
} else if (WIFCONTINUED(wstatus)) {
|
||||||
|
TRACE("continued\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
} while (!(WIFSTOPPED(wstatus) && WSTOPSIG(wstatus) == SIGSTOP));
|
||||||
|
|
||||||
|
// since thread is properly stopped we can continue to the next one
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void process_detach_all(process_status_t* threads, size_t thread_count)
|
||||||
|
{
|
||||||
|
while (thread_count--) ptrace(PTRACE_DETACH, threads[thread_count].pid, NULL, NULL);
|
||||||
}
|
}
|
||||||
Loading…
Add table
Reference in a new issue