none
実行中のEXEファイルの名前を変更しても大丈夫なの? RRS feed

  • 質問

  • OS:Windows XP/7
    開発環境 VisualC++ 6.0

    実行中のEXEファイルの名前を変更する処理というのは、やっても大丈夫なのでしょうか。

    前任者から受けついたプログラムのソースを解析しております。
    EXEファイルの更新を行うプログラムのソースを調べていたところ、プロセスが、自身の本体であるEXEファイルの名前を_wrename()により変える処理を見つけました。(仮に、foo.exeが元のEXEファイル名だとすると、foo.oldexeに変えています。)
    実際、このプログラムを動かすとEXEファイルの名前が変更されます。

    まさかとおもい、ためしに日ごろ使用しているプログラムについて実行中に手動で名前を変更して見たところ、特にエラー表示など出ることなく変更できました。(Vix.exe を Vix.oldexe に変更、など)

    プロセスが動いている最中、そのプロセスの元であるEXEファイルを削除しようとするとエラーになるのに、リネームが出来るというのは、なにかおかしな気がします。

    このような手法を使ってよいのかどうか、技術的な裏付けを探しております。
    ご存知の方、いらしたら根拠となる資料を教えて頂けないでしょうか。

    どうかよろしくお願い致します。

    2013年10月11日 5:14

回答

  • 残念ながらそのものズバリの根拠が書いてある情報は見つけられませんでした。
    あしからず。

    さて、傍証の説明になってしまいますが、まず、バイナリを実行する手順はやや複雑で、
    そのバイナリファイルの中が正しい手続きで記述されていなければなりません。
    つまり、実行ファイルは一種の構造体をバイナリファイルで保管している
    イメージに近いわけですね。
    で、OSが実際にそのバイナリファイルが実行できるかどうかの判定は、
    そのファイルの先頭部分を読み込んでからでないと、できないわけです。
    (PEヘッダ、IMAGE_DOS_HEADERヘッダ、exeファイルのフォーマットなどの
    キーワードで調べてみてください)

    EXEファイルに限らず、OS側から見ると、ファイル名はそれが何であるかの
    ヒントにはなりますが、実際にはそれを読んでみるまでわからないということですね。
    つまり、ファイル名称はそれをオープンするまでは必要ですが、読込が始まれば不要です。
    従って、ファイル名がどうなろうと知ったことではないということになります。

    また、実際のところ、UI用のシェルだけが唯一、ファイル名の特に拡張子で
    その内容を類推すると考えられます。
    従って、単にファイル名を変更するだけならOS上での問題はありません。
    単にシェルから実行できなくなる程度ではないでしょうか。

    ただし、実行ファイルにはその実行権限などがあり、場合によっては当該の
    コードが実行できない場合があります。またOSが所有管理している
    実行ファイルの名称を変更するのは危険なうえ面倒です。

    さて、一般に実行ファイルの名称を変更する必要やその効果とは、
    実行中にアップグレードするなどの需要を除けば、まったくありません。
    そうなると、問題なのはなぜ実行中の、自身のファイル名称を変更する
    必要があったのかという点を突き詰めるべきだと考えられます。

    場合によっては、まったく狙った効果が発揮できない場合が考えられ、
    この場合は、相当する全てのコードを削除してしまっても問題が無いと
    考えられるわけで、このようなことに頭を悩ます必要もなくなるわけですね。

    2013年10月11日 7:36

すべての返信

  • 残念ながらそのものズバリの根拠が書いてある情報は見つけられませんでした。
    あしからず。

    さて、傍証の説明になってしまいますが、まず、バイナリを実行する手順はやや複雑で、
    そのバイナリファイルの中が正しい手続きで記述されていなければなりません。
    つまり、実行ファイルは一種の構造体をバイナリファイルで保管している
    イメージに近いわけですね。
    で、OSが実際にそのバイナリファイルが実行できるかどうかの判定は、
    そのファイルの先頭部分を読み込んでからでないと、できないわけです。
    (PEヘッダ、IMAGE_DOS_HEADERヘッダ、exeファイルのフォーマットなどの
    キーワードで調べてみてください)

    EXEファイルに限らず、OS側から見ると、ファイル名はそれが何であるかの
    ヒントにはなりますが、実際にはそれを読んでみるまでわからないということですね。
    つまり、ファイル名称はそれをオープンするまでは必要ですが、読込が始まれば不要です。
    従って、ファイル名がどうなろうと知ったことではないということになります。

    また、実際のところ、UI用のシェルだけが唯一、ファイル名の特に拡張子で
    その内容を類推すると考えられます。
    従って、単にファイル名を変更するだけならOS上での問題はありません。
    単にシェルから実行できなくなる程度ではないでしょうか。

    ただし、実行ファイルにはその実行権限などがあり、場合によっては当該の
    コードが実行できない場合があります。またOSが所有管理している
    実行ファイルの名称を変更するのは危険なうえ面倒です。

    さて、一般に実行ファイルの名称を変更する必要やその効果とは、
    実行中にアップグレードするなどの需要を除けば、まったくありません。
    そうなると、問題なのはなぜ実行中の、自身のファイル名称を変更する
    必要があったのかという点を突き詰めるべきだと考えられます。

    場合によっては、まったく狙った効果が発揮できない場合が考えられ、
    この場合は、相当する全てのコードを削除してしまっても問題が無いと
    考えられるわけで、このようなことに頭を悩ます必要もなくなるわけですね。

    2013年10月11日 7:36
  • 仲澤様、ありがとうございました。

    いくつか書籍をめくって見ましたが、裏づけとなるような情報はやはり見つけることが出来ませんでした。

    今回試した実行ファイルについては、たまたま上手く行っただけの話で、メーカーが保証しているわけではないのでやはりこの手法はやめておいたほうがいいのだろうと判断します。

    どうもありがとうございました。

    2013年10月18日 10:35
  • NTのローダは、FILE_SHARE_DELETEをつけてEXE/DLLをロードするので、名前を変えることができる、みたいな説明は下記のblogにありますネ。

    http://blogs.msdn.com/b/larryosterman/archive/2004/05/13/131263.aspx

    The NT loader takes advantage of this – when it opens DLL’s or programs for execution, it specifies FILE_SHARE_DELETE.  That means that you can rename the executable of a currently running application (or DLL).  This can come in handy when you want to drop in a new copy of a DLL that’s being used by a running application.  I do this all the time when working on winmm.dll.  Sine winmm.dll’s used by lots of processes in the system, including some that can’t be stopped, I can’t stop all the processes that reference the DLL, so instead, when I need to test a new copy of winmm, I rename winmm.dll to winmm.old, copy in a new copy of winmm.dll and reboot the machine.

    jzkey

    2013年10月19日 4:07