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

C++ Builder 5编HOOK程序相关推荐

  1. adsl拨号无公网地址如何用ddns_【好玩的网络-第5期】分享自编ddns程序,17行代码轻松实现免费ddns,服务器或nas玩家的福音...

    [好玩的网络]系列面向普通人的网络科普视频.我在我的哔哩哔哩账号(up主:旋律果子)更新[好玩的网络]视频版,在我的知乎(用户:曾彦)专栏更新[好玩的网络]文字版.最新消息以及预告在我的个人网站www ...

  2. c语言两个字符串比较,将两个字符串s1和s2比较,如果s1s2,作业 - 编一个程序,将两个字符串s1和s2比较,如果.doc...

    作业 - 编一个程序,将两个字符串s1和s2比较,如果 作业(第一次) 求下面表达式的值: x+a%3*(int)(x+y)%2/4 设x=2.5,a=7,y=4.7 (float)(a+b)/2+( ...

  3. C++ Builder开发AutoCAD应用程序的方法

    ※ 编程技巧 应用实践 ※ C++ Builder开发AutoCAD应用程序的方法 周永军(水利部山西水利水电勘测设计研究院  030024) [摘要]进行AutoCAD二次开发的程序设计方法为数众多 ...

  4. java设计一个形状shape_编程定义一个图形接口 Shape, 内含2个抽象方法 get... JAVA编程题:编一个程序包含一个接口 shape(该接......

    导航:网站首页 > 编程定义一个图形接口 Shape, 内含2个抽象方法 get... JAVA编程题:编一个程序包含一个接口 shape(该接... 编程定义一个图形接口 Shape, 内含2 ...

  5. 编一程序,将两个字符串连接起来,不要用strcat函数。

    [描述] 编一程序,将两个字符串连接起来,不要用strcat函数. [输出示例] Hello world! [C语言] #include<stdio.h> #include<stri ...

  6. 【C】编一程序,将两个字符串连接起来,不要用strcat函数

    //编一程序,将两个字符串连接起来,不要用strcat函数 #include <stdio.h> int main(){char str1[80],str2[80],str3[160];i ...

  7. 铁路托运行李规定:行李重不超过50公斤的,托运费按每公斤0.15元计费;如超过50公斤,超过部分每公斤加收0.10元。编一程序实现自动计费功能。

    练习十二 铁路托运行李规定:行李重不超过50公斤的,托运费按每公斤0.15元计费:如超过50公斤,超过部分每公斤加收0.10元.编一程序实现自动计费功能. package lianXiTi;impor ...

  8. C语言 编一程序,从键盘输入一个实数,输出其绝对值。

    编一程序,从键盘输入一个实数,输出其绝对值. 常规方法: #include<stdio.h> main() {float fx;printf("please input a fl ...

  9. java中double身高_用JAVA编一个程序 输入10名同学的身高,找出最高升高,要求使用对象数组类型的带参方法来实现...

    用JAVA编一个程序 输入10名同学的身高,找出最高升高,要求使用对象数组类型的带参方法来实现 关注:285  答案:5  mip版 解决时间 2021-02-05 07:44 提问者女人不需要倾国倾 ...

最新文章

  1. python关联规则挖掘_Python3:文本关联规则挖掘实现案例分析
  2. 请求Get和Post对于utf-8字符的处理的考虑
  3. 利用源代码搭建lnmp环境
  4. sql server 数据库 ' ' 附近有语法错误
  5. oracle 多个表 join 的先后顺序
  6. SSM项目使用GoEasy 获取客户端上下线实时状态变化及在线客户列表
  7. HttpHandler
  8. android jni java调用c,Android与JNI(一) ---- Java调用C 静态调用
  9. java osg_java,osg学习心得
  10. api 微信内置浏览器js_微信小程序和HTML的区别
  11. 学习MySQL:使用SELECT语句从MySQL服务器查询数据
  12. 吴恩达深度学习——机器学习策略(二)
  13. 【机器学习】逻辑回归原理及其实现
  14. mysql 1118_mysql innodb 引擎 ,建表时报错:ERROR 1118 (42000)
  15. tdscdma手机linux,全方位介绍——TD-SCDMA无线技术(1)
  16. 华为HCIE云计算培训笔记第一天
  17. 沈阳建筑大学811c语言真题,沈阳建筑大学C语言试题.doc
  18. rrweb学习案例(网页录制,回放)-demo
  19. 机器学习——决策树+随机森林
  20. 量产国产服务器cpu芯片,中国第一!百度自研芯片量产:配国产CPU

热门文章

  1. Linux文本模式中文乱码
  2. C++多继承中重写不同基类中相同原型的虚函数
  3. Oracle日期函数集锦
  4. 【蓝桥杯-第五届】 啤酒和饮料
  5. poj 1160(Post Office)
  6. POJ 3628 Bookshelf 2 (01背包)
  7. Serverless的理解
  8. 浅谈Base64编码算法
  9. 死锁的四个必要条件,及处理方法
  10. 2017《面向对象程序设计》课程作业六