C++:模拟键盘


Warning: WP_Syntax::substituteToken(): Argument #1 ($match) must be passed by reference, value given in /www/wwwroot/fawdlstty.com/wp-content/plugins/wp-syntax/wp-syntax.php on line 383

Warning: WP_Syntax::substituteToken(): Argument #1 ($match) must be passed by reference, value given in /www/wwwroot/fawdlstty.com/wp-content/plugins/wp-syntax/wp-syntax.php on line 383

模拟键盘是一个简单的话题,随便普通程序猿都能说出好多种方式。不同的方式应用于不同场合,总的来说分为三大类:
1、用户层模拟键盘
这个层来模拟是最方便的,但也是最容易无效的。总的来说有三种方式,第一种是直接往目标窗口发送按键消息;第二种是使用剪贴板复制待粘贴消息然后在目标窗口模拟Ctrl+V;第三种是用户层触发按键事件
这儿贴一个模拟输入一个字节的函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
bool input (char ch)
{
    DWORD KeyScan = ::OemKeyScan (ch);
    bool bShift = !!(KeyScan >> 16);
    UINT uCode = KeyScan & 0xFFFF;
    UINT uScanCode = ::MapVirtualKey (uCode, MAPVK_VK_TO_VSC);
    UINT uShiftScanCode = ::MapVirtualKey (VK_SHIFT, MAPVK_VK_TO_VSC);
    if (bShift)
    {
        ::keybd_event (VK_SHIFT, (BYTE) uShiftScanCode, KEYEVENTF_EXTENDEDKEY, 0);
        std::this_thread::sleep_for (std::chrono::milliseconds (20));
    }
    ::keybd_event (uCode, (BYTE) uScanCode, KEYEVENTF_EXTENDEDKEY, 0);
    std::this_thread::sleep_for (std::chrono::milliseconds (20));
    ::keybd_event (uCode, (BYTE) uScanCode, KEYEVENTF_KEYUP, 0);
    std::this_thread::sleep_for (std::chrono::milliseconds (20));
    if (bShift)
    {
        ::keybd_event (VK_SHIFT, (BYTE) uShiftScanCode, KEYEVENTF_KEYUP, 0);
        std::this_thread::sleep_for (std::chrono::milliseconds (20));
    }
    return true;
}

这个函数很可能在一些有简单安全措施的软件里面失效。软件屏蔽键盘模拟按键一般是使用钩子,那么可以dll注入然后反钩子,挂钩SetWindowsHookEx即可。注意反钩子必须和目标在同一个进程里,否则M$的Copy-On-Write会让反钩子失效。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
BOOL func_unhook (LPVOID func_ptr, WORD param_num, DWORD ret_val)
{
    // mov eax, 12345678h
    // ret 0004h
    BYTE bBuf [] = { '\xB8', '\x00', '\x00', '\x00', '\x00', '\xC2', '\x00', '\x00' };
    *(DWORD*) (&bBuf [1]) = ret_val;
    *(WORD*) (&bBuf [6]) = param_num * 4;
    DWORD dw = 0, dw2 = 0;
    BOOL bRet = ::VirtualProtect (func_ptr, 8, PAGE_EXECUTE_READWRITE, &dw);
    if (!bRet)
        return FALSE;
    ::memcpy (func_ptr, bBuf, 8);
    if (func_ptr != ::VirtualProtect)
        ::VirtualProtect (func_ptr, 8, dw, &dw2);
    return TRUE;
}
 
func_unhook (::SetWindowsHookA, 2, 1);
func_unhook (::SetWindowsHookW, 2, 1);
func_unhook (::UnhookWindowsHook, 2, 1);
func_unhook (::SetWindowsHookExA, 4, 1);
func_unhook (::SetWindowsHookExW, 4, 1);
func_unhook (::UnhookWindowsHookEx, 1, 1);

反钩子后模拟键盘事件差不多可以过绝大部分弱保护的安全措施了,不过这也不完全总是灵的。如果以上方法都不行,可以试试其他方案。
继续阅读C++:模拟键盘

加密介绍


加密通讯总共有四大类,签名算法、对称加密算法、非对称加密算法与量子加密技术,下面分别对几大类算法进行介绍

1、签名算法

代表算法:md5、sha1、crc32
有的地方叫签名算法,有的地方叫哈希算法,有的地方叫指纹算法、数字摘要等等,都代表一个意思。在解释这个之前我先说说“哈希”的意思。哈希也叫散列,意思是,将一串任意长度数据经过某种特定的算法转为固定长度的输出。比如10000个字符将其转为20个字符,这样的算法就叫哈希算法。20个字符虽然容易重复,但随着字符的增多,重复概率将会指数级下降,但通过20个字符很容易就能确定10000个字符的范围,比如对N组10000个字符进行对比,这样做的好处是通过比对20个字符的签名就能筛选出绝大部分数据,剩下的数据经过简单的比对就行了,非常省时省力。
签名算法有什么优势呢?
(1)、校验数据准确性。数据的准确性在通信领域有着举足轻重的作用。纠错编码比如海明码等等可以使错误编码在一定范围内时对其进行纠正,但一旦超过阈值,就算使用编码纠错,最终得出的结果也是错误的。这时候就需要哈希算法对数据进行签名,以确保数据准确性。
(2)、对数据进行归纳整理。比如哈希表就基于哈希算法,将一堆数据均匀分布在哈希结构中,使得寻找某个数据非常简单方便。
(3)、做验证之用。比如用户登录界面,在客户端经过哈希算法计算之后,服务器端只需要验证结果是不是符合就可以了,不用传输整个密码。就算黑客在中途截获数据包也无法推算出密码(暂时不考虑彩虹表等玩意儿,哈希算法可以定义为信息不可逆)。
优势挺多,但劣势也比较严重:
(1)、数据不可逆。也就是说,生成的签名几乎不可能再推导回原数据。
(2)、相对来说不那么安全。彩虹表有一定概率可以在短时间破解MD5加密的密码,王小云研究出来的哈希碰撞也能在一定程度上削弱MD5的安全性。
继续阅读加密介绍