Solved

About Shell hook

Posted on 2003-11-18
9
343 Views
Last Modified: 2010-04-05
Why my shell hook can only hook my process messages? I want to hook other process window create and destroy.

This is my code(DebugTrace function can out put the debug info.
function shellHookProc(iCode:Integer;wParam1:wParam;lParam1:lParam):LRESULT;stdcall;
begin
  Result:=0;
  debugtrace(inttostr(iCode));
  if iCode<0 then Result := CallNextHookEx(hHook1,iCode,wParam1,lParam1);
end;

procedure SetshellHook(hnd:HWND);
begin
  hHook1:=SetwindowsHookEx(WH_SHELL,TaskHookProc,hInstance,0);
  if hHook1 <=0 then messagebox(0,'hookError','task',16);
end;

procedure RemoveshellHook;
begin
   UnhookWindowsHookEx(hhook1);
end;
0
Comment
Question by:cookey
  • 3
  • 3
  • 2
  • +1
9 Comments
 

Author Comment

by:cookey
ID: 9776416
I want a system shell hook, not only hook my process
0
 
LVL 11

Expert Comment

by:robert_marquardt
ID: 9776510
Such a hook has to reside in a DLL.
Windows maps this DLL into all running applications.

The problem with such a DLL is that each mapped instance has its own data segment and therefore
all global variables are in fact local to the specific instance.
This affects the hHook variable which has to be shared by all instances.

The easiest way is to write the DLL in C with MS VC++ because it allows to easily set up
shared segments. I have written such a DLL myself and it works without problems.
If you want to write the DLL in Delphi then search for "Delphi WH_SHELL" on Google and
you should get enough links to satisfy you.
0
 
LVL 5

Expert Comment

by:DeerBear
ID: 9777117
Hi,

As Robert pointed out, there's a problem with system-wide hooks.

The best option is to use a Memory Mapped File for communication
among several DLL instances or just a file, which in turn has several
disadvantages.

You should look deeply into the Delphi Help File for the PROCESS_ATTACH and
PROCESS_DETATCH options on DLL loading.

HTH,

Andrew
0
VMware Disaster Recovery and Data Protection

In this expert guide, you’ll learn about the components of a Modern Data Center. You will use cases for the value-added capabilities of Veeam®, including combining backup and replication for VMware disaster recovery and using replication for data center migration.

 
LVL 6

Expert Comment

by:GloomyFriar
ID: 9778383
>The best option is to use a Memory Mapped File for communication

I don't agree whit this.
The best way is shared data segment, imho.
0
 
LVL 6

Accepted Solution

by:
GloomyFriar earned 125 total points
ID: 9778413
cookey, here is sample for you

//#include "stdafx.h"
//#include <afxdllx.h>
//#include "HookEx.h"
#include <windows.h>
#include <stdio.h>


//Shared data among all instances
#pragma data_seg("myshare")//Shared data among all instances.
//HHOOK hook = NULL;
//static HWND h = NULL;
__declspec(allocate("myshare")) HHOOK hook = NULL;
__declspec(allocate("myshare")) HWND hWnd = NULL;
//HHOOK hook;
//HWND h;
#pragma data_seg()

#pragma comment(linker, "/SECTION:myshare,RWS")

HINSTANCE hInst = NULL;

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define KEYDLL3_API extern "C" __declspec(dllexport)
//static AFX_EXTENSION_MODULE HookExDLL = { NULL, NULL };

extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
    // Remove this if you use lpReserved
    UNREFERENCED_PARAMETER(lpReserved);

    if (dwReason == DLL_PROCESS_ATTACH)
    {
//         TRACE0("HOOKEX.DLL Initializing!\n");
         
         // Extension DLL one-time initialization
//         if (!AfxInitExtensionModule(HookExDLL, hInstance))
//              return 0;

         // Insert this DLL into the resource chain
         // NOTE: If this Extension DLL is being implicitly linked to by
         //  an MFC Regular DLL (such as an ActiveX Control)
         //  instead of an MFC application, then you will want to
         //  remove this line from DllMain and put it in a separate
         //  function exported from this Extension DLL.  The Regular DLL
         //  that uses this Extension DLL should then explicitly call that
         //  function to initialize this Extension DLL.  Otherwise,
         //  the CDynLinkLibrary object will not be attached to the
         //  Regular DLL's resource chain, and serious problems will
         //  result.

//         new CDynLinkLibrary(HookExDLL);
    }
    else if (dwReason == DLL_PROCESS_DETACH)
    {
//         TRACE0("HOOKEX.DLL Terminating!\n");
//         // Terminate the library before destructors are called
//         AfxTermExtensionModule(HookExDLL);
    }
    hInst = hInstance;
    return 1;   // ok
}


LRESULT CALLBACK hookproc( int ncode, WPARAM wparam,LPARAM lparam)
{
  if (ncode >= 0)
  {
    if (( lparam & 0x80000000 ) == 0x00000000)
    {
      //Only when it is pressed not released
      char str[256];
      sprintf(str, "hookproc: idProc = %d(%x) hWnd(%.8x) = %d(%x)",
             GetCurrentProcessId(), GetCurrentProcessId(),
             &hWnd, hWnd, hWnd);
      MessageBox(NULL, str, "hookproc", MB_OK);
    }
  }
 
  return ( CallNextHookEx(hook,ncode, wparam,lparam) );//pass control to next hook in the hook chain.
}

KEYDLL3_API void  installhook( HWND handle )
{
  hook = NULL;
  hWnd = handle;

  char str[256];
  sprintf(str, "installhook: idProc = %d(%x) hWnd(%.8x) = %d(%x)",
             GetCurrentProcessId(), GetCurrentProcessId(),
             &hWnd, hWnd, hWnd);
  MessageBox(NULL, str, "installhook", MB_OK);

    if( hInst == NULL )       MessageBox(NULL,"NULL Instance","Error!",MB_OK);
    hook = SetWindowsHookEx( WH_KEYBOARD, hookproc, GetModuleHandle("hooktest.dll"), NULL );
    if( hook == NULL )      MessageBox(NULL,"Unable to install hook","Error 101!",MB_OK);
   
}


KEYDLL3_API void removehook(void)
{
    UnhookWindowsHookEx( hook );
}
0
 
LVL 5

Expert Comment

by:DeerBear
ID: 9778415
Hi,

Using MMFs, to my knowledge, basically means using shared memory and I
fail to see where a "data segment" can be considered different from "Memory".

Cheers,

Andrew
0
 
LVL 6

Expert Comment

by:GloomyFriar
ID: 9778548
2 DeerBear,
Of caurse I understand what are you talking about.
But try to explain this to cookey ;-)))

And by the way
#pragma data_seg("myshare")

is rather different then somethig like the following
   SECURITY_ATTRIBUTES sa;
   memset(&sa, 0, sizeof(sa));
   HANDLE h_file = CreateFile(FileName, GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
   DWORD FileSize = GetFileSize(h_file, NULL);
   HANDLE map_file = CreateFileMapping(h_file, &sa, PAGE_READWRITE, 0, 0, NULL);
   char* Data = (char*)MapViewOfFile(map_file, FILE_MAP_ALL_ACCESS, 0, 0, 0);
   memmove(Data+Position, Data+Position+LenToClip, FileSize-Position);    
     UnmapViewOfFile(Data);
   CloseHandle(map_file);
   SetFilePointer(h_file, FileSize-LenToClip, NULL, FILE_BEGIN);
   SetEndOfFile(h_file);
   CloseHandle(h_file);


Or you can't agree?
0
 
LVL 5

Expert Comment

by:DeerBear
ID: 9778599
Eheheheheheh yeah ok, sorry ^_^

Just think I had arrived to a point where I was imagining this "data segment" as a
sort of C++ meta-instruction <g>, ya know some of those black magic C++ tricks that
make you go nuts in debugging <g>.

Andrew
0
 

Author Comment

by:cookey
ID: 9856619
I think I find out the way to solve this problem, that Delphi write system wild hook very hard, I already write it in VC++

Thanks every body give me very good advices, but it seems the scores can only give one person,  so I give the scores to GloomyFriar because of the longest code :-)
0

Featured Post

NAS Cloud Backup Strategies

This article explains backup scenarios when using network storage. We review the so-called “3-2-1 strategy” and summarize the methods you can use to send NAS data to the cloud

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Create Database on Android via Delphi dbExpress 3 92
Delphi XE10 Round Image 2 128
delphi parse string to params 3 123
how to send memory stream from ics Client To ics server ? 11 110
A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

810 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question