首页
社区
课程
招聘
[求助]关于DLL中的全局共享的一点疑惑。。。
发表于: 2007-4-30 02:38 9671

[求助]关于DLL中的全局共享的一点疑惑。。。

2007-4-30 02:38
9671

DLL代码:

#include <windows.h>
HWND g_hWnd=NULL; 疑惑一 :已经做了全局变量定义
HWND  hCDC=NULL;

#pragma data_seg("MySec")

HHOOK g_hKeyboard=NULL;

#pragma data_seg()

extern "C" _declspec (dllexport) void SetHook(HWND hwnd);

LRESULT CALLBACK KeyboardProc(
  int code,       // hook code
  WPARAM wParam,  // virtual-key code
  LPARAM lParam   // keystroke-message information
)

{

    if(VK_HOME==wParam)
        {
        if (!g_hWnd)MessageBox(NULL,"1111","2222",MB_OK); 疑问二: 这里g_hWnd总是为0

           if (!hCDC)MessageBox(NULL,"122222","3333",MB_OK); 疑问二: 这里hCDC总是为0

                     UnhookWindowsHookEx(g_hKeyboard);     

        }
        return 0 ;
}

void SetHook(HWND hwnd)
{       
    if (hwnd){
        g_hWnd=hwnd; 疑问三: 这里已经传递进来了。。但上面回调函数仍为0

        hCDC=hwnd;   疑问四: 这里已经传递进来了。。但上面回调函数仍为0

        if (!hCDC)
        {
                MessageBox(NULL,"1111","2222",MB_OK);
        }

     g_hKeyboard=SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,GetModuleHandle("SetHook"),GetWindowThreadProcessId(
                hwnd,NULL));
//                SendMessage(g_hWnd,WM_KEYDOWN,VK_NUMPAD0,0 );
        }               
}

用MFC写了一个调用上面DLL的程序。。主要是调用 SetHook 这个函数。。同时我传递进目标窗口的句柄。。
试图在 疑问三 和四的地方用全局变量来保存这个句柄被在 回调函数中使用。。。。

但回调函数中的 获得的句柄总是为零的。。。。。
不明白。。我已经传递进来了。。而且钩子也成功钩上线程。。但这个句柄好象都保存不到给回调函数用。。。。

各位指导下。。。。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (11)
雪    币: 254
活跃值: (126)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
2
进程空间不一样
2007-4-30 10:56
0
雪    币: 3227
活跃值: (2908)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
不懂。。。同一个 DLL中进程空间居然不一样?那有没有办法把参数保存到给回调函数用呢?
2007-4-30 12:17
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
在Win16环境中,DLL的全局数据对每个载入它的进程来说都是相同的;而在Win32环境中,情况却发生了变化,DLL函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有。当进程在载入DLL时,操作系统自动把DLL地址映射到该进程的私有空间,也就是进程的虚拟地址空间,而且也复制该DLL的全局数据的一份拷贝到该进程空间。也就是说每个进程所拥有的相同的DLL的全局数据,它们的名称相同,但其值却并不一定是相同的,而且是互不干涉的。
因此,在Win32环境下要想在多个进程中共享数据,就必须进行必要的设置。在访问同一个Dll的各进程之间共享存储器是通过存储器映射文件技术实现的。也可以把这些需要共享的数据分离出来,放置在一个独立的数据段里,并把该段的属性设置为共享。必须给这些变量赋初值,否则编译器会把没有赋初始值的变量放在一个叫未被初始化的数据段中。
#pragma data_seg预处理指令用于设置共享数据段。例如:
#pragma data_seg("SharedDataName")
HHOOK hHook=NULL;
#pragma data_seg()
在#pragma data_seg("SharedDataName")和#pragma data_seg()之间的所有变量将被访问该Dll的所有进程看到和共享。再加上一条指令#pragma comment(linker,"/section:.SharedDataName,rws"),那么这个数据节中的数据可以在所有DLL的实例之间共享。所有对这些数据的操作都针对同一个实例的,而不是在每个进程的地址空间中都有一份。
当进程隐式或显式调用一个动态库里的函数时,系统都要把这个动态库映射到这个进程的虚拟地址空间里(以下简称"地址空间")。这使得DLL成为进程的一部分,以这个进程的身份执行,使用这个进程的堆栈。
2007-4-30 12:35
0
雪    币: 209
活跃值: (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
那代码呢,我想在Kernel.dll中ExitWindowsEx函数下断点并希望系统所有进程在调用这个函数时被断下,我应该怎么做呢
2007-4-30 13:42
0
雪    币: 3227
活跃值: (2908)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
应该没有这样下断的。。。不过SOFT没用过。。。你一个个进程附加然后找到 Kernel.dll中ExitWindowsEx函数下断 应该就可以了。。
2007-4-30 14:59
0
雪    币: 3227
活跃值: (2908)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
在原程序上修改成:
#pragma data_seg("MySec")

HHOOK g_hKeyboard=NULL;
HWND g_hWnd=NULL;
HWND  hCDC=NULL;
#pragma data_seg()
#pragma comment(linker,"/section:.MySec,rws")
后回调中的 hCDC 和g_hWnd仍为0。。。。。
不明白了。。
2007-4-30 15:08
0
雪    币: 750
活跃值: (228)
能力值: ( LV9,RANK:780 )
在线值:
发帖
回帖
粉丝
8
你可以搜下我的文章
2007-4-30 16:00
0
雪    币: 209
活跃值: (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
我想很多监控象杀读软件就是通过安装全局钩子来实现的吧,或着是通过修改系统的DLL文件实现的
2007-5-3 13:59
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
确实是这样的,像360安全卫士就是钩住CreateProcess来实现某些功能的
2007-5-4 00:26
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
刚刚看到罗云斌的WIN32的hook那章,里面有个例子程序跟你这个差不多,

                .data?
hWnd                dd        ?
hHook                dd        ?
dwMessage        dd        ?
szAscii                db        4 dup (?)

DLL_LINK_FLAG = /subsystem:windows /section:.bss,S
他把.data设置为共享段,为了弄明白点为什么要共享段,我把这四个参数一个一个移到.data里,发现只有hWnd一定要在共享段里,后来在看了一边程序原来,hWnd是在loader程序里传进来,但是全局dll是映射到每个进程,这里非共享段里的变量应该会被初始化全局变量就是0,局部的就不清楚了,你这里g_hWnd是用SetHook(HWND hwnd)的,而SetHook应该是loader程序调用,别的进程没调用
SetHook,所以g_hWnd也就没有被赋值
2007-5-6 21:04
0
雪    币: 3227
活跃值: (2908)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
首先这是个钩子程序。。既然是HOOK。。那被HOOK的程序当然不会那个SetHook(HWND hWnd)。。。而非共享段就初始化为0,那么我放到共享段中仍为0。。。。

至于我为什么那么无聊一定要传递这个HWND 呢?为了获得目标程序的DC用。。在它上面写几个字而已。。。
2007-5-7 20:41
0
游客
登录 | 注册 方可回帖
返回
//