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