セキュリティを楽しく学ぶ、触れる。セキュリティごった煮ブログ

ネットエージェント
セキュリティごった煮ブログ

 コース:元祖こってり

「元祖こってり」記事はネットエージェント旧ブログ[netagent-blog.jp]に掲載されていた記事であり、現在ネットエージェントに在籍していないライターの記事も含みます。

第1回 Win32 API 探検隊

長谷川陽介

 こんにちは。ネットエージェント株式会社、研究開発部の長谷川です。
 今回は、ちょっと軽めのネタということで、MSDN Library を眺めていて見つけた、少し変わった Windows API 関数を紹介したいと思います。

■ 使い道がありそうで見つからない PathIsExe
 Shell32.dll に含まれる PathIsExe 関数は、引数で指定したファイルが実行可能なファイルかどうかを、ファイル名の拡張子を見て判断します。例えば、"*.exe" や "*.cmd" といった拡張子であれば TRUE が返ります。
 Shell32 に含まれるということで、Explorer のようなシェルやシェル拡張などを書いている場合には(もしかすると)利用するかも知れませんが、一般のアプリケーションを開発する場合にはあまりお世話になる機会はなさそうです。
 同じ Shell32.dll には、PathIsSlow という面白い関数もあります。これは、指定したパスが遅延の大きなネットワークドライブなどであった場合に TRUE を返すようです。
 また、Shlwapi.dll にはこれらとよく似た名前で、PathIsURL という関数もあります。引数で指定された文字列がURLの書式に合致すれば TRUE を返すようですが、"http:" や "ftp:" だけでなく、"+-:" や "..:" などでも TRUE が返ってくるというおもしろ仕様なので、大抵の場合は自分で似たような関数を用意しなければなりません。

■ ちょっと便利な StrFormatByteSize
 Shlwapi.dll に含まれる StrFormatByteSize 関数一族は、数値を KB や MB といった単位付きのサイズ文字列に変換する関数です。
 例えば、23506 という数値を StrFormatByteSize64 に渡すと、"22.9KB" という、人間に読みやすい形に単位を変換して書式化した文字列を得られます。ファイルやメモリのサイズを表示する場合に、自分で書いてもたいしたコード量にはなりませんが、覚えておくとちょっとだけ便利です。
 さて、MSDN Library には、以下の5種類の関数の説明が掲載されています。

  1. StrFormatByteSize64
  2. StrFormatByteSizeA
  3. StrFormatByteSizeEx
  4. StrFormatByteSizeW
  5. StrFormatByteKBSize
 

ぱっと見て気がつくのは、ANSI バージョンである StrFormatByteSizeA と Unicodeバージョンである StrFormatByteSizeW がそれぞれ別々に定義されている点です。実は、StrFormatByteSizeA と StrFormatByteSizeW は、単純に ANSI 版と Unicode 版という関係ではなく、ANSI 版が DWORD で 32 ビットまでのサイズにしか対応していないのに対して、Unicode 版は LONGLONG で 64 ビットのサイズに対応しています。また、StrFormatByteSize64 という関数は、ANSI 版である StrFormatByteSize64A しか定義されておらず、Unicode 環境では StrFormatByteSizeW が呼び出されます。
 使いそうであまり使わず、それでいて自分で作ってもたいしたコードでもないような関数が用意されていて、にも関わらずチグハグ感が満載というあたり、いかにも Windows らしいですね(編注:そんなWindowsが大好きなんです!)。

■ 末尾の Ex が 2 段重ねの関数
 Windows API で、あとから機能が拡張されたために名前の末尾に Ex のつく関数はたくさんありますが、EnumCalendarInfoExExEnumDateFormatsExExLogOnUserExExW は、末尾の Ex が 2 個重ねられた名前となっています。あと 3 年くらいしたら、ExExEx などになるのでしょうか。
 ちなみに、Win32 API で現存するもっとも長い関数名は、おそらく ConvertSecurityDescriptorToStringSecurityDescriptor あるいは ConvertStringSecurityDescriptorToSecurityDescriptor の 51 文字だそうです。IDE やエディタの入力支援がなければ、何度も打つのはうんざりしてしまいそうです。

■ APIとしては高機能すぎる SendARP
 Iphlpapi.dll に含まれる SendARP 関数は、その名前の通りコマンドラインの arp コマンドのように、ARP リクエストを送信します。なかなかアプリケーションから ARP を送ることは少ないと思いますし、ARP 自体が小さいとはいえ単一のプログラムとして成り立つくらいのものであり、それを API関数 として用意しているというのはちょっとビックリです。

■ 指定したアドレスのメモリの読み書き権限を調べる IsBadReadPtr / IsBadWritePtr
 Kernel32.dllに含まれる IsBadReadPtr 関数や IsBadWritePtr 関数は、引数として指定されたアドレスのメモリが読み書きできるかを調べる関数です(Vista以降ではサポートされていません)。サードパーティ DLL において渡されたパラメータが適切なものかどうかを判断するといった利用が想定されていたようですが、普通に考えると SEH を利用してコード全体を保護するほうが効率が良さそうです。

■ さいごに
 最後にちょっとしたTIPSを。MSDN Libraryは、表示の設定を "Classic"、"Lightweight"、"ScriptFree" から選択できますが、URLにおいて ( ) 内に "classic"、"lightweight"、"loband" などを指定することでも表示を切り替えられます。例えば http://msdn.microsoft.com/en-us/library/aa363858(VS.85,classic).aspx にアクセスすると classic 表示に、http://msdn.microsoft.com/en-us/library/aa363858(VS.85,loband).aspx にアクセスすると ScriptFree の表示に切り替わります。覚えておくとちょっと便利ですね。

メルマガ読者募集 採用情報 2020年卒向けインターンシップ

月別