2009年03月14日 22:30 [Edit]

perl - FreeBSD::i386::Ptrace released!

cpan

FreeBSD::i386::PtraceをCPANに上げたのでお知らせします。

FreeBSD-i386専用ですが、これを使うと、ptrace(2) を Perl からお手軽に使うことが出来ます。

以前からあったらいいなと思っていたのですが、いざ作ってみるとあっさり出来ちゃいました。必要は発明の母とはよく言ったものです。


たとえば、配布のt/pstrace.plはこんな感じです。

#!/usr/local/bin/perl
use strict;
use warnings;
use FreeBSD::i386::Ptrace;
use FreeBSD::i386::Ptrace::Syscall;

die "$0 prog args ..." unless @ARGV;
my $pid = fork();
die "fork failed:$!" if !defined($pid);
if ($pid == 0){
    pt_trace_me;
    exec @ARGV;
}else{
    wait; # for exec;
    my $count = 0; # odd on entry, even on exit
    my ($call, $retval);
    while(pt_syscall($pid) == 0){ 
        last if wait == -1;
        if (++$count & 1){
            $call = pt_getcall($pid);
        }else{
            $retval = pt_getcall($pid);
            my $name = $SYS{$call} || 'unknown';
            warn "$name -> $retval";
            }
        }
    }
    warn $count/2," system calls issued";
}

こんな風に動きます。

% /bin/ls
Changes     Makefile.PL README      t
MANIFEST    Ptrace.xs   lib
% perl -Mbib t/pstrace.pl /bin/ls
__sysctl -> 0 at t/pstrace.pl line 25.
mmap -> 671588352 at t/pstrace.pl line 25.
......
ioctl -> 0 at t/pstrace.pl line 25.
Changes     Makefile.PL README      t
write -> 31 at t/pstrace.pl line 25.
MANIFEST    Ptrace.xs   lib
write -> 23 at t/pstrace.pl line 25.
.......
sigprocmask -> 0 at t/pstrace.pl line 25.
exit -> -1077941784 at t/pstrace.pl line 25.
92 system calls issued at t/pstrace.pl line 29.

また、t/rperl.tを使うと、特定のシステムコールを禁止しつつ任意の perl script を実行できます。ファイル名を指定しない場合、標準入力からソースを読むのも perl と一緒です。また、STDINとSTDERRを分けてキャプチャーしてくれます。

perl -Mblib t/rperl.pl 
use LWP::Simple;
print get("http://example.com/");
# stdout
<HTML>
<HEAD>
  <TITLE>Example Web Page</TITLE>
</HEAD> 
<body>  
<p>You have reached this web page by typing "example.com",
"example.net",
  or "example.org" into your web browser.</p>
<p>These domain names are reserved for use in documentation and are not available 
  for registration. See <a href="http://www.rfc-editor.org/rfc/rfc2606.txt">RFC 
  2606</a>, Section 3.</p>
</BODY>
</HTML>


# stderr


% perl -Mblib t/rperl.pl webserver.pl
# 5641 killed: SYS_bind banned.
# stdout

# stderr
Use of uninitialized value in pack at /tmp/xmls1atH43 line 4.
Use of uninitialized value in pack at /tmp/xmls1atH43 line 4.
Use of uninitialized value in pack at /tmp/xmls1atH43 line 4.
Use of uninitialized value in pack at /tmp/xmls1atH43 line 4.

というわけで、FreeBSDをお使いのみなさん、より安全で快適な perl hacking をお楽しみくださいませ。

Dan the (Perl|FreeBSD) Monger

NAME
    FreeBSD::i386::Ptrace - Ptrace for FreeBSD-i386

VERSION
    $Id: Ptrace.pm,v 0.1 2009/03/14 12:45:27 dankogai Exp dankogai $

SYNOPSIS
      # simple strace in perl
      use strict;
      use warnings;
      use FreeBSD::i386::Ptrace;
      use FreeBSD::i386::Ptrace::Syscall;
      die "$0 prog args ..." unless @ARGV;
      my $pid = fork();
      die "fork failed:$!" if !defined($pid);
      if ($pid == 0){ # son
        pt_trace_me;
        exec @ARGV;
      }else{  mom
        wait; # for exec;
        my $count = 0; # odd on enter, even on leave
        my ($call, $retval);  
        while(pt_syscall($pid) == 0){
            last if wait == -1;
            if (++$count & 1){
                $call = pt_getcall($pid);
            }else{
                $retval = pt_getcall($pid);
                my $name = $SYS{$call} || 'unknown';
                warn "$name -> $retval";

            }
        }
        warn $count/2," system calls issued";
      }

EXPORT
    "ptrace", "pt_trace_me", "pt_attach", "pt_detach", "pt_syscall"
    "pt_getcall" "pt_kill" and PT_* constants.

    for %SYS, use <FreeBSD::i386::Ptrace::Syscall>.

FUNCTIONS
    ptrace($request, $pid, $addr, $data)
      A thin wrapper to "2" in ptrace.

           #include <sys/types.h>
           #include <sys/ptrace.h>
           int
           ptrace(int request, pid_t pid, caddr_t addr, int data);

      All arguments are integer from perl.

    pt_trace_me()
      Shortand for "ptrace(PT_TRACE_ME, 0, 0, 0)".

    pt_attach($pid)
      Shortand for "ptrace(PT_ATTACH, pid, 0, 0)".

    pt_detach($pid)
      Shortand for "ptrace(PT_DETACH, pid, 0, 0)".

    pt_syscall($pid)
      Shortand for "ptrace(PT_SYSCALL, pid, 1, 0)". Unlike Linux the 3rd
      argument must be 1 or it loops infinitely.

      Note PT_SYSCALL is invoked both on entry to and return from the system
      call. See "SYNOPSIS" to see how to switch between them.

    pt_getcall($pid)
      Returns the value of EAX register which holds the system call NUMBER
      on entry and the return value on return.
      "FreeBSD::i386::Ptrace::Syscall" and use %SYS.

        my $call = pt_getcall(pid);
        my $name = %SYS{$call};

    pt_kill($pid)
      Shortand for "ptrace(PT_KILL, $pid, 0, 0"; "ptrace", "pt_trace_me",
      "pt_attach", "pt_detach", "pt_syscall" "pt_getcall" "pt_kill" and PT_*
      constants.

AUTHOR
    Dan Kogai, "<dankogai at dan.co.jp>"

BUGS
    Please report any bugs or feature requests to "bug-freebsd-i386-ptrace
    at rt.cpan.org", or through the web interface at
    <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=FreeBSD-i386-Ptrace>. I
    will be notified, and then you'll automatically be notified of progress
    on your bug as I make changes.

SUPPORT
    You can find documentation for this module with the perldoc command.

        perldoc FreeBSD::i386::Ptrace

    You can also look for information at:

    * RT: CPAN's request tracker
        <http://rt.cpan.org/NoAuth/Bugs.html?Dist=FreeBSD-i386-Ptrace>

    * AnnoCPAN: Annotated CPAN documentation
        <http://annocpan.org/dist/FreeBSD-i386-Ptrace>

    * CPAN Ratings
        <http://cpanratings.perl.org/d/FreeBSD-i386-Ptrace>

    * Search CPAN
        <http://search.cpan.org/dist/FreeBSD-i386-Ptrace>

ACKNOWLEDGEMENTS
    Sys::Ptrace

COPYRIGHT & LICENSE
    Copyright 2009 Dan Kogai, all rights reserved.

    This program is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.


この記事へのトラックバックURL

この記事へのトラックバック
t/rperl.tを使うと、特定のシステムコールを禁止しつつ任意の perl ...
FreeBSD の ptrace ではサンドボックスを作れないという話【Kazuho@Cybozu Labs】at 2009年03月16日 14:57
この記事へのコメント
面白い絵本シリーズ
岩波書店
『はじめて出会うコンピュータ科学』
を見つけたので紹介させて下さい。
以下は私のブログでの書評です。
http://omoitukanai.cocolog-nifty.com/blog/2009/03/post-75b3.html
どうぞよろしくお願いします。
Posted by rikeitenkou at 2009年03月15日 12:12