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
?
三
當(dāng)你的DLL程序被其它各個程序調(diào)用時,每調(diào)用一次,將產(chǎn)生一個
DLL的實例,其實代碼在內(nèi)存中僅有一套,但DLL中的變量即數(shù)據(jù)段將
產(chǎn)生多個,這若干個數(shù)據(jù)段是互不干擾、是不能共享的,但在一些特
殊情況下,就不能滿足我們的要求了,比如,用戶的全局鉤子程序就
是一個.DLL,這個.DLL會被內(nèi)存所有的進(jìn)程調(diào)用, 如果它的數(shù)據(jù)段不
能共享,就變成了多個局部鉤子了,好在API已替你想好了一個間接
辦法,你可用一個“共享名”申請一塊共享內(nèi)存塊,進(jìn)行讀寫:
HANDLE? GetShare(char * &ShareP,int size,char *ShareName)
????? {? ShareP申請的內(nèi)存塊地址,size字節(jié)數(shù),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);? // 共享區(qū)初始化
??????????? return(fh);
????? }
char * ShareP=NULL;
void? test()? // 申請一塊128個字節(jié)的字符數(shù)組
????? {
????????? HANDLE fh=GetShare(ShareP,128,"ShareForMyProg");
????????? for (int i=0;i<128;i++)
????????????? ShareP[i]=i;
????????? CloseHandle(fh);
????? }
??? 如果你的多個程序之間或同一個程序多次同時運行,也可借助這個辦法進(jìn)
變量通訊;
??? 在VC++中,若要為DLL定義一個共享內(nèi)存段更簡單,這是一種直接定義的
辦法:
????? #pragma??? data_seg("Shared")
????? int x,y;
????? char s[128];
????? #pragma??? data_seg
????? #pragma??? comment(linker,"/section:Shared,rws")
真簡單,可惜在C++BUILDER5.0中經(jīng)試驗好象不能接受這種方法;
??? 對于BCB,能不能實現(xiàn)DLL中直接定義共享內(nèi)存塊內(nèi),請看下列一段文字:
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已能提供直接實現(xiàn)DLL內(nèi)存段共享問題,請高手邦忙一起
試一試:在BCB或DELPHI具體應(yīng)怎樣做?
?
?
四
// 下面的程序?qū)a(chǎn)生有三個導(dǎo)出函數(shù)的MouseHook.DLL
#include <windows.h>
#pragma argsused
typedef????????? // 為共享區(qū)定義結(jié)構(gòu)
??? struct
??????? {
????????? POINT? MouseLoc;? // 存放鼠標(biāo)位置
????????? HHOOK? NewHook;??? // 存放新鉤子句柄
????????? int??? LoadCount;? // DLL裝入次數(shù)計數(shù)
??????? }? TShareMem;
TShareMem? *ShareMem=NULL;
HINSTANCE? DllHinst;
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
??? DllHinst=hinst;
??? static HANDLE? fh;? // DLL共享區(qū)句柄
??? if (reason==DLL_PROCESS_ATTACH)??? // DLL入口
??????? {??????????????? // 為共享區(qū)申請共享單元
????????? 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));
??????????????????? // 共享區(qū)初始化
????????? ShareMem->LoadCount+=1;??? // 裝入計數(shù)
??????? }
??? 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導(dǎo)出函數(shù)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;? //送鼠標(biāo)位置
????? }
??? return(CallNextHookEx(ShareMem->NewHook,nCode,wParam,lParam));
}
extern "C" __declspec(dllexport)
void EnableHook()??????? // 導(dǎo)出函數(shù)EnableHook()
{
? if (ShareMem!=NULL)
????? if (ShareMem->NewHook==NULL)??? //? 安裝新鉤子
??????? ShareMem->NewHook=SetWindowsHookEx(WH_MOUSE,
??????????????????? (HOOKPROC)MouseHook,
????????????????????? DllHinst,0);
}
extern "C" __declspec(dllexport)
void DisableHook()????? // 導(dǎo)出函數(shù)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導(dǎo)入函數(shù)1
extern "C" __declspec(dllimport)
void? DisableHook();??????????? // DLL導(dǎo)入函數(shù)2
extern "C" __declspec(dllimport)
void? GetMouse(int &mx,int &my,int &loadcount); // DLL導(dǎo)入函數(shù)3
void __fastcall TForm1::Button1Click(TObject *Sender)
{
??? EnableHook();
??? int x,y,loadcount;
??? while (!Application->Terminated)
????? {? // 不停在從DLL中取回鼠標(biāo)位置
????????? 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中的工程中,假設(shè)為MouseHook.bpr(產(chǎn)生MouseHook.DLL)
????? 1.在Unit1.cpp的最前面(#include <windows.h>之前)加上
????????? #pragma option -zRSHSEG????? // 改變?nèi)笔?shù)據(jù)段名
????????? #pragma option -zTSHCLASS??? // 改變?nèi)笔?shù)據(jù)類名
????? 2.新建一工程同名的純文本文件MouseHook.def,其內(nèi)容只要
??????? 一行:
??????????? SEGMENTS??? SHSEG??? CLASS??? 'SHCLASS'? SHARED
??????? 并將此文件用Project->Add Project增加到工程中;
????? 3.在你的程序代碼的前面定義的全局變量都將是DLL共享的,
??????? 在Unit1.cpp中,例如:
?????
// 下面的程序?qū)a(chǎn)生有三個導(dǎo)出函數(shù)的MouseHook.DLL
// 純文本文件? MouseHook.def的內(nèi)容如下:
// SEGMENTS??? SHSEG??? CLASS??? 'SHCLASS'? SHARED
#pragma option -zRSHSEG????? // 改變?nèi)笔?shù)據(jù)段名
#pragma option -zTSHCLASS??? // 改變?nèi)笔?shù)據(jù)類名
#include <windows.h>
#pragma argsused
// 以下都將是共享區(qū)內(nèi)存變量
POINT? MouseLoc={0,0};????? // 存放鼠標(biāo)位置
HHOOK? NewHook=NULL;??????? // 存放新鉤子句柄
int??? LoadCount=0;??????? // DLL裝入次數(shù)計數(shù)
HINSTANCE? DllHinst;
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
??? DllHinst=hinst;
??? if (reason==DLL_PROCESS_ATTACH)??? // DLL入口
????????? LoadCount+=1;??????????????? // 裝入計數(shù)
??? else
??????? if (reason==DLL_PROCESS_DETACH) // DLL出口處理
??????????? LoadCount-=1;
??? return 1;
}
extern "C" __declspec(dllexport)
void GetMouse(int &mx,int &my,int &js)? // DLL導(dǎo)出函數(shù)GetMouse()
{
??? mx=MouseLoc.x;????? // 送出鼠標(biāo)位置
??? my=MouseLoc.y;
??? js=LoadCount;????? // 送出DLL裝入次數(shù)
}
LRESULT CALLBACK MouseHook(int nCode,
????????????????? WPARAM wParam,LPARAM lParam)
{
??? if (nCode==HC_ACTION)
????? {
????????? MOUSEHOOKSTRUCT *l=(MOUSEHOOKSTRUCT *)lParam;
????????? MouseLoc=l->pt;? //送鼠標(biāo)位置
????? }
??? return(CallNextHookEx(NewHook,nCode,wParam,lParam));
}
extern "C" __declspec(dllexport)
void EnableHook()??????? // 導(dǎo)出函數(shù)EnableHook()
{
????? if (NewHook==NULL)??? //? 安裝新鉤子
??????? NewHook=SetWindowsHookEx(WH_MOUSE,
??????????????????? (HOOKPROC)MouseHook,
????????????????????? DllHinst,0);
}
extern "C" __declspec(dllexport)
void DisableHook()????? // 導(dǎo)出函數(shù)DisableHook()
{
??? if (NewHook!=NULL)
??????? {
????????? UnhookWindowsHookEx(NewHook);
????????? NewHook=NULL; // 卸掉新鉤子
??????? }
}
//==========================================================
// CallHook.EXE,將調(diào)用全局鼠標(biāo)全局鉤子MouseHook.DLL
// 靜態(tài)裝入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導(dǎo)入函數(shù)1
extern "C" __declspec(dllimport)
void? DisableHook();??????????? // DLL導(dǎo)入函數(shù)2
extern "C" __declspec(dllimport)
void? GetMouse(int &mx,int &my,int &loadcount); // DLL導(dǎo)入函數(shù)3
void __fastcall TForm1::Button1Click(TObject *Sender)
{
??? EnableHook();
??? int x,y,loadcount;
??? while (!Application->Terminated)
????? {? // 不停在從DLL中取回鼠標(biāo)位置
????????? GetMouse(x,y,loadcount);
????????? Edit1->Text=String(x)+","+String(y);
????????? Edit2->Text=loadcount;? // 顯示DLL裝入次數(shù)
????????? Application->ProcessMessages();
????? }
}
void __fastcall TForm1::Button2Click(TObject *Sender)
{
??? DisableHook();
}
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
??? DisableHook();
}
// ok,已經(jīng)深夜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);
}
總結(jié)
以上是生活随笔為你收集整理的C++ Builder 5编HOOK程序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 插件不既有Chrome版也有飞鸽传书
- 下一篇: C++Builder如何响应消息及自定义