Dll代码里没有DllMain函数,为什么也能生成DLL啊??我正在看王艳平《windows程序》我看的是他的第一版,第九章《动态链接库和钩子》,9.3.5 Hook实例---进程保护器,这个例子是创建了 一个dll,dll包含了Jeffrey Richter写的CAPIHook类了(这个不是重点)王艳平的dll的代码里面,没有DllMain函数,我尝试过了,他的代码是可以生成dll的,VC 6没有报错。书上不是说,每个dll里面要有DllMain吗??为什么能通过啊??  希望大家能解决我的疑问啊。
//////////////////////////////////////////////////
// HookTermProLib.cpp文件
#include <windows.h>
#include "APIHook.h"   //CAPIHook类的头文件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;
}

解决方案 »

  1.   

    VC6.0 看到代码里面没有DllMain函数,就生成了一个默认的DllMain,但是没有看到而已,自己顶一下啊。不知道是不是这样解释,比较合理
      

  2.   

    DllMain应该是系统调用DLL时,默认调用的函数,没有这个函数,也可以直接使用DLL的,只要知道DLL暴露的函数地址入口就可以了。
    其实,DllMain和你写的其他DLL暴露的函数一样,只是一个函数入口地址而已。
      

  3.   

    你好啊,能再解决一个问题吗??这就是王艳平写的这个dll为什么不起任何作用啊?
    第一贴里面有详细的代码了CAPIHook是个全局对象,在extern CAPIHook g_TerminateProcess;  这一句已经申明了
    后面有个初始化  :// 挂钩TerminateProcess函数
    CAPIHook g_TerminateProcess("kernel32.dll", "TerminateProcess",  
    (PROC)Hook_TerminateProcess);再看他的代理函数,(代理结束进程的函数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;
    }return ((PFNTERMINATEPROCESS)(PROC)g_TerminateProcess)(hProcess, uExitCode);
    这一句代码中有个g_TerminateProcess和我们的全局对象重名了,是怎么回事啊??
    按照上下文理解,这句代码应该是调用系统本身的API TerminateProcess 函数啊,是怎么调用的啊??
    大牛,希望帮忙解决一下啊。谢谢啊。
      

  4.   

    BOOL WINAPI Hook_TerminateProcess(HANDLE hProcess, UINT uExitCode)  是代理TerminateProcess的函数
      

  5.   

    CAPIHook 可能覆盖了()你的工程文件夹有没有DllMain.cpp?
      

  6.   

    你好啊昨天你就这么说了,可是我真的找了,没有啊 ,它这个工程里面就有CAPIHook,和作者自己的dll代码DllMain函数还真没有
      

  7.   

    把整个目录发到[email protected]给我看
      

  8.   

    刚才看了一下,的确没有dllmain
    如果不显式规定入口点,vc的dll入口点是_DllMainCRTStartup,在这里会执行crt初始化,全局对象的创建等工作
      

  9.   

    多谢了啊, 我看刚才你没回复,我以为你没收到呢,又发送了一次,太感激你了啊祝你工作顺利,money越来越多,心想事成啊
      

  10.   

    然后这个dll是可以挂钩加载它的进程的模块的TerminateProcess
      

  11.   

    DllMain不是必须的啊,大部分的普通DLL在Attach和Detach时都没有什么事情要干。
    还有那种纯资源DLL,更是没啥可干的。
      

  12.   

    dllmain()不是象main()一样必须,而是在运行前(调入内存后)对属性初始化.