Address Space Layout Randomization
--なぜSafariだったのですか。IEやFirefoxでなかったのは?
簡単なことです。Mac上のSafariの方が攻撃が簡単だからです。Windows上のいくつかの技術は攻撃を成功させるのを難しくしていますが、Macではそういうことはしていません。Macをハッキングする方がずっと簡単です。曲芸をして、Windows上で見られる耐攻撃措置を相手にする必要がないからです。
これは、対象となるプログラムではなくオペレーティングシステムの問題です。Mac上のFirefoxも比較的簡単です。その下にあるOSに、攻撃に対抗する仕組みが組み込まれていないからです。
(参照:10 questions for MacBook hacker Dino Dai Zovi)
私が使ったSafariに対する攻撃では、コードをプロセスに埋め込むと、そのコードの場所を正確に知ることができます。ランダム化されたりはしません。そこにジャンプすれば、コードはそこにあり、そこから実行することができます。Windowsでは、コードは現れるかもしれませんが、それがどこにあるか分かりません。コードの場所にたどり着いたとしても、実行できません。これら2つの障害は、Macにはないものです。
3つすべてのブラウザ(Safari、IE、Firefox)にバグがあるのは明らかです。コードを実行できるセキュリティホールがあちこちにあります。しかし、それは公式の片側の辺に過ぎません。もう一方の辺には、それを悪用するということがあります。Mac OS Xでは、そこにほとんど障害がありません。
何だかんだで ASLR (Address Space Layout Randomization) は役立ってるんだのぅ *1.ということは,もし仮にこのコンテストで使用される OS が Windows XP だったり *2,Firefox が Visual C++ 6.0 や Visual C++ .NET 2003 でコンパイル (というかリンク) されていたりしだすと,だんだん話が違ってくるわけか.
Mac OS is fine, there's no need to worry like you.
「Mac の OS は平気。キミみたいに心配する必要はないんだ」
追記: Mac OS X の ASLR とか NX-bit
詳しくはないんですが,軽く検索してみるとこういう話が.
This is already present to an extent in today's Leopard Server, which runs some services, such as the Apache web server, as 64-bit processes. Using the vmmap command reveals that no memory allocated by these 64-bit apps is both writable and executable. On 32-bit Intel systems, while no memory is marked as both writable and executable, the legacy x86 processor design does not enforce the permissions bits, but 64-bit CPUs do. This feature prevents exploits from injecting malicious executable code into memory and tricking the app to run it as it if were its own instructions.
Another security weakness in the x86 architecture solved in the move to 64-bits is the use of registers for function call arguments. This makes exploits using return-into-libc techniques much more difficult. On 32-bit x86, function arguments are passed directly on the stack, so when an attacker has overwritten the stack segment, they can completely control the arguments passed to a function that they cause the compromised program to "return into," according to a security researcher.
The move to 64-bits also greatly enhances the Address Space Layout Randomization (ASLR) techniques used to secure Leopard. Currently, 32-bit binaries are restricted to a relatively small 4GB allocation, making it easier to predict useful addresses for malicious code to target. Additionally, Leopard keeps dyld, Mac OS X's dynamic loader (responsible for loading all of the frameworks, dylibs, and bundles needed by a process) in the same known location, making it relatively trivial to bypass the existing ASLR.
With the much larger address space available to 64-bit binaries, Snow Leopard's ASLR will make it possible to hide the location of loaded code like a needle in a haystack, thwarting the efforts of malicious attackers to maintain predictable targets for controlling the code and data loaded into memory. Without knowing what addresses to target, the "vast majority of these exploits will fail," the security expert explained.
追記2
107 名前: 名刺は切らしておりまして [sage] 投稿日: 2009/03/24(火) 14:08:03 ID:iCro0TNFWikipediaにはMac OS XはNXビットをサポートしてると書いてある
ttp://en.wikipedia.org/wiki/Executable_space_protection#Mac_OS_X
このプレゼンによるとライブラリアドレスのランダム化もやっているようだ
ttp://trailofbits.files.wordpress.com/2009/03/macosxploitation_source2009.pdf
108 名前: 名刺は切らしておりまして [sage] 投稿日: 2009/03/24(火) 14:12:34 ID:iCro0TNF>>107の下のプレゼンは今回のハッキングコンテストの後で書かれたようで
Mac OS Xのセキュリティを他のOSと比較しているので非常に参考になる109 名前: 名刺は切らしておりまして [sage] 投稿日: 2009/03/24(火) 14:36:53 ID:iCro0TNFざっとまとめると
・VistaとLinuxはヒープとスタックの両方が実行不可だが、
Mac OS Xはスタックのみ実行不可でヒープに書き込んだプログラムは実行可能
・VistaとLinuxはライブラリ、ヒープ、スタックの位置を動的にランダムに変えているが
Mac OS Xはライブラリのみをインストール/アップデート時にランダム化するだけ
後で突っ込まれないように念のため付け加えておくと
・Linuxでも32bit版ではPAEを有効にしたカーネルでないとスタックは実行不可にならない。
ほとんどのディストリビューションはデフォルトでPAE無効のカーネルをインストールする
・Linuxでprelinkを有効にしておくと、ライブラリ位置が変化するのは
Mac OS Xと同様にインストール/アップデート時のみになる(手動で更新も可能)
prelinkが有効になっているかどうかはディストリビューションによってまちまち
後で調べてみるか.
DirectDrawウィンドウモードでのティアリング回避 (1)
DWMの無いXPでも垂直同期を待てばティアリングを防ぐことは出来ます。
ただしウィンドウモードで垂直同期を待てるようになったのはつい最近で、DirectX9.0になってからです。
あたりから始まって色々コメントを書いた成り行き上,ちょいとばかり昔の資料を漁って書いてみます.と言っても私もそんなに詳しくないので,嘘を書いちゃった場合はひげねこさんの突っ込みに期待.
まずは基礎編から.
DirectDraw ウィンドウモードでのティアリング回避アルゴリズム
実際のところ DirectDraw ウィンドウモードでのティアリング回避アルゴリズムは,DirectDraw 初期から変わっていないはずです.
アルゴリズムのコンセプトは単純で,デスクトップへの BilBlt が走査線通過中に行われないようにタイミング調整を行うというもの.走査線のタイミングに合わせるのは DirectDraw 初期の頃から存在する GetScanLine / WaitForVerticalBlank が使えます.即時的な BitBlt には,いわゆる NOWAIT 系のフラグが利用できて,ドライバ内でブロックされてタイミングが狂う可能性を減らすことができます.
ドライバモデルについて
Windows 2000,Windows XP,Windows Server 2003 は同じドライバモデルを利用しています.このドライバモデルは,DirectDraw のファンクションを基本とし,建て増し的にコマンドバッファ方式の DrawPrimitive 機能を追加した構造をしています.
さて,Windows 2000 から Windows XP,Windows Server 2003 までの間に DirectX 6 から DirectX 9までがリリースされましたが,実はこの間にドライバモデルは変わっていません.一般には DirectX 8 で DirectDraw と Direct3D が統合されたと思われていますが,あれは単に API 層でラップしただけです.実際には Direct3D のランタイムライブラリがラッパー化していき,内部でせっせと DirectDraw 相当のドライバファンクションを使い分けるようになっただけでした.
例として,先ほど登場した GetScanLine を見てみましょう.Windows 2000 のドライバモデルで,ドライバは以下のファンクションを提供します.
Windows 2000 から Windows Server 2003 までの間で,この仕組みは基本的に変わりません.一方でアプリケーションからは,走査線位置の取得方法が複数あるように見えます.
- IDirectDraw::GetScanLine
- IDirectDraw2::GetScanLine
- IDirectDraw4::GetScanLine
- IDirectDraw7::GetScanLine
- IDirect3DDevice8::GetRasterStatus
- IDirect3DDevice9::GetRasterStatus
- IDirect3DSwapChain9::GetRasterStatus
- NtGdiDdGetScanLine
しかしこれらの API,同一のドライバファンクションの異なるラッパーに過ぎません.
(続く)
書籍紹介: Advanced Windows 第5版
『Windows VIA C/C++ , Fifth Edition - NyaRuRuの日記』をお伝えしてから10ヶ月,日本語翻訳版がいよいよ発売です.日本だと『Advanced Windows』が7年ぶりに改訂と言った方が伝わりやすそうですな.

Advanced Windows 第5版 上 (マイクロソフト公式解説書)
- 作者: Jeffrey Richter,Christophe Nasarre,(株)クイープ
- 出版社/メーカー: 日経BPソフトプレス
- 発売日: 2008/10/23
- メディア: 単行本
- 購入: 7人 クリック: 48回
- この商品を含むブログ (20件) を見る

Advanced Windows 第5版 下 (マイクロソフト公式解説書)
- 作者: Jeffrey Richter,Christophe Nasarre,(株)クイープ
- 出版社/メーカー: 日経BPソフトプレス
- 発売日: 2008/10/23
- メディア: 単行本
- 購入: 8人 クリック: 32回
- この商品を含むブログ (13件) を見る
原書持ってますが,例によって私は引用目的買いで.
個人的にお気に入りの Vista 新機能のうち,同書で解説されているものを紹介しておきます.
- Wait Chain Traversal
- Windows Vista の新しい同期プリミティブ
- condition variable
- slim reader/writer lock
one-time initialization(訂正)よく見たら解説入ってませんでした
- Application Recovery and Restart
つまりここに挙げたような内容についての記事を書くときに引用チャンスと.というわけでまあ買いで.
Transactional NTFS の解説が入っていないのはちょっと悲しいところですかね.でもまあ買いで.
あわせて予約したい (原書)
『インサイド Microsoft Windows 第5版』(恐らく上下巻) になるであろう本の原書 (になるであろうはずのもの) にして,出版延期を繰り返した結果 Windows 7 より先に出るかが気になる今日この頃のような,そんな Mark Russinovich 大先生の至高の一冊 (になるはずのもの).

Windows® Internals, Fifth Edition (PRO-Developer)
- 作者: Mark E. Russinovich,David A. Solomon,Alex Ionescu
- 出版社/メーカー: Microsoft Press
- 発売日: 2009/06/17
- メディア: ハードカバー
- 購入: 1人 クリック: 87回
- この商品を含むブログ (15件) を見る
SSD による体感速度向上ただ飯時代
今がんばって OS やファイルシステムを SSD に最適化させるより,SSD 自体が HDD みたいに気軽に使えるようになるのを待つ方が頭良くね? という話.
Alan CoxのLinux 3.0(注1)が否決されたほか、I/O周りをSSDに最適化しようという提案も否決(注2)、カーネルトレース機能(注3)もLinusの「オレ、イラネー」発言で否決と、予想どおりというか、あまり意外性のない結果になったようです。記事を書く立場としては、ネタを拾えなくて少し残念です。
注2:現在のSSDは、登場して間もないこともあってさまざまな欠点があり、ソフトウェア側で改善できる余地がたくさんあります。ですが、SSDのデバイス自体が猛烈な勢いで進化しており、近い将来、デバイス側で解決される確率が高い。そのため、いまのデバイスに最適化してもデッドコードを量産するだけになるのではないか、というのが理由のようです。Intelが「うちのSSDは、単に高速なHDDとして使えるよう作ったぜ」と豪語しているのも大きかったのかも。
同じく Intel SSD を購入した身としては,「いまのデバイスに最適化してもデッドコードを量産するだけになるのではないか」というのに激しく同意.むしろ SSD でも HDD のように使い倒すぐらいで十分と.ツン期ですな.
何はともあれ,今後数年はディスク I/O 周りのパフォーマンスが勝手に改善されていくという,ソフト屋さんにとっての“ただ飯時代”になりそうです.フロッピーディスクからハードディスクへの移行以来 15 年ぶりという感じで.
来年度あたりに発売される OS は,「なんだかとてつもなく高速化した OS」というイメージ戦略が簡単に採れそうですね.それも OS 側は特に何もする必要がなくて,プリインストールモデルを高速 SSD と一緒に出荷してもらうよう誘導できれば十分そうな.マーケティング勝負なんですかね.
そろそろイベント告知時に iCalendar 形式を使うことを検討してみる
IT勉強会カレンダー
- 第4回 はなずきん――IT勉強会カレンダーは「自分のために」 - @IT自分戦略研究所
- アタシ 今日も “ままーり”と 勉強会を たくさん 見つけた みたいな 「IT勉強会カレンダー」はなずきんさんインタビュー :CodeZine - インフラ管理者の独り言(はなずきん@酒好テム管理者)
- アタシ 今日も “ままーり”と 勉強会を たくさん 見つけた みたいな - 「IT勉強会カレンダー」はなずきんさんインタビュー - CodeZine
たくさん更新するために工夫していることはありますか?
- はなずきん
- はじめは、いちいちGoogleカレンダーの「カレンダーに登録」を押して、入れてました。それで、はせがわさんに「もっと簡単にできる方法あるよー」って。
- はせがわ
- Googleカレンダーを英語版にしておけば「QuickAdd」って機能が使えるんですよ。
- はなずきん
- でも日本語のGUIで見てたんで探すのに時間がかかって、「ほかなんかないかなー?」って見てたらGoogleのヘルプに「CSVで登録できるよー」って書いてあったんで、「ステキ!」と思って、今はCSV。右クリックからMakelink(タイトルやURLを簡単にコピペするFirefox機能拡張)でちょっと取って、みたいな。
- まっちゃ だいふく
- 途中から地域入れたでしょ。あれ良かった。
- はなずきん
- あれは、kanasanが言ってくれたこと反映して。昔のまでさかのぼって入れたと思う。
- 編集部
- 全部1人で情報を探してるんですか?
- はなずきん
- 編集権限あるのは全部で6人いる。
- まっちゃ だいふく
- でも99.8%くらいはこの人(笑)。
そういえば IT 勉強会カレンダー には XNA オフ会もいつの間にか登録していただおり,ありがたやありがたやでした.
そろそろイベント告知時に iCalendar 形式を使うことを検討してみる
さて,最近自分でイベントを開いたり,参加イベントを紹介したりすることが増えてきました.よくよく考えてみると,紹介用の情報をテキストで書いてさらにそれを手入力でカレンダーに取り込んでもらうのもあれな話です.そこで iCalendar 形式をまじめに使おうかと考えています.たとえば前回の XNA オフ会であればこんな感じで.
http://www.dwahan.net/nyaruru/hatena/xnaoff2008.ics
(UTF-8 な) ファイルとして置くのであれば,.htaccess に次の一文を入れておくと良いかもしれません.
AddType text/calendar;charset=utf-8 .ics
あとは,はてなダイアリーでカレンダー公開用モジュールみたいなのがサポートされればハッピーなんですかね.
Google カレンダーと iCalendar 形式のエクスポート
Google カレンダーは iCalendar 形式のエクスポートに対応しており,先ほどの「IT 勉強会カレンダー」であれば,以下の URL で公開されています*1.これを購読することで外部からイベント情報を利用することができるようになります.
http://www.google.com/calendar/ical/fvijvohm91uifvd9hratehf65k@group.calendar.google.com/public/basic.ics
Windows Vista に標準でついてくる「Windows カレンダー」であれば,メニューから「共有」→「購読」でオンラインの iCalendar データを定期購読できます.

個人で参加予定のイベントリストを iCalendar 形式で公開,なんてのもやってみたいところ.
Intel X25-M と ICH7 標準ドライバ
先週末に Intel X25-M (80GB) を購入,これを Lenovo T60 のシステムディスクに変更し,Windows Vista SP1 の再インストールを行いました.
感想としては速いの一言です.Vista はとにかくディスク I/O の多い OS ですが,Intel X25-M はこれを十分にさばききります.ブロッキング I/O が全く気になりません.このクラスの SSD が一般的になるであろう Windows 7 世代では,PC のカジュアル用途でディスク I/O は問題にはならないということになりそうです.
ここまでディスクアクセスが高速化されると,ディスクアクセスを無理して減らすことがメリットにならなくなるやもしれません.がんがんインデックスファイル/キャッシュファイルを生成する方がおもしろいソフトウェアにつながるケースがあると良いですね.それはそれで,プログラム屋さんとしては楽しめそうです.
さてさて,一点気になったのが,Windows Vista の標準 AHCI ドライバです.今回は Windows Vista SP1 統合済みイメージをインストールしたのですが,下記ページにあるように標準 ICH7 ドライバが組み込まれていました.
このときのデバイスマネージャで,表示→デバイス(接続別),を選択すると,確かに互換モード的な動作を暗示させるようなそうでないような UATA のジェネリックドライバが ICH7 と X25-M の間に挟まっています.
そこで記事にあるように「インテル® マトリックス・ストレージ・マネージャー」を入れてみたところ,ICH7 直下に X25-M がぶら下がるようになり,何となく SATA-II で動いているよ的な構成に変化しました.
参考までにベンチマーク結果もはっておきます.マトリックス・ストレージ・マネージャー付属ドライバ使用時の方が高い性能を示しています*1.ただし,標準ドライバでの測定時にバックグラウンドタスクのチェックをちゃんとやっていなかったので,もしかしたらこの違いはフェイクかもしれません.
暇を見てテストコードを書いて色々と実験してみたいところです.
Windows Vista SP1 標準ドライバ使用時

インテル・マトリックス・ストレージ・マネージャー (8.5.0.1032) 付属ドライバ使用時

テストサイズ 500MB での結果も追加.

おまけ
WinHEC 2008 のカンファレンスペーパーより.Microsoft Research の中の人による SSD デザインの話.
ゲームプレイ中のスクリーンセーバやディスプレイ休止を回避する方法
主にゲームパッドのみでプレイできる PC ゲームでは,ゲームプレイ中にスクリーンセーバが起動したりディスプレイの電源が切れたりして「むがー!」ということがあります.
これはプログラム側の対応である程度防止できますので,その辺のメモでも.
もっとも保守的で無難な方法は,ウィンドウメッセージのトラップです.WM_SYSCOMMAND メッセージのうち SC_MONITORPOWER と SC_SCREENSAVE を DefWindowProc に渡さないようにします.
Once a screen saver is chosen, Windows monitors keystrokes and mouse movements and then starts the screen saver after a period of inactivity. However, Windows does not start the screen saver if any of the following conditions exist:
- The active application is not a Windows-based application.
- A computer-based training (CBT) window is present.
- The active application receives the WM_SYSCOMMAND message with the wParam parameter set to the SC_SCREENSAVE value, but it does not pass the message to the DefWindowProc function.
Windows Vista and later: If password protection is enabled by policy, the screen saver is started regardless of what an application does with the SC_SCREENSAVE notification.
case WM_SYSCOMMAND: switch( ( wParam & 0xFFF0 ) ) { case SC_MONITORPOWER: case SC_SCREENSAVE: return 0; // DefWindowProc は呼ばない break; ...以下略
これだけでかなりのケースは対応できます.以下各論.
ゲームパッドの操作でディスプレイ休止は阻止できることもある
これは手元の Windows Vista SP1 (x86) + Xbox 360 パッド (純正ドライバ) で確認したケースですが,Xbox 360 パッドの操作中はディスプレイの休止は発生せず,またディスプレイ休止状態に Xbox 360 パッドを操作するとディスプレイ休止状態から回復することを確認しています.
ただややこしいことに,スクリーンセーバには効果がないようでした.
SetThreadExecutionState API ではスクリーンセーバを阻止中断できない
This function does not stop the screen saver from executing either.
(2009年10月12日追記)
- 一度実行してしまったスクリーンセーバを SetThreadExecutionState で中断することはできない.
- スクリーンセーバ起動防止に使うためには,SetThreadExecutionState(ES_DISPLAY_REQUIRED) のように ES_DISPLAY_REQUIRED 単独で指定する必要がある.ES_DISPLAY_REQUIRED | ES_CONTINUOUS 等は効果がない.
参考:
WM_SYSCOMMAND の wParam の扱い
本来 0xfff0 と & を取るのが正しい……はず.
In WM_SYSCOMMAND messages, the four low-order bits of the wParam parameter are used internally by the system. To obtain the correct result when testing the value of wParam, an application must combine the value 0xFFF0 with the wParam value by using the bitwise AND operator.
でも KB とか見ると結構適当.
2. あるアプリケーションが起動中にスクリーンセーバを起動させない方法
スクリーンセーバの機動を止めるには WM_SYSCOMMAND の wParam == SC_SCREENSAVE の時 return 1 を返してください。
例 case WM_SYSCOMMAND: if ( wParam == SC_SCREENSAVE ) { return 1; } return (DefWindowProc(hWnd, message, wParam, lParam));
何も考えずに wParam == SC_SCREENSAVE とかやってますけどいいんすかねこれ.みんなコピペ大好きですよ?
WM_SYSCOMMAND トラップ時の返値は 0 にすべきか 1 にすべきか
2. あるアプリケーションが起動中にスクリーンセーバを起動させない方法
スクリーンセーバの機動を止めるには WM_SYSCOMMAND の wParam == SC_SCREENSAVE の時 return 1 を返してください。
例 case WM_SYSCOMMAND: if ( wParam == SC_SCREENSAVE ) { return 1; } return (DefWindowProc(hWnd, message, wParam, lParam));
ここだけ読むと 1 を返すことが重要なように読めますが……
Return Value
An application should return zero if it processes this message.
Once a screen saver is chosen, Windows monitors keystrokes and mouse movements and then starts the screen saver after a period of inactivity. However, Windows does not start the screen saver if any of the following conditions exist:
- The active application is not a Windows-based application.
- A computer-based training (CBT) window is present.
- The active application receives the WM_SYSCOMMAND message with the wParam parameter set to the SC_SCREENSAVE value, but it does not pass the message to the DefWindowProc function.
戻り値としては 0 の方が適切だし,スクリーンセーバ避けには DefWindowProc を呼ばないことの方が重要にも読めます.一方で,昔の Windows だと違った系の可能性も.
Windows Vista 以降,スクリーンセーバのパスワードロックが有効だと,メッセージトラップでスクリーンセーバを阻止できない
Windows Vista and later: If password protection is enabled by policy, the screen saver is started regardless of what an application does with the SC_SCREENSAVE notification.

Windows Vista 以降,ここにチェックが入っていると,SC_SCREENSAVE トラップを行ってもスクリーンセーバは起動します.
これを気にするのであれば,ダミーのキーイベントかマウスイベントを発生させることを検討した方が良いのかもしれず.