2025年微信hook原理(微信hook技术)

微信hook原理(微信hook技术)p 什么是 Hook 就是在一个已有的方法上加入一些钩子 使得在该方法执行前或执行后另在做一些额外的处理 那么 Hook 技巧有什么作用以及我们为什么需要使用它呢 事实上如果一个项目在设计架构时考虑的足够充分 模块抽象的足够合理 设计之初为以后的扩展预留了足够的接口 那么我们完全可以不需要 Hook 技巧 但恰恰架构人员在项目设计之初往往没办法想的足够的深远 p

大家好,我是讯享网,很高兴认识大家。




讯享网

 <p>  什么是Hook,就是在一个已有的方法上加入一些钩子,使得在该方法执行前或执行后另在做一些额外的处理,那么Hook技巧有什么作用以及我们为什么需要使用它呢,事实上如果一个项目在设计架构时考虑的足够充分,模块抽象的足够合理,设计之初为以后的扩展预留了足够的接口,那么我们完全可以不需要Hook技巧。但恰恰架构人员在项目设计之初往往没办法想的足够的深远,使得后续在扩展时深圳面临重构的痛苦,这时Hook技巧似乎可以为我们带来一记缓兵之计,通过对旧的架构进行加钩子来满足新的扩展需求。</p><p>  下面我们就来看看如果进行Hook处理,我们按照Hook的对象的层级来逐一介绍</p><p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2FolUPYemlW5MBfX7tVWceF96AzPD3D8Mh5Tm5NuVSDv3nR89.jpeg&thumbnail=660x&quality=80&type=jpg"/><br/></p><p>  对类进行Hook</p><p>  也就是说我们得钩子需要监控到类的创建等操作,然后在此之前或之后做我们希望的操作</p><p>  1、Hook类的创建</p><p>  你可以在写一个类的时候为其添加__metaclass__属性</p><p>  classFoo(Bar):__metaclass__=something…</p><p>  Python创建类的过程是这样的:</p><p>  Foo中有__metaclass__这个属性吗?如果是,Python会在内存中通过__metaclass__创建一个名字为Foo的类。如果Python没有找到__metaclass__,它会继续在Bar(父类)中寻找__metaclass__属性,并尝试做和前面同样的操作。如果Python在任何父类中都找不到__metaclass__,它就会在模块层次中去寻找__metaclass__,并尝试做同样的操作。如果还是找不到__metaclass__,Python就会用内置的type来创建这个类对象。</p><p>  所以我们需要在给__metaclass__属性的值是一个能够创建一个类的东西,即一个继承type的类。</p><p>  比如:</p><p>  classSingleton(type):def__init__(cls,name,bases,dict):super(Singleton,cls).__init__(name,bases,dict)cls._instance=Nonedef__call__(cls,*args,kw):ifcls._instanceisNone:cls._instance=super(Singleton,cls).__call__(*args,kw)returncls._instanceclassMyClass(object):__metaclass__=Singleton</p><p>  Singleton就是一个能够创建类的对象,因为它继承了type</p><p>  也正因为此,我们可以在Singleton这个类中去监控MyClass的创建过程</p><p>  2、Hook实例属性</p><p>  这里我们需要操作的属性是__getattribute__和__getattr__</p><p>  object.__getattribute__(self,name):无论访问存在还是不存在的属性都先访问该方法</p><p>  object.__getattr__(self,name):当不存在__getattribute__方法或者引发了AttributeError异常时访问该方法</p><p>  classC(object):a='abc'def__getattribute__(self,*args,kwargs):print(__getattribute__()iscalled)returnobject.__getattribute__(self,*args,kwargs)def__getattr__(self,name):print(__getattr__()iscalled)returnnamec=C()printc.a__getattribute__()iscalledabcprintc.aa__getattribute__()iscalled__getattr__()iscalledaa</p><p>  可以看到,访问已有属性a时,__getattribute__被调用,访问未定义的属性aa时__getattribute__先被调用,接着__getattr__被调用</p><p>  3、Hook类属性</p><p>  python描述符是一个“绑定行为”的对象属性,在描述符协议中,它可以通过方法重写属性的访问。这些方法有__get__(),__set__(),和__delete__()。如果这些方法中的任何一个被定义在一个对象中,这个对象就是一个描述符。</p><p>  classDesc(object):def__get__(self,instance,owner):print(__get__...)def__set__(self,instance,value):print('__set__...')classTestDesc(object):x=Desc()t=TestDesc()t.x__get__...</p><p>  -self:Desc的实例对象,其实就是TestDesc的属性x</p><p>  -instance:TestDesc的实例对象,其实就是t</p><p>  -owner:即谁拥有这些东西,当然是TestDesc这个类,它是最高统治者,其他的一些都是包含在它的内部或者由它生出来的</p><p>  为了让描述符能够正常工作,它们必须定义在类的层次上。否则Python无法自动为你调用__get__和__set__方法。</p><p>  而根据之前对类方法的说明,引用t.x的时候是否会先引用TestDesc的__getattribute__方法呢?答案是会的,其实访问属性时在python中真实的查找顺序是这样的:</p><p>  1)__getattribute__(),无条件调用</p><p>  2)数据描述符(定义了__set__或__delete__的描述符):由1)触发调用(若人为的重载了该__getattribute__()方法,可能会导致无法调用描述符)</p><p>  3)实例对象的字典</p><p>  4)类的字典</p><p>  5)非数据描述符(只定义了__get__的描述符)</p><p>  6)父类的字典</p><p>  7)__getattr__()方法</p><p>  4、使用修饰符来Hook类</p><p>  defsingleton(cls,*args,kw):instances={}def_singleton():ifclsnotininstances:instances[cls]=cls(*args,kw)returninstances[cls]return_singleton@singletonclassMyClass(object):a=1def__init__(self,x=0):self.x=x</p><p>  我们使用singleton方法把MyClass修饰为了一个单例模式,同时我们也在singleton方法中实现了对MyClass实例过程的监控。</p><p>  对方法进行Hook</p><p>  1、修饰符来Hook方法</p><p>  1)修饰不带参数的方法</p><p>  defsomething(func):defwrap():printstartfunc()printendreturnwrap@somethingdeffunc():pass</p><p>  2)修饰带参数的方法</p><p>  defsomething(func):defwrap(*args,kargv):printstartfunc(*args,kargv)printendreturnwrap@somethingdeffunc(a,b):pass</p><p>  3)使用带参数的修饰符来修饰方法</p><p>  defsomething(a,b):defnew_func(func):defwrap(*args,kargv):printafunc(*args,kargv)printbreturnwrapreturnnew_func@something(1,2)deffunc(a,b):pass</p><p>  其他Hook</p><p>  1、Hook内建方法</p><p>  #Hookopen方法real_open=__builtins__.open__builtin__.open=my_open#Hookimport方法real_importer=__import____builtins__.__import__=my_importer</p><p>  上述操作使得my_open代替了python内置的open方法,故而我们可以使用我们自己的my_open方法来监控后续对open方法的调用了</p><p>  2、MonkeyPatch</p><p>  fromSomeOtherProduct.SomeModuleimportSomeClassdefspeak(self):return"ookookeeeeeeeee!"SomeClass.speak=speak</p><p>  实际上这是所有语言都会使用到的Hook技巧,往往在我们使用了第三方的包,希望在之上做一些扩展,但又不想改动原有的代码时使用</p><p>  多说一句</p><p>  上述提到了修饰符的操作,那么我们在使用修饰符时有一些小技巧需要了解</p><p>  1、使用functools</p><p>  防止使用修饰器后函数签名被改变</p><p>  fromfunctoolsimportwrapsdefmy_dec(func):@wraps(func)defwrapped():print%siscalled%func.__name__returnfunc()returnwrapped@my_decdeffoo():pass</p><p>  这样处理后,foo方法的签名与被修饰之前保持了一致,否则签名将会变成my_dec方法的签名</p><p>  2、使用decorator模块来做修饰器</p><p>  fromdecoratorimportdecorator@decoratordefwrap(f,*args,kw):printstartf(*args,kw)printend#这样wrap方法就变成了一个decorator@wrapdeffunc():printfunc</p><p>  3、使用类做修饰器</p><p>  classtest(object):def__init__(self,func):self._func=funcdef__call__(self):printstartself._func()printend@testdeffunc():printfuncfunc()startfuncend</p><p>  实际应用中很少遇到可以使用一个类作为修饰器,但实际上只要一个类实现了__call__方法,其就可以作为一个修饰器存在了,并且由于类的可操作性较方法更强大,所以类做修饰器也可以实现更丰富的特性.</p> 

讯享网
小讯
上一篇 2025-05-27 18:44
下一篇 2025-04-27 10:31

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/192663.html