Hatena::ブログ(Diary)

kazuhoのメモ置き場

2009-03-13

perl から任意の C ライブラリを呼び出す方法

syscall って組込関数システムコールはできますけど、libc やその他ライブラリ関数を呼びたい、ってこともありますよね。i386 かつ dlopen な環境なら、こんな風に書けます。

use DynaLoader;
use ops;
sub ccall {
  my $r = '1111';
  my $s =
    "\x68" . pack("L", $_[5]) .
    "\x68" . pack("L", $_[4]) .
    "\x68" . pack("L", $_[3]) .
    "\x68" . pack("L", $_[2]) .
    "\x68" . pack("L", $_[1]) .
    "\xb8" . pack("L", ("Dyna"."Loader")->can("dl_find_symbol")->(("Dyna"."Loader")->can("dl_load_file")->("libc.so"), $_[0])) .
    "\xff\xd0" .
    "\x83\xc4\x14" .
    "\xa3" . pack("p", $r) .
    "\xc3";
  my $p = pack("P" . length($s), $s);
  my $f = "my$_[0]";
  ("Dyna"."Loader")->can("dl_install_xsub")->($f, unpack("L", $p));
  &$f();
  unpack("L", $r);
}
# 実際の呼び出し
print ccall("stat", unpack("L", pack("p", "/")));

引数と返り値は syscall のそれと同等。システムコールも libc 経由で実行可能です。これは便利?

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証