js逆向_知识小结

目录

一、Chrome之调试小结
  • 很早之前的笔记,先发出来,后面有很多没有完善起来
① chrome查看资源文件
  • chrome查看资源文件:Sources>Page
    在这里插入图片描述
② chrome关联本地文件夹
  • chrome关联本地文件夹:Sources>Filesystem>Add folder to workspace
    在这里插入图片描述
③ chrome重写js文件并替换
  • chrome重写js文件并替换:第一步先添加文件夹:Sources>Overrides>Select folder for overrides;第二步去请求包Network页面选择js文件>右击Open in Sources panel>重新编辑js文件>刷新即可运行
    在这里插入图片描述
    在这里插入图片描述
④ chrome新建js文件并执行
⑤ Console打印输出勾选
  • Console打印输出勾选:下面右侧设置齿轮,勾选如下6个,可以查看xhr请求的打印日志
    在这里插入图片描述
    • 如果页面多次打印某个函数,可对该函数进行置空,如console.log = function(){}
⑥ 断点(DOM、事件、xhr、debugger)
  • 断点:DOM断点、DOM事件下断点、xhr断点、代码行断点(自己下的js断点)、代码断点(代码里的debugger)、捕获异常断点
  • DOM断点:右击元素attribute modifications下断点(不推荐)
    在这里插入图片描述
  • DOM事件下断点:Event Listeners、点击、Canvas、load等事件断点
    在这里插入图片描述在这里插入图片描述
  • xhr断点:只针对xhr请求
    在这里插入图片描述
  • 捕获异常断点:右侧暂停按钮,勾选Pause on caught exceptions,可捕获全局断点
    在这里插入图片描述
⑦ 调用栈Call Stack
  • 调用栈:Network里面Initiator或者是断点调试Source面板下的Call Stack
    在这里插入图片描述
    在这里插入图片描述
⑧ 清缓存、清cookie
  • 清缓存、清cookie:Application下Clear site data或者cookie的清除符号
    在这里插入图片描述
    在这里插入图片描述
⑨ 过无限debugger
  • 针对静态网页:可以用fiddler替换网页js文件,并将其中的debugger删掉
  • 针对动态网页
    • 常用方式过debugger:鼠标右击选择Never pause here
      在这里插入图片描述
    • Function原理的debugger,可以重写函数构造器
      Function.prototype.constructor_bc = Function.prototype.constructor
      Function.prototype.constructor = function() {
          if (arguments[0] === "debugger") {} 
          else {
              Function.prototype.constructor_bc.apply(this, arguments)
          }
      }
      
    • eval类型的debugger,可以重构eval函数
      eval_bc = eval
      eval = function(a) {
          if (a === '(function() {var a = new Date(); debugger; return new Date() - a > 100;}())') {} 
          else {
              return eval_bc(a)
          }
      }
      
    • (function() {var a = new Date(); debugger; return new Date() - a > 100;}()):定时器的无限debugger,可用上面的方法,或者以下两种方法
      在这里插入图片描述
      setinval_b= setInterval
      setInterval = function(a, b) {
          if (a.toString().indexOf('debugger') == -1) {
          	console.log(a);
              return setinval_b(a, b)
          }
      }
      
      for (var i = 1; i < 99999; i++)window.clearInterval(i);
      
    • 向上找堆栈,在进入无限debugger之前打上断点将触发无限debugger的函数置空
⑩ hook之js
  • hook之window的属性
    (function() {
        'use strict';
        var pre = "";
        Object.defineProperty(window, '_pt_', {
            get: function() {
                console.log('Getting window.属性');
                return pre
            },
            set: function(val) {
                console.log('Setting window.属性', val);
                debugger ;
                pre = val;
            }
        })
    })();
    
  • hook之cookie
    (function() {
       'use strict';
        var _cookie = ""; // hook cookie
        Object.defineProperty(document, 'cookie', {
            set: function(val) {
                console.log('cookie set->', new Date().getTime(), val);
                debugger;
                _cookie = val;
                return val;
            },
            get: function(val) {
                return _cookie;
            }
       });
    })()
    
    
二、Fiddler之抓包小结
① 模拟postman请求
  • 模拟请求,复制请求头raw的数据在Composer页面raw可以重新执行Execute,类似于postman工具
    在这里插入图片描述
② 重放再次请求
  • 重放再次请求,响应请求右击Replay>Reissue Sequentially或者直接点上方Replay;即进行重新请求,可选择多个请求同时操作,重放攻击如果成功则模拟请求,失败则找原因
    在这里插入图片描述
③ 本地文件替换网页js文件
  • 通过Fiddler用本地js文件替换源网页的js文件 ,将网页端的js文件保存到本地,并修改js内容里面想要改的地方,比如保存为ticket.js
  • 打开Fiddler选择AutoResponder进行文件替换
  • 刷新一下网页,查看js文件是否已经被替换成你想替换的内容,并做相应的测试
  • 刷新后fiddler替换js文件如果失败,可如下操作,网页端谷歌开发者工具勾选Network>Disable cache或js文件与网页一致取压缩状态的文件
    在这里插入图片描述
④ 查看tls指纹

在这里插入图片描述

三、js代码之知识点小结
① js基础(数据类型、对象、数组)
  • (1)js的使用:内部js放在<script></script>标签中;外部js通过src属性引入:<script src=“javascript.js”></script>;onclick、href等属性绑定执行js
    在这里插入图片描述

  • (2)数据类型:基本数据类型:字符串(String)、数字(Number)、布尔(Boolean)、空(Null)、未定义(Undefined);引用数据类型:对象(Object)、数组(Array)、函数(Function),可通过typeof()检查数据类型
    在这里插入图片描述

  • (3)当你通过var声明变量时,可以使用关键词 “new” 来声明其类型

    var carname=new String;
    var x=      new Number;
    var y=      new Boolean;
    var cars=   new Array;
    var person= new Object;
    
  • (4)变量声明提前,使用var关键字声明的变量,会在所有代码执行之前被声明(但不会被赋值),但是如果声明变量不使用var关键字,则变量不会被声明提前

  • (5)在函数中,不使用var声明的变量都会成为全局变量

  • (6)对象Object:对象属性名可加双引号可不加双引号,只能是字符串,值可以是任意的数据类型

    • 内建对象:由ES标准中定义的对象,在任何的ES的实现中都可以使用,比如:Math,String,Number,Boolean,Function,Object
    • 宿主对象:由JS运行环境提供的对象,目前来讲主要是浏览器提供的对象,比如BOM,DOM
    • 自定义对象:由开发人员自定创建的对象
    // 定义一个对象
    let obj = {hello: 'world'};
    // 浅拷贝,只复制对象的内存地址,类似于指针,只要其中之一改变,则另一个也随之改变
    let obj2 = obj;
    // 深拷贝,完全克隆,生成一个新对象
    let obj3 = JSON.parse(JSON.stringify(obj));
    // 定义
    let me = {
        name: 'shir',
        age: "18",
        fullname: function() {
            return
        }
    };
    // 赋值也可以取值
    me.education = 'College'
    me['sex'] = '女'
    me[love] = 'flower'
    // 取值
    console.log(Object.keys(me))  // ["name", "age", "education", "sex", "love"]
    console.log(Object.values(me))  // ["shir", "18", "College", "女", "flower"]
    // 删除属性
    delete me.education
    // 遍历
    for (let key in me) {
        if (me.hasOwnProperty(key)){
            const value = me[key]
            console.log(key, value)  // name shir  age 18   
        }
    }
    
  • (7)数组Array:值可以是任意的数据类型,map()和forEach()方法遍历数组

    • 创建一个数组的三种方式:
      // 常规方式
      var myCars=new Array();
      myCars[0]="Saab";      
      myCars[1]="Volvo";
      myCars[2]="BMW";
      // 简洁方式
      var myCars=new Array("Saab","Volvo","BMW");
      // 字面方式
      var myCars=["Saab","Volvo","BMW"];
      
    • 数组的长度.length,数组的追加push(),数组的尾部删除pop(),数组的头部增加unshift(),数组的头部删除shift(),数组排序sort(),数组逆序排序reverse()
      let items = [1, 2, 3, 4, 5]
      console.log(items[2]);   // 3
      items[3] = "4shir";   // 第4个位置赋值
      items.length;   // 5
      items.indexOf(5);  //  读索引值
      items.push(6);  // 相当于python的append(),追加一个元素
      items.pop();  // 删除最后一个元素
      items.unshift("Lemon","Pineapple") // 头部增加第一个元素
      items.shift(); // 删除第一个元素
      items.sort();  // 正序排序
      items.reverse();  // 反序排序
      
    • 数组的插入splice(index, 0, 元素)与删除splice(index,个数)
      let items = [1, 2, 3, 4, 5]
      // 指定索引添加或删除
      items.splice(
          0, // 指定索引添加
          0, // 不删除即为添加
          "0", // 添加的元素值
      );
      items.splice(
          0, // 指定索引删除
          2, // 删除多少个
      );
      
    • 数组的遍历.map().forEach()
      //数组遍历方式1,map会返回新数组
      var items = [1,2,3,4,5];
      var result = items.map(function( value ) {
          return value * 2;
      });
      console.log(result);
      	
      // 数组遍历方式2,forEach不会有新数组返回,也没有break和continue,可通过some和every实现
      var arr = [1, 2, 3, 4, 5];
      arr.forEach(function (item) {
          if (item === 3) {
              return;  // return语句实现continue 关键字的效果:
          }
          console.log(item);
      });
      
    • 数组的合并concat()
      var parents = ["Jani", "Tove"];
      var brothers = ["Stale", "Kai Jim", "Borge"];
      var children = ["Cecilie", "Lone"];
      var family = parents.concat(brothers, children); //["Jani", "Tove", "Stale", "Kai Jim", "Borge", "Cecilie", "Lone"]
      
  • (8)逗号运算符使用逗号, ,可以分割多个语句,一般在声明多个变量时使用

  • (9)在JS中可以使用{}来为语句进行分组,一个{}中的语句我们称为一组语句或代码块,它们要么都执行,要么都不执行,在代码块后边就不用再写分号;了

  • (10)三元表达式:条件表达式?语句1:语句2
    在这里插入图片描述

② 函数(构造、有名、匿名、自执行、arguments)
  • (1)函数定义:

    • 声明式函数定义:function mytest(){console.log(‘haha’)}
    • 函数表达式定义:let fun = function(){console.log(‘haha’)}
    • new Function形式:var fun1 = new Function (arg1 , arg2 ,arg3 ,…, argN , body)
  • (2)构造函数:使用new关键字调用的函数,最后一个位置为函数执行体,前面的位置可加形参

    let sum = new Function('a', 'b', 'return a + b');
    sum(1, 2)
    
    let sayHi = new Function('console.log("Hello")');
    sayHi()
    
    function Person(){
        this.name="小明";
        this.age=18;
    }
    var p1=new Person();
    console.log(p1, p1.name,p1.age);
    
  • (3)有名函数:function关键字后面指定名字的,如下案例,指定函数名myNameFun

    function myNameFun(a,b){
        console.log(a+b)
    }
    myNameFun(1, 1)
    
  • (4)匿名函数:function关键字后面没有名字的

    // 匿名函数格式
    function(a,b){
        console.log(a+b)
    }
    
  • (5)自执行函数:顾名思义,就是立即自动执行的函数,有名函数和匿名函数都可以自执行,举例几个匿名函数自执行的方式如下;因为js是函数作用域,所以如果想实现某个功能又不想污染全局变量的时候可以使用自执行函数样例见某盾core.js一个典型的实际用例,逐步调试看看就懂了

    • 自执行方式1:变量=匿名函数(传入参数),把匿名函数赋给一个变量自执行,
      // 自执行方式1
      var myNamefun = function(a,b){
          console.log(a+b)
      }(1,1)
      
    • 自执行方式2:(匿名函数)(传入参数),样例如下
      // 自执行方式2
      (function(a,b){
          console.log(a+b)
      })(1,1);
      
    • 自执行方式3:(匿名函数(传入参数)),样例如下
      (function(a,b){
          console.log(a+b)
      }(1,1));
      
    • 更多自执行方式详见
      !function () { /* code */ } ();  
      !(function () { /* code */ } )();  
      ~function () { /* code */ } ();  
      -function () { /* code */ } ();  
      +function () { /* code */ } (); 
      
  • (6)箭头函数:(参数1, 参数2, …, 参数N) => 表达式(单一)

    // ES5
    var x = function(x, y) {
         return x * y;
    }
    // ES6
    const x = (x, y) => x * y;
    
  • (7)函数的参数:显式参数(Parameters)与隐式参数(Arguments),JavaScript 函数有个内置的对象 arguments 对象,argument 对象包含了函数调用的参数数组,arguments是个类数组对象; 在调用函数时浏览器每次都会传递两个隐含的参数:函数的上下文对象this、封装实参的对象arguments

    funciton test(){
    	var m = arguments[0]; //第一个传入的参数
    	var n = arguments[1]; //第二个传入的参数,如果只传入一个参数,那么该值为undefined
    	var l = argument.length;//该值对应的函数调用时传入参数的个数
    	var ll = fun.length;//该值对应的函数定义的参数个数
    }
    
  • (8)函数的特征熟悉

    • 函数声明提前,使用function声明创建的函数,function 函数(){},会在所有代码执行前创建,可以在函数声明前提前调用;使用函数表达式即定义变量的形式创建的函数,不会被提前创建
    • 函数也可以作为对象的属性值
    • 函数的实参可以是任意的数据类型,可以是对象,也可以是函数
    • 函数的返回值可以是任意数据类型,可以是对象,也可以是函数
    • 调用函数时创建函数作用域,调用结束就销毁,在函数中要访问全局变量,可以使用window.变量
③ 作用域(局部、全局、this、apply、call、bind)
  • (1)作用域:在JS中一共有两种作用域,一种是全局作用域,一种是函数作用域

  • (2)局部作用域:在函数内通过var声明的变量,变量为局部变量,所以只能在函数内部访问它,该变量的作用域是局部的;

  • (3)全局作用域:在函数外通过var声明的变量为全部变量,不使用var声明的变量默认都是全局变量

    • 直接编写在script标签中的Js代码,都在全局作用域
    • 在全局作用域中有一个全局对象window,它代表的是一个浏览器的窗口,它由浏览器创建,我们可以直接使用
    • 在全局作用域中创建的变量都会作为window对象的属性保存
    • 在全局作用域中创建的函数都会作为window对象的方法保存
  • (4)this:表示当前对象的一个引用,不是固定不变的,它会随着执行环境的改变而改变,换言之当前谁是this的拥有者,this就指向谁

    • 全局作用域中,this指向全局对象window
    • 以方法的形式调用时,this是调用方法的对象
    • 以函数形式调用时,this永远都是window
    • 以构造函数形式调用时,this是新创建的那个对象
    • 使用call和apply和bind调用是,this就是指定的那个对象
    • 全局中的this:全局作用域中,this指向全局对象window
      //在全局作用域中声明变量num
      var num=1;
      console.log(window.num);//1
      //修改this对象身上的num属性,将num属性的值修改为2
      this.num=2;
      console.log(window.num);//2
      console.log(this===window);//true 
      
    • 方法中的this:this是调用方法的对象;在方法中,this指向该方法所属的对象,如下this指向了p1对象,因为p1对象是speak方法的所有者
      var p1={
          name:"11",
          speak:function(){
              console.log("我是"+this.name);  // 我是11
              console.log(this===p1);//true
          }
      }
      p1.speak();
      
    • 普通函数中的this:this永远都是window;函数的所属者默认绑定到this上,即谁拥有这个函数,即指向了window,因为在全局作用域中创建的函数都会作为window对象的方法保存
      function Person(){
         this.name="小明";
         console.log(this===window); // true
      }
      Person();//实际上相当于window.Person()
      
      var p1={
          friend:"小明",
          speak:function(){
              console.log(this===p1);//false
              console.log(this===window);//true
              console.log("我的朋友是"+this.friend);
              //我的朋友是undefined,因为此时this指向window,
              //window身上并没有friend这个属性,所以读取结果是undefined
              //speak2属于全局变量,全局变量作为window对象属性保存,所以指向window
          }
      }
      
      var speak2=p1.speak;
      speak2();//此处相当于window.speak2()
      
    • 构造函数中的this:this是新创建的那个对象
      在这里插入图片描述
  • (5)call()、apply()、bind():可以强制改变函数内部this的指向,this就是指定的那个对象;执行结果一致,如下案例this本来应该指向obj对象,但是最终指向了了obj2对象

    • call 、bind 、 apply 这三个函数的第一个参数都是 this 的指向对象,差别在于第二个以及后面的参数

    • call 的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔,直接放到后面 obj.func.call(obj2,‘成都’, … ,’)

    • apply 的所有参数都必须放在一个数组里面传进去obj.func.apply(obj2,[‘成都’, …, ])

    • bind 除了返回是函数以外,它的参数和 call 一样

      let obj = {
          name:'张三',
          age:18,
          func:function(fm, t){
              console.log(this.name + "年龄" + this.age + "来自" + fm + "去向" + t);
          }
      }
      let obj2 = {
          name:'李四',
          age:20
      }
      obj.func.call(obj2, '成都', '上海') //李四年龄20来自成都去向上海
      obj.func.apply(obj2, ['成都', '上海']); //李四年龄20来自成都去向上海
      obj.func.bind(obj2, '成都', '上海')(); //李四年龄20来自成都去向上海
      
  • (6) 关于JS中作用域的销毁和不销毁的情况总结

④ 常见的函数方法 (escape、eval、slice、splice、charCodeAt、JSON.stringify、parseInt、 String.fromCharCode())
  • (1)escape():对普通字符串编码。unescape():对字符串普通解码。encodeURIComponent():对URL进行编码,编码范围大于encodeURI()decodeURIComponent():对URL进行解码,解码范围大于decodeURI()
    在这里插入图片描述

  • (2)eval():用来执行一个字符串表达式,并返回表达式的值
    在这里插入图片描述

  • (3)JSON.stringify():类似python的json.dumps(),将json对象转换成json字符串。 JSON.parse():类似python的json.loads(),将json字符串转换成json对象
    在这里插入图片描述

  • (4)slice():不会改变原始数组,截取某段索引范围的数据 。splice():指定数组某个索引值是添加元素还是删除多少个元素,第二个位置参数数字代表删除多少个。substr(): 的参数指定的是子串的开始位置和长度
    在这里插入图片描述
    在这里插入图片描述

  • (5)parseInt():其中之一作用是将字符串中有效的整数取出来转换为Number类型
    在这里插入图片描述

  • (6)charCodeAt():返回指定位置的字符的 Unicode 编码,String.fromCharCode():返回Unicode编码对应的字符,charAt():可返回指定位置的字符
    在这里插入图片描述

  • (7) Math.random,Math.ceil,Math.floor,Math.abs,Math.log

⑤ js补环境介绍BOM、DOM
  • 如window、navigator、location、document脱离浏览器、在外部不能直接调用,当你从全局复制js,则需要补齐环境

  • (1)window是一个全局变量,由浏览器提供的,一般缺的是浏览器环境
    在这里插入图片描述

  • (2)navigator:navigator.plugins
    在这里插入图片描述在这里插入图片描述

  • (3)location
    在这里插入图片描述

  • (4)document

    document = {
        write:function(){}
    }
    document.write.toString = function(){return "function write() { [native code] }"}
    

    在这里插入图片描述

  • (5)html事件

    • 当用户点击鼠标时:登录
    • 当网页已加载时:浏览器指纹、收集是否是浏览器环境
    • 当图像已加载时:滑块图片还原、canvas
    • 当鼠标移动到元素上时:浏览器指纹、无感验证
⑥ js原型与原型链
⑦ 逻辑运算符与移位运算符
四、浏览器指纹
① 全局相关:window、document
  • window
    • window.XMLHttpRequest
    • window.ActiveXObject:用来判断浏览器是否支持ActiveX控件,只有IE才能装ActiveX插件,所以通过此方法判断是不是ie浏览器
    • window.msCrypto:IE11的Web Crypto位于window.msCrypto内部,而对于Firefox或Chrome,它可以在window.crypto中访问,Web Crypto提供了一些加密
    • window.addEventListener(event, function, useCapture):事件监听函数,第一个参数是事件的类型 (如 “click” 或 “mousedown”),第二个参数是事件触发后调用的函数,第三个参数是个布尔值用于描述事件是冒泡(false,先内后外)还是捕获,该参数是可选的
    • window.removeEventListener(event, function):移除事件监听
    • window.localStoragelocalStorage不能被爬虫抓取到
    • window.unload
    • window.top.location
    • window.setTimeout
    • window.setInterval
    • window.eval
    • escape, Number
    • decodeURIComponent
  • document
    • document.characterSetdocument.charset:返回当前文档的字符编码
② 环境相关: navigator(包括经纬度在内都在这个接口里),screen,history
③ 请求相关:XMLHttpRequest fetch worker
④ dom相关:canvas ,所有对dom节点操作,包括 jquery等三方库以及自设导入接口
⑤ 其他:caches WebGL AudioContext WebRTC
⑤ 数据库相关: Storage IndexedDB cookie
五、node之运行js小结
① node与vscode搭配模拟谷歌调试js
② aes、des、rsa、base64、md5、hash
③ node起服务运行js
六、python之执行js小结
① execjs、miniracer
② md5、base64、aes、des、rsa
③ requests请求封装
  • requests基础代码:至少要包含请求头、timeout,resp.json()
  • 请求头保持顺序不变:用session.headers=headers可以防止请求头的顺序乱掉,而requests请求(由于python字典特性)会让headers的请求头乱
  • 响应请求头快速转换,右击开发者工具,copy all as cURL, 复制到转换为python代码
④ soup、xpath
⑤ excel、word、pdf、img
⑥ mongodb、mysql
⑦ 时间戳与日期的转换格式化
⑧ urlencode、quote
  • 47
    点赞
  • 168
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值