Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* C standard headers */
- #include <errno.h>
- #include <inttypes.h>
- #include <setjmp.h>
- #include <stdbool.h>
- #include <stddef.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- /* Linux headers */
- #include <dirent.h>
- #include <fcntl.h>
- #include <sys/mman.h>
- #include <sys/ptrace.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <unistd.h>
- #include <sys/user.h>
- /* Architecture-specific headers */
- #include <asm/ptrace.h>
- #include <asm/unistd.h>
- #include <signal.h>
- #include <assert.h>
- typedef void fun_moved_from_context();
- // using namespace std;
- void attachTo(pid_t pid, char* id) {
- long ret = ptrace(PTRACE_ATTACH, pid, NULL, NULL);
- printf("\t%s\tattachTo: %ld\n", id, ret);
- if (ret == -1) perror("err: ");
- }
- void seizeTo(pid_t pid, char* id) {
- long ret = ptrace(PTRACE_SEIZE, pid, NULL, NULL);
- assert(ret > 0);
- printf("\t%s\tseizeTo: %ld\n", id, ret);
- }
- void detachFrom(pid_t pid, char* id) {
- long ret = ptrace(PTRACE_DETACH, pid, NULL, NULL);
- printf("\t%s\tdetachFrom: %ld\n", id, ret);
- }
- void setOptions(pid_t pid, char* id) {
- long ret = ptrace(
- PTRACE_SETOPTIONS, pid, NULL,
- (void*)(PTRACE_O_TRACECLONE | PTRACE_O_TRACEEXEC | PTRACE_O_TRACEEXIT |
- PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK));
- printf("\t%s\tsetOptions: %ld\n", id, ret);
- }
- void setVarData(pid_t pid, volatile bool* can_run, void* data, char* id) {
- long ret = ptrace(PTRACE_POKEDATA, pid, (void*)can_run, (void*)data);
- printf("\t%s\tsetVarData: %ld\n", id, ret);
- }
- void cont(pid_t pid, char* id) {
- long ret = ptrace(PTRACE_CONT, pid, NULL, NULL);
- printf("\t%s\tcont: %ld\n", id, ret);
- }
- void interrupt(pid_t pid, char* id) {
- long ret = ptrace(PTRACE_INTERRUPT, pid, NULL, NULL);
- printf("\t%s\tinterrupt: %ld\n", id, ret);
- }
- int main() {
- volatile bool can_runA = false, can_runB = false;
- pid_t procA = getpid();
- volatile pid_t procB = 0;
- if (fork() > 0) { // process A
- while (!can_runA) {
- printf("\tA\twaiting to continue...\n");
- sleep(1);
- }
- attachTo(procB, "A");
- waitpid(procB, NULL, __WALL);
- setOptions(procB, "A");
- setVarData(procB, &can_runB, 1, "A");
- cont(procB, "A");
- printf("\tA\tfinished\n");
- } else { // process B
- procB = getpid();
- attachTo(procA, "B");
- waitpid(procA, NULL, __WALL);
- setOptions(procA, "B");
- setVarData(procA, &can_runA, 1, "B");
- setVarData(procA, &procB, procB, "B");
- cont(procA, "B");
- while (!can_runB) {
- printf("\tB\twaiting to continue...\n");
- sleep(1);
- }
- printf("\tB\tfinished\n");
- }
- return 0;
- }
Add Comment
Please, Sign In to add comment