当前位置:首页 >> 编程开发 >> Visual C++ >> 内容

用C++ Builder编HOOK程序

时间:2008/1/5 作者:平凡之路 来源:xuhantao.com 浏览:

一,

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);
}

相关文章
  • 没有相关文章
共有评论 0相关评论
发表我的评论
  • 大名:
  • 内容:
  • 徐汉涛(www.xuhantao.com) © 2024 版权所有 All Rights Reserved.
  • 部分内容来自网络,如有侵权请联系站长尽快处理 站长QQ:965898558(广告及站内业务受理) 网站备案号:蒙ICP备15000590号-1