hook框架设计

承接上一节讲的讲的如何hook ,我们今天这节讲的是把上一节的内容封装成一个函数以便于反复调用。

本节内容用到了前几节的知识,不懂的话去翻看前几节的文章

(在学习js逆向之前呢给大家一点小小的建议就是先对js基础有一个了解,系统的学习一下js这门语言   这里呢我推荐一门课程)【【路飞学城】JavaScript核心编程详解】https://www.bilibili.com/video/BV1Dv411y7Z9?vd_source=ba017adc1d6555500de71f0ea6bc52dd

大家跟这个视频系统学习一下就能对js有很深的了解 对大家的逆向有很大的帮助

最终成品


window.reNameFunc=function reNameFunc (func,name){
    Object.defineProperty(func,"name",{
        configurable: true,
        enumerable: false,
        value: name,
        writable: false
    })
}
!(function (){
    const  $toString=Function.prototype.toString
    const mysymbol=Symbol()
    const toString=function (){
        return typeof this==="function"&& this[mysymbol]|| $toString.call(this)
    }
    function set_native(func,key,value){
       Object.defineProperty(func,key,{
           enumerable:false,
           configurable:true,
           writable:true,
           value:value
       });

    }
    delete Function.prototype.toString;
    set_native(Function.prototype,"toString",toString)
    set_native(Function.prototype.toString,mysymbol,"function toString() { [native code] }")
    window.setNative=function (func,funcname){
        set_native(func,mysymbol,`function ${funcname || func.name || ""}() { [native code] }`)

    }
})()


//hook 实现hook插件的实现
 window.hook=function (func,funcInfo,isDebug,onEnter,onLeave,isExec){
    if(typeof func !=="function"){
        return func
    }
    if(funcInfo===undefined){
        funcInfo={
        };
        funcInfo.objname="globalThis";
        funcInfo.name=func.name||"";
    }
    if(isDebug===undefined){
        isDebug=false
    }
    if(!onEnter){
        onEnter=function (obj){
            console.log(`{hook|${funcInfo.objname}[${funcInfo.name}]正在被调用,参数事${JSON.stringify(obj.arg)}`);
        };
    }
    if(!onLeave){
        onLeave=function (obj){
                        console.log(`{hook|${funcInfo.objname}[${funcInfo.name}]返回值是一个${JSON.stringify(obj.res)}`);

        }
    }
    if(!isExec){
        isExec=true
    }
    hookFunc=function (){
        if(isDebug){
            debugger
        }
        let obj={}
        obj.arg=[]
        obj.res

        for(let index=0;index<arguments.length;index++){
            obj.arg[index]=arguments[index]
        }
        //原函数执行前需要执行的内容
        onEnter.call(this,obj)


        //原函数执行
        if(isExec){
          obj.res=  func.apply(this,obj.arg)
        }
       jieguo= onLeave.call(this,obj)

      return obj.res

    }
    window.setNative(hookFunc,funcInfo.name)
     window.reNameFunc(hookFunc,funcInfo.name)
    return hookFunc
 }
 //hook对象属性的本质就是替换属性描述符
 window.hookObj=function hookObj (obj,objName,propName,isDebug){
    //obj 这个参数就是需要hook的对象
     //objname 被hook对象的名字、
     //propName 需要hook对象的的属性的名字
     //isdebug 是否进行调试

     //在进行hook之前我们就先把这个对象属性的描述符先保存一份
     // 用上节讲过的这个方法获取一个对象属性描述符 Object.getOwnPropertyDescriptor
     //第一个参数就是 对哪个对象进行属性获取 , 第二个参数就是要获取哪个属性的描述符
   let initial_prop=  Object.getOwnPropertyDescriptor(obj,propName);
   //接下来声明一个我们要替换的属性描述符
     let Replacement_prop={}//属性描述符本身就是一个 字典
     //在属性描述符中有两个恒定的属性就是[[Configurable]][[Enumerable]]不知道啥意思的朋友去看上一级,有详细说明
     //我们读取原来的属性描述符 ,添加到我们要替换的属性描述符中
     //首先要看一下原先的属性描述符是不是可配置的 如果不可配置我们就无法进行替换
     if(!initial_prop.configurable){
         console.log("给属性不可以被配置")
         return
     };
     Replacement_prop.configurable= initial_prop.configurable;
     Replacement_prop.enumerable=initial_prop.enumerable;
     if(initial_prop.hasOwnProperty("writable")){
         Replacement_prop.writable=  initial_prop.writable

     }

     if(initial_prop.hasOwnProperty("value")){
         let value=initial_prop.value
         if(!typeof value==="function"){
             console.log("value不是一个函数")
             return;
         }
         let funcInfo={
            "objname":obj,
             "name":propName,
         }
         Replacement_prop.value=window.hook(value,funcInfo,isDebug)
     }
     if(initial_prop.hasOwnProperty("get")){
         let get=initial_prop.get
         let funcInfo={
            "objname":obj,
             "name":`get ${propName}`,
         }
         Replacement_prop.get=window.hook(get,funcInfo,isDebug)
     }
      if(initial_prop.hasOwnProperty("set")){
         let set=initial_prop.set
         let funcInfo={
            "objname":obj,
             "name":`set ${propName}`,
         }
         Replacement_prop.set=window.hook(set,funcInfo,isDebug)
     }
      Object.defineProperty(obj,propName,Replacement_prop)


 }
 window.hookproto=function hookProto (protp,isdebug){
    let protoObj=protp.prototype
     let name =protp.name
    for (let i in Object.getOwnPropertyDescriptors(protoObj)){
    window.hookObj(protoObj,`${name}.prototype`,i,isdebug)
}
     console.log(`{hook} |${name}.prototype `);

 }

下面我们来看一下效果

将我们的代码添加到我们的代码段里面 点击运行

然后运行我们的函数 把Document 传进去

马上就吐出了 参数日志

 下 节 预 知 : hook 全局对象window 

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值