首页
社区
课程
招聘
对DllMain编程的几点说明:what you can do, and what you CANNOT do
2006-8-4 03:29 11871

对DllMain编程的几点说明:what you can do, and what you CANNOT do

2006-8-4 03:29
11871
// From MSDN:

BOOL WINAPI DllMain(
    HINSTANCE hinstDLL,  // handle to DLL module
    DWORD fdwReason,     // reason for calling function
    LPVOID lpReserved )  // reserved
{
        case DLL_PROCESS_ATTACH:
         // Initialize once for each new process.
         // Return FALSE to fail DLL load.
            break;

        case DLL_THREAD_ATTACH:
         // Do thread-specific initialization.
            break;

        case DLL_THREAD_DETACH:
         // Do thread-specific cleanup.
            break;

        case DLL_PROCESS_DETACH:
         // Perform any necessary cleanup.
            break;
    }
    return TRUE;  // Successful DLL_PROCESS_ATTACH.
}

DllMain只是在Windows系统里注册的一个回调函数(call back)。在系统初始化你的DLL的时候,它(PE Loader)会自动定义一个进程内的global lock,防止进程里的其他线程同时运行函数里的代码,或者说是它要线性化(serialize)对DllMain的调用。

所以,哪些是你不能做的?

1。 不要调用LoadLibrary(Ex),或者可以引起线程/进程载入DLL的API,比如:
    CreateProcess / CreateThread
    GUI API (载入gdi32.dll或user32.dll)
    Registry API (advapi32.dll)
    CoInitiaklize(Ex), CoUnInitialize (ole32.dll)
    malloc / calloc / free (msvcrt.dll)
    GetModuleFileName, GetModuleHandle, 等等:尽管它们不载入DLL,但会引起系统产生一个Lock,因此有可能产生死锁(deadlock)。
    ExitThread:如果你在DllMain里调用它,则会再次进入DllMain,你当然明白这意味着什么。
    I/O(输入输出)函数,可能会引起等待。

如果你的DllMain里没有特别需要每个thread都必须作的事情,可以在函数里调用DisableThreadLibraryCall():

        case DLL_PROCESS_ATTACH:
            DisableThreadLibraryCall( hinstDLL );
            break;

“呵呵”,你可能注意到了,“hinstDLL是HINSTANCE,不是HNODULE。”

在16位的Windows上,它们确实不同;32位?一样的。

WinDef.h:
    typedef HANDLE HINSTANCE;
    typedef HINSTANCE HMODULE;

可参考The old new thing: What is the difference between HINSTANCE and HMODULE? (http://blogs.msdn.com/oldnewthing/archive/2004/06/14/155107.aspx)

好了,剩下哪些是我们可以做的?

    初始化全局变量和全局数据结构
    初始化CriticalSection
    TLS API: alloc/set/get/free
    Win32 内存管理API:Virtualxxx / Heapxxx,仅仅限于使用进程的堆(heap)
    CreateFile / ReadFile / WriteFile等等

:-)

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
点赞7
打赏
分享
最新回复 (8)
雪    币: 249
活跃值: (10)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
wiaa 6 2006-8-4 14:50
2
0
哦,学习了
我一直以为DllMain里可以为所欲为
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
北极星2003 25 2006-8-4 16:01
3
0
学习了
这些确实是平时不怎么注意确又是很重要的细节
雪    币: 32410
活跃值: (18735)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
kanxue 8 2006-8-4 16:06
4
0
bookworm是Microsoft的?
雪    币: 237
活跃值: (31)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
JiYangTX 2006-8-4 16:46
5
0
最初由 wiaa 发布
哦,学习了
我一直以为DllMain里可以为所欲为

我和wiaa的想法一致,我也一直以为可以为所欲为,而且我在程序中就使用了CreateThreadA...,这里看来是第一大不能干的事
雪    币: 139
活跃值: (111)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
bookworm 3 2006-8-5 02:08
6
0
多看看MSDN,这其实是最好的信息来源,上面的很大一部分就是从中而来。
雪    币: 249
活跃值: (10)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
wiaa 6 2006-8-5 09:21
7
0
似乎现在流行这么一种技术,尤其是利用微软的Detours,很容易实现:

强行在一个磁盘PE文件中挂上自己的DLL(比如自己写的木马),通过目标PE文件在加载的时候调用该DLL的初始化函数来实现无进程的木马。一切工作都在DllMain中完成(比如CreateThread)

既然如楼主所说,那么这些技术是怎么办到的?
雪    币: 272
活跃值: (143)
能力值: ( LV15,RANK:930 )
在线值:
发帖
回帖
粉丝
dummy 23 2006-8-5 13:45
8
0
这个在 windows 核心编程里也有介绍,以前没有注意这些问题

上些天就犯个这错,因为写壳, 想在 DllMain 中创建双线程,然后通过 消息来通信解码,可是第 2 线程非得在 DllMain 返回后才被调度,没办法
最后只好换成了双纤程,凑合一下了
雪    币: 139
活跃值: (111)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
bookworm 3 2006-8-5 18:37
9
0
请看我的下一个帖子。没办法,回帖不会加分,请各位体谅。
游客
登录 | 注册 方可回帖
返回