首页
社区
课程
招聘
句柄的本质
发表于: 2006-1-3 17:44 6160

句柄的本质

2006-1-3 17:44
6160
一、书上定义:

<<Microsoft Windows 3 Developer's Workshop>>(Microsoft Press,by Richard Wilton)
    在Windows环境中,句柄是用来标识项目的,这些项目包括:模块(module)、任务(task)、实例 (instance)、文件(file)、内存块(block of memory)、菜单(menu)、控制(control)、字体(font)、资源(resource),包括图标(icon),光标 (cursor),字符串(string)等、GDI对象(GDI object),包括位图(bitmap),画刷(brush),元文件(metafile),调色板(palette),画笔(pen),区域 (region),以及设备描述表(device context)。

<<WINDOWS编程短平快>>(南京大学出版社):
    句柄是WONDOWS用来标识被应用程序所建立或使用的对象的唯一整数,WINDOWS使用各种各样的句柄标识诸如应用程序实例,窗口,控制,位图,GDI对象等等。WINDOWS句柄有点象C语言中的文件句柄。

二、MFC源代码:

#ifdef STRICT
typedef void *HANDLE;
#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
#else
typedef PVOID HANDLE;
#define DECLARE_HANDLE(name) typedef HANDLE name
#endif

DECLARE_HANDLE(HMODULE);
DECLARE_HANDLE(HINSTANCE);
DECLARE_HANDLE(HLOCAL);
DECLARE_HANDLE(HGLOBAL);
DECLARE_HANDLE(HDC);
DECLARE_HANDLE(HRGN);
DECLARE_HANDLE(HWND);
DECLARE_HANDLE(HMENU);
DECLARE_HANDLE(HACCEL);
DECLARE_HANDLE(HTASK);

三、理解:
    HANDLE就是PVOID,也就是无类型指针,
    上面这些资源的句柄Handles都不过是指向struct的指针,至于这个struct的用处,连M$都说unused了,现在解释下M$这么做的意义,这就是所谓数据封装,你可以在你的程序中把M$的内部结构指针传来传去,可是你却不知道它到底指向的内容是什么。

    句柄与指针确实是完全不同的两个概念。句柄仅仅是一个32位整数,WIN32中用于标记某个系统或进程的对象,可以理解为对象索引(由于M$未完全公开相关技术,在一定程度上只能如此理解),这个索引更像是一种映射关系(从句柄到对象指针的映射),而不是纯粹意义上的“数组下标”。

     句柄可以理解为用于指向或标识内存的一块“资源”,这些资源如:文件(file)、内存块(block of memory)、菜单(menu)等等。操作系统通过句柄来定位核心对象和系统资源。
    指针即为指向内存的“数据或指令”某一单元。

    说的确切一点,句柄实际上是一种指向某种资源的指针,但与指针又有所不同:指针对应着一个数据在内存中的地址,得到了指针就可以自由地修改该数据。Windows并不希望一般程序修改其内部数据结构,因为这样太不安全。所以Windows给每个使用GlobalAlloc等函数声明的内存区域指定一个句柄(本质上仍是一个指针,但不要直接操作它),平时你只是在调用API函数时利用这个句柄来说明要操作哪段内存。

   
四、引喻:
   牧童遥指杏花村
   牧童的手为指针,杏花村的牌子为句柄,杏花村酒店为对象的实例.

附注:获得窗口句柄三种方法

1.HWND FindWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName)

   HWND FindWindowEx(HWND hwndParent, HWND hwndChildAfter,LPCTSTR lpClassName, LPCTSTR lpWindowName)

2.HWND WindowFromPoint(POINT& Point)//获得当前鼠标光标位置的窗口HWND

3.BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)

   BOOL CALLBACK EnumChildWindows(HWND hWndParent, WNDENUMPROC lpEnumFunc,LPARAM lParam)

   BOOL CALLBACK EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)

   BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)

[培训]传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (14)
雪    币: 2319
活跃值: (565)
能力值: (RANK:300 )
在线值:
发帖
回帖
粉丝
2
学习

对这些特别有兴趣
2006-1-3 19:38
0
雪    币: 133
活跃值: (22)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
蛋蛋这个帖子一定要顶
2006-1-3 19:44
0
雪    币: 389
活跃值: (912)
能力值: ( LV9,RANK:770 )
在线值:
发帖
回帖
粉丝
4
fcfK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6h3y4F1K9r3q4U0K9$3g2J5i4K6u0W2j5$3!0E0i4K6u0r3j5X3u0K6i4K6u0r3M7X3g2S2k6q4)9J5k6i4m8Z5M7q4)9K6c8Y4c8A6k6q4)9K6c8o6x3J5x3o6f1#2
2006-1-3 19:56
0
雪    币: 0
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
5
最初由 kyc 发布
129K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6h3y4F1K9r3q4U0K9$3g2J5i4K6u0W2j5$3!0E0i4K6u0r3j5X3u0K6i4K6u0r3M7X3g2S2k6q4)9J5k6i4m8Z5M7q4)9K6c8Y4c8A6k6q4)9K6c8o6x3J5x3o6f1#2
2006-1-3 20:14
0
雪    币: 438
活跃值: (927)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
6
学习
很少见楼主写这样的文章
2006-1-3 20:14
0
雪    币: 367
活跃值: (157)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
最初由 winndy 发布
学习
很少见楼主写这样的文章

他会写出这样的??不抄错就算不错了
2006-1-3 20:18
0
雪    币: 438
活跃值: (927)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
8
最初由 DarkNess0ut 发布

他会写出这样的??不抄错就算不错了


楼主认识N多牛人...
想必是老鸟了..
近来很少自己动手破解了吧。
2006-1-3 20:29
0
雪    币: 228
活跃值: (119)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
斗胆补充一下下:
句柄说白了就是对象的引出接口。句柄最终会关联上对象,Object Manager为各种目标创建对象,然后方便使用显露一个句柄出来(也就相当于别名),通过句柄可以访问指定对象。下边的函数实现句柄到对象的映射。实际上是个查表的操作

//
// We need the fully qualified pathname
// of the directory referenced by Buffer->RootDir
// Once we have that we should then be able to
// append the contents of Buffer->FileName to
// construct the fully qualified target pathname
//
status = ObReferenceObjectByHandle(renameInfo->RootDirectory,
STANDARD_RIGHTS_REQUIRED,
NULL,
KernelMode,
(PVOID *)&dirObject,
NULL);
另外句柄有个特点就是与进程相关的,在一个进程中打开对象的句柄只能在本进程中使用有效,别的进程使用该句柄将不能通过有效性检查而返回INVALID.来保证不被非法进程访问。
2006-1-3 20:42
0
雪    币: 438
活跃值: (927)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
10
Good!
2006-1-3 20:44
0
雪    币: 300
活跃值: (422)
能力值: ( LV9,RANK:410 )
在线值:
发帖
回帖
粉丝
11
最初由 winndy 发布


楼主认识N多牛人...
想必是老鸟了..
近来很少自己动手破解了吧。


2006-1-3 20:58
0
雪    币: 390
活跃值: (707)
能力值: ( LV12,RANK:650 )
在线值:
发帖
回帖
粉丝
12
最初由 machoman 发布
句柄有个特点就是与进程相关的,在一个进程中打开对象的句柄只能在本进程中使用有效,别的进程使用该句柄将不能通过有效性检查而返回INVALID.来保证不被非法进程访问。
........


补充一下
内核对象的句柄可以继承
2006-1-4 09:06
0
雪    币: 233
活跃值: (130)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
13
windows核心编程这本书中说得很详细
2006-1-4 09:12
0
雪    币: 237
活跃值: (115)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
14
做人要厚道:)
2006-1-4 09:34
0
雪    币: 214
活跃值: (85)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
15
少了[转帖]...
2006-1-4 10:36
0
游客
登录 | 注册 方可回帖
返回