歡迎您光臨本站 註冊首頁

Apache Hook 結構分析(二)

←手機掃碼閱讀     火星人 @ 2014-03-04 , reply:0

Apache Hook 結構分析(二)

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; \
}

[火星人 ] Apache Hook 結構分析(二)已經有803次圍觀

http://coctec.com/docs/service/show-post-23836.html