2011-09-02 8 views
8

Anche se ho cercato molto, non mi è ancora chiaro cosa sia esattamente un "gancio". Ad esempio, ho letto questo post su wiki answers:Che cos'è un "gancio" e come posso scriverne uno in Java? E come comunicare con il kernel per conoscere i tasti premuti dall'utente/registrazione con OS

Un gancio è un metodo di interporre un pezzo di codice di fronte a un'altra pezzo di codice, in modo che il primo pezzo di codice eseguito prima del secondo pezzo di codice, dando al primo pezzo di codice un'opportunità di monitorare e/o filtrare il comportamento del secondo pezzo di codice. Un esempio di potrebbe essere un hook del mouse, consentendo al codice hook di monitorare il mouse conservando allo stesso tempo la funzionalità della routine di elaborazione degli eventi del mouse originale .

Ho letto anche questo post, ma ancora non capisco cosa sia esattamente un "gancio". Qualcuno può spiegare, in parole povere, cos'è un "gancio"? Perché alcuni scrivono esattamente un "gancio"? Inoltre, è possibile scrivere un "hook" in Java?

Nota:

Volevo scrivere un keylogger in Java e un mio amico ha detto che si dovrà scrivere un "gancio" in C. non riesco a scrivere il tutto keylogger in Java (da operare solo su Windows)?

EDIT

si prega di dare una risposta w.r.t keylogger. Come posso chiedere a kernel di fornire le informazioni sul tasto premuto sulla mia applicazione utilizzando l'aggancio? O come posso registrare la mia applicazione con sistema operativo usando JNI? Voglio che la mia applicazione registri i tasti premuti dall'utente.

+1

Penso che il tuo amico intendesse dire che dovrai usare il metodo nativo. È possibile scrivere un metodo nativo in C e chiamarlo da Java utilizzando Java Native Interface (JNI). – toto2

+0

@ toto2 e cosa farà il metodo nativo? – saplingPro

+0

Questa sarebbe una funzione di sistema che registra le chiavi. In realtà è meglio rinunciare completamente a Java per un simile lavoro. Java è pensato per essere portatile e il rovescio della medaglia è che non può fare roba relativa al sistema operativo. Non conosco molto Windows, ma probabilmente C# sarebbe più appropriato. – toto2

risposta

2

vorrei associare il gancio di parola con almeno due concetti diversi:

a) del pattern Observer, dove una classe consente di aggiungere un ascoltatore che verrà comunicata su determinati eventi. Puoi trovare tutto questo su Swing, l'API Servlet e molti framework di terze parti.

b) Il modello Metodo modello. Una classe astratta definisce quali metodi vengono chiamati in quale ordine e la classe di implementazione può sovrascrivere questi metodi. Esempi di questo non sono comune a, ma li vedi ogni tanto.

1

Altri nomi potrebbero essere delegati o richiamati.

Un esempio di questo in Java è il MouseListener (http://download.oracle.com/javase/tutorial/uiswing/events/mouselistener.html). MouseListener è un'interfaccia con metodi come mouseClicked(MouseEvent e). Per rispondere alle azioni del mouse da parte dell'utente, è necessario implementare MouseListener e quando l'utente fa clic, la libreria Java Swing chiamerà la classe del listener (dopo averla registrata chiamando addMouseListener.

1

Ecco un semplice esempio:

public void hookableMethod(HookObject hook, String param) { 
String innerParam = param; 
if(hook != null) { 
innerParam = hook.someHookMethod(innerParam); 
} 

//rest of the code is working with inner param 
} 

In questo esempio semplificato il hookableMethod fornisce un modo per un'entità esterna per agganciarlo - cioè passare riferimento oggetto esterno e tale scopo esterna sta per essere eseguito prima . Quindi, se è necessario disporre di una sorta di elaborazione che non fa parte dell'implementazione originale, è possibile farlo semplicemente passando un riferimento e non rattoppando la fonte originale.

5

Da Hooking - Wikipedia,

Nella programmazione di computer, il termine aggancio copre una gamma di tecniche utilizzato per modificare o convertire il comportamento di un sistema operativo, di applicazioni, o di altri componenti software per funzione intercettando chiamate o messaggi o eventi passati tra componenti software. Il codice che gestisce chiamate, eventi o messaggi con funzioni intercettate è chiamato "hook".

Un buon esempio incorporato in Java sarebbe Runtime.addShutdownHook. Un gancio di arresto è un thread inizializzato ma non avviato. Quando la macchina virtuale inizia la sua sequenza di spegnimento, avvierà tutti i ganci di arresto registrati in un ordine non specificato e li lascerà correre simultaneamente.

Runtime.addShutdownHook(new Thread(){ 
    @Override 
    public void run(){ 
     // do something before application terminates 
    } 
}); 
1

Per quanto riguarda il keylogger: sì, si può scrivere la maggior parte di esso in Java ma una piccola parte dovrà andare in un modulo JNI, perché per esempio con un gancio globale una DLL/thread/qualunque cosa ottiene "iniettato" in altri processi ... poiché non tutti i processi ospitano una JVM ecc. questo non funzionerà in Java ... quindi è necessario utilizzare JNI e alcuni C per scrivere una DLL per quella parte del keylogger ...

EDIT - come da commento:

This article descrive in modo approfondito ciò hook globali fanno e cosa si intende per iniezione ecc ...

+0

@ Yahia '" gancio globale una DLL/thread/qualsiasi cosa viene "iniettata" in altri processi .. "" puoi renderlo più chiaro e includere la parte nella tua risposta – saplingPro

+0

@grassPro - per favore il link nel mio EDIT ... – Yahia

1

Nel tuo caso, un gancio è un meccanismo software per registrare un listener (gestore) nel sistema operativo. Questo gestore (ad esempio un metodo nell'applicazione) verrà informato dal sistema operativo quando viene attivato un evento chiave (tasto premuto).

Questa è solo un'applicazione del modello di osservatore.

Un esempio fittizio:

class MyKBHandler implements ISomeKeyboardListener { 
     public void onKeyDown(<params containing key info here>){ 
      //Your code here, doing something with the params. 
     } 
    } 

    MyKBHandler handler = new MyKBHandler(); 
    <someOSLibrary>.register(handler); 

come ti hanno detto in altre risposte, non c'è modo per fare questo in Java senza fare affidamento a qualche pezzo di code.I nativi pensano che il modo più semplice per andare è quello di scegli una lingua correlata al sistema operativo che hai scelto come target. Per Windows, lo farei con C#.

controllare questo link:

http://msdn.microsoft.com/en-us/library/ms632589%28VS.85%29.aspx

+0

e come posso parlare con il kernel? – saplingPro

+0

Parla con il kernel? Non devi. Basta registrarsi con il sistema operativo e chiamerà il gestore su ogni tratto chiave. In questa pagina http://en.wikipedia.org/wiki/Hooking hai un esempio di keylogger in C#, ci sono molti codici open source e tutta la rete. –

+0

@ Mister Smith Desidero registrare la mia applicazione utilizzando JNI. io voglio usare Java e codice nativo in particolare C per farlo. Questa è la domanda. Ora come posso registrarmi con il sistema operativo in modo che chiami il mio gestore su ciascun tratto chiave. – saplingPro

1

Cattura di eventi per dispositivi a basso livello ha bisogno di eseguire codice nativo (JNI, JNA, ecc) ed è altamente dipendente dal sistema . Su Linux non sarà probabilmente necessario comunicare con il kernel, molto probabilmente con X11 sever.

0

Prima di tutto bisogna definire una classe dirigente, che è qualcosa di simile:

package foo.bar 

public class SomeHookManager { 
    public static void initialize (...) { 
     // <pre-initialization-routing> 
     _native_init_(); 
     // <post-initialization-routing> 
    } 

    public static void registerCallback (IHookCallback callback) 
    { /* save this callback */ } 

    // this method will be invoked in your C code. 
    protected static void invokeCallback() { /* invoke the saved callback */ } 

    // this is a native method, the native modifier tells the compiler this method 
    // is implemented in C, and linked at runtime. 
    protected native static void _native_init_(); 
} 

Quindi utilizzare javah per generare un colpo di testa C, il risultato è qualcosa di simile (non ho fatto compilare questo codice, quindi questo è ipotetica):

/* 
* Class:  Win32 
* Method: _native_init_ 
* Signature:()V 
*/ 
JNIEXPORT void JNICALL Java_foo_bar_Win32_native_init_ 
    (JNIEnv * env, jobject obj); 

Creare un progetto C, includere questo file e implementare questo metodo. Assicurarsi che quando il gancio reale innescato, chiamare invokeCallback nel codice C:

jclass cls = (*env)->GetObjectClass(env, obj); 
jmethodID mId = (*env)->GetStaticMethodID(env, cls, "invokeCallback", "()V"); 
if (mId == 0) { /* error handling */ } 
(*env)->CallStaticVoidMethod(env, cls, mId); 

Compilare il progetto C in un file DLL, dire hookimpl_win32.dll e dynamicly collegamento da qualche parte nel codice Java:

static { 
    System.loadLibrary("hookimpl_win32"); // no need of .dll or .so in Unix alike OS's 
} 

Assicurati che la dll si trovi nella stessa cartella con il tuo jar. Oppure specificare -Djava.library.path=/path/to/your/dlls in argomenti VM.

Per quanto riguarda il modo in cui è possibile registrare ogni tratto chiave, il sistema operativo in genere fornisce alcune API per l'intercettazione di eventi chiave. Per i sistemi Windows, è possibile raggiungere questo problema intercettando i messaggi chiave globali. Non ho esperienze su altri sistemi. In ogni caso, è possibile impostare interrupt appropriati, che è di basso livello. Puoi sempre google la tua risposta. :)