0

次のコードを使用して、単純なキーストロークキャッチャーを実装しようとしました。ユーザーがキーをタップすると、通知が届きます。Javaコードは、メソッドdllを実行するをロードし、DllMainそこから新しいスレッドも開始します。`

Javaコードは、静的ブロックにライブラリをロードします。には、いくつかのステートメントを実行して出力dllするDllMainメソッドがあります。また、から新しいスレッドを開始しますDllMain。2ミリ秒スリープするJavaプログラムでも新しいスレッドが開始されます。出力から、は複数回呼び出されているようDllMainですinstallHook。何故ですか ?何が問題ですか ?

キーをタップするとユーザーに通知されますが、なぜ同じ関数が複数回呼び出されるのですか?関数を実装したinstallHookか、スレッドロジックを不適切に実装したと思います。

Javaコード:

package keylogger;

public class TestKeys {
private static int i = 0;
private native void setWinHook();
private native void unregisterWinHook();

public static void main(String args[]) {

    //TestKeys o = new TestKeys();


    System.out.println("After the call to load library !");

    Runnable r = new Runnable() {
        @Override
        public void run() {
            try {
                System.out.println("Sleeping...");
                Thread.sleep(2);
            }catch(Exception exc) {
                exc.printStackTrace();
            }
        }
    };
    new Thread(r,"new thread").start();       
}

static {
    System.loadLibrary("MyHook");
}
}

Cコード:

#include <stdio.h>
#include <windows.h>
#include <w32api.h>
#include "keylogger_TestKeys.h"

static HHOOK handleKeyboardHook = NULL;
HINSTANCE hInst = NULL;
static DWORD hookThreadId = 0;
static HANDLE hookThreadHandle = NULL;
BOOL WINAPI installHook(HINSTANCE hinstDLL, DWORD fwdReason, LPVOID lpvReserved);

static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
 printf("You pressed the key !\n");
 return CallNextHookEx(handleKeyboardHook, nCode, wParam, lParam);
}

BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fwdReason, LPVOID lpvReserved) {
  LPTHREAD_START_ROUTINE lpStartAddress = &installHook;
  printf("From DllMain : %u\n",fwdReason);
  hookThreadHandle = CreateThread(NULL, 0, lpStartAddress, NULL, 0, &hookThreadId);
  if(hookThreadHandle == NULL) {
    printf("\nhookThreadHandle is NULL\n");
  }
  return TRUE;
}

JNIEXPORT void JNICALL Java_keylogger_TestKeys_unregisterWinHook
 (JNIEnv *env, jobject obj) {
   if(handleKeyboardHook != NULL) {
    UnhookWindowsHookEx(handleKeyboardHook);
    printf("Keyboard hook successfully unregistered !");
   } else {
      printf("Coudn't Unhook the keyboard hook !");
     }
} 

BOOL WINAPI installHook(HINSTANCE hinstDLL, DWORD fwdReason, LPVOID lpvReserved) {
printf("From installHook : %u",fwdReason);
handleKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hinstDLL, 0);
MSG msg;

while(GetMessage(&msg, NULL, 0, 0))
{
  TranslateMessage(&msg);
  DispatchMessage(&msg);
}
return msg.wParam;

}

出力:

From DllMain : 1
From DllMain : 2
From installHook : 66321916From DllMain : 2
After the call to load library !From installHook : 65797624
From DllMain : 2
From installHook : 67304108From DllMain : 2
From installHook : 60423404From DllMain : 2
From installHook : 67893304From DllMain : 2
From installHook : 68484828From DllMain : 2
From installHook : 69204012From DllMain : 2 
From installHook : 61799988From DllMain : 2
From installHook : 62847812From DllMain : 2
From DllMain : 2
Sleeping... 
From installHook : 71695184From DllMain : 2
From installHook : 70907884From DllMain : 2
From installHook : 70581032From DllMain : 2
From installHook : 72219984From DllMain : 2
From installHook : 73071020From DllMain : 2
From installHook : 66649544From DllMain : 2
From installHook : 73399648From DllMain : 3
From DllMain : 2
From DllMain : 3
From installHook : 73858604From DllMain : 2
From DllMain : 3
From installHook : 75955548From DllMain : 3
From DllMain : 2
From installHook : 72548100From DllMain : 2
From installHook : 74643796From DllMain : 2
From installHook : 75560952From DllMain : 3
From DllMain : 2
From installHook : 71236420From DllMain : 2
From installHook : 74316888From DllMain : 2
From installHook : 77265476From DllMain : 0

hookThreadHandle is NULL
4

1 に答える 1

1

DllMainドキュメントから:

ダイナミックリンクライブラリ(DLL)へのオプションのエントリポイント。システムがプロセスまたはスレッドを開始または終了すると、プロセスの最初のスレッドを使用して、ロードされた各DLLのエントリポイント関数が呼び出されます。また、システムは、LoadLibrary関数とFreeLibrary関数を使用してDLLがロードまたはアンロードされるときに、DLLのエントリポイント関数を呼び出します。

その関数でスレッドを作成しているので、基本的にそこに無限ループがあります- DllMain(ロード時に)スレッドを作成しますDllMain。つまり、スレッドを開始しますDllMain

DLL_PROCESS_ATTACHそのドキュメントを注意深く読んでください。理由が( )でない場合は、おそらく何もしてはいけません1。(その手順からスレッドを開始することが合法かどうかは実際にはわかりません。)

于 2012-05-30T12:15:16.690 に答える