• 浅析什么是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

  • 相关阅读:
    jquery键盘事件
    如何将奇艺、优酷等平台的视频嵌入到项目中
    ubuntu 10.04 常用 设置
    博客风格收集
    多张图片上传预览
    动态计算输入框字符个数
    Ubuntu Linux下设置IP的配置命令
    js事件浏览器兼容
    开源软件下载站
    PHPstrom的一个小技巧
  • 原文地址:https://www.cnblogs.com/ArsenalfanInECNU/p/12871887.html
Copyright © 2020-2023  润新知