721 Views
March 30, 09
スライド概要
Shibuya Perl Mongersテクニカルトーク#11
はせがわようすけ Yosuke HASEGAWA
第1部 WindowsでもPerlを使いたい How can I use Perl on Windows?
WindowsでもPerlを使いたい! How can I use Perl on Windows? それ、ActivePerlでできるよ! You can do that with ActivePerl!
第1部 完
第2部 PerlからDLLを呼びたい! Calling DLL from Perl!
PerlからDLLを呼びたい!
Calling DLL from Perl!
❤それ、Win32::APIでできるよ!
use Win32::API;
my $MessageBox = Win32::API->new(
DLL名
"user32",
関数名
"MessageBoxA",
"NPPN",
引数:整数、ポインタ、ポインタ、整数
"N"
戻り値:整数
);
$MessageBox->Call( 0,
"Happy Wedding", "Perl", 0 );
第2部 完
第3部 Perlからx86コードを 呼びたい! Calling x86 code from Perl
Perlからx86コードを呼びたい! Calling x86 code from Perl ❤シグナルハンドラを利用 Using signal handlers ❤実行コードのバイト列を用意 Preparing binary array for executable code ❤シグナルハンドラとしてバイト列を指定 Assign the array as a signal handler ❤シグナルの生成 Raise signal to call binary code ❤ActivePerlはヒープごとDEP解除? Disabled DEP for all of heap area?
Perlからx86コードを呼びたい!
Calling x86 code from Perl
❤シグナルハンドラでやってみた
my
.
.
.
.
.
;
$x86 = ""
"¥x83¥x7d¥x08¥x00"
"¥x74¥x05"
"¥x33¥xc0"
"¥xc2¥x04¥x00"
…(略)…
#
#
#
#
シグナルハンドラ
実効するコード
cmp [dwCtrlEvent], 0
je if( not Ctrl+C ) return
xor eax, eax
ret 4
シグナルハンドラ
の設定
$SetConsoleCtrlHandler->Call(
unpack( 'L', pack( 'P', $x86 ) ), TRUE );
$GenerateConsoleCtrlEvent->Call( CTRL_C_EVENT, 0 );
Ctrl+C(SIGINT)
シグナル発生
Perlからx86コードを呼びたい! Calling x86 code from Perl DEMO
第3部 完
第4部 x86コードからPerlを 呼びたい! Calling Perl subs from x86 code
x86コードからPerlを呼びたい!
Calling Perl subs from x86 code
❤これもシグナルハンドラでやってみた
sub handler { print "signal¥n"; }
$SIG{INT} = ¥&handler;
シグナルハンドラ
ハンドラの設定
my $x86 = "…(略) …"
. "¥x6a¥0"
# push 0 Process Group Id
. "¥x6a¥0"
# push 0 Ctrl-C Event
. "¥xb8"
# mov eax, addr
シグナルの発生
. $addr{'GenerateConsoleCtrlEvent'}
. "¥xff¥xd0"
# call eax
. …(略)…
;
$SetConsoleCtrlHandler->Call(
x86コードの呼出
unpack( 'L', pack( 'P', $x86 ) ), TRUE );
$GenerateConsoleCtrlEvent->Call( CTRL_BREAK_EVENT, 0 );
x86コードからPerlを呼びたい! DEMO
x86コードからPerlを呼びたい! Calling Perl subs from x86 code シグナルを使ったプロセス内通信 InProc communication with signal ❤シグナルを使い分ける Separate signals ❤Perl → x86 : SIGBREAK (Ctrl-Break) ❤x86 → Perl : SIGINT (Ctrl-C) ❤ シグナルハンドラ内でシグナルを発生させてる>< Raise signal in signal handler. X-(
x86コードからPerlを呼びたい! Calling Perl subs from x86 code シグナルを使ったプロセス内通信 InProc communication with signal Perlさ~ん バイナリさ~ん
命 バ シッ 名 高 林 哲 さ ん 公 認 通グド 信ナ ル
x86コードからPerlを呼びたい! Calling Perl subs from x86 code それ Win32::API::Callback で できるよ You can do that with Win32::API::Callback orz
x86コードからPerlを呼びたい! Calling Perl subs from x86 code DEMO
第4部 完
第5部 まともな使い道! Decent use
まともな使い道! Decent use ❤stdcall以外のDLL関数も呼び出せる! Calling non-stdcall functions 呼出規約 引数の渡し方 引数のクリア stdcall 右から左にスタックに格納 関数内 cdecl 右から左にスタックに格納 呼び出し側 fastcall レジスタを使用 ❤Win32::API はstdcallのみ 呼び出し側 Win32::API is only for stdcall
まともな使い道! Decent use DEMO
第5部 完
まとめ ❤頑張れば結構なんでもできる! ❤バイナリコード書くの難しい? →「迷ったときはテキスト」 ❤printfデバッグ万歳! print unpack( 'H2 ' x length( $x86 ), $x86 ); Thanks to TAKESAKOさん、kazuhoさん、tokuhiromさん