お世話になってます。
VC++7.1 or VC++8 で、特定フォルダ内以下にあるファイルが実行された事
を監視するプログラムを作成しなければならなくなったのですが、その方
法がわからなく、質問した次第です・・・
ファイルが更新/削除されたことはReadDirectoryChangesWでとる事はでき
たのですが、同じような API はあるのでしょうか・・・
レクチャー御願い致します・・・
顔がかわいい(^^
TxTさん、俺と結婚しない?
いくつか方法は考えられます。
1:(対象プログラムのソースに手を加えられるのなら)イベント等を使って通信する。
2:タイマーで定期的に、現在実行されているプロセスを列挙して調べる
3:IShellExecuteHook を使う。CreateProcess で起動されたら捕捉できないかも?
4:(対象のプログラムがウィンドウを持つのなら)SetWindowsHookEx で WH_SHELL を
フックする。
シャノン様、レスありがとうございます。
曖昧な文章ですみません・・・
補足になりますが、やりたいことは、定期的にフォルダーを監視していて
フォルダー内にあるファイルが実行された時に、実行を行うかどうかのメ
ッセージを上げ、OKなら実行を継続するといったプログラムなのです・・・
(セキュリティソフトのようなイメージです・・・)
となると、3:となるのでしょうか・・・?
えーと、実行されたことを知るだけなら俺の挙げたいずれかの方法でできると思います
が、キャンセルはたぶんどの方法でも無理です。
ドライバ作るとかしないとダメなんじゃないかなぁ。
試してないけど
DLLインジェクションつかって各プロセスのCreateProcessをフック
以降CreateProcessで新しいプロセスが起動されるたびにそれぞれフック
対象プログラムがCreateProcessされたらダイアログ出して
キャンセルされたらオリジナルのCreateProcessを呼ばずに
ERROR_ACCESS_DENIEDを返すとか…?
「実行されたら検出してキャンセルする」
というのは少し矛盾があるようなのですが、
「実行したことを検出してそれを終了させるのか。」
「実行する前にそれを検出して実行しないのか。」
どちらなのででしょうか?
前者なら、シャノンさんがおっしゃっている方法で
対象プロセスを見つけて終了させればよいと思います。
後者だとやはりというかカーネルモードで動作するドライバを作って、
OSのAPIなどをフックするのが堅実ではないかと思います。
俺なら当該ファイルの .EXE を「起動していいか」と操作員に尋ねるアプリに
差し替えるかな(Yes といわれたら別のところにコピーしてある本物を起動)
うまく動くかどうかは別として案のみ
毎度、文献の案内ですが。
シャノンさんが書かれていますが、恐らくはドライバレベルでないと
無理だと思われます。
(ユーザーモードからcsrss.exeあたりをゴニョゴニョしてみましたが、見事にブルーバ
ック。)
>> Hooking the native API and controlling process creation on a system-wide
basis
> http://www.codeproject.com/KB/system/soviet_protector.aspx
サンプルで動作確認しました@WinXP SP2
他の参考文献としては以下だと思われます。
>> Hokking Software Interrupts
> http://www.windowsitlibrary.com/Content/356/09/toc.html
カーネル周りも詳しくないので、Win2008でのセキュリティ強化がどこまで影響するかも
知りません。よほど熟知していない限りは使うべきではないです。
毎度恒例の文言ですが、お勧めはしません。目的如何ではやらない方がいいでしょう。
tetrapodさんが書かれたように、操作側での徹底をお勧めします。
# がんばればcsrssあたりで出来ると思うのですけどね。いかんせん、文献が
# 厳しいところです。
誤字訂正です。
> >> Hokking Software Interrupts
「Hooking」です。
どうしてそういうプログラムを作成しなくてはいけないのかとか
どういう目的でそれを使うのかとかの部分が説明されると
他の有効な案の提案があるかもしれませんし。
> 特定フォルダ内以下にあるファイルが実行された事
> 他の有効な案の提案があるかもしれませんし。
指定のフォルダ以下のすべての実行可能なファイルがランチャー式に
自動列挙される、というのも手カナ。ReadDirectoryChangesWが使えるので
あれば、動的な変更も対応可能だと思います。
後は、ランチャーからの起動前に自前のプログラムからメッセージボックスを
出せば、それが起動確認の同意になるでしょう。
たくさんのレスありがとうございます。
何かかなり難しいのと、敷居が高い・・・のがわかりました・・・
私にはレベルが高すぎます・・・
Haru様
>「実行したことを検出してそれを終了させるのか。」
>「実行する前にそれを検出して実行しないのか。」
>どちらなのででしょうか?
>
後者の「実行する前にそれを検出して実行しないのか。」
です・・・
PATIO 様
> どうしてそういうプログラムを作成しなくてはいけないのかとか
> どういう目的でそれを使うのかとかの部分が説明されると
> 他の有効な案の提案があるかもしれませんし。
>
お客様の要望で、特定のフォルダー内のファイルだけは、どうしても
実行前にワンクッション置いて欲しいと要望がありましたので・・・
とりあえずは、皆様のおっしゃる通り「操作側」で行うようにまずは
交渉、実装してみます・・・
後は、自分の勉強のためになりそうですが、ドライバレベルでも可能
な限りやってみます・・・
駄レスです。
> お客様の要望で、
顧客が相手であるなら余程ドライバは注意したほうが良いです。作業中に
ブルーバックなんて洒落になりませんから(汗
もしそれでもドライバでの実装というのであれば、その部分だけをドライバを
専門に扱う企業に依頼するのも手カモしれません。(サイ○ンスパークとか、
デバドラ書籍で有名な会社に聞いてみるとかカナ、やったことないので不明ですが)
# 顧客側も、やることに対してのリスク認識が把握できてないように思われます。
> 自分の勉強のためになりそうですが
役に立つか・・・は、びみょ~なところです(多分)。フィルタドライバとも
かなり異なる部分なので・・・。
別案としては、対象とするPCがXP(SP2)以降であるのであれば、対象のフォルダ以下の
ファイルにZoneId制約を付加するとかできるのカナ、とか思いました。
(ダウンロードファイルの実行前に出てくる「セキュリティ警告」のアレです)
> お客様の要望で、特定のフォルダー内のファイルだけは、どうしても
> 実行前にワンクッション置いて欲しいと要望がありましたので・・・
どういうレベルまでのブロックを求めているのかによるかなぁと思います。
詳しくない人を相手にするならフォルダーを隠しにしておいて
そこにあるプログラムを使うときは必ず特定のランチャソフトを使うように
しむけると言うのも一つの手だと思います。
ランチャは常に起動状態にしておいてワンタッチで起動できるようするなら
わざわざエクスプローラーを起動してフォルダーから直接起動する確立は
減りそうですし。
隠しフォルダを見えるようにエクスプローラーを設定した上で
わざわざエクスプローラーを起動してフォルダーを開いて実行ファイルを
ダブルクリックするような人ならある程度は理解している人だと言う考え方も
あると思います。
ワンクッション欲しい程度の話なら上記のような対応でもいいカナと思うんですけれど。
セキュリティ云々を言うのであれば、
ほんとにヤバイ機能なら起動時にパスワードを聞いてくるくらいしてもいいかな
とも思います。ただし、それはそのソフトに仕様にするべきで他のソフトに影響が
出かねない様な対応はするべきではないように思います。