【问题标题】:Can Keylogger apps able to see the messages sent via SendMessage()?Keylogger 应用程序能否看到通过 SendMessage() 发送的消息?
【发布时间】:2014-03-20 03:18:15
【问题描述】:

我正在创建一个 c# 应用程序以使用 SendMessage() 函数在记事本中发送消息。我已成功将字符串传递给记事本。字符串非常重要,我想知道键盘记录​​程序是否可以看到此消息?

如果是,您对如何安全地发送字符串还有其他想法吗?

下面是我使用的示例代码。

    [DllImport("user32.dll", EntryPoint = "FindWindowEx")]
    public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string   lpszClass, string lpszWindow);

    [DllImport("User32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);


    Process[] notepads = Process.GetProcessesByName("notepad");
    if (notepads.Length == 0) return;
    if (notepads[0] != null)
    {
        IntPtr child = FindWindowEx(notepads[0].MainWindowHandle, new IntPtr(0), "Edit", null);
        SendMessage(child, 0x000C, 0, TextBox1.Text);
    }

【问题讨论】:

  • 我认为 Keyloggers 会记录键盘上的击键,因此不应记录使用 SendMessage 功能发送的消息,因为实际上没有人按下键盘,这取决于那些消息的来源您正在发送到记事本
  • @juanreyesv 取决于您是指物理(硬件)键盘记录器还是软件键盘记录器。软件键盘记录器可能会安装 WH_KEYBOARD_LL 挂钩,因此它会拾取虚拟击键以及物理击键。
  • @TheFrustratedProgrammer 看看你的代码会很好。实际上,您的设置对我来说听起来不是很安全,尤其是您将敏感数据发送到记事本的部分。任何对您的数据感兴趣的人都可以直接从记事本中提取文本,甚至无需理会您的消息。
  • @computerfreaker ,记事本场景只是简化我的问题的一个示例,我会将字符串发送到另一个应用程序,但我仍会使用 SendMessage 来执行此操作。

标签: c# windows keylogger


【解决方案1】:

你所做的并不安全;任何人都可以通过多种方式监视SendMessage 电话。

SetWindowsHookExWH_CALLWNDPROCWH_CALLWNDPROCRET 将让攻击者监视发送到给定线程的所有消息,或者他们可以监视整个系统中的所有消息并过滤掉那些发往 SendMessage 目标的消息.

或者,攻击者可以将自己注入您的接收进程,使用WriteProcessMemory 将DLL 名称写入接收进程,然后CreateRemoteThreadLoadLibrary 将DLL 加载到目标进程。在那之后,监控进程的消息应该是相当简单的。

为避免使用 DLL,攻击者还可以使用WriteProcessMemory 将代码直接写入目标进程的内存空间,然后使用CreateRemoteThread 调用它。

所有这三种监控方法都记录在in this CodeProject article。诚然,它有点老了,但方法应该仍然是相关的,尤其是 SetWindowsHookEx

攻击者也可以hook various Windows APIs directly;这很困难且有些风险,但根据您数据的敏感性,攻击者可能会发现这是一种值得的方法。

老实说,试图保护您的数据将非常困难。您可以查看KeePass 如何保证密码安全;它有一个设置(至少在 1.x 分支中;KeePass 2.x 是一个完全不同的应用程序)“只允许粘贴一次并防止剪贴板间谍”,这可能对您有一些好处。从 KeePass 获得另一个提示,您还可以查看 Windows 的 Data Protection API

作为旁注,您可能需要替换

SendMessage(child, 0x000C, 0, TextBox1.Text);

SendMessage(child, WM_SETTEXT, 0, TextBox1.Text);

为了可读性。没有多少人会单独识别 0x000C,尽管可以根据上下文猜测消息是什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-25
    • 2021-08-30
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 2020-06-15
    相关资源
    最近更新 更多