Changeset 3873


Ignore:
Timestamp:
11/02/09 16:07:54 (4 years ago)
Author:
pterjan
Message:
  • Improve consoles state after grabbing
Location:
neercs/trunk/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • neercs/trunk/src/grab.c

    r3501 r3873  
    1717#define _XOPEN_SOURCE 500 /* getsid() */ 
    1818 
    19 #include <stdio.h> 
    20 #include <stdlib.h> 
     19#include <dirent.h> 
    2120#include <errno.h> 
    2221#include <fcntl.h> 
    2322#include <signal.h> 
     23#include <stdio.h> 
     24#include <stdlib.h> 
    2425#include <string.h> 
    2526#include <unistd.h> 
     
    4142    char fdstr[1024]; 
    4243    struct mytrace *parent, *child; 
    43     int i, fd = 0, ret; 
    44     char to_open[3]; 
    45     int mode[3]; 
     44    int i = 0, fd = 0, ret; 
     45    char to_open[128]; 
     46    int mode[128]; 
     47    int fds[128]; 
    4648    struct stat stat_buf; 
     49    struct termios tos; 
     50    int validtos = 0; 
     51    DIR *fddir; 
     52    struct dirent *fddirent; 
    4753 
    4854    debug("pty is %s", ptyname); 
     
    5460        return -1; 
    5561    } 
    56  
     62     
    5763    child = mytrace_fork(parent); 
    58     ret = mytrace_exec(parent, "/usr/bin/reset"); 
    59     if(ret < 0) 
    60         mytrace_exit(parent, 0); 
    61     mytrace_detach(parent); 
    62     waitpid(pid, NULL, 0); /* Wait for reset to finish before displaying */ 
    63     mytrace_write(child, 1, "\x1b[H\x1b[2J", 7); 
    64     mytrace_write(child, 1, "\n[Process stolen by neercs]\r\n\n", 30); 
    65     pid = mytrace_getpid(child); 
     64  
     65    snprintf(fdstr, sizeof(fdstr), "/proc/%ld/fd", pid); 
     66    fddir = opendir(fdstr); 
    6667 
    6768    /* Look for file descriptors that are PTYs */ 
    68     for(i = 0; i <= 2; i++) 
     69    while((fddirent = readdir(fddir)) && i < (int)sizeof(to_open)-1) 
    6970    { 
    70         snprintf(fdstr, sizeof(fdstr), "/proc/%ld/fd/%d", pid, i); 
     71        fd = atoi(fddirent->d_name); 
     72        fds[i] = fd; 
    7173        to_open[i] = 0; 
    7274        lstat(fdstr, &stat_buf); 
     
    7880            mode[i] = O_RDONLY; 
    7981 
     82        snprintf(fdstr, sizeof(fdstr), "/proc/%ld/fd/%s", pid, fddirent->d_name); 
     83    
    8084        if(stat(fdstr, &stat_buf) < 0) 
    8185            continue; 
     
    8589            continue; 
    8690 
    87         debug("found pty %d for pid %d", i, pid); 
     91        debug("found pty %d for pid %d", fd, pid); 
    8892 
    89         ret = mytrace_close(child, i); 
    90         if(ret < 0) 
     93        if(!validtos) 
    9194        { 
    92             perror("mytrace_close"); 
     95            ret = mytrace_tcgets(child, fd, &tos); 
     96            if(ret < 0) 
     97            { 
     98                perror("mytrace_tcgets"); 
     99            } 
     100            else 
     101            { 
     102                validtos = 1; 
     103            } 
    93104        } 
    94105        to_open[i] = 1; 
     106        i++; 
     107    } 
     108    closedir(fddir); 
     109     
     110    if(i>=(int)sizeof(to_open)-1) 
     111    { 
     112        fprintf(stderr, "too many open pty\n"); 
     113        mytrace_detach(child); 
     114        return -1; 
     115    } 
     116 
     117    if(parent) 
     118    { 
     119        ret = mytrace_exec(parent, "/usr/bin/reset"); 
     120        if(ret < 0) 
     121            mytrace_exit(parent, 0); 
     122        mytrace_detach(parent); 
     123        waitpid(pid, NULL, 0); /* Wait for reset to finish before displaying */ 
     124        mytrace_write(child, 2, "\x1b[H\x1b[2J", 7); 
     125        mytrace_write(child, 2, "\n[Process stolen by neercs]\r\n\n", 30); 
    95126    } 
    96127 
     
    124155 
    125156    /* Reopen PTY file descriptors */ 
    126     for(i = 0; i <= 2; i++) 
     157    for(; i >= 0; i--) 
    127158    { 
    128159        if(!to_open[i]) 
    129160            continue; 
     161        ret = mytrace_close(child, fds[i]); 
     162        if(ret < 0) 
     163        { 
     164            perror("mytrace_close"); 
     165            continue; 
     166        } 
    130167        fd = mytrace_open(child, ptyname, mode[i]); 
    131168        if(fd < 0) 
    132169        { 
    133170            perror("mytrace_open"); 
     171            continue; 
    134172        } 
    135         ret = mytrace_dup2(child, fd, i); 
     173        if(validtos) 
     174        { 
     175            ret = mytrace_tcsets(child, fd, &tos); 
     176            if(ret < 0) 
     177            { 
     178                perror("mytrace_tcsets"); 
     179            } 
     180            validtos = 0; 
     181        } 
     182        ret = mytrace_dup2(child, fd, fds[i]); 
    136183        if(ret < 0) 
    137184        { 
  • neercs/trunk/src/mytrace.c

    r3871 r3873  
    2424 
    2525#if defined USE_GRAB 
     26#   include <sys/ioctl.h> 
    2627#   include <sys/ptrace.h> 
    2728#   include <sys/stat.h> 
     
    8990#define MYCALL_EXIT     8 
    9091#define MYCALL_EXECVE   9 
     92#define MYCALL_IOCTL   10 
    9193 
    9294#if defined __x86_64__ 
    9395/* from unistd_32.h on an amd64 system */ 
    94 int syscalls32[] = { 5, 6, 4, 63, 57, 66, 37, 2, 1, 11 }; 
     96int syscalls32[] = { 5, 6, 4, 63, 57, 66, 37, 2, 1, 11, 54 }; 
    9597int syscalls64[] = 
    9698#else 
     
    98100#endif 
    99101    { SYS_open, SYS_close, SYS_write, SYS_dup2, SYS_setpgid, SYS_setsid, 
    100       SYS_kill, SYS_fork, SYS_exit, SYS_execve }; 
     102      SYS_kill, SYS_fork, SYS_exit, SYS_execve, SYS_ioctl }; 
    101103 
    102104char const *syscallnames[] = 
    103105    { "open", "close", "write", "dup2", "setpgid", "setsid", "kill", "fork", 
    104       "exit", "execve" }; 
     106      "exit", "execve", "ioctl" }; 
    105107 
    106108#endif /* USE_GRAB */ 
     
    403405    ret = remote_syscall(t, MYCALL_EXECVE, regs.RSP, argvaddr, envptraddr); 
    404406 
     407    return ret; 
     408#else 
     409    errno = ENOSYS; 
     410    return -1; 
     411#endif 
     412} 
     413 
     414int mytrace_tcgets(struct mytrace *t, int fd, struct termios *tos) 
     415{ 
     416#if defined USE_GRAB 
     417    char backup_data[4096]; 
     418    struct user_regs_struct regs; 
     419    size_t size = sizeof(struct termios); 
     420    int ret, err; 
     421     
     422    if(ptrace(PTRACE_GETREGS, t->pid, NULL, &regs) < 0) 
     423    { 
     424        perror("PTRACE_GETREGS (tcgets)\n"); 
     425        return -1; 
     426    } 
     427     
     428    /* Backup the data that we will use */ 
     429    if(memcpy_from_target(t, backup_data, regs.RSP, size) < 0) 
     430        return -1; 
     431     
     432    ret = remote_syscall(t, MYCALL_IOCTL, fd,TCGETS, regs.RSP); 
     433    err = errno; 
     434 
     435    memcpy_from_target(t, (char *)tos, regs.RSP, size); 
     436     
     437    /* Restore the data */ 
     438    memcpy_into_target(t, regs.RSP, backup_data, size); 
     439     
     440    errno = err; 
     441    return ret; 
     442#else 
     443    errno = ENOSYS; 
     444    return -1; 
     445#endif 
     446} 
     447 
     448int mytrace_tcsets(struct mytrace *t, int fd, struct termios *tos) 
     449{ 
     450#if defined USE_GRAB 
     451    char backup_data[4096]; 
     452    struct user_regs_struct regs; 
     453    size_t size = sizeof(struct termios); 
     454    int ret, err; 
     455     
     456    if(ptrace(PTRACE_GETREGS, t->pid, NULL, &regs) < 0) 
     457    { 
     458        perror("PTRACE_GETREGS (tcsets)\n"); 
     459        return -1; 
     460    } 
     461 
     462    /* Backup the data that we will use */ 
     463    if(memcpy_from_target(t, backup_data, regs.RSP, size) < 0) 
     464        return -1; 
     465     
     466    memcpy_into_target(t, regs.RSP, (char *)tos, size); 
     467     
     468    ret = remote_syscall(t, MYCALL_IOCTL, fd, TCSETS, regs.RSP); 
     469    err = errno; 
     470     
     471    /* Restore the data */ 
     472    memcpy_into_target(t, regs.RSP, backup_data, size); 
     473     
     474    errno = err; 
    405475    return ret; 
    406476#else 
  • neercs/trunk/src/mytrace.h

    r3551 r3873  
    1212 *  http://sam.zoy.org/wtfpl/COPYING for more details. 
    1313 */ 
     14 
     15#include <termios.h> 
    1416 
    1517struct mytrace; 
     
    2931int mytrace_exit(struct mytrace *t, int status); 
    3032int mytrace_exec(struct mytrace *t, char const *command); 
     33int mytrace_tcgets(struct mytrace *t, int fd, struct termios *tos); 
     34int mytrace_tcsets(struct mytrace *t, int fd, struct termios *tos); 
Note: See TracChangeset for help on using the changeset viewer.