System32 に入っているのは 32ビット版ではない
プログラム話です。
はい、タイトル通りです。これですごくハマったことがありました。
DLLの関数を呼び出す部分で落ちる、というバグが以前ありまして、デバッガで追ってみたところ、64ビットなアドレス値が入っていました。
そこで、自分では32ビット版のDLLを呼んでいるつもりが実は64ビット版のDLLを呼んでしまっているのではないか?といういう疑惑が発生したわけですが、それを確認するのにすごく手間取ったんです。
自分が使っているツールにDependencyWalkerというものがありまして、これはEXEファイルをドロップすればそれが依存しているDLLを一覧表示し、DLLをドロップすればDLLに入っている関数を一覧表示してくれる便利なモノです。このときDLLが32ビット版なのか64ビット版なのかも一緒に表示してくれるので、これを使って確認しました。
エクスプローラでWindows/System32を開いて中にあるDLLをDependencyWalkerにドロップすると、結果は32ビットでした。一応Windows/SysWOW64にある同名DLLもドロップしてみると、これも32ビットでした。そこで「あれ?」となったわけです。自分はSystem32には32ビット版のDLLが、SysWOW64には64ビット版が入っていると思っていましたから、SysWOW64のDLLをDependencyWalkerに入れれば64ビットと表示されるものと思っていたのです。
もっとよく確認してみようと思い、とりあえずSystemフォルダの中身を直接いじるのもアレなのでSystem32のDLLを適当な場所にコピーして、それをDependencyWalkerで開きました。すると今度は64ビットと表示されました。もう大混乱です。
と、このあたりでピーンと来ました。
System32は重要なフォルダなので、通常とは扱いが違っていて特殊な挙動をするのでは?と。
で、調べてみて驚きました。
まず大きな勘違いだったのは、System32に入っているのは32ビットではなく64ビット版のDLLだということです。逆にSysWOW64に入っているが32ビット版のDLLです。これには完全にやられました。
なぜこんな名前に?と思ったら WOW64 が "Windows 32-bit On Windows 64-bit" (64ビットWindows上で32ビットWindowsを動かす仕組み)の略だから、みたいです。ややこしい。
そしてこれが最大の混乱原因だったのですが、自分の使っていたDependencyWalkerが32ビット版のアプリだったという事です
なぜかというと、32ビットアプリでSystem32のファイルを開こうとした場合、Windowsが「あれ?32ビットアプリが64ビット用のファイルを開こうとしているぞ」と空気を読んで、勝手にSysWOW64に読み替えてくれるというのです。
というわけで32ビット版のDependencyWalkerにSystem32フォルダ内のDLLをドロップすると、Windows側によって自動的にSysWOW64内の同名DLLと差し替えられますから、DependencyWalkerはこのファイルを32ビットDLLと判定します。SysWOW64内のDLLをドロップしたときはそのままSysWOW64内のファイルが渡され、これも32ビットDLLとして判定されたということです。
ちなみにSystem32からSysWOW64への読み替えはドラッグドロップに限らず、たとえばCopyFileとか普通にAPIを使った時にも発生するので気を付けてください。DLLに限らずテキストファイルとかを開こうとした時も同様です。32ビットなテキストエディタでSystem32内のテキストを開こうとすると、勝手にSysWOW64内の同名ファイルが開かれることになります。
詳しく知りたい方は以下のリンクを参照してみてください
ファイル システム リダイレクタ
"https://msdn.microsoft.com/ja-jp/windows/aa384187(v=vs.80)"
WOW64
https://ja.wikipedia.org/wiki/WOW64
So Why Is System32 64-bit, and SysWOW64 32-bit?
https://www.howtogeek.com/326509/whats-the-difference-between-the-system32-and-syswow64-folders-in-windows/