Inline::ASM
perlから他言語を使うInlineモジュールの中にアセンブリを扱う
Inline::ASMがあることは以前から知っていたのですが、使ったことはありませんでした。
Inline::ASM - Write Perl Subroutines in assembler. - metacpan.org
ためしに触ってみたらすんなり動かすことが出来なかったのでメモ。
SYNOPSISを信じて下のコードを動かしたらエラーが出ました。
(Win7 + Strawberry Perl + nasm)
#!perl print "9 + 16 = ", add(9, 16), "\n"; use Inline ASM => 'DATA', AS => 'nasm', PROTO => {add => 'int(int,int)'}; __DATA__ __ASM__ global add section .text add: mov eax,[esp+4] add eax,[esp+8] ret
エラー
error_pl_fbdc.o:error_pl_fbdc.c:(.text+0x601): undefined reference to `add'
アセンブリコードのシンボル名にアンダースコアつけないとダメかなと思って
つけてみましたが、また別のエラーが・・・。
エラー
Use of inherited AUTOLOAD for non-method main::add() is deprecated at error.pl line 2.
アンダースコアつけてないヤツもglobalしなきゃだめか?と思って追加してみたところうまくいきました。
#!perl print "9 + 16 = ", add(9, 16), "\n"; use Inline ASM => 'DATA', AS => 'nasm', PROTO => {add => 'int(int,int)'}; __DATA__ __ASM__ global _add global add section .text _add: mov eax,[esp+4] add eax,[esp+8] ret
出力
9 + 16 = 25
おまけでHello, World!しておきました。
#!perl use DynaLoader; my $path = "$ENV{SystemRoot}\\system32\\user32.dll"; my $libref = DynaLoader::dl_load_file($path); my $sym = DynaLoader::dl_find_symbol($libref, "MessageBoxA"); call_msgbox($sym, 0, "title", "Hello, World!", 0); use Inline ASM => 'DATA', AS => 'nasm', PROTO => {call_msgbox => 'void(long,long,char*,char*,long)'}; __END__ __ASM__ GLOBAL _call_msgbox GLOBAL call_msgbox SECTION .text _call_msgbox: mov ebx,esp mov eax,[ebx+4] push dword [ebx+8] push dword [ebx+12] push dword [ebx+16] push dword [ebx+20] call eax ret
UbuntuのインストールUSB作成
ノートPCがほしいです。
今持ってるノートはファンが大声で鳴くようになったしまったので、最近は勉強会にも参加できず・・・。
もういっそ買ってしまおうかと考え中です。
それで色々見ていて疑問に思ったのが、今のノートはDVDドライブがない型が多いので
Linuxなんかを入れようと思ったらUSBからインストールするとして、
USB版インストールディスクは簡単に作れるのかなってことです。
調べた結果、簡単に出来そうです。(Ubuntu)
UbuntuTips/UsbInstall/CreateUSBStartupDisk - Ubuntu Japanese Wiki
これであとは買うだけ・・・。
行くかどうか分からないけど、YAPC::Asia前には買いたいなぁ。
YAPC::Asia Tokyo 2011
PEBやらTIBやら
最近「アナライジング・マルウェア」を読んだためか若干アセンブリ熱が出てきて、
愛甲健二さんの本等を引っ張り出してきてごちゃごちゃ調べています。
その中でkernel32のアドレスを自前で引っ張ってきてLoadLibraryとGetProcAddressを
呼ぶというサンプルコードはWindows7でも動くのかなと気になって少し調べてみました。
結果、kernel32.dllより先にkernelbase.dllが呼ばれるようになったため、
少し変更が必要みたいです。
勉強と復習を兼ねてWindows7版を書いてみようかなと思います。
続きは明日?
アナライジング・マルウェア ―フリーツールを使った感染事案対処 (Art Of Reversing)
- 作者: 新井悠,岩村誠,川古谷裕平,青木一史,星澤裕二
- 出版社/メーカー: オライリージャパン
- 発売日: 2010/12/20
- メディア: 単行本(ソフトカバー)
- 購入: 8人 クリック: 315回
- この商品を含むブログ (22件) を見る
- 作者: 愛甲健二
- 出版社/メーカー: データハウス
- 発売日: 2006/03
- メディア: 単行本
- 購入: 8人 クリック: 69回
- この商品を含むブログ (18件) を見る
PerlからWin32 apiを使ってみた(アイコンの取り出し)
1ヶ月位前にMSDNのサイトに、よく使われるWindows APIリストを集めたページが公開されました。
Windows API リスト: Windows API、Win32 API、Win32API | MSDN
頭から眺めて何か面白そうなAPIは無いかなと思っていると、ど頭の「アイコン」カテゴリが少し気になったので
Win32apiを叩いて、exeファイルからアイコンを取り出すperlスクリプトを書くことにしました。
#!perl use strict; use warnings; use Win32::API; use Imager; Win32::API::Struct->typedef( ICONINFO => qw { INT fIcon; INT xHotspot; INT yHotspot; LONG hbmMask; LONG hbmColor; }); Win32::API::Struct->typedef( BITMAP => qw { LONG bmType; LONG bmWidth; LONG bmHeight; LONG bmWidthBytes; WORD bmPlanes; WORD bmBitsPixel; LPVOID bmBits; }); my $ExtractIcon = new Win32::API( 'shell32.dll', 'ExtractIcon', 'NPI', 'N' ) or die; my $GetIconInfo = new Win32::API( 'user32.dll', 'GetIconInfo', 'NS', 'I' ) or die; my $GetObject1 = new Win32::API( 'gdi32.dll', 'GetObject', 'NIP', 'I' ) or die; my $GetObject2 = new Win32::API( 'gdi32.dll', 'GetObject', 'NIS', 'I' ) or die; my $GetBitmapBits = new Win32::API( 'gdi32.dll', 'GetBitmapBits', 'NNP', 'I' ) or die; #ExtractIconでexeファイルから0番目のアイコンハンドルを取得 my $hicon = $ExtractIcon->Call($$, 'C:/EXCEL.EXE', 0) or die; #ICONINFO構造体を用意して、GetIconInfoでアイコンの情報を取得 my $piconinfo = Win32::API::Struct->new('ICONINFO') or die; $GetIconInfo->Call( $hicon, $piconinfo )or die; #GetObjectの第3引数に0を指定して必要なバッファサイズを取得 my $size = $GetObject1->Call( $piconinfo->{hbmColor}, 0, 0 ); #BITMAP構造体を用意して、GetObjectでアイコンのビットマップ情報を取得 my $bmp = Win32::API::Struct->new('BITMAP') or die; $GetObject2->Call( $piconinfo->{hbmColor}, $size, $bmp ); #上で得たビットマップ情報から、必要なバッファサイズを計算 my $bmp_size = ($bmp->{bmBitsPixel} * $bmp->{bmHeight} * $bmp->{bmWidth})/4; my $bmp2 = ' ' x $bmp_size; #GetBitmapBitsでビットマップビット列を取得 $GetBitmapBits->Call($piconinfo->{hbmColor}, $bmp_size, $bmp2 ); #後はImagerを使って書き出す my $newimg = Imager->new(xsize => $bmp->{bmWidth}, ysize => $bmp->{bmHeight} ); for( my $i=0; '' ne $bmp2; $i++ ){ my $pix = join( '', unpack("H8", $bmp2) ); $newimg->setpixel(x => $i % $bmp->{bmWidth}, y => int($i / $bmp->{bmWidth}), color => $pix); my $del = quotemeta pack("H8", $pix); $bmp2 =~ s/^$del//; } $newimg->write(file =>"test.bmp") or die;
Chrome ExtensionでYouTube&ニコニコ動画のダウンローダを書いてみた
昨日の続きです。
折角おぼろげながらにも、Chrome Extensionの作り方が分かってきたので何か作ってみることにしました。
テーマを探していると、ありそうで無いのがyoutubeとニコニコ動画の両方に対応したダウンローダ。
ググるとあるにはあるんですが、外部のダウンロードサイトに飛ばされたりしてしまって直接落とせるのが見つかりませんでした。
設計?というか作成イメージはこんな感じです。
・ページアクションで動く(youtubeかニコニコ動画のページを開いているときのみアイコンを表示する)
・ページアクションアイコンをクリックされると新しいタブを開いて、ダウンロードボタンを表示する
ファイルは4つのシンプル構成
・background.html
(クリックされたときに裏で走る処理を記述)
・down.html
(ダウンロードボタンを表示する画面)
・icon.png
(アイコン)
・manifest.json
(マニフェスト)
ソースはgithubにあげてみました。
2011/06/19追記
megavideoにも対応しました。
■使い方
1. 下記リンク先から、getyousmile.crxをダウンロード
2.Chrome画面へドラッグアンドドロップ
3.インストールするか尋ねられるので、インストール
4.YouTubeまたはニコニコ動画のページを開く
5.アドレスバーの右端にトランプのマークが表示されるのでクリック
6.自動的に開いたタブのdownというリンクを右クリックして名前をつけて保存
GitHub - satsubatsutaro/get_you_smile: youtube & nicovideo downloader by chrome extension
Chrome Extensionを書いてみた
以前からFirefoxのアドオンかけたら便利だろうなと思いつつも、敷居の高さにしり込みしてましたが、
最近自宅ではほぼGoogle Chromeをメインブラウザにしているので「もしかしてChromeのExtensionは簡単だったりしないかな・・・。」
と期待を持って検索をかけてみました。
google:chrome 拡張 開発
http://blog.smartnetwork.co.jp/staff/node/44
「開発がとてもカンタン」など、僕の願望が投影されたような記事を発見。幸先がいいです。
javascriptとHTMLがかければ色々出来るとのことで、とりあえず記事に従って"hello, world"アプリを作成して流れをつかみました。
用意するものは
とシンプル。
Chrome Extensionには大まかに分けて2つの種類があるようです。
1つ目はブラウザアクションといってevernoteやskypeのように、アドレスバーの右に常に出ているタイプのものです。
これは汎用的な機能を持った拡張に有効とのことです。
2つ目はページアクションといってRSSフィードの登録ボタンのように、アドレスバー内部の右端に出るタイプのものです。
これはページの内容によって表示させたり、させなかったりする時に使うもののようです。
続きは明日書くと思います。