2_js逆向学习笔记-js基础

js基础

js的组成:

  • EDMAScript:制定了一些JavaScript的标准

  • DOM:文档对象模型:DOM可以把html看作文档树,通过DOM提供的api可以操作这个文档树

  • BOM:浏览器对象模型:通过BOM可以操作浏览器窗口比如弹出框、控制浏览器跳转

BOM:

window对象:不但充当全局作用域,而且表示浏览器窗口,它有如何属性和方法:

window对象的属性:

  • closed:窗口是否已被关闭,值为true或者false
  • defaultStatus:设置或返回窗口状态栏的默认文本
  • innerHeight、innerWidth:返回窗口的文档县市区的高度、宽度
  • length:设置或返回窗口的数量
  • name:设置或返回窗口的名称,绝大数窗口都是没设置的
  • opener:返回创建此窗口的窗口的引用,并不是此窗口的引用
  • outerHeight:返回窗口的外部高度,包含工具条与滚动条,ie没有此属性
  • outerWidth: 返回窗口的外部宽度,包含工具条与滚动条,ie没有此属性

window对象的方法:

js的常规语法

特点:

  • 区分大小写
  • 变量类型为弱类型
  • 尾部分号可有可无,最好写上
  • 单行注释用:// 多行注释:/* */
  • 代码块用{ }

变量的命名规则:

  • 包含数字、字母、下划线、$
  • 不能以数字开头
  • 不能与js中的关键字、保留字相同
  • 也可以是unicode字符

变量类型

  • 整型

  • 浮点型

  • null

  • undefined

变量声明:

// 变量可以声明的同时并赋值
var a = 1;

// 变量也可以先声明,然后再赋值
var a;
a = 1;

// 在对变量赋值的时候也可以不用var来进行声明变量,不过这种方式会污染全局变量
a = 1; 

// 不可以不使用var声明变量的同时也不对变量赋值
a;  // 错误写法


// 可以同时声明多个变量, 不同变量之间使用,号进行分隔
var a = 1, b = 2;

// 或者下面这样
var a, b;
a = 1;
b = 2;

// 变量可以在使用之后再进行声明,因为javascript中有个变量提升的问题:所有的变量声明(仅仅是var a,赋值操作并不会进行提升)都会被提升到函数的最顶端
console.log(a);
var a = 1;


ES6:
let关键字:
// 在es6之前是没有块级作用域的,在es6中如果让某个变量具有块级作用域可以使用关键字let
if(true){
    let a = 1; // 使用var 声明的变量不具有块级作用域,在花括号外部也是可以使用的,另外需要注意的是1.使 		       // 用let声明的全局变量不会绑定到window上,不能使用window.变量名的方式来进行访问 2.在
    		// 相同作用域内不能使用let 重置var 声明的变量,反过来亦然,是会报错的
    
}
console.log(a)  //报错

const关键字:
// const关键字用来声明常量,声明的同时,必须对常量赋值,声明之后,不能再次对常量进行赋值,并且具有块级作用域
const b = 1;
b = 2 // 报错

运算符:

// 赋值运算符
var a = 1;

// 加法运算符
a = a + '2'  //  "12"

a = a + true  // "12true"

// ===  和 ==
// ===:是全等的意思,不仅会比较值而且会比较类型 而 == 仅会比较值而不会比较类型 1 == "1"得到的就是true
1 === "1" // false
1 == "1"  // true
undefined == null; // true
undefined === null; // false


// 自增运算符
a ++  // 自增1
b --  // 自减1

// 三元运算符
var a = 1?2:3;  // 如果1为真的话,那么将2赋值给a不然将3赋值给a

// && 与运算符可以调整赋值
var a = 1;
false && (a=2);  // a = 1

var a = 1;
true && (a=2);  // a = 2

// 查看变量类型
typeof a  // number

js的一些特殊语法:

// 下面不会报错,但是不建议这样书写代码,因为在javascript中,会根据上号 如果能和下行组成完整的语句,会
// 自动填充;,但是有两种情况例外,那就是return, continue, break等,特别是return value必须在同一
// 行不然,return的是undefined,其二就是 ++ ,--运算符,当作为后缀运算符的时候,必须和前面的变量在同一
// 行

var a
a 
= 
1  // 会被解析成 var a; a = 1;


// 会被解析成function a(){return; true;}
function a(){
    return 
    true
}

// 会被解析成 c; ++a;
c
++
a

// 对变量进行多次声明,不会丢失变量保存的值
var carname = "BWM";
var carname;
carname // "BWM"
// 这种方式结果也是'BWM'
var carname;
var carname = "BWM";
carname // "BWM"

// 不能同时将生命的多个变量赋值给同一个值
var a, b, c = 1;
a //undefined
b //undefined
c // 1

js逻辑控制语句

//if语句
if(条件){条件为真执行的代码}else{条件不成立执行的代码}

// while语句
while(条件){条件成立执行的代码}

//do   while语句:先循环一次,在判断条件
do{先执行的代码}while(条件){条件满足执行的代码}


// for循环
for(初始化语句;逻辑值;每次循环后执行的语句){逻辑值成立,运行此处代码}
// for 循环在js混淆中的使用
 

// 使用for循环知识常用的混淆手段如下:
function xx(){
    return "hello world"
}
// 注意for循环中的第一个括号中的内容可能非常复杂,因此需要特别注意,可能有上千行代码
for(var a = 1, b=xx(); a< 5;a++){
    console.log(b)
}


// js逆向必了解的知识点
var a = (1, function(){
    return "hello world"
})  // 这种有括号中间用逗号分隔的,a就是最后表达式执行的结果,在这里就是最后的那个函数


var a  = function(){
    return function(x){
        return x + "hello world"
    }
}

var d = (1, 3, a())("fdsjf");
// d的值就是fdsjfhello world

js数据类型

  • 简单数据类型(值类型):String、Number、Null 、Boolean、Undefined、Symbol(ES6引入的一种的新的原始数据类型,表示独一无二的值)
  • 复杂数据类型(引用数据类型):Object、Array、Function
// 数组

//创建数组的第一种方式
var cars = new Array();  // var cars = new Array("Saab", "Volvo", "BWM")也是可以的
cars[0] = 'Saab';
cars[1] = 'Volvo';
cars[2] = 'BMW';
// 创建数组的第二种方式:
var cars = ["Saab", "Volvo", "BWM"]

//javascript对象:object:是拥有属性和方法的数据

// Javascript对象:一对花括号分隔,对象的属性和值以键值对的形式定义,属性由逗号进行分隔
var person = {firstname:"John", lastname:"Doe", id:4445};
typeof person  // object
// object取值方式有以下两种
person.lastname
person["firstname"]
x// 对象的方法
var person = {    
    firstname:"zheng",     
    name:function(){console.log("hello world")}};
// 访问方法的方式和访问属性的方式相同
person["name"]()
person.name()


// 函数
function functionname(参数1, 参数2){
    调用参数执行的代码
    return // 返回指定的值到函数调用处
};
// 函数的调用方式
functionname();

注意:

  • 在函数内部不使用var,直接对不存在的变量进行赋值,实际上创建的是一个全局变量,会自动绑定的到全局变量window上。并且是可以使用关键字delete进行删除, 使用var声明的全局变量是不可以进行删除的。

作用域

function xx(){ 
    var a = "我是局部变量";  // a为局部变量,只能在函数中使用
    return a;  
}

xx()
console.log(a) // a is not defined
function xx(){ 
    a = "我是全局变量";  // a为局部变量,只能在函数中使用
    return a;  
}

xx() // 如果没有这一行的话,那么下面仍然会报错,因为那时候a仍然没有被定义
console.log(a) // 我是全局变量

变量的生命周期

  • 局部变量在函数执行完成之后销毁
  • 全局变量在窗口关闭之后销毁

自执行函数

  • js加载的时候就会自动执行
// 自执行函数的定义
!(function(){  // 这个感叹号不写也是可以的,但是标准的自执行函数是需要添加叹号的
    要执行的代码;
})() // 这个函数就会在js自动加载的时候自动执行

// 这也是自执行函数
!function(){
	console.log("hello world");
}()

// 如何在外部调用函数内部定义的函数,利用自执行函数
var xx_
!(function(){
    function xx(){
        console.log("inner function")
    };
    xx_ = xx;
})()

xx_() // inner function

js事件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- this指的就是这个标签对象 -->
    <button onclick="this.innerHTML=Date()">这是现在的时间:</button>
</body>
</html>

浏览器环境:网站js有可能会利用这个浏览器环境做检测,是不是真的在浏览器之中

  • 脱离了浏览器的时候在外部不能直接调用

  • window:window是一个全局变量,浏览器提供的,他保存了浏览器环境、引擎的环境、自己写的代码(全局变量)

    • window.location:返回对当前窗口关联的位置对象的引用
      • window.location.href:返回当前页面的url地址
    • window.navigator:对象包含有关访问者浏览器的信息。
//这个操作叫做补头,主要用来过检测
window = {
    location:{
        href:"chrome://newtab"
    }
}

html渲染环境

  • window中的引擎环境又包含了js引擎环境也就是v8引擎,有时候也是网页中也需要html渲染环境,这时候我们仍然需要补html渲染环境
  • document:也是一个全局变量,如果缺少的话,仍然需要进行补头-补齐缺失的环境
    • document.write(content)会将content写入到html输出流中,如果页面已经加载完成之后,执行document.write(content)那么会将页面的html的内容覆盖

使用document来操作dom的方式

// 使用document来替换标签的包裹的内容
document.getElementById("标签的id名称").innerHTML = "要设置的值"
// 使用document来替换标签属性的值
document.getElementByid("标签的id名称").src(属性名) = "属性值"
// 使用document改变html的样式
document.getElementById("标签的id名称").style.color = "red";
// 小知识:字符串的match方法
"hello world".match("hello")  // 在指定的字符串中查找指定的值,如果没找到返回null,找到了,返回一个数组
  • 需要补的内容主要是:点击事件 滑动事件(滑块)
//当我们脱离浏览器单独执行某个js的时候,有可能就会被检测,这时候我们需要进行补头
document = {
    write:function(){}
}
document.write.toString = function(){
    return "function write() { [native code] }"
}  // hook:替换原有方法来执行代码

// js代码中有这样一段,脱离浏览器的时候就会报错, 为了这句代码的正确执行,需要进行上述操作
document.write + ""   // document.write + "" 实际上就是调用document.write.toString()方法

一些事件完成时在js中可能处理的事情:

1、当用户点击鼠标时:登录

2、当网页已加载的时候:可能会生成浏览器指纹,检测是不是出于浏览器环境,如果不是处于浏览器环境的话,可能会让你卡死在桌面上

3、当图像已经加载的时候:可能canvas在不同的机器上可能生成不同的图片从而做浏览器指纹,或者在滑块验证码中js在检测到你图片已经加载完成之后把乱码之后的图片进行图片还原

4、当鼠标移动到元素上时:浏览器指纹,无感校验:当你鼠标移动到元素上时记录鼠标轨迹发给后端做校验

5、当输入字段被改变时:

6:当提交html表单时:

7:当用户触发按键时:

浏览器插件环境(不需要进行补全)

// js代码获取浏览器插件
navigator.plugins  // 获取浏览器插件数组列表

网站可能会根据几个主要插件判断是否处于浏览器环境之中。

javascript中的this指向:

在 JavaScript 中 this 不是固定不变的,它会随着执行环境的改变而改变。

  • 在方法中,this 表示该方法所属的对象。
  • 如果单独使用,this 表示全局对象window。
  • 在函数中,this 表示全局对象window。
  • 在函数中,在严格模式下,this 是未定义的(undefined)。
  • 在事件中,this 表示接收事件的元素。
  • 类似 call() 和 apply() 方法可以将 this 引用到任何对象。
  • es6中的箭头函数的this与外层this指向一致
var person1 = {
  fullName: function() {
    return this.firstName + " " + this.lastName;
  }
}
var person2 = {
  firstName:"John",
  lastName: "Doe",
}
person1.fullName.call(person2);  // 返回 "John Doe"

void关键字

// void(表达式)  // 计算指定的表达式,不会返回任何值
var a = 1;
void(a = 2);  // undefined
a  // 2

//格式大致有如下几种:
void(func());
javascript: void(func())
void func()
javascript:void func()

href="#"与href=“javascript:void(0)的区别:

  • # 包含了一个位置信息,默认的锚是**#top** 也就是网页的上端。而javascript:void(0), 仅仅表示一个死链接。在页面很长的时候会使用 # 来定位页面的具体位置,格式为:# + id,如果你要定义一个死链接请使用javascript:void(0)
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值