免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2332 | 回复: 0
打印 上一主题 下一主题

Ruby 版的 PinkTrace 示例 pink-simple-strace-linux.rb [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-01-16 18:19 |只看该作者 |倒序浏览
  1. #!/usr/bin/env ruby
  2. # coding: utf-8
  3. # vim: set sw=2 sts=2 et nowrap fenc=utf-8 :

  4. require 'socket'
  5. require 'PinkTrace'

  6. PF_INET6   = (PinkTrace::HAVE_IPV6 and Socket.const_defined? 'AF_INET6') ? Socket::AF_INET6 : -999
  7. PF_NETLINK = (PinkTrace::HAVE_NETLINK and Socket.const_defined? 'AF_NETLINK') ? Socket::AF_NETLINK : -9999

  8. def print_ret pid
  9.   ret = PinkTrace::Syscall.get_ret pid

  10.   if ret >= 0
  11.     print "= #{ret}"
  12.   else
  13.     print "= #{ret} #{Errno.constants[-ret]}"
  14.   end
  15. end

  16. def decode_open pid, bitness
  17.   path = PinkTrace::String.decode pid, 0, -1, bitness
  18.   flags = PinkTrace::Syscall.get_arg pid, 1, bitness

  19.   print "open(\"#{path}\", #{flags})"
  20. end

  21. def decode_execve pid, bitness
  22.   path = PinkTrace::String.decode pid, 0, -1, bitness
  23.   addr = PinkTrace::Syscall.get_arg pid, 1, bitness

  24.   print "execve(\"#{path}\", ["

  25.   i = 0
  26.   sep = ''
  27.   loop do
  28.     path = PinkTrace::StringArray.decode pid, addr, i
  29.     if path
  30.       print "#{sep}\"#{path}\""
  31.       i += 1
  32.       sep = ', '
  33.     else
  34.       print '], envp[]'
  35.       break
  36.     end
  37.   end
  38. end

  39. def decode_socketcall pid, bitness, scname
  40.   subname = nil
  41.   if PinkTrace::Socket.has_socketcall? bitness
  42.     subcall = PinkTrace::Socket.decode_call pid, bitness
  43.     subname = PinkTrace::Socket.name subcall

  44.     unless subname =~ /(bind|connect)/
  45.       print subname + '()'
  46.       return
  47.     end
  48.   end

  49.   addr, fd = PinkTrace::Socket.decode_address_fd pid, 1, bitness
  50.   print (subname ? subname : scname) + '(' + fd.to_s + ', '

  51.   case addr.family
  52.   when -1
  53.     print 'NULL'
  54.   when Socket::AF_UNIX
  55.     print '{sa_family=AF_UNIX, path=' + (addr.abstract? ? '@' + addr.path : addr.path) + '}'
  56.   when Socket::AF_INET
  57.     print '{sa_family=AF_INET, sin_port=htons(' + addr.port.to_s + '), sin_addr=inet("' + addr.ip + '")}'
  58.   when PF_INET6
  59.     print '{sa_family=AF_INET6, sin6_port=htons(' + addr.port.to_s + '), inet_pton(AF_INET6, "' + addr.ipv6 + ', &sin6_addr)}'
  60.   when PF_NETLINK
  61.     print '{sa_family=AF_NETLINK, pid=' + addr.port.to_s + ', groups=' + sprintf('%08x', addr.groups) + '}'
  62.   else
  63.     print '{sa_family=???}'
  64.   end

  65.   print ', ' + addr.length.to_s
  66. end

  67. unless ARGV.size > 0
  68.   puts "Usage: #{$0} program [arguments..]"
  69.   exit 1
  70. end

  71. pid = fork do
  72.   PinkTrace::Trace.me
  73.   Process.kill 'STOP', Process.pid

  74.   exec(*ARGV)
  75. end

  76. Process.waitpid pid
  77. PinkTrace::Trace.setup pid, (PinkTrace::Trace::OPTION_SYSGOOD | PinkTrace::Trace::OPTION_EXEC)

  78. # Figure out the bitness of the child.
  79. bitness = PinkTrace::Bitness.get pid
  80. puts "Child #{pid} runs in #{PinkTrace::Bitness.name bitness} mode"

  81. dead = false
  82. insyscall = false
  83. sig = 0
  84. exit_code = 0

  85. loop do
  86.   # At this point the traced child is stopped and needs to be resumed.
  87.   PinkTrace::Trace.syscall pid, sig
  88.   sig = 0
  89.   Process.waitpid pid

  90.   # Check the event, if no argument is given PinkTrace::Event.decide uses
  91.   # $?.status and Process.waitpid sets $?.
  92.   event = PinkTrace::Event.decide

  93.   case event
  94.   when PinkTrace::Event::EVENT_SYSCALL
  95.     # We get this event twice, one at entering a system call and one at
  96.     # exiting a system call.
  97.     if insyscall
  98.       print ' '
  99.       print_ret pid
  100.       puts
  101.     else
  102.       # Get the system call number and call the appropriate decoder.
  103.       scno = PinkTrace::Syscall.get_no pid
  104.       scname = PinkTrace::Syscall.name scno
  105.       case scname
  106.       when nil then print "#{scno}()"
  107.       when 'open' then decode_open pid, bitness
  108.       when 'execve' then decode_execve pid, bitness
  109.       when 'socketcall'
  110.       when 'bind'
  111.       when 'connect' then decode_socketcall pid, bitness, scname
  112.       else print "#{scname}()"
  113.       end
  114.     end
  115.     insyscall = (not insyscall)
  116.   when PinkTrace::Event::EVENT_EXEC
  117.     # Update bitness
  118.     bitness = PinkTrace::Bitness.get pid
  119.   when PinkTrace::Event::EVENT_GENUINE
  120.   when PinkTrace::Event::EVENT_UNKNOWN
  121.     # Send the signal to the traced child as it was a genuine signal.
  122.     sig = $?.stopsig
  123.   when PinkTrace::Event::EVENT_EXIT_GENUINE
  124.     exit_code = $?.exitstatus
  125.     puts "Child #{pid} exited normally with return code #{exit_code}"
  126.     dead = true
  127.   when PinkTrace::Event::EVENT_EXIT_SIGNAL
  128.     exit_code = 128 + $?.termsig
  129.     puts "Child #{pid} exited with signal #{$?.termsig}"
  130.     dead = true
  131.   end

  132.   break if dead
  133. end
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP