Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
“a”是什么;钩;我如何用Java编写一个呢?以及如何与内核通信以了解用户按下的键/注册操作系统_Java_Java Native Interface_Hook_Kernel_Keylogger - Fatal编程技术网

“a”是什么;钩;我如何用Java编写一个呢?以及如何与内核通信以了解用户按下的键/注册操作系统

“a”是什么;钩;我如何用Java编写一个呢?以及如何与内核通信以了解用户按下的键/注册操作系统,java,java-native-interface,hook,kernel,keylogger,Java,Java Native Interface,Hook,Kernel,Keylogger,虽然我搜索了很多,但我仍然不清楚“钩子”到底是什么。例如,我在以下网站上读到了这篇文章: 钩子是将一段代码插入另一段代码之前的一种方法 一段代码,以便第一段代码在 第二段代码,让第一段代码有机会 监视和/或过滤第二段代码的行为。一 示例可能是鼠标钩子,允许钩子代码监视 鼠标,同时保留 原始的鼠标事件处理例程 我也读过这篇文章,但我仍然不明白“钩子”到底是什么。有人能用外行的话解释一下什么是“钩子”吗?为什么有些人会写“钩子”?另外,是否可以用Java编写一个“钩子” 注意: 我想用java写一个

虽然我搜索了很多,但我仍然不清楚“钩子”到底是什么。例如,我在以下网站上读到了这篇文章:

钩子是将一段代码插入另一段代码之前的一种方法 一段代码,以便第一段代码在 第二段代码,让第一段代码有机会 监视和/或过滤第二段代码的行为。一 示例可能是鼠标钩子,允许钩子代码监视 鼠标,同时保留 原始的鼠标事件处理例程

我也读过这篇文章,但我仍然不明白“钩子”到底是什么。有人能用外行的话解释一下什么是“钩子”吗?为什么有些人会写“钩子”?另外,是否可以用Java编写一个“钩子”

注意:

我想用java写一个键盘记录程序,我的一个朋友说你必须用C写一个“钩子”。我不能用java写整个键盘记录程序吗(只能在windows上操作)

编辑


请回答w.r.t键盘记录器。我如何要求
kernel
提供有关使用挂钩将按键输入应用程序的信息?或者如何使用JNI向操作系统注册我的应用程序?我希望我的应用程序记录用户按下的键。

我会将hook一词与至少两个不同的概念联系起来:

a) 观察者模式,其中一个类允许您添加一个侦听器,该侦听器将在某些事件中收到通知。您可以在Swing、ServletAPI和许多第三方框架中找到这一点


b) 模板方法模式。抽象类定义以什么顺序调用什么方法,实现类可以重写这些方法。这方面的例子并不常见,但您偶尔会看到它们。

这方面的其他名称可能是委托或回调


Java中的一个例子是MouseStener(http://download.oracle.com/javase/tutorial/uiswing/events/mouselistener.html).
MouseListener
是一个带有
mouseClicked(MouseEvent e)
等方法的接口。为了响应用户的鼠标操作,您将实现
MouseListener
,当用户单击时,Java Swing库将调用您的侦听器类(在您通过调用
addMouseListener
注册它之后)。下面是一个简单的示例:

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
}
在这个过于简化的示例中,hookableMethod为外部实体提供了一种钩住它的方法——即传递外部对象引用,并且首先执行这个外部对象。因此,如果您需要某种处理,而不是原始实现的一部分,您可以通过传递引用而不是正在修补原始源。

来自

在计算机编程中,挂钩一词涵盖了一系列技术 用于改变或增强操作系统的行为,例如 应用程序或其他软件组件的拦截功能 在软件组件之间传递的调用、消息或事件。代码 处理此类截获函数调用、事件或消息的 被称为“钩子”

Java内置的一个很好的例子是。关闭挂钩只是一个初始化但未启动的线程。当虚拟机开始其关闭序列时,它将以某种未指定的顺序启动所有注册的关闭挂钩,并让它们并发运行

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

至于键盘记录器:是的,您可以用Java编写大部分代码,但一小部分必须进入JNI模块,因为例如,使用全局钩子,DLL/线程/任何被“注入”的东西其他进程…因为不是所有进程都承载JVM等。这在Java中不起作用…因此您需要使用JNI和一些C为键盘记录器的该部分编写DLL

编辑-根据评论:


深入描述全局钩子的作用以及注入等的含义。

在您的情况下,钩子是一种在操作系统中注册侦听器(处理程序)的软件机制。当触发键事件(按下键)时,操作系统将通知此处理程序(例如,应用程序中的方法)

这只是观察者模式的一个应用

一个虚构的例子:

    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);
类MyKBHandler实现键盘侦听器{
public void onKeyDown(){
//你的代码在这里,用params做些什么。
}
}
MyKBHandler=新的MyKBHandler();
.登记(经办人);
正如他们在其他答案中告诉你的那样,在Java中,如果不依赖一些本机代码,就无法做到这一点。我认为最简单的方法是选择与目标操作系统相关的语言。对于windows,我会使用C#

检查此链接:


捕获低级设备事件需要运行本机代码(JNI、JNA等),并且高度依赖于系统。在Linux上,您可能不需要与内核通信,最有可能是与X11服务器通信。

首先必须定义一个管理器类,类似于:

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_ ();
}
创建一个C项目,包括此文件并实现此方法。确保在触发实际挂钩时,在C代码中调用
invokeCallback

jclass cls = (*env)->GetObjectClass(env, obj);
jmethodID mId = (*env)->GetStaticMethodID(env, cls, "invokeCallback", "()V");
if (mId == 0) { /* error handling */ }
(*env)->CallStaticVoidMethod(env, cls, mId);
将C项目编译成DLL文件,比如说
hookimpl_win32.DLL
,并在Java代码中的某个地方动态链接它:

static {
    System.loadLibrary("hookimpl_win32"); // no need of .dll or .so in Unix alike OS's
}
确保dll与jar位于同一文件夹中。或者在VM参数中指定
-Djava.library.path=/path/to/your/dlls

至于如何记录每次击键,操作系统通常会提供一些API供您截取击键事件。对于Windows系统,您可以通过截取全局击键消息来实现这一点。我在其他系统上没有任何经验。无论如何,您可以设置适当的中断,这是非常重要的
static {
    System.loadLibrary("hookimpl_win32"); // no need of .dll or .so in Unix alike OS's
}