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);
}
總結
以上是生活随笔為你收集整理的C++ Builder 5编HOOK程序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 插件不既有Chrome版也有飞鸽传书
- 下一篇: C++Builder如何响应消息及自定义