免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1968 | 回复: 0
打印 上一主题 下一主题

[Web] Apache Hook 结构分析(二) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-03-18 17:18 |只看该作者 |倒序浏览
Apache Hook 结构分析(二)
                                          杨学刚
                                          2009-3-18
                                          xuegangyang@eyou.com


一、简介        1
二、Hook array结构分析        2
三、Hook 函数分析        3
3.1 hook函数实现        3
3.2 Run函数实现        4
3.2.1 FIRST处理流程对应的run函数定义        4
3.2.2 ALL处理流程对应的run函数定义        5
3.2.3 VOID处理流程对应的run函数定义        5
3.3 get_hook函数实现        6
四、HOOK宏分析        6
4.1 HOOK_STRUCT宏分析        6
4.2 EXTERNAL_HOOK宏分析        7
4.3 VOID宏分析        7
4.4 RUN_ALL宏分析        8
4.5 RUN_FIRST宏分析        9
4.6 使用宏定义HOOK        10
五、HOOK定义扩展        10
六、小结和思考        11

四、HOOK宏分析
        通过以上分析可以看出apache中HOOK实现需要编写一个Hook array和三个函数,为了简化实现hook的方法和提高代码开发效率,Apache定义了五个HOOK宏来实现HOOK:APR_HOOK_STRUCT、APR_DECLARE_EXTERNAL_HOOK、APR_IMPLEMENT_EXTERNAL_HOOK_VOID、APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL、APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST,为描述方便,以上五个宏按照其名字分别简称为:HOOK_STRUCT、EXTERNAL_HOOK、VOID、RUN_ALL和RUN_FIRST宏
4.1 HOOK_STRUCT宏分析
        APR_HOOK_STRUCT主要用于定义hook对应的_hooks变量,该宏的代码为:
#define APR_HOOK_STRUCT(members) \
static struct { members } _hooks;

但在apache源码中,该宏通常以以下形式使用:
APR_HOOK_STRUCT(
           APR_HOOK_LINK(header_parser)
)

        以上使用涉及到APR_HOOK_LINK宏,其定义非常简单:
#define APR_HOOK_LINK(name) \
apr_array_header_t *link_##name;

结合APR_HOOK_LINK和HOOK_STRUCT宏,便可以定义_hooks 变量。
4.2 EXTERNAL_HOOK宏分析
        EXTERNAL_HOOK宏主要用于声明Hook对应的hook、run和get_hook函数(注意:仅仅是声明而不是实现),声明了hook array中对应的element类型,其源码如下:
/** macro to declare the hook correctly */   
#define APR_DECLARE_EXTERNAL_HOOK(ns,link,ret,name,args) \
typedef ret ns##_HOOK_##name##_t args; \
link##_DECLARE(void) ns##_hook_##name(ns##_HOOK_##name##_t *pf, \
                                      const char * const *aszPre, \
                                      const char * const *aszSucc, int nOrder); \
link##_DECLARE(ret) ns##_run_##name args; \
APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name); \
typedef struct ns##_LINK_##name##_t \
    { \
    ns##_HOOK_##name##_t *pFunc; \
    const char *szName; \
    const char * const *aszPredecessors; \
    const char * const *aszSuccessors; \
    int nOrder; \
} ns##_LINK_##name##_t;


从以上源码中可以看到涉及APR_IMPLEMENT_HOOK_GET_PROTO宏,其功能是用于声明HOOK的get_hook函数,其源码如下:
/** macro to return the prototype of the hook function */   
#define APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name) \
link##_DECLARE(apr_array_header_t *) ns##_hook_get_##name(void)

4.3 VOID宏分析
        VOID 宏主要用于实现处理流程为VOID时的run函数,其源码如下:
#define APR_IMPLEMENT_EXTERNAL_HOOK_VOID(ns,link,name,args_decl,args_use) \
APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \
link##_DECLARE(void) ns##_run_##name args_decl \
    { \
    ns##_LINK_##name##_t *pHook; \
    int n; \
\
    if(!_hooks.link_##name) \
    return; \
\
    pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
&nbsp;&nbsp;&nbsp;&nbsp;for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
&nbsp;&nbsp;&nbsp;&nbsp;pHook[n].pFunc args_use; \
}

源码中用到了APR_IMPLEMENT_EXTERNAL_HOOK_BASE宏,该宏用于实现HOOK对应的hook和get_hook函数,其源码如下:
#define APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \
link##_DECLARE(void) ns##_hook_##name(ns##_HOOK_##name##_t *pf,const char * const *aszPre, \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const char * const *aszSucc,int nOrder) \
&nbsp;&nbsp;&nbsp;&nbsp;{ \
&nbsp;&nbsp;&nbsp;&nbsp;ns##_LINK_##name##_t *pHook; \
&nbsp;&nbsp;&nbsp;&nbsp;if(!_hooks.link_##name) \
&nbsp;&nbsp;&nbsp;&nbsp;{ \
&nbsp;&nbsp;&nbsp;&nbsp;_hooks.link_##name=apr_array_make(apr_hook_global_pool,1,sizeof(ns##_LINK_##name##_t)); \
&nbsp;&nbsp;&nbsp;&nbsp;apr_hook_sort_register(#name,&_hooks.link_##name); \
&nbsp;&nbsp;&nbsp;&nbsp;} \
&nbsp;&nbsp;&nbsp;&nbsp;pHook=apr_array_push(_hooks.link_##name); \
&nbsp;&nbsp;&nbsp;&nbsp;pHook->pFunc=pf; \
&nbsp;&nbsp;&nbsp;&nbsp;pHook->aszPredecessors=aszPre; \
&nbsp;&nbsp;&nbsp;&nbsp;pHook->aszSuccessors=aszSucc; \
&nbsp;&nbsp;&nbsp;&nbsp;pHook->nOrder=nOrder; \
&nbsp;&nbsp;&nbsp;&nbsp;pHook->szName=apr_hook_debug_current; \
&nbsp;&nbsp;&nbsp;&nbsp;if(apr_hook_debug_enabled) \
&nbsp;&nbsp;&nbsp;&nbsp;apr_hook_debug_show(#name,aszPre,aszSucc); \
&nbsp;&nbsp;&nbsp;&nbsp;} \
&nbsp;&nbsp;&nbsp;&nbsp;APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name) \
&nbsp;&nbsp;&nbsp;&nbsp;{ \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return _hooks.link_##name; \
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP