下面是dll中的代码:

//我的经验,编译的时候会提示DllMain,已在DllMain.cpp中定义,把DllMain.cpp从源文件里删掉就好了

#include "stdafx.h"
#include<Windows.h>
HHOOK hkey=NULL;
HINSTANCE h_dll;
 
#pragma data_seg(".MySec")  //定义字段,段名.MySec
HWND h_wnd=NULL;
#pragma data_seg()
#pragmacomment(linker,"/section:.MySec,RWS")
 
BOOL WINAPI DllMain(HINSTANCEhinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
       h_dll=hinstDLL;
//     MessageBox(0,"运行dllman","",MB_OK);
       returnTRUE;
}
 
LRESULT CALLBACK my_test(int nCode,WPARAMwParam,LPARAM iParam)//
{
/*
       if(nCode==HC_ACTION)
       {
              MessageBox(0,"成功!!","标题",MB_OK);
       }
       else
       {
              MessageBox(0,"失败!!","标题",MB_OK);
       }
*/
       MessageBox(0,"被截取","",MB_OK);
       UnhookWindowsHookEx(hkey);
       return1;
}
void SetHook(HWND hwnd)
{
       h_wnd= hwnd;
//     MessageBox(0,"运行sethook","",MB_OK);
       hkey=SetWindowsHookEx(WH_KEYBOARD,my_test,h_dll,0);
 
}



下面是EXE的代码:有很多头文件是没用上的,我个人习惯都带着- -,虽然这不是好习惯

//
#include "stdafx.h"
#include <windows.h>
#include <sstream>
#include <stdlib.h>
#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <string>
#include <shlwapi.h>
#include <shlobj.h>
#include <wctype.h>
#include <Winbase.h>
#include <strsafe.h>
#include <conio.h>
#include <Psapi.h>
#include <Tlhelp32.h>
#pragma comment (lib,"PSAPI.LIB")
#pragma comment(lib,"shlwapi.lib")
#pragma comment(lib,"Kernel32.lib")
using namespace std;
typedef void (__cdecl * pfunc)(HWND); //定义函数指针类型
void main()
{
       HINSTANCEhmod;
       pfuncsethook;
       hmod=LoadLibrary("c:\dll_hook.dll");//动态加载dll
 
       if(hmod!=NULL)
       {
              sethook=(pfunc)GetProcAddress(hmod,"SetHook");//调用dll中的函数
              sethook(NULL);
       }
       system("pause");
 
}



    Win32环境下要想在多个进程中共享数据,就必须进行必要的设置。在访问同一个Dll的各进程 之间共享存储器是通过存储器映射文件技术实现的。也可以把这些需要共享的数据分离出来,放置在一个独立的数据段里,并把该段的属性设置为共享。必须给这些 变量赋初值,否则编译器会把没有赋初始值的变量放在一个叫未被初始化的数据段中。

  #pragma data_seg预处理指令用于设置共享数据段。例如:

  #pragma data_seg("SharedDataName")

  HHOOK hHook=NULL;

  #pragma data_seg()

  在#pragmadata_seg("SharedDataName")和#pragma data_seg()之间的所有变量将被访问该Dll的所有进程看到和共享。再加上一条指令#pragmacomment(linker,"/section:.SharedDataName,rws"),那么这个数据节中的数据可以在所有DLL的实例之间共 享。所有对这些数据的操作都针对同一个实例的,而不是在每个进程的地址空间中都有一份。

  当进程隐式或显式调用一个动态库里的函数时,系统都要把这个动态库映射到这个进程的虚拟地址空间里(以下简称"地址空间")。这使得DLL成为进程的一部分,以这个进程的身份执行,使用这个进程的堆栈。

  4、系统钩子与线程钩子:

  SetWindowsHookEx()函数的最后一个参数决定了此钩子是系统钩子还是线程钩子。

// DllMain.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"

//HHOOK hkey=NULL;
HINSTANCE h_dll;
HWND h_wnd=NULL;//
#pragma data_seg(".MySec")  //定义字段,段名.MySec
//HWND h_wnd=NULL;
HHOOK hkey=NULL;//
#pragma data_seg()
#pragma comment(linker,"/section:.MySec,RWS")

BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
	h_dll=hinstDLL;
 	MessageBox(0,"运行dllman","",MB_OK);
	return TRUE;
}

LRESULT CALLBACK my_test(int nCode,WPARAM wParam,LPARAM iParam)//
{
//*
	if(nCode==HC_ACTION)
	{
		MessageBox(0,"成功!!","标题",MB_OK);
	}
	else
	{
		MessageBox(0,"失败!!","标题",MB_OK);
	}
//*/
	MessageBox(0,"被截取","",MB_OK);
	UnhookWindowsHookEx(hkey);
	return 1;
}
void SetHook(HWND hwnd)
{
	h_wnd = hwnd;
 	MessageBox(0,"运行sethook","",MB_OK);
	/*
	建立钩子:SetWindowsHookEx, 
	其四个参数分别为
	钩子类型, 钩子函数地址, 钩子函数所在DLL的实例句柄,安装钩子后想监控的线程的ID号, 
	返回参数为钩子句柄
	*/
	hkey=SetWindowsHookEx(WH_KEYBOARD,my_test,h_dll,0);

}
//
/
//


/*
BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    return TRUE;
}

*/



; lib.def : 导出DLL函数
LIBRARY DllMain
EXPORTS
SetHook @ 1



// TestDll.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <windows.h>
#include <sstream> 
#include <stdlib.h>
#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <string>
#include <shlwapi.h>
#include <shlobj.h>
#include <wctype.h>
#include <Winbase.h>
#include <strsafe.h> 
#include <conio.h>
#include <Psapi.h> 
#include <Tlhelp32.h>
#pragma comment (lib,"PSAPI.LIB")
#pragma comment (lib,"shlwapi.lib")
#pragma comment (lib,"Kernel32.lib")
using namespace std;
typedef void (__cdecl * pfunc)(HWND); //定义函数指针类型
void main()
{
	HINSTANCE hmod;
	pfunc sethook;
	hmod=LoadLibrary("..\\Debug\\DllMain.dll");//动态加载dll

	if(hmod!=NULL)
	{
		sethook=(pfunc)GetProcAddress(hmod,"SetHook");//调用dll中的函数
		sethook(NULL);
		system("pause");
	    FreeLibrary(hmod);
	}

}