不说废话了,贴代码吧,这是一个dll,它的功能实现:保护 某进程的作用,给外界提供了一个接口函数:BOOL WINAPI SetSysHook(BOOL bInstall, DWORD dwThreadId) 参数1:安装或卸载钩子?参数2:要保护的进程的pid!!!参数1:为false时候,则卸载之,为true时候,则安装之。dll里面还有一个全局对象,即:CAPIHook g_OpenProcess("kernel32.dll", "OpenProcess", (PROC)    Hook_OpenProcess);      // 挂钩OpenProcess函数,g_OpenProcess对象初始化时候会自动挂钩的
,这个是由 APIHook.h 封装的类实现 的。
具体代码如下:
#include <windows.h>
#include "APIHook.h"    //JF大牛写的,包含之
extern CAPIHook g_OpenProcess;#pragma data_seg("YCIShared")
HHOOK g_hHook = NULL;
DWORD dwCurrentProcessId=0;     //需要保护的进程的id
#pragma data_seg()
HANDLE WINAPI Hook_OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
{
typedef HANDLE (WINAPI *PFNTERMINATEPROCESS)(DWORD, BOOL,DWORD);if(dwProcessId != dwCurrentProcessId)  //也就是说,如果不是结束本进程,那么就可以放行
{
return ((PFNTERMINATEPROCESS)(PROC)g_OpenProcess)(dwDesiredAccess,bInheritHandle,dwProcessId);
}
return 0;
}// 挂钩OpenProcess函数,g_OpenProcess对象初始化时候会自动挂钩的
CAPIHook g_OpenProcess("kernel32.dll", "OpenProcess", (PROC)Hook_OpenProcess);static HMODULE ModuleFromAddress(PVOID pv) 
{
MEMORY_BASIC_INFORMATION mbi;
if(::VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
{
return (HMODULE)mbi.AllocationBase;
}
else
{
return NULL;
}
}
//回调函数,无功能,只是加载dll而已.static LRESULT WINAPI GetMsgProc(int code, WPARAM wParam, LPARAM lParam) 
{
return ::CallNextHookEx(g_hHook, code, wParam, lParam);
}
//接口函数,第一个参数的意思是是否安装或卸载,第二个参数的意思:将要保护的进程的pid
//原作者参数名字起的不好
BOOL WINAPI SetSysHook(BOOL bInstall, DWORD dwThreadId)
{
BOOL bOk;
dwCurrentProcessId=dwThreadId;
if(bInstall) 
{
g_hHook = ::SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, 
ModuleFromAddress(GetMsgProc), 0);
bOk = (g_hHook != NULL);

else 
{
bOk = ::UnhookWindowsHookEx(g_hHook);
g_hHook = NULL;
}
return bOk;
}//dll的入口函数BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
 )
{
    switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
    }
    return TRUE;
}问题是我写了一个基于对话框的mfc程序加载这个dll,然后再任务管理程序里面结束之,结果可以结束。按道理说,是不能结束的啊。为什么啊??
谢谢大家了啊。

解决方案 »

  1.   

    你在dllmainDLL_PROCESS_ATTACH:中创建那个对象还有iat hook效果不怎样,没法对付用GetProcAddress的api,比如vb6的declare
      

  2.   

    你好啊 ,我是楼主,可否说一下,为什么在dllmainDLL_PROCESS_ATTACH:中创建那个全局对象,
    就会成功呢??什么原因啊?还有GetProcAddress的api, 这个APIHook.h里面是有的,Jeffrey Richter 写的类,我只是没有用而已,
      

  3.   

    因为没地方初始化那个全局对象你用visual basic做一个OpenProcess的,你的应该防不住
      

  4.   


    你好啊,可以不可以再请教一个问题,我这几天在看王艳平<Windows程序设计>  第九章 的Hook API那一节,具体地说,9.3.5 Hook实例-----进程保护器,HookTermProLib.cpp文件的代码:它也是调用了 "APIHook.h"  里面的类 (这个类,网上都有,据说是<Windows 核心编程里面的>)但是它这个dll代码里面没有DllMain ,这是为什么啊??  没有DllMain为什么也会生成Dll,而且它的这个dll,后来在调用的时候感觉没有任何作用!!!就像我的这个楼上的第一个帖子一样,我的这个帖子里的代码基本就是他的。他是Hook TerminateProcess,而我是Hook OpenProcess。王艳平的具体代码如下://////////////////////////////////////////////////
    // HookTermProLib.cpp文件
    #include <windows.h>
    #include "APIHook.h"extern CAPIHook g_TerminateProcess;// 自定义TerminateProcess函数
    BOOL WINAPI Hook_TerminateProcess(HANDLE hProcess, UINT uExitCode)
    {
    typedef BOOL (WINAPI *PFNTERMINATEPROCESS)(HANDLE, UINT); // 取得主模块的文件名称
    char szPathName[MAX_PATH];
    ::GetModuleFileName(NULL, szPathName, MAX_PATH); // 构建发送给主窗口的字符串
    char sz[2048];
    wsprintf(sz, "\r\n 进程:(%d)%s\r\n\r\n 进程句柄:%X\r\n 退出代码:%d",
    ::GetCurrentProcessId(), szPathName, hProcess, uExitCode); // 发送这个字符串到主对话框
    COPYDATASTRUCT cds = { ::GetCurrentProcessId(), strlen(sz) + 1, sz };
    if(::SendMessage(::FindWindow(NULL, "进程保护器"), WM_COPYDATA, 0, (LPARAM)&cds) != -1)
    {
    // 如果函数的返回值不是-1,我们就允许API函数执行
    return ((PFNTERMINATEPROCESS)(PROC)g_TerminateProcess)(hProcess, uExitCode);
    }
    return TRUE;
    }// 挂钩TerminateProcess函数
    CAPIHook g_TerminateProcess("kernel32.dll", "TerminateProcess", 
    (PROC)Hook_TerminateProcess);
    ///////////////////////////////////////////////////////////////////////////#pragma data_seg("YCIShared")
    HHOOK g_hHook = NULL;
    #pragma data_seg()static HMODULE ModuleFromAddress(PVOID pv) 
    {
    MEMORY_BASIC_INFORMATION mbi;
    if(::VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
    {
    return (HMODULE)mbi.AllocationBase;
    }
    else
    {
    return NULL;
    }
    }static LRESULT WINAPI GetMsgProc(int code, WPARAM wParam, LPARAM lParam) 
    {
    return ::CallNextHookEx(g_hHook, code, wParam, lParam);
    }BOOL WINAPI SetSysHook(BOOL bInstall, DWORD dwThreadId)
    {
    BOOL bOk;
    if(bInstall) 
    {
    g_hHook = ::SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, 
    ModuleFromAddress(GetMsgProc), dwThreadId);
    bOk = (g_hHook != NULL);

    else 
    {
    bOk = ::UnhookWindowsHookEx(g_hHook);
    g_hHook = NULL;
    }
    return bOk;
    }
      

  5.   

    整个工程就一个原代码文件?
    dllmain一般放在dllmain.cpp中
      

  6.   

    还要hook LoadLibrary .GetProcAddress  等api.防止动态加载api.绕过了你的导入表hook.