Raw InputのGetRawInputBufferの正しい(?)使い方

  1. 新しいスレッドを立てる
  2. 新しいスレッド上で不可視のウィンドウを作成する
  3. 作成したウィンドウを指定してRaw Inputデバイス登録
  4. GetMessage/PeekMessageを「呼ばない」ポーリングループを回す
  5. GetRawInputBufferのpcbSizeが0以外を返すよ!やったね!
  6. スレッドから抜けるときはウィンドウをちゃんと処分!

ただし、2度目のGetRawInputBuffer呼び出しで、pcbSizeそのままのバッファで突撃すると、その間のバッファリングデータ増加で残念なことになりがちなので、2倍とか、16倍とかに水増ししてバッファを確保するのがオススメのようだ。

DirectInput?これからはRaw Input+XInputの時代でしょう?

PCに何枚もキーボードを刺して操作できることを最近知った。それで別々のことが出来るかというと、それぞれのキーボードから入力してみると、まるで一枚のキーボードから入力したかのようになってしまう。キーボードの入力状態を操作する旧来のWindows APIは、キーボードが一枚であることを前提としているようで、それぞれのキーボードからの入力を識別することが出来ないようだった。DirectInputですら、一枚のキーボード扱いしてくれる。
しかし、ぴったりな方法はあるもので、Windows XPからRaw InputなるAPIが提供されている。これは、HID(ヒューマンインターフェースデバイス)からの入力情報を、個々のデバイスを分別可能な状態で取得することを可能にする。うぃきぺたんが言うには、DirectInputはもう更新しないから、キーボードやマウスの入力を読み取るときはRaw Input使ってね(はぁと)、ってことになっているらしい。
しかし、ウィンドウメッセージで逐一イベントを受けるよりも、ポーリングで入力マップを見る方が、安定してゲームに使えるような印象があるんだけどなぁ。
あと、ジョイパッドはX360に特化したXInputなるAPIが出来上がってて、それをつかいましょうね、ってことになってるらしい。へぇ〜

C言語インタプリタCINT

CINT is an interpreter for C and C++ code.

http://root.cern.ch/drupal/content/cint

以前からC言語インタプリタがこの世にあることは知っていたけど、ようやく具体例を見つけた。
曰く、標準に大体従っているらしい。
移植性が素晴らしい。ライセンスも素晴らしい(X11/MIT license)。
あとでさわってみよう。

パスワード強度について本気出して考えてみようとしたけどやめた

ここ数年、ログイン制のサイトでパスワードを設定するときによく見かける「パスワード強度」。これは、入力したパスワードの「強度」を随時計算し、「非常に弱い」「非常に強い」と言った単純明快な言葉で、我々にパスワードの安全性を提示してくれるものだ。この仕組みが、「password」や、「redfox」のような、どうしようもないパスワードを付けることがどれほど危ないかを知らしめ、よりセキュアなパスワードを付けるよう誘導するのに一役買っていることは想像に難くない。
かなりの広まりを見せているものだから、一つや二つ、定番の「パスワード強度」評価関数があるんじゃないか、と思って調べてみると、てんでばらばら。おい、これはどういうことだ?
1つ目の例として、IBMではパスワード強度のことを「パスワード・クオリティー」と呼んで、0〜16までのレベルを定義している。(http://www.ibm.com/developerworks/jp/lotus/iris_today/20010904_5.html)
ここの解説では、レベル6,8,10の要求定義だけが示されていて、ほかのレベルがどうなっているのかを読み取ることは出来なかったが、この3つだけでも、「パスワード強度」評価の方針を考える際の足がかりとしては十分。それらに共通する条件として、次の三つを見いだすことが出来る。

  • 最低パスワード長
  • 使用するシンボルと、その大まかな組み合わせ
  • 辞書攻撃への耐性

非常に単純明快な条件。それぞれの評価の実装にかかるコストも、3つめの辞書作成を除けば、高くなさそうだ。オリジナルの「パスワード強度」評価関数を構成するのも難しくないだろう。
2つめはcracklib。(http://sourceforge.net/projects/cracklib)
このライブラリは、指定したパスワードの辞書攻撃への耐性を確かめることが出来るライブラリらしい・・・?コードを流し読みしただけなので、断定は出来ないけど・・・。これだけでは、先ほど挙げたIBMの評価条件のうち最後の一つしか評価できないことになるので、辞書攻撃への耐性評価のために利用するのが良いように見える。
3つめはExt.us.PasswordMeter。(http://testcases.pagebakers.com/PasswordMeter/)
クライアントサイドで実行出来る、軽量の評価関数を用いている。パスワード長、使用シンボルの種類、シンボルの組み合わせに応じてスコアを付けているようだ。IBMの評価条件に照らし合わせると、最低パスワード長・使用するシンボルと、その大まかな組み合わせが、それらに一致する。
・・・あれ?この世のすべての評価関数を評価した訳じゃないけど、どれもこれもIBMが示している評価条件の一部ばかりじゃないか。
つまりは、だ。この3つの条件が「パスワード強度」評価関数のキモで、具体的にどう定義、評価付けするかは、評価関数の開発者にゆだねられる、ってことなのか・・・?

DirectInputを使うソフトにキー入力情報を送信する

Windowsで、プログラムに対してキーボード入力があったと偽るには、SendMessage, PostMessageで、対象プログラムのスレッドメッセージキューにWM_KEYDOWN/WM_KEYUP等のキーボード系メッセージを積んだり、keybd_event/SendInputでキーボードインプットストリームに入力情報を流し込むのが常套手段となっている。
しかし、対象プログラムがDirectInputを用いてキーボード入力をフェッチしている場合は別問題。メッセージキューはまず無視されるので、SendMessage/PostMessageは使えない。残るはkeybd_event/SendInputだけど、これも普通に仮想キーコードを与えただけでは、対象プログラムはうんともすんとも言わない。
何かものを言わせるためには、仮想キーコードに加えて、スキャンコードを指定する必要がある。しかし、keybd_eventではスキャンコードの指定は「使用しない」とMSDNライブラリに書かれているため、結局SendInputだけ使えることになる。(非文書化仕様では、keybd_eventでもスキャンコードを送信できるのだけど、あくまで隠し仕様なので使わない方が賢明)
http://homepage1.nifty.com/yasunari/VB/VB2005/ScreenKeyBoardMaking.htm(homepage1.nifty.com)のサンプル:スクリーンテンキーボードで書かれているSendInput周りのコードが、SendInputを用いてプログラムにスキャンコードを付加したキー入力情報を送信する手順となっている。ExtendedKeyFlagW関数で天下り的に拡張キーの判定が与えられているけど、http://community.osdev.info/index.php?%28AT%29keyboard(community.osdev.info)にあるとおり、PC/AT互換機PS/2キーボードコントローラの仕様として定められているようだ(?)。

x86アセンブリニーモニックを機械語にアセンブルするプラグイン

ATOKダイレクトでASがサポートされないから無視するなんていうのは、宝の持ち腐れにも程があるってもので、何か作ってみることにした。
しかし、作るからには誰ともかぶってなくて、ありそうでないようなものが作りたい。小一時間思案に耽ってみたところ、「x86アセンブラ」というキーワードが思い浮かんだ。
そう、今求めているのはきっとこれだ。これでいこう。
x86アセンブラと言えば、MicrosoftMASMや、BorlandのTASM、オープンソースプロジェクトのNASM、GNUのGAS辺りが有名だと思う。こいつらを呼び出して、出力をunpackしてもいいんだけど、スクリプトでやるなら100% Pure Rubyで行きたいところだ。
検索サイトで調べてみると、Metasploitと関連深いプロジェクトにMetasmというものがあって、Rubyアセンブラ・逆アセンブラ・リンカ・Cコンパイラ・デバッガを開発しているらしい。しかもクロスアーキテクチャ

Metasm is a cross-architecture assembler, disassembler, compiler, linker and debugger.

It has some advanced features such as remote process manipulation, GCC-compatible preprocessor, automatic backtracking in the disassembler ("slicing"), C headers shrinking, linux/windows debugging API interface, a C compiler, a gdb-server compatible debugger, and various advanced features. It is written in pure Ruby.

http://metasm.cr0.org/

こ、これはすごい……今回の目的遂行手段にぴったりすぎる。
すぐにインストールしたけど、どうやらリファレンスマニュアルはないらしい。まだ、サンプルとソースコードがマニュアル代わりという状態のようだ。
とりあえず、サンプルを眺めながら、プラグインスクリプトをサラサラっと書き下してみた。

module Atok_plugin
  def run_process(req)
    require 'metasm-shell'
    {'candidate'=>[
{'hyoki'=>(req['composition_string'].gsub("$","\n").encode.unpack('H*')[0] rescue 'error')}]}
  end
end

あまりにも簡単に書けすぎでしょう、これは・・・?動かしてみると、これはおもしろい。ちゃんとアセンブルされてる。

ということで、キットを使って固めたものはこちらから。
ダウンロードする (MediaFire)
Ruby 1.9.1で動作確認済み。ただ、普通の状態では動かなくて、動かすにはMetasm(http://metasm.cr0.org/)をインストールする必要があり。
ふとアセンブルしたくなったとき、ハンドアセンブルできなくても素早く出来る利点がステキ!って、なったらいいなぁ。なーんかそんな都合のいいシーンが思い当たらないんだけど・・・
あと、Metasm-shellのデフォルトアーキテクチャx86になってるけど、一応MIPSPPCもいけるらしいので、いじってそっち向けのプラグインにしてもおもしろそうだ。

unofficial ActiveScriptRuby 1.9.1.0

エイプリルフールなのは知っていたけど、別にネタを仕込むほどでもなかった。http://www.geocities.co.jp/SiliconValley-PaloAlto/9251/ruby/で公開されているActiveScriptRubyのunofficial版を作ってみた。
公式版との違いは、

  • ruby 1.9.1-p0
  • Visual C++ 2008でビルド(ランタイムDLL使用, あとオプション普通)
  • ↑の関係で実行にVisual C++ 2008 Redistributable Packageが必要
  • ↑の関係でモジュールのビルドにVisual C++ 2008が必要
  • ActiveScriptRubyにOrthoclase上で動作可能にするパッチを適用
  • ActiveScriptRubyにruby 1.9.1-p0で動作可能にするパッチを適用
  • GlobalRubyScriptはエンバグしたのでドナドナ

Download (from MediaFire)
ライセンスはGPL2(?)とのこと。サポートとかは知らない。

ということでこれを使うと、Orthoclaseでrubyを動かせるようになる、と思う。あと、RScriptを登録しなければ、ruby 1.9.1-p0 (i386-mswin32_90)としても使えるので、モジュールビルドしたいけど、Visual C++ 6.0なんてもってねーよばーかってひとは、試してみるといいかもしれない。