2.6. System Call Tracing Example

2.6. System Call Tracing Example

Given what we’ve learned from reverse engineering strace, we now have enough information to build a simple strace-like utility from scratch. Building a tool like strace includes a lot of formatting work. Error numbers and system call numbers need to be formatted, as do the various system call arguments. This is the reason for the two large arrays in the following source code, one for error numbers and one for system call numbers.

考虑到我们从逆向工程 strace 中学到的知识, 我们现在有足够的信息来从头开始构建一个简单的类似 strace实用工具。构建像 strace 这样的工具包括许多格式化工作。错误号和系统调用号需要格式化, 就像各种系统调用参数一样。这是以下源代码中两个大数组的原因, 一个用于错误号, 一个用于系统调用编号。

Note: Notice the check for -ENOSYS. In the kernel source, we saw that the kernel set EAX to -ENOSYS for system call entries.

注: 注意检查 -ENOSYS。在内核源代码中, 我们看到内核设置EAX 为-ENOSYS,作为系统调用条目。

2.6.1. Sample Code

Code View: Scroll / Show All

#include <asm/unistd.h>

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <stdarg.h>

#include <errno.h>

#include <string.h>

#include <sys/types.h>

#include <sys/wait.h>

#include <sys/ptrace.h>

#include <asm/user.h>

 

const char *errors[] =

{

 "NULL:"

,"EPERM"                  //numeric value: 1

,"ENOENT"                 //numeric value: 2

,"ESRCH"                  //numeric value: 3

,"EINTR"                  //numeric value: 4

,"EIO"                    //numeric value: 5

,"ENXIO"                  //numeric value: 6

,"E2BIG"                  //numeric value: 7

,"ENOEXEC"                //numeric value: 8

,"EBADF"                  //numeric value: 9

,"ECHILD"                 //numeric value: 10

,"EAGAIN"                 //numeric value: 11

,"ENOMEM"                 //numeric value: 12

,"EACCES"                 //numeric value: 13

,"EFAULT"                 //numeric value: 14

,"ENOTBLK"                //numeric value: 15

,"EBUSY"                  //numeric value: 16

,"EEXIST"                 //numeric value: 17

,"EXDEV"                  //numeric value: 18

,"ENODEV"                 //numeric value: 19

,"ENOTDIR"                //numeric value: 20

,"EISDIR"                 //numeric value: 21

,"EINVAL"                 //numeric value: 22

,"ENFILE"                 //numeric value: 23

,"EMFILE"                 //numeric value: 24

,"ENOTTY"                 //numeric value: 25

,"ETXTBSY"                //numeric value: 26

,"EFBIG"                  //numeric value: 27

,"ENOSPC"                 //numeric value: 28

,"ESPIPE"                 //numeric value: 29

,"EROFS"                  //numeric value: 30

,"EMLINK"                 //numeric value: 31

,"EPIPE"                  //numeric value: 32

,"EDOM"                   //numeric value: 33

,"ERANGE"                 //numeric value: 34

,"EDEADLK"                //numeric value: 35

,"ENAMETOOLONG"           //numeric value: 36

,"ENOLCK"                 //numeric value: 37

,"ENOSYS"                 //numeric value: 38

,"ENOTEMPTY"              //numeric value: 39

,"ELOOP"                  //numeric value: 40

,"NULL"                   //numeric value: 41

,"ENOMSG"                 //numeric value: 42

,"EIDRM"                  //numeric value: 43

,"ECHRNG"                 //numeric value: 44

,"EL2NSYNC"               //numeric value: 45

,"EL3HLT"                 //numeric value: 46

,"EL3RST"                 //numeric value: 47

,"ELNRNG"                 //numeric value: 48

,"EUNATCH"                //numeric value: 49

,"ENOCSI"                 //numeric value: 50

,"EL2HLT"                 //numeric value: 51

,"EBADE"                  //numeric value: 52

,"EBADR"                  //numeric value: 53

,"EXFULL"                 //numeric value: 54

,"ENOANO"                 //numeric value: 55

,"EBADRQC"                //numeric value: 56

,"EBADSLT"                //numeric value: 57

,"NULL"                   //numeric value: 58

,"EBFONT"                 //numeric value: 59

,"ENOSTR"                 //numeric value: 60

,"ENODATA"                //numeric value: 61

,"ETIME"                  //numeric value: 62

,"ENOSR"                  //numeric value: 63

,"ENONET"                 //numeric value: 64

,"ENOPKG"                 //numeric value: 65

,"EREMOTE"                //numeric value: 66

,"ENOLINK"                //numeric value: 67

,"EADV"                   //numeric value: 68

,"ESRMNT"                 //numeric value: 69

,"ECOMM"                  //numeric value: 70

,"EPROTO"                 //numeric value: 71

,"EMULTIHOP"              //numeric value: 72

,"EDOTDOT"                //numeric value: 73

,"EBADMSG"                //numeric value: 74

,"EOVERFLOW"              //numeric value: 75

,"ENOTUNIQ"               //numeric value: 76

,"EBADFD"                 //numeric value: 77

,"EREMCHG"                //numeric value: 78

,"ELIBACC"                //numeric value: 79

,"ELIBBAD"                //numeric value: 80

,"ELIBSCN"                //numeric value: 81

,"ELIBMAX"                //numeric value: 82

,"ELIBEXEC"               //numeric value: 83

,"EILSEQ"                 //numeric value: 84

,"ERESTART"               //numeric value: 85

,"ESTRPIPE"               //numeric value: 86

,"EUSERS"                 //numeric value: 87

,"ENOTSOCK"               //numeric value: 88

,"EDESTADDRREQ"           //numeric value: 89

,"EMSGSIZE"               //numeric value: 90

,"EPROTOTYPE"             //numeric value: 91

,"ENOPROTOOPT"            //numeric value: 92

,"EPROTONOSUPPORT"        //numeric value: 93

,"ESOCKTNOSUPPORT"        //numeric value: 94

,"EOPNOTSUPP"             //numeric value: 95

,"EPFNOSUPPORT"           //numeric value: 96

,"EAFNOSUPPORT"           //numeric value: 97

,"EADDRINUSE"             //numeric value: 98

,"EADDRNOTAVAIL"          //numeric value: 99

,"ENETDOWN"               //numeric value: 100

,"ENETUNREACH"            //numeric value: 101

,"ENETRESET"              //numeric value: 102

,"ECONNABORTED"           //numeric value: 103

,"ECONNRESET"             //numeric value: 104

,"ENOBUFS"                //numeric value: 105

,"EISCONN"                //numeric value: 106

,"ENOTCONN"               //numeric value: 107

,"ESHUTDOWN"              //numeric value: 108

,"ETOOMANYREFS"           //numeric value: 109

,"ETIMEDOUT"              //numeric value: 110

,"ECONNREFUSED"           //numeric value: 111

,"EHOSTDOWN"              //numeric value: 112

,"EHOSTUNREACH"           //numeric value: 113

,"EALREADY"               //numeric value: 114

,"EINPROGRESS"            //numeric value: 115

,"ESTALE"                 //numeric value: 116

,"EUCLEAN"                //numeric value: 117

,"ENOTNAM"                //numeric value: 118

,"ENAVAIL"                //numeric value: 119

,"EISNAM"                 //numeric value: 120

,"EREMOTEIO"              //numeric value: 121

,"EDQUOT"                 //numeric value: 122

,"ENOMEDIUM"              //numeric value: 123

,"EMEDIUMTYPE"            //numeric value: 124

} ;

 

#define MAX_ERRORS (sizeof( errors )/sizeof( char * ) )

 

const char *syscalls[] =

{

 "NULL"

,"exit"                   // numeric value: 1

,"fork"                   // numeric value: 2

,"read"                   // numeric value: 3

,"write"                  // numeric value: 4

,"open"                   // numeric value: 5

,"close"                  // numeric value: 6

,"waitpid"                // numeric value: 7

,"creat"                  // numeric value: 8

,"link"                   // numeric value: 9

,"unlink"                 // numeric value: 10

,"execve"                 // numeric value: 11

,"chdir"                  // numeric value: 12

,"time"                   // numeric value: 13

,"mknod"                  // numeric value: 14

,"chmod"                  // numeric value: 15

,"lchown"                 // numeric value: 16

,"break"                  // numeric value: 17

,"oldstat"                // numeric value: 18

,"lseek"                  // numeric value: 19

,"getpid"                 // numeric value: 20

,"mount"                  // numeric value: 21

,"umount"                 // numeric value: 22

,"setuid"                 // numeric value: 23

,"getuid"                 // numeric value: 24

,"stime"                  // numeric value: 25

,"ptrace"                 // numeric value: 26

,"alarm"                  // numeric value: 27

,"oldfstat"               // numeric value: 28

,"pause"                  // numeric value: 29

,"utime"                  // numeric value: 30

,"stty"                   // numeric value: 31

,"gtty"                   // numeric value: 32

,"access"                 // numeric value: 33

,"nice"                   // numeric value: 34

,"ftime"                  // numeric value: 35

,"sync"                   // numeric value: 36

,"kill"                   // numeric value: 37

,"rename"                 // numeric value: 38

,"mkdir"                  // numeric value: 39

,"rmdir"                  // numeric value: 40

,"dup"                    // numeric value: 41

,"pipe"                   // numeric value: 42

,"times"                  // numeric value: 43

,"prof"                   // numeric value: 44

,"brk"                    // numeric value: 45

,"setgid"                 // numeric value: 46

,"getgid"                 // numeric value: 47

,"signal"                 // numeric value: 48

,"geteuid"                // numeric value: 49

,"getegid"                // numeric value: 50

,"acct"                   // numeric value: 51

,"umount2"                // numeric value: 52

,"lock"                   // numeric value: 53

,"ioctl"                  // numeric value: 54

,"fcntl"                  // numeric value: 55

,"mpx"                    // numeric value: 56

,"setpgid"                // numeric value: 57

,"ulimit"                 // numeric value: 58

,"oldolduname"            // numeric value: 59

,"umask"                  // numeric value: 60

,"chroot"                 // numeric value: 61

,"ustat"                  // numeric value: 62

,"dup2"                   // numeric value: 63

,"getppid"                // numeric value: 64

,"getpgrp"                // numeric value: 65

,"setsid"                 // numeric value: 66

,"sigaction"              // numeric value: 67

,"sgetmask"               // numeric value: 68

,"ssetmask"               // numeric value: 69

,"setreuid"               // numeric value: 70

,"setregid"               // numeric value: 71

,"sigsuspend"             // numeric value: 72

,"sigpending"             // numeric value: 73

,"sethostname"            // numeric value: 74

,"setrlimit"              // numeric value: 75

,"getrlimit"              // numeric value: 76

,"getrusage"              // numeric value: 77

,"gettimeofday"           // numeric value: 78

,"settimeofday"           // numeric value: 79

,"getgroups"              // numeric value: 80

,"setgroups"              // numeric value: 81

,"select"                 // numeric value: 82

,"symlink"                // numeric value: 83

,"oldlstat"               // numeric value: 84

,"readlink"               // numeric value: 85

,"uselib"                 // numeric value: 86

,"swapon"                 // numeric value: 87

,"reboot"                 // numeric value: 88

,"readdir"                // numeric value: 89

,"mmap"                   // numeric value: 90

,"munmap"                 // numeric value: 91

,"truncate"               // numeric value: 92

,"ftruncate"              // numeric value: 93

,"fchmod"                 // numeric value: 94

,"fchown"                 // numeric value: 95

,"getpriority"            // numeric value: 96

,"setpriority"            // numeric value: 97

,"profil"                 // numeric value: 98

,"statfs"                 // numeric value: 99

,"fstatfs"                // numeric value: 100

,"ioperm"                 // numeric value: 101

,"socketcall"             // numeric value: 102

,"syslog"                 // numeric value: 103

,"setitimer"              // numeric value: 104

,"getitimer"              // numeric value: 105

,"stat"                   // numeric value: 106

,"lstat"                  // numeric value: 107

,"fstat"                  // numeric value: 108

,"olduname"               // numeric value: 109

,"iopl"                   // numeric value: 110

,"vhangup"                // numeric value: 111

,"idle"                   // numeric value: 112

,"vm86old"                // numeric value: 113

,"wait4"                  // numeric value: 114

,"swapoff"                // numeric value: 115

,"sysinfo"                // numeric value: 116

,"ipc"                    // numeric value: 117

,"fsync"                  // numeric value: 118

,"sigreturn"              // numeric value: 119

,"clone"                  // numeric value: 120

,"setdomainname"          // numeric value: 121

,"uname"                  // numeric value: 122

,"modify_ldt"             // numeric value: 123

,"adjtimex"               // numeric value: 124

,"mprotect"               // numeric value: 125

,"sigprocmask"            // numeric value: 126

,"create_module"          // numeric value: 127

,"init_module"            // numeric value: 128

,"delete_module"          // numeric value: 129

,"get_kernel_syms"        // numeric value: 130

,"quotactl"               // numeric value: 131

,"getpgid"                // numeric value: 132

,"fchdir"                 // numeric value: 133

,"bdflush"                // numeric value: 134

,"sysfs"                  // numeric value: 135

,"personality"            // numeric value: 136

,"afs_syscall"            // numeric value: 137

,"setfsuid"               // numeric value: 138

,"setfsgid"               // numeric value: 139

,"_llseek"                // numeric value: 140

,"getdents"               // numeric value: 141

,"_newselect"             // numeric value: 142

,"flock"                  // numeric value: 143

,"msync"                  // numeric value: 144

,"readv"                  // numeric value: 145

,"writev"                 // numeric value: 146

,"getsid"                 // numeric value: 147

,"fdatasync"              // numeric value: 148

,"_sysctl"                // numeric value: 149

,"mlock"                  // numeric value: 150

,"munlock"                // numeric value: 151

,"mlockall"               // numeric value: 152

,"munlockall"             // numeric value: 153

,"sched_setparam"         // numeric value: 154

,"sched_getparam"         // numeric value: 155

,"sched_setscheduler"     // numeric value: 156

,"sched_getscheduler"     // numeric value: 157

,"sched_yield"            // numeric value: 158

,"sched_get_priority_max" // numeric value: 159

,"sched_get_priority_min" // numeric value: 160

,"sched_rr_get_interval"  // numeric value: 161

,"nanosleep"              // numeric value: 162

,"mremap"                 // numeric value: 163

,"setresuid"              // numeric value: 164

,"getresuid"              // numeric value: 165

,"vm86"                   // numeric value: 166

,"query_module"           // numeric value: 167

,"poll"                   // numeric value: 168

,"nfsservctl"             // numeric value: 169

,"setresgid"              // numeric value: 170

,"getresgid"              // numeric value: 171

,"prctl"                  // numeric value: 172

,"rt_sigreturn"           // numeric value: 173

,"rt_sigaction"           // numeric value: 174

,"rt_sigprocmask"         // numeric value: 175

,"rt_sigpending"          // numeric value: 176

,"rt_sigtimedwait"        // numeric value: 177

,"rt_sigqueueinfo"        // numeric value: 178

,"rt_sigsuspend"          // numeric value: 179

,"pread"                  // numeric value: 180

,"pwrite"                 // numeric value: 181

,"chown"                  // numeric value: 182

,"getcwd"                 // numeric value: 183

,"capget"                 // numeric value: 184

,"capset"                 // numeric value: 185

,"sigaltstack"            // numeric value: 186

,"sendfile"               // numeric value: 187

,"getpmsg"                // numeric value: 188

,"putpmsg"                // numeric value: 189

,"vfork"                  // numeric value: 190

,"ugetrlimit"             // numeric value: 191

,"mmap2"                  // numeric value: 192

,"truncate64"             // numeric value: 193

,"ftruncate64"            // numeric value: 194

,"stat64"                 // numeric value: 195

,"lstat64"                // numeric value: 196

,"fstat64"                // numeric value: 197

,"lchown32"               // numeric value: 198

,"getuid32"               // numeric value: 199

,"getgid32"               // numeric value: 200

,"geteuid32"              // numeric value: 201

,"getegid32"              // numeric value: 202

,"setreuid32"             // numeric value: 203

,"setregid32"             // numeric value: 204

,"getgroups32"            // numeric value: 205

,"setgroups32"            // numeric value: 206

,"fchown32"               // numeric value: 207

,"setresuid32"            // numeric value: 208

,"getresuid32"            // numeric value: 209

,"setresgid32"            // numeric value: 210

,"getresgid32"            // numeric value: 211

,"chown32"                // numeric value: 212

,"setuid32"               // numeric value: 213

,"setgid32"               // numeric value: 214

,"setfsuid32"             // numeric value: 215

,"setfsgid32"             // numeric value: 216

,"pivot_root"             // numeric value: 217

,"mincore"                // numeric value: 218

,"madvise"                // numeric value: 219

,"getdents64"             // numeric value: 220

,"fcntl64"                // numeric value: 221

,"<none>"                 // numeric value: 222

,"security"               // numeric value: 223

,"gettid"                 // numeric value: 224

,"readahead"              // numeric value: 225

,"setxattr"               // numeric value: 226

,"lsetxattr"              // numeric value: 227

,"fsetxattr"              // numeric value: 228

,"getxattr"               // numeric value: 229

,"lgetxattr"              // numeric value: 230

,"fgetxattr"              // numeric value: 231

,"listxattr"              // numeric value: 232

,"llistxattr"             // numeric value: 233

,"flistxattr"             // numeric value: 234

,"removexattr"            // numeric value: 235

,"lremovexattr"           // numeric value: 236

,"fremovexattr"           // numeric value: 237

,"tkill"                  // numeric value: 238

,"sendfile64"             // numeric value: 239

,"futex"                  // numeric value: 240

,"sched_setaffinity"      // numeric value: 241

,"sched_getaffinity"      // numeric value: 242

} ;

 

#define MAX_SYSCALLS (sizeof( syscalls )/sizeof( char * ) )

 

/* *** eprintf ***

   * Description: general error printing function

*/

 

void eprintf( char const *fmt, ... )

{

  va_list ap;

 

  va_start(ap, fmt);

 

  vfprintf( stderr, fmt, ap ) ;

 

  va_end(ap);

}

 

int readString( pid_t pid, void *addr, char *string, size_t maxSize)

{

 

   int rc = 0 ;

   long peekWord ;

   char *peekAddr ;

   int i ;

   int stringIndex = 0 ;

   char *tmpString ;

   int stringFound = 0 ;

 

   string[0] = '\0' ;

   peekAddr = (char *) ((long)addr & ~(sizeof(long) - 1 ) ) ;

 

   // The PTRACE_PEEKDATA feature reads full words from the process'

   // address space.

   peekWord = ptrace( PTRACE_PEEKDATA, pid, peekAddr, NULL ) ;

 

   if ( -1 == peekWord )

   {

      perror( "ptrace( PTRACE_PEEKDATA..." ) ;

      rc = -1 ;

      goto exit ;

   }

 

   // Keep in mind that since peekAddr is aligned

   // it might contain a few characters at the beginning

 

   int charsToCopy = sizeof( long ) - ( (long)addr - long)peekAddr );

 

   tmpString = (char *)&peekWord ;

   tmpString += sizeof( long ) - charsToCopy ;

 

   for ( i = 0 ; i < charsToCopy ; i++ )

   {

      string[ stringIndex ] = tmpString[ i ] ;

      stringIndex++ ;

      if ( maxSize - 1 == stringIndex )

         {

           string[ stringIndex ] = '\0';

         goto exit ;

      }

   }

 

   tmpString = (char *)&peekWord ;

   peekAddr += sizeof( long) ;

 

   // Fall into a loop to find the end of the string

   do

   {

      peekWord = ptrace( PTRACE_PEEKDATA, pid, peekAddr, NULL ) ;

 

      if ( -1 == peekWord )

      {

         perror( "ptrace( PTRACE_PEEKDATA..." ) ;

         rc = -1 ;

         goto exit ;

      }

 

      for ( i = 0 ; i < sizeof(long) ; i++ )

      {

         string[ stringIndex ] = tmpString[ i ] ;

 

         if ( maxSize - 1 == stringIndex )

         {

            string[ stringIndex ] = '\0';

            goto exit ;

         }

 

         if ( string[ stringIndex ] == '\0' )

         {

            stringFound = 1 ;

            break ;

         }

         stringIndex++ ;

      }

 

      peekAddr += sizeof( long) ;

 

   } while ( !stringFound ) ;

 

   exit:

 

   return rc ;

}

 

int spawnChildProcess( int argc, char *argv[] )

{

   int   mRC = 0 ;      // Return code for this function

   int   sRC = 0 ;      // Return code for system calls

   sRC = ptrace( PTRACE_TRACEME, 0, 0, 0 ) ;

 

   if ( -1 == sRC )

   {

      eprintf( "ptrace failed with request \"PTRACE_TRACEME\": %s\n", strerror( errno ) ) ;

      sRC = errno ;

      goto exit ;

   }

 

   sRC = execv( argv[0], argv ) ;

 

   if ( -1 == sRC )

   {

      eprintf( "exec failed: %s\n", strerror( errno ) ) ;

      sRC = errno ;

      goto exit ;

   }

 

   exit :

 

   return mRC ;

}

 

int traceChildProcess( pid_t tracedPid )

{

 

   int   mRC        = 0 ;  // Return code for this function

   int   sRC        = 0 ;  // Return code for system calls

   int   status     = 0 ;  // Status of the stopped child process

   pid_t stoppedPid = 0 ;  // Process ID of stopped child process

   struct user_regs_struct registers;

 

   stoppedPid = waitpid( tracedPid, &status, 0 ) ;

 

   printf( "Child process stopped for exec\n" ) ;

   if ( -1 == stoppedPid )

   {

      eprintf( "waitpid failed: %s\n", strerror( errno ) ) ;

      mRC = 1 ;

      goto exit ;

   }

 

   // Tell the child to stop in a system call entry or exit

   ptrace( PTRACE_SYSCALL, stoppedPid, 0, 0 ) ;

 

   // This is the main tracing loop. When the child stops,

   // we examine the system call and its arguments

   while ( ( stoppedPid = waitpid( tracedPid, &status, 0 ) ) != -1 )

   {

      sRC = ptrace( PTRACE_GETREGS, stoppedPid, 0, &registers ) ;

      if ( -1 == sRC )

      {

         eprintf( "ptrace failed with request PTRACE_GETREGS: %s\n", strerror( errno ) ) ;

         mRC = 1 ;

         goto exit ;

      }

 

      if ( registers.eax == -ENOSYS )

      {

         fprintf( stderr, "%d: %s( ", stoppedPid, syscalls[registers.orig_eax] ) ;

         switch( registers.orig_eax )

         {

            case __NR_open:

            {

              // Get file name and print the "file name" argument in a more fancy way

              char fileName[1024] = "";

              readString( stoppedPid, (void *)registers.ebx, fileName, 1024 ) ;

              fprintf( stderr, "\"%s\", %#08x, %#08x",

                      fileName, registers.ecx, registers.edx ) ;

            }

            break ;

            case __NR_exit:

               // If the traced process is bailing, so should we

               fprintf( stderr, "%#08x, %#08x, %#08x ) = ?\n",

                       registers.ebx, registers.ecx, registers.edx) ;

               goto exit ;

            break ;

            default:

            fprintf( stderr, "%#08x, %#08x, %#08x",

                    registers.ebx, registers.ecx, registers.edx) ;

            break ;

         }

         fprintf( stderr, " ) = " ) ;

      }

      else

      {

         if ( registers.eax < 0 )

         {

            // error condition

            fprintf( stderr, "#Err: %s\n", errors[ abs(registers.eax ) ] ) ;

         }

         else

         {

            // return code

            fprintf( stderr, "%#08x\n", registers.eax ) ;

         }

      }

 

      ptrace( PTRACE_SYSCALL, stoppedPid, 0, 0 ) ;

   }

 

   exit :

 

   fclose( stdin ) ;

   fclose( stderr ) ;

   fclose( stdout ) ;

 

   exit( 1 ) ;

 

   return mRC ;

}

 

int main( int argc, char *argv[] )

{

   int   mRC  = 0 ;      // Return code for this function

   pid_t cpid     ;      // Child process ID

 

   cpid = fork() ;

 

   if ( cpid > 0 )

   {

      // Parent

      traceChildProcess( -1 ) ;

   }

   else if ( 0 == cpid )

   {

      // Child

      spawnChildProcess( argc, &argv[1] ) ;

   }

   else

   {

      fprintf( stderr, "Could not fork child (%s)\n", strerror(errno ) ) ;

      mRC = 1 ;

   }

 

   return mRC ;

}

2.6.2. The System Call Tracing Code Explained

The spawnChildProcess() function forks off a child process and runs ptrace with PTRACE_TRACEME to ensure that the child process will stop when entering or exiting a system call. The function then executes the process to be traced.

spawnChildProcess () 函数复制子进程, 并以 PTRACE_TRACEME为参数 运行 ptrace, 以确保在输入或退出系统调用时子进程将停止。然后, 该函数执行要跟踪的进程。

The traceChildProcess() function waits for the process to stop (presumably due to a system call entry or exit) and then gets information about the stopped process. It uses the ptrace call with PTRACE_GETREGS to get the registers for the process. In particular, it tests the EAX register to see whether the process is stopped on an entry or exit from a system call. When the traced process stops on a system call entry, the EAX register will contain -ENOSYS. The EAX normally contains the return code from the system call, and because the process stopped on a system call entry, ENOSYS is an impossible return for a system call to return (hence making it a good differentiator). For a system call exit, the EAX register will be some value that is not -ENOSYS.

traceChildProcess () 函数等待进程停止 (可能是由于系统调用进入或退出), 然后获取有关已停止进程的信息。它使用以 PTRACE_GETREGS 为参数的 ptrace 调用来获取进程的寄存器。特别是, 它测试 EAX 寄存器, 以查看该进程是在系统调用的出入口上停止。当被跟踪的进程在系统调用入口上停止时, EAX 寄存器将包含-ENOSYS。EAX 通常包含来自系统调用的返回值, 并且由于进程在系统调用入口上停止, 因此 ENOSYS 不可能是系统调用返回的(因此使它成为一个很好的区别)。对于系统调用退出, EAX 寄存器将是一些非 -ENOSYS 的值。

When a system call is entered, the original EAX will contain the system call number. When a system call is identified, the system call calling convention provides information about the arguments to the system call as shown in the following code snippet:

当系统调用被进入时, 原始 EAX 将包含系统调用号。当系统调用被识别时, 系统调用约定提供了有关系统调用的参数的信息, 如下面的代码段所示:

char fileName[1024] = "";

readString( stoppedPid, (void *)registers.ebx, fileName, 1024 ) ;

fprintf( stderr, "\"%s\", %#08x, %#08x",

         fileName, registers.ecx, registers.edx ) ;

 

The readString function reads in a single string at a particular address space in the stopped process. For the open system call, the code reads the first argument at the address stored in EBX. This is the file name for the open system call.

readString 函数在停止进程中的特定地址空间中读取单个字符串。对于open系统调用, 代码读取存储在 EBX 中的地址的第一个参数。这是open系统调用的文件名。

This is how strace prints symbolic information for a system call. For every system call, there is an opportunity to print the symbolic information that is more descriptive than the numeric values in the registers.

这就是 strace 为系统调用打印符号信息的方式。对于每个系统调用, 都有机会打印比寄存器中数字值更具描述性的符号信息。

If the EAX contains a value that is not minus ENOSYS, then the process is presumed to be stopped at the exit of a system call. A positive value in EAX means a successful completion of the system call, and the return code would contain the successful return code of the system call. If the return code is negative, it is assumed to be an error, and an error is printed in the strace output.

如果 EAX 包含的值不是减号 ENOSYS, 则假定该进程在系统调用的出口处停止。EAX 中的正值意味着系统调用成功完成, 返回代码将包含系统调用的成功返回代码。如果返回代码为负值, 则假定它为错误, 并且在 strace 输出中打印错误。

The main loop in traceChildProcess() continues until the traced process exits for some reason:

traceChildProcess () 中的主循环继续, 直到被跟踪的进程由于某种原因退出:

while ( ( stoppedPid = waitpid( tracedPid, &status, 0 ) ) != -1 )

 

It continuously waits for the traced process to stop and then prints the information for the system call entry and exit. Most of the source code is used for formatting of the information.

它不断等待被跟踪过程停止, 然后打印系统调用进入和退出的信息。大多数源代码用于格式化信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mounter625

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值