淺析什麼是HOOK

首先明確一點:hook是一個編程機制,與語言無關

貼一段維基百科中對鉤子的定義:

鉤子編程(hooking),也稱作“掛鉤”,是計算機程序設計術語,指通過攔截軟件模塊間的函數調用、消息傳遞、事件傳遞來修改或擴展操作系統、應用程序或其他軟件組件的行爲的各種技術處理被攔截的函數調用、事件、消息的代碼,被稱爲鉤子(hook)。

Hook原意是指鉤子,它表示的就是在某個函數的上下文做自定義的處理來實現我們想要的黑科技

生搬硬套的理解HOOK,其實容易一知半解。要想要比較好的理解HOOK,最好是結合相應的語言/技術棧。

在很多技術領域都存在的這種Hook技術,比如下面這些:

    • PythonWeb框架中,如DjangoFlask都存在這種Hook技術,可以在請求的上下文應用的上下文做自定義操作。
    • Scrapy框架中,可以自定義MiddlerWare,在請求解析的時候做自定操作。
    • K8S編排框架中,我們也可以在執行某些函數的上下文中插入Hook函數,這也是和Web框架同理
    • Hook 是 PyTorch 中一個十分有用的特性。利用它,我們可以不必改變網絡輸入輸出的結構,方便地獲取、改變網絡中間層變量的值和梯度。這個功能被廣泛用於可視化神經網絡中間層的 feature、gradient,從而診斷神經網絡中可能出現的問題,分析網絡有效性。

Hook大概原理

創建一個代理對象,然後把原始對象替換爲我們的代理對象,這樣就可以在這個代理對象爲所欲爲,修改參數或替換返回值。

正常調用:

HOOK調用:

 

有時我們可能會理解不清什麼是handle,什麼是hook。總的來說,handle是對計算機資源(文件,設備,網絡,窗口等等)的抽象表示。程序員可以通過handle來操作系統中的各類資源。而hook指通過攔截系統或者應用中的事件,信號和調用,來更改系統或者應用的默認行爲

 摘錄一個別人寫的例子,便於理解:

import time

class LazyPerson(object):
    def __init__(self, name):
        self.name = name
        self.watch_tv_func = None
        self.have_dinner_func = None

    def get_up(self):
        print("%s get up at:%s" % (self.name, time.time()))

    def go_to_sleep(self):
        print("%s go to sleep at:%s" % (self.name, time.time()))

    def register_tv_hook(self, watch_tv_func):
        self.watch_tv_func = watch_tv_func

    def register_dinner_hook(self, have_dinner_func):
        self.have_dinner_func = have_dinner_func

    def enjoy_a_lazy_day(self):

        # get up
        self.get_up()
        time.sleep(3)
        # watch tv
        # check the watch_tv_func(hooked or unhooked)
        # hooked
        if self.watch_tv_func is not None:
            self.watch_tv_func(self.name)
        # unhooked
        else:
            print("no tv to watch")
        time.sleep(3)
        # have dinner
        # check the have_dinner_func(hooked or unhooked)
        # hooked
        if self.have_dinner_func is not None:
            self.have_dinner_func(self.name)
        # unhooked
        else:
            print("nothing to eat at dinner")
        time.sleep(3)
        self.go_to_sleep()

def watch_daydayup(name):
    print("%s : The program ---day day up--- is funny!!!" % name)

def watch_happyfamily(name):
    print("%s : The program ---happy family--- is boring!!!" % name)

def eat_meat(name):
    print("%s : The meat is nice!!!" % name)


def eat_hamburger(name):
    print("%s : The hamburger is not so bad!!!" % name)


if __name__ == "__main__":
    lazy_tom = LazyPerson("Tom")
    lazy_jerry = LazyPerson("Jerry")
    # register hook
    lazy_tom.register_tv_hook(watch_daydayup)
    lazy_tom.register_dinner_hook(eat_meat)
    lazy_jerry.register_tv_hook(watch_happyfamily)
    lazy_jerry.register_dinner_hook(eat_hamburger)
    # enjoy a day
    lazy_tom.enjoy_a_lazy_day()
    lazy_jerry.enjoy_a_lazy_day()

#代碼原作者鏈接:https://blog.csdn.net/Mybigkid/java/article/details/78383898

運行結果:

Tom get up at:1509246940.32
Tom : The program ---day day up--- is funny!!!
Tom : The meat is nice!!!
Tom go to sleep at:1509246949.34
Jerry get up at:1509246949.34
Jerry : The program ---happy family--- is boring!!!
Jerry : The hamburger is not so bad!!!
Jerry go to sleep at:1509246958.37
————————————————
#原作者代碼鏈接:https://blog.csdn.net/Mybigkid/java/article/details/78383898

 

 參考鏈接:

https://zhuanlan.zhihu.com/p/55276265

https://www.zhihu.com/question/57130969/answer/151896360

https://zhuanlan.zhihu.com/p/75054200

https://zhuanlan.zhihu.com/p/89566158

https://blog.csdn.net/Mybigkid/article/details/78383898?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.nonecase

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章