質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

1803閲覧

メッセージループを使用し、32ビットプロセスから64ビットプロセスをフックする方法を教えてください

trons

総合スコア20

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

4クリップ

投稿2018/08/23 06:13

編集2018/08/27 05:31

先日の質問「C#よりDLL(C++)を使用し、グローバルフック をおこないたい」
https://teratail.com/questions/142061
にて各32/64BitのEXEから対応する32/64Bitのプロセスへグローバルフックを
おこなうことができました。

上記の作業中の調査過程で、見つけたHP
monoの開発ブログ
64bit対応なフックを使ったアプリの作り方
https://blog.mono0x.net/blog/2009/09/13/64bit-hook/

のコメント欄に記載されていた
32ビットのプロセスで64ビットプロセスのフックは可能です。
私の場合は下層レベルキーボードフックを32ビットプログラムで仕掛け、
64ビット版のcmd.exeのキー操作を制限しています。
勿論、フックプロシージャは自プロセスのインスタンス内にあります。
64ビット版も作りましたが、同じ方法でフックできています。
ある工夫とはメッセージループです。メインスレッドでフックを仕掛け、
同じスレッドでメッセージループを開始すればフックは機能します。

WEB上の検索でも、呼び出し元のEXEとフック先のビット数を一致させるか方法か、
読みだし元のEXEのコンパイルをAnyCPUにし、OSやフック先のアプリのビット数に合わせて
フック制御用のDLL動的に読み込ませてフックを行う方法の2種類が主のようなのですが
メッセージループを使用するケースに関しては、具体的なコードを見つけることができませんでした。

メッセージループを使用すれば、わざわざ2種類のEXEとDLLを作成せずに
32Bitプロセスから64Bitのアプリを直接制御できるようなのですが、
どなたかご存知の方はいらっしゃらないでしょうか?

宜しくお願い致します。

追加記載
キーボードのグローバルフックですが、同じようなことをしている記事を
見つけましたので、URL等を追記します。
https://stackoverflow.com/questions/15542783/global-keyhook-on-64-bit-windows

ただ上記記事を元に、コードを修正してみましたがまだ動きません。
32BitExeから32BitDLL=>32Bitプロセスへフックはかかりますが、解除が動きません。
32BitExeから32BitDLL=>64Bitプロセスへは、フック事態が動きません。
引き続き調べてみたいと思います。

再度追加記載
一部コードを変更しました。
変更により「UnCloseHook32_MsgLoop」から「CloseHook32_MsgLoop」を呼び出しでの終了を行えました。
が「UnhookWindowsHookEx(hHwnd)」がエラーを返却するため、フックを解除できません。

C++

1// 共有領域(共有領域のデータは初期化してないとうまく確保されない) 2#pragma data_seg("share") 3HHOOK hHookWnd = NULL; 4HINSTANCE hdll = NULL; 5HWND hTarget = NULL; 6volatile static bool runHooked = false;  7#pragma data_seg() 8 9// フックを組み込む 10int CALLBACK CloseHook32_MsgLoop(HWND HandleofTarget) 11{ 12 if(hdll == NULL) return 99; 13 hTarget = HandleofTarget; 14 HHOOK hHwnd=SetWindowsHookEx(WH_CBT,(HOOKPROC)CallWndProc, hdll, 0); 15 16 if(hHwnd == NULL) 17 { 18 return 100; 19 } 20 21 MSG msg; 22 runHooked = true; 23 //Loop 24 while(runHooked) 25 { 26 if( PeekMessage(&msg, nullptr, 0, 0, PM_NOREMOVE)) 27 { 28 if (GetMessage(&msg, NULL, 0, 0) > 0) 29 { // GetMessageでPeekMessageで確認したメッセージを取得. 30 TranslateMessage(&msg); 31 DispatchMessage(&msg); 32 Sleep(10); 33 } 34 else 35 { 36 break; 37 } 38 } 39 } 40 41 int ans = UnhookWindowsHookEx(hHwnd); 42 43 hHwnd = NULL; 44 45 if(ans == 0) 46 { 47 return ans; 48 } 49 else 50 { 51 return ans; 52 } 53} 54 55 56void CALLBACK UnCloseHook32_MsgLoop(void) 57{ 58 runHooked=false; 59}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

私が回答したところで hmmm さんの回答内容の詳細な説明になってしまうので恐縮ですが・・・。

グローバルフックには DLL が必要なものと必要でないものがあります。そして、DLL が必要ではないグローバルフックは必ずメッセージループを持つ必要があります。hmmm さんが提示されている SetWinEventHook もその1つです。元のコメントにある以下の引用文

ある工夫とはメッセージループです。メインスレッドでフックを仕掛け、
同じスレッドでメッセージループを開始すればフックは機能します。

はマイクロソフトのドキュメントにもはっきりと記載してあり、ドキュメントに記載してあることを工夫と言われると・・・何とも言えない微妙な気分になりますね。

現時点では SetWinEventHook 以外に DLL が不要なグローバルフックは低レベルキーボードフック(WH_KEYBOARD_LL)と低レベルマウスフック(WH_MOUSE_LL)の2つのみとなります。提示されているコードで使用されている CBT フックも含めてその他のグローバルフックはすべて DLL が必要となります。そのため、必ず 32 ビットと 64 ビットを分けて作成する必要があります。

また、前回の投稿にあった他プロセスのウィンドウをサブクラス化するためには DLL インジェクションが必須となるため、DLL を使ったグローバルフックが正しい手段となります。

投稿2018/08/27 15:23

atata0319

総合スコア881

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

trons

2018/08/28 00:35

ご回答ありがとうございます。 MSのSetWindowsHookExではご指摘の通りの記述があるのが分かっていたのですが、 何か所かのコメントで提示させていただいたコメントを記載された方がメッセージループで グローバルフックが可能と書かれていたので実現可能かと思いましたが、実現は出来ないので それぞれのビットに合わせたDLLを作成する、方法で実現したいと思います。 詳細な説明ありがとうございました。
guest

0

SetWindowsHookExのフックの実現方法がDLLを対象プロセスにロードさせるものであれば無理です。

SetWindowsHookExの一部の機能の代替としてはSetWinEventHookが利用できます。
WINEVENT_OUTOFCONTEXTで使用すれば32bitプロセスからでも、64bitのイベントを監視することができます。
詳しくは以下を参照してください。
WinEvent

投稿2018/08/23 15:31

hmmm

総合スコア818

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

先日はどうも。
僕もそのブログの記事を思い出していたのですが、.NETはプロセスの制約上低レベルフックしか出来ないという結論だと思います。
先日の質問のように、C++のコードからグローバルフックを設定する場合は
その限りではないという話かと。

投稿2018/08/23 12:28

tekka

総合スコア514

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tekka

2018/08/23 14:49

また頓珍漢な回答したかも。何度もすいません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問