C++ Builder 5编HOOK程序

 

C++ Builder 5编HOOK程序

一,

HINSTANCE g_hinstDll = NULL;
HHOOK g_hhook      = NULL;
HWND  g_hwndPost  = NULL;
UINT  g_uMsgNotify = WM_USER;


HOOKPROC KeyboardHook_HookProc ( int nCode, WPARAM wParam, LPARAM lParam)
{
  LRESULT lResult = CallNextHookEx(g_hhook, nCode, wParam, lParam);
  if (nCode == HC_ACTION)
  {
      PostMessage(g_hwndPost, g_uMsgNotify, wParam, lParam);
  }
  return((HOOKPROC)lResult);
}
///
BOOL WINAPI SetKeyboardHook (HWND hWndPost, UINT Msg)
{
  HHOOK hhook;
  if (g_hhook != NULL) return(FALSE);
  g_hwndPost  = hWndPost;
  g_uMsgNotify = Msg;
  Sleep(0);
  if  (g_hLogHook==NULL)
  hhook = SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardHook_HookProc,g_hinstDll, 0);
  InterlockedExchange((PLONG) &g_hhook, (LONG) hhook);
  return(g_hhook != NULL);
}
///
BOOL WINAPI ReleaseKeyboardHook()
{
  BOOL fOK = TRUE;

  if (g_hhook != NULL)
  {
      fOK = UnhookWindowsHookEx(g_hhook);
      g_hhook = NULL;
  }
  return(fOK);
}

BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
{
  switch (fdwReason)
  {
      case DLL_PROCESS_ATTACH:
        g_hinstDll = hinstDll;
        break;
  }
  return(TRUE);
}

 

二,

在Borland的Community上找到了这篇文章,可以解决这个问题了。如下:
http://community.borland.com/article/0,1410,20008,00.html
///
C++Builder 4.0 is the first C++Builder compiler that supports shared memory segments. This document explains how to use this feature in windows DLL.

To change the data segment and the class name, you need to add #pragma option -zR[SEGMENT NAME] and #pragma option -zT[CLASS NAME] to the file you want the data shared from. Below is the source file I am going to export the integer named 'data':

File: SharedData.cpp
//---------------------------------------------------------------------------
// Borland C++Builder
// Copyright (c) 1987, 1999 Inprise Corporation. All Rights Reserved.
//---------------------------------------------------------------------------

#pragma option -zRSHSEG      // change default data segment name
#pragma option -zTSHCLASS    // change default data class name

// Here is the initialized data that will be shared.
int data = 0;

Notice that the segment name for this file is: SHSEGSHCLASS. A .def file is required for the linker to create the shared segement. Below is what the .def file looks like:

File: Shared.def
LIBRARY SHAREDDLL

SEGMENTS
  SHSEG CLASS 'SHCLASS' SHARED

 


当你的DLL程序被其它各个程序调用时,每调用一次,将产生一个
DLL的实例,其实代码在内存中仅有一套,但DLL中的变量即数据段将
产生多个,这若干个数据段是互不干扰、是不能共享的,但在一些特
殊情况下,就不能满足我们的要求了,比如,用户的全局钩子程序就
是一个.DLL,这个.DLL会被内存所有的进程调用, 如果它的数据段不
能共享,就变成了多个局部钩子了,好在API已替你想好了一个间接
办法,你可用一个“共享名”申请一块共享内存块,进行读写:

HANDLE  GetShare(char * &ShareP,int size,char *ShareName)
      {  ShareP申请的内存块地址,size字节数,ShareName共享名
            HANDLE fh=CreateFileMapping((HANDLE)-1,0,
                            PAGE_READWRITE,0,
                            Size,
                            ShareName);
            ShareP=(char *)MapViewOfFile(fh,
                            FILE_MAP_ALL_ACCESS,
                            0,0,0);
            if (GetLastError()!=ERROR_ALREADY_EXISTS)
                ZeroMemory(ShareP,size);  // 共享区初始化
            return(fh);
      }

char * ShareP=NULL;
void  test()  // 申请一块128个字节的字符数组
      {
          HANDLE fh=GetShare(ShareP,128,"ShareForMyProg");
          for (int i=0;i<128;i++)
              ShareP[i]=i;
          CloseHandle(fh);
      }

    如果你的多个程序之间或同一个程序多次同时运行,也可借助这个办法进
变量通讯;
    在VC++中,若要为DLL定义一个共享内存段更简单,这是一种直接定义的
办法:
      #pragma    data_seg("Shared")
      int x,y;
      char s[128];
      #pragma    data_seg
      #pragma    comment(linker,"/section:Shared,rws")

真简单,可惜在C++BUILDER5.0中经试验好象不能接受这种方法;
    对于BCB,能不能实现DLL中直接定义共享内存块内,请看下列一段文字:


http://community.borland.com/article/0,1410,20008,00.html
///
C++Builder 4.0 is the first C++Builder compiler that supports shared memory segments.

This document explains how to use this feature in windows DLL.

To change the data segment and the class name, you need to add
#pragma option -zR[SEGMENT NAME] and
#pragma option -zT[CLASS NAME] to the file you want the data shared from.
Below is the source file I am going to export the integer named 'data':

File: SharedData.cpp
//---------------------------------------------------------------------------
// Borland C++Builder
// Copyright (c) 1987, 1999 Inprise Corporation. All Rights Reserved.
//---------------------------------------------------------------------------

#pragma option -zRSHSEG      // change default data segment name
#pragma option -zTSHCLASS    // change default data class name

// Here is the initialized data that will be shared.
int data = 0;

Notice that the segment name for this file is: SHSEGSHCLASS. A .def file
is required for the linker to create the shared segement. Below is what the
.def file looks like:

File: Shared.def
LIBRARY SHAREDDLL

SEGMENTS
  SHSEG CLASS 'SHCLASS' SHARED 

可见C++BUILDER4.0与DELPHI已能提供直接实现DLL内存段共享问题,请高手邦忙一起
试一试:在BCB或DELPHI具体应怎样做?

 

 

// 下面的程序将产生有三个导出函数的MouseHook.DLL
#include <windows.h>
#pragma argsused
typedef          // 为共享区定义结构
    struct
        {
          POINT  MouseLoc;  // 存放鼠标位置
          HHOOK  NewHook;    // 存放新钩子句柄
          int    LoadCount;  // DLL装入次数计数
        }  TShareMem;
TShareMem  *ShareMem=NULL;

HINSTANCE  DllHinst;
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
    DllHinst=hinst;
    static HANDLE  fh;  // DLL共享区句柄
    if (reason==DLL_PROCESS_ATTACH)    // DLL入口
        {                // 为共享区申请共享单元
          fh=CreateFileMapping((HANDLE)-1,0,
                              PAGE_READWRITE,0,
                              sizeof(TShareMem),
                              "ShareForMouseHook");
          ShareMem=(TShareMem *)MapViewOfFile(fh,
                              FILE_MAP_ALL_ACCESS,
                              0,0,0);
          if (GetLastError()!=ERROR_ALREADY_EXISTS)
              ZeroMemory(ShareMem,sizeof(TShareMem));
                    // 共享区初始化
          ShareMem->LoadCount+=1;    // 装入计数
        }
    if (reason==DLL_PROCESS_DETACH)  // DLL出口处理
        {
          ShareMem->LoadCount-=1;
          CloseHandle(fh);
        }
    return 1;
}
extern "C" __declspec(dllexport)
void GetMouse(int &mx,int &my,int &loadcount)  // DLL导出函数GetMouse()
{
    if (ShareMem!=NULL)
      {
          mx=ShareMem->MouseLoc.x;
          my=ShareMem->MouseLoc.y;
          loadcount=ShareMem->LoadCount;
      }
}
LRESULT CALLBACK MouseHook(int nCode,
                  WPARAM wParam,LPARAM lParam)
{
    if (nCode==HC_ACTION)
      {
          MOUSEHOOKSTRUCT *l=(MOUSEHOOKSTRUCT *)lParam;
          ShareMem->MouseLoc=l->pt;  //送鼠标位置
      }
    return(CallNextHookEx(ShareMem->NewHook,nCode,wParam,lParam));
}
extern "C" __declspec(dllexport)
void EnableHook()        // 导出函数EnableHook()
{
  if (ShareMem!=NULL)
      if (ShareMem->NewHook==NULL)    //  安装新钩子
        ShareMem->NewHook=SetWindowsHookEx(WH_MOUSE,
                    (HOOKPROC)MouseHook,
                      DllHinst,0);
}
extern "C" __declspec(dllexport)
void DisableHook()      // 导出函数DisableHook()
{
  if (ShareMem!=NULL)
    if (ShareMem->NewHook!=NULL)
        {
          UnhookWindowsHookEx(ShareMem->NewHook);
          ShareMem->NewHook=NULL; // 卸掉新钩子
        }
}

//=======================================================================

#include <vcl.h>
#pragma hdrstop
#include "CallUnit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

extern "C" __declspec(dllimport)
void  EnableHook();              // DLL导入函数1
extern "C" __declspec(dllimport)
void  DisableHook();            // DLL导入函数2
extern "C" __declspec(dllimport)
void  GetMouse(int &mx,int &my,int &loadcount); // DLL导入函数3

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    EnableHook();
    int x,y,loadcount;
    while (!Application->Terminated)
      {  // 不停在从DLL中取回鼠标位置
          GetMouse(x,y,loadcount);
          Edit1->Text=String(x)+","+String(y)+":"+String(loadcount);
          Application->ProcessMessages();
      }
}
void __fastcall TForm1::Button2Click(TObject *Sender)
{
    DisableHook();
}
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
    DisableHook();
}
//---------------------------------------------------------------------------

 



步骤如下:
  在DLL中的工程中,假设为MouseHook.bpr(产生MouseHook.DLL)
      1.在Unit1.cpp的最前面(#include <windows.h>之前)加上
          #pragma option -zRSHSEG      // 改变缺省数据段名
          #pragma option -zTSHCLASS    // 改变缺省数据类名
      2.新建一工程同名的纯文本文件MouseHook.def,其内容只要
        一行:
            SEGMENTS    SHSEG    CLASS    'SHCLASS'  SHARED
        并将此文件用Project->Add Project增加到工程中;
      3.在你的程序代码的前面定义的全局变量都将是DLL共享的,
        在Unit1.cpp中,例如:
     
// 下面的程序将产生有三个导出函数的MouseHook.DLL
// 纯文本文件  MouseHook.def的内容如下:
// SEGMENTS    SHSEG    CLASS    'SHCLASS'  SHARED

#pragma option -zRSHSEG      // 改变缺省数据段名
#pragma option -zTSHCLASS    // 改变缺省数据类名

#include <windows.h>
#pragma argsused
// 以下都将是共享区内存变量
POINT  MouseLoc={0,0};      // 存放鼠标位置
HHOOK  NewHook=NULL;        // 存放新钩子句柄
int    LoadCount=0;        // DLL装入次数计数

HINSTANCE  DllHinst;
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
    DllHinst=hinst;
    if (reason==DLL_PROCESS_ATTACH)    // DLL入口
          LoadCount+=1;                // 装入计数
    else
        if (reason==DLL_PROCESS_DETACH) // DLL出口处理
            LoadCount-=1;
    return 1;
}
extern "C" __declspec(dllexport)
void GetMouse(int &mx,int &my,int &js)  // DLL导出函数GetMouse()
{
    mx=MouseLoc.x;      // 送出鼠标位置
    my=MouseLoc.y;
    js=LoadCount;      // 送出DLL装入次数
}
LRESULT CALLBACK MouseHook(int nCode,
                  WPARAM wParam,LPARAM lParam)
{
    if (nCode==HC_ACTION)
      {
          MOUSEHOOKSTRUCT *l=(MOUSEHOOKSTRUCT *)lParam;
          MouseLoc=l->pt;  //送鼠标位置
      }
    return(CallNextHookEx(NewHook,nCode,wParam,lParam));
}
extern "C" __declspec(dllexport)
void EnableHook()        // 导出函数EnableHook()
{
      if (NewHook==NULL)    //  安装新钩子
        NewHook=SetWindowsHookEx(WH_MOUSE,
                    (HOOKPROC)MouseHook,
                      DllHinst,0);
}
extern "C" __declspec(dllexport)
void DisableHook()      // 导出函数DisableHook()
{
    if (NewHook!=NULL)
        {
          UnhookWindowsHookEx(NewHook);
          NewHook=NULL; // 卸掉新钩子
        }
}
//==========================================================
// CallHook.EXE,将调用全局鼠标全局钩子MouseHook.DLL
// 静态装入MouseHook.DLL,工程中须用 MouseGook.Lib
#include <vcl.h>
#pragma hdrstop
#include "CallUnit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

extern "C" __declspec(dllimport)
void  EnableHook();              // DLL导入函数1
extern "C" __declspec(dllimport)
void  DisableHook();            // DLL导入函数2
extern "C" __declspec(dllimport)
void  GetMouse(int &mx,int &my,int &loadcount); // DLL导入函数3

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    EnableHook();
    int x,y,loadcount;
    while (!Application->Terminated)
      {  // 不停在从DLL中取回鼠标位置
          GetMouse(x,y,loadcount);
          Edit1->Text=String(x)+","+String(y);
          Edit2->Text=loadcount;  // 显示DLL装入次数
          Application->ProcessMessages();
      }
}
void __fastcall TForm1::Button2Click(TObject *Sender)
{
    DisableHook();
}
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
    DisableHook();
}
// ok,已经深夜1点了,别忘了给俺加点分!!!!!!!!!!!!!!!!

 


 

VC的程序


#include <windows.h>
#include <windowsx.h>
#include <tchar.h>

HINSTANCE g_hinstDll = NULL;

#pragma data_seg(".drectve")
    static char szLinkDirectiveShared[] = "-section:Shared,rws";
#pragma data_seg()
#pragma data_seg("Shared")

HHOOK g_hhook      = NULL;
HWND  g_hwndPost  = NULL;
UINT  g_uMsgNotify = WM_USER;

#pragma data_seg()

static LRESULT WINAPI KeyboardHook_HookProc (
  int nCode,
  WPARAM wParam,
  LPARAM lParam)
{

  LRESULT lResult = CallNextHookEx(g_hhook, nCode, wParam, lParam);

  if (nCode == HC_ACTION)
  {
      PostMessage(g_hwndPost, g_uMsgNotify, wParam, lParam);
  }
  return(lResult);
}

BOOL WINAPI SetKeyboardHook (HWND hWndPost, UINT Msg)
{
  HHOOK hhook;

  if (g_hhook != NULL) return(FALSE);

  g_hwndPost  = hWndPost;
  g_uMsgNotify = Msg;
  Sleep(0);

  hhook = SetWindowsHookEx(WH_KEYBOARD, KeyboardHook_HookProc, g_hinstDll, 0);
  InterlockedExchange((PLONG) &g_hhook, (LONG) hhook);
  return(g_hhook != NULL);
}

BOOL WINAPI ReleaseKeyboardHook()
{
  BOOL fOK = TRUE;

  if (g_hhook != NULL)
  {
      fOK = UnhookWindowsHookEx(g_hhook);
      g_hhook = NULL;
  }
  return(fOK);
}

BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
{
  switch (fdwReason)
  {
      case DLL_PROCESS_ATTACH:
        g_hinstDll = hinstDll;
        break;
  }
  return(TRUE);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值