天天看點

百煉成鋼;JavaScript逆向九大專題詳解

作者:天天不吃飯阿

JavaScript是一種腳本語言,通常用于在Web浏覽器中編寫互動式前端應用程式。它是一種解釋性語言,可以在用戶端(浏覽器)和伺服器端(Node.js)上運作。

JavaScript可以用于建立動态網頁、Web應用程式、遊戲、移動應用程式等。它是一種弱類型語言,意味着變量的類型可以在運作時動态更改。JavaScript具有豐富的内置函數和庫,可以輕松地與HTML和CSS內建,使其成為Web開發的重要組成部分。

百煉成鋼;JavaScript逆向九大專題詳解

本系列将從九個方面講解JavaScript逆向專題

1.浏覽器調試

  • js作用域
  • 浏覽器對象屬性
  • 浏覽器控制台

2.國标雜湊演算法

  • sha1算法
  • sha256算法
  • sha512算法
  • md5
  • hmac算法
  • python和JavaScript實作

3.國标對稱加密

  • DES算法
  • AES算法
  • crypto-js子產品使用
  • pycryptodome

4. 國标非對稱加密

  • RAS算法原理
  • 非對稱特征
  • JavaScript算法還原
  • ras子產品
  • jesencrypt

5.webpack子產品打包

  • webpack打包原理
  • webpack構造形式
  • 全局導出加密函數

6.JS混淆

  • JavaScript壓縮 混淆原理
  • OB混淆特性
  • OB混淆JavaScript

7.cookie反爬處理

  • cookie加解密原理
  • cookie和session機制
  • cookie hook技巧
  • acw_sc_v2調試

8.AST抽象文法樹

  • AST 技術介紹
  • 字元串和編碼還原
  • evaluate方法學習
  • JavaScript實戰解混淆

9.JS安全産品攻防

  • 瑞數
  • acw_sc_v2
百煉成鋼;JavaScript逆向九大專題詳解

專題文章較長,建議關注+收藏,以免找不到

關注+評論(python)或者私信(python)擷取

第一章:浏覽器調試

JavaScript是一種在浏覽器中運作的腳本語言,它可以通過浏覽器對象來通路和操作浏覽器的各種屬性和方法。在進行JavaScript逆向分析時,了解浏覽器對象的屬性和方法是非常重要的。

1.JS作用域

在JavaScript中,作用域是指變量和函數的可通路範圍。JavaScript中有兩種作用域:全局作用域和局部作用域。

全局作用域是指在整個JavaScript程式中都可以通路的變量和函數,而局部作用域是指隻能在函數内部通路的變量和函數。

2.浏覽器對象屬性

在JavaScript中,浏覽器對象是指浏覽器提供的一些對象,可以通過這些對象來通路和操作浏覽器的各種屬性和方法。以下是一些常用的浏覽器對象屬性:

  • window:表示目前浏覽器視窗或标簽頁。
  • document:表示目前文檔對象。
  • location:表示目前文檔的URL。
  • navigator:表示目前浏覽器的資訊。
  • history:表示目前浏覽器的曆史記錄。

3.浏覽器控制台

浏覽器控制台是開發者工具中的一個重要組成部分,可以用來調試JavaScript代碼、檢視網絡請求、分析頁面性能等。以下是一些常用的浏覽器控制台指令:

  • console.log():用于輸出日志資訊。
  • console.dir():用于輸出對象的屬性和方法。
  • console.error():用于輸出錯誤資訊。
  • console.warn():用于輸出警告資訊。
  • console.clear():用于清空控制台。

示例代碼:

// 輸出日志資訊
console.log("Hello, world!");

// 輸出對象的屬性和方法
var obj = {name: "Tom", age: 18};
console.dir(obj);

// 輸出錯誤資訊
console.error("Something went wrong!");

// 輸出警告資訊
console.warn("This is a warning!");

// 清空控制台
console.clear();           

以上是JavaScript逆向專題之浏覽器介紹的一些基礎知識,對于進行JavaScript逆向分析的開發者來說,了解這些知識是非常重要的。

第二章:國标雜湊演算法

國标雜湊演算法是一種将任意長度的消息壓縮成固定長度摘要的算法,常用于資料完整性校驗、數字簽名等領域。本文将從sha1算法、sha256算法、sha512算法、md5算法、hmac算法以及Python和JavaScript實作六個方向詳細介紹國标雜湊演算法。

1.sha1算法

sha1算法是一種安全性較高的雜湊演算法,将任意長度的消息壓縮成160位的摘要。以下是Python實作sha1算法的示例代碼:

import hashlib

def sha1(data):
      sha1 = hashlib.sha1()
      sha1.update(data.encode('utf-8'))
      return sha1.hexdigest()           

以下是JavaScript實作sha1算法的示例代碼:

function sha1(data) {
  const sha1 = crypto.createHash('sha1');
  sha1.update(data);
  return sha1.digest('hex');
}           

2.sha256算法

sha256算法是一種更安全的雜湊演算法,将任意長度的消息壓縮成256位的摘要。以下是Python實作sha256算法的示例代碼:

import hashlib

def sha256(data):
      sha256 = hashlib.sha256()
      sha256.update(data.encode('utf-8'))
      return sha256.hexdigest()           

以下是JavaScript實作sha256算法的示例代碼:

function sha256(data) {
  const sha256 = crypto.createHash('sha256');
  sha256.update(data);
  return sha256.digest('hex');
}           

3.sha512算法

sha512算法是一種更安全的雜湊演算法,将任意長度的消息壓縮成512位的摘要。以下是Python實作sha512算法的示例代碼:

import hashlib

def sha512(data):
      sha512 = hashlib.sha512()
      sha512.update(data.encode('utf-8'))
      return sha512.hexdigest()           

以下是JavaScript實作sha512算法的示例代碼:

function sha512(data) {
  const sha512 = crypto.createHash('sha512');
  sha512.update(data);
  return sha512.digest('hex');
}           

4.md5算法

md5算法是一種較為常用的雜湊演算法,将任意長度的消息壓縮成128位的摘要。以下是Python實作md5算法的示例代碼:

import hashlib

def md5(data):
      md5 = hashlib.md5()
      md5.update(data.encode('utf-8'))
      return md5.hexdigest()           

以下是JavaScript實作md5算法的示例代碼:

function md5(data) {
  const md5 = crypto.createHash('md5');
  md5.update(data);
  return md5.digest('hex');
}           

5.hmac算法

hmac算法是一種基于哈希函數和密鑰的消息認證碼算法,常用于資料完整性校驗和數字簽名。以下是Python實作hmac算法的示例代碼:

import hmac
import hashlib

def hmac_sha256(key, data):
      hmac_sha256 = hmac.new(key.encode('utf-8'), data.encode('utf-8'), hashlib.sha256)
      return hmac_sha256.hexdigest()           

以下是JavaScript實作hmac算法的示例代碼:

function hmac_sha256(key, data) {
  const hmac_sha256 = crypto.createHmac('sha256', key);
  hmac_sha256.update(data);
  return hmac_sha256.digest('hex');
}           

6.Python和JavaScript實作

以下是Python和JavaScript實作sha256算法的示例代碼:

Python:

import hashlib

def sha256(data):
      sha256 = hashlib.sha256()
      sha256.update(data.encode('utf-8'))
      return sha256.hexdigest()           

JavaScript:

javascript
function sha256(data) {
  const sha256 = crypto.createHash('sha256');
  sha256.update(data);
  return sha256.digest('hex');
}           

以上是國标雜湊演算法的介紹,包括sha1算法、sha256算法、sha512算法、md5算法、hmac算法以及Python和JavaScript實作。在實際應用中,需要根據具體需求選擇合适的雜湊演算法。

第三章:國标對稱加密

國标對稱加密算法是指由中國國家密碼管理局釋出的加密算法标準,包括DES算法、AES算法等。在JavaScript逆向中,了解這些算法的原理和使用方法是非常重要的。

1.DES算法

DES算法是一種對稱加密算法,密鑰長度為56位,分為加密和解密兩個過程。在JavaScript中,可以使用crypto-js子產品進行DES加密和解密操作。

加密示例代碼:

var key = CryptoJS.enc.Utf8.parse("1234567890123456");
var iv = CryptoJS.enc.Utf8.parse("1234567890123456");
var encrypted = CryptoJS.DES.encrypt("Hello World", key, {
   iv: iv,
   mode: CryptoJS.mode.CBC,
   padding: CryptoJS.pad.Pkcs7
});
console.log(encrypted.toString());           

解密示例代碼:

var key = CryptoJS.enc.Utf8.parse("1234567890123456");
var iv = CryptoJS.enc.Utf8.parse("1234567890123456");
var decrypted = CryptoJS.DES.decrypt(encrypted, key, {
   iv: iv,
   mode: CryptoJS.mode.CBC,
   padding: CryptoJS.pad.Pkcs7
});
console.log(decrypted.toString(CryptoJS.enc.Utf8));           

2.AES算法

AES算法是一種對稱加密算法,密鑰長度可以是128位、192位或256位,分為加密和解密兩個過程。在JavaScript中,可以使用crypto-js子產品進行AES加密和解密操作。

加密示例代碼:

var key = CryptoJS.enc.Utf8.parse("12345678901234567890123456789012");
var iv = CryptoJS.enc.Utf8.parse("1234567890123456");
var encrypted = CryptoJS.AES.encrypt("Hello World", key, {
   iv: iv,
   mode: CryptoJS.mode.CBC,
   padding: CryptoJS.pad.Pkcs7
});
console.log(encrypted.toString());           

解密示例代碼:

var key = CryptoJS.enc.Utf8.parse("12345678901234567890123456789012");
var iv = CryptoJS.enc.Utf8.parse("1234567890123456");
var decrypted = CryptoJS.AES.decrypt(encrypted, key, {
   iv: iv,
   mode: CryptoJS.mode.CBC,
   padding: CryptoJS.pad.Pkcs7
});
console.log(decrypted.toString(CryptoJS.enc.Utf8));           

3.crypto-js子產品使用

crypto-js是一個JavaScript加密庫,支援多種加密算法,包括DES、AES、SHA-1、SHA-256等。在使用之前,需要先引入crypto-js庫。

<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>           

4.pycryptodome

pycryptodome是一個Python加密庫,支援多種加密算法,包括DES、AES、SHA-1、SHA-256等。在使用之前,需要先安裝pycryptodome庫。

pip install pycryptodome           

使用示例:

from Crypto.Cipher import AES

key = b'1234567890123456'
iv = b'1234567890123456'
cipher = AES.new(key, AES.MODE_CBC, iv)
msg = b'Hello World'
encrypted = cipher.encrypt(msg)
print(encrypted)

cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted = cipher.decrypt(encrypted)
print(decrypted)           

第四章:國标非對稱加密

1.RSA算法原理:

RSA算法是一種非對稱加密算法,它的安全性基于大數分解的困難性。RSA算法的核心是選擇兩個大質數p和q,計算它們的乘積n=pq,然後選擇一個整數e,使得1<e<φ(n)且e與φ(n)互質,其中φ(n)=(p-1)(q-1)。接着計算d,使得d*e mod φ(n)=1,d稱為e的模反元素。公鑰為(n,e),私鑰為(n,d)。

2.非對稱特征:

非對稱加密算法有兩個密鑰,一個是公鑰,一個是私鑰。公鑰可以公開,任何人都可以使用公鑰對資料進行加密,但隻有私鑰的持有者才能解密。非對稱加密算法的安全性基于數學難題,如大數分解、離散對數等,這些問題在計算機領域内是非常困難的。

3.JavaScript算法還原:

在JavaScript中,可以使用BigInt類型來處理大數運算。首先,需要實作一個函數來判斷一個數是否為質數:

function isPrime(n) {
   if (n <= 1) {
     return false;
   }
   for (let i = 2; i <= Math.sqrt(n); i++) {
     if (n % i === 0) {
      return false;
     }
   }
   return true;
}           

接着,可以實作一個函數來生成大質數:

function generatePrime(bits) {
   let p;
   do {
     p = BigInt(Math.floor(Math.random() * 2 ** bits));
   } while (!isPrime(p));
   return p;
}           

然後,可以實作一個函數來計算兩個數的最大公約數:

function gcd(a, b) {
   if (b === 0) {
     return a;
   }
   return gcd(b, a % b);
}           

接着,可以實作一個函數來計算兩個數的模反元素:

function modInverse(a, m) {
   let [x, y, u, v] = [0n, 1n, 1n, 0n];
   while (a !== 0n) {
       let q = m / a;
       let r = m % a;
       let m1 = x - u * q;
       let m2 = y - v * q;
       m = a;
       a = r;
       x = u;
       y = v;
      u = m1;
      v = m2;
  }
  return x < 0n ? x + m : x;
}           

最後,可以實作一個函數來生成RSA密鑰對:

function generateRSAKeyPair(bits) {
   let p = generatePrime(bits / 2);
   let q = generatePrime(bits / 2);
   let n = p * q;
   let phi = (p - 1n) * (q - 1n);
   let e = 65537n;
   let d = modInverse(e, phi);
   return {
      publicKey: [n, e],
      privateKey: [n, d],
  };
}           

4.ras子產品

在Node.js中,可以使用crypto子產品來實作RSA加密和解密。首先,需要生成RSA密鑰對:

const { generateKeyPairSync } = require('crypto');

const { publicKey, privateKey } = generateKeyPairSync('rsa', {
   modulusLength: 2048,
   publicKeyEncoding: {
       type: 'spki',
      format: 'pem',
   },
   privateKeyEncoding: {
      type: 'pkcs8',
      format: 'pem',
  },
});           

接着,可以使用公鑰對資料進行加密:

const crypto = require('crypto');

const data = 'hello world';
const encrypted = crypto.publicEncrypt(publicKey, Buffer.from(data));
console.log(encrypted.toString('base64'));           

使用私鑰對資料進行解密:

const decrypted = crypto.privateDecrypt(privateKey, encrypted);
console.log(decrypted.toString());           

5.jesencrypt

jesencrypt是一個基于JavaScript實作的RSA加密庫,可以在浏覽器中使用。它的使用方法與Node.js中的crypto子產品類似。首先,需要生成RSA密鑰對:

const { generateKeyPair } = require('jesencrypt');

generateKeyPair().then(({ publicKey, privateKey }) => {
   console.log(publicKey);
   console.log(privateKey);
});           

接着,可以使用公鑰對資料進行加密:

const { encrypt } = require('jesencrypt');

const data = 'hello world';
encrypt(data, publicKey).then((encrypted) => {
   console.log(encrypted);
});           

使用私鑰對資料進行解密:

const { decrypt } = require('jesencrypt');

const encrypted = '...';
decrypt(encrypted, privateKey).then((decrypted) => {
   console.log(decrypted);
});           

第五章:webpack子產品打包

1.webpack打包原理

Webpack是一個子產品打包工具,它可以将多個子產品打包成一個檔案,以便于在浏覽器中使用。Webpack的打包原理是将所有的子產品打包成一個或多個bundle檔案,這些檔案可以是JavaScript、CSS、圖檔等資源檔案。

Webpack的打包過程分為三個階段:

  • 解析子產品:Webpack會從入口檔案開始,遞歸地解析所有的依賴子產品,形成一個依賴樹。
  • 編譯子產品:Webpack會将每個子產品編譯成一個可執行的JavaScript代碼塊。
  • 輸出檔案:Webpack會将所有的JavaScript代碼塊合并成一個或多個bundle檔案,以便于在浏覽器中使用。

2.webpack構造形式

Webpack的構造形式分為兩種:

  • 指令行形式:通過指令行輸入webpack指令,可以将所有的子產品打包成一個或多個bundle檔案。
  • 配置檔案形式:通過配置檔案webpack.config.js,可以對Webpack進行更加詳細的配置,包括入口檔案、輸出檔案、子產品解析規則、插件等。

3.全局導出加密函數

在Webpack中,可以通過全局導出加密函數來保護JavaScript代碼的安全性。全局導出加密函數的原理是将JavaScript代碼通過加密算法進行加密,然後将加密後的代碼作為一個函數的傳回值,這個函數可以在全局範圍内調用,進而實作對JavaScript代碼的保護。

全局導出加密函數的實作步驟如下:

  • 将需要加密的JavaScript代碼通過加密算法進行加密。
  • 将加密後的代碼作為一個函數的傳回值。
  • 将這個函數通過module.exports導出,進而可以在全局範圍内調用。

示例代碼如下:

const encrypt = require('encrypt');

const code = 'console.log("Hello, World!");';

const encryptedCode = encrypt(code);

module.exports = function() {
   return eval(encryptedCode);
};           

在上面的代碼中,encrypt函數是一個加密函數,它将JavaScript代碼進行加密,并傳回加密後的代碼。然後,将這個加密後的代碼通過`module.exports`導出,進而可以在全局範圍内調用。最後,通過eval函數執行加密後的代碼。

第六章:JS混淆

JavaScript混淆是一種将JavaScript代碼進行壓縮和混淆的技術,旨在增加代碼的複雜度和難度,使得代碼難以被逆向工程師或黑客破解和篡改。下面從JavaScript壓縮混淆原理、OB混淆特性和OB混淆JavaScript三個方向詳細介紹。

1.JavaScript壓縮混淆原理

JavaScript壓縮混淆的目的是為了減小檔案體積,提高加載速度,同時也可以增加代碼的安全性,防止被惡意篡改或者盜用。JavaScript壓縮混淆的原理主要是通過删除無用的空格、注釋、換行符等來減小檔案體積,同時通過重命名變量、函數名等來增加代碼的難度,使得代碼難以被了解和修改。

2.OB混淆特性

OB混淆是一種常見的JavaScript混淆方式,它的特點是将JavaScript代碼中的變量、函數名等進行随機重命名,使得代碼難以被了解和修改。OB混淆的主要特性包括:

  • 變量、函數名随機重命名:OB混淆會将JavaScript代碼中的變量、函數名等進行随機重命名,使得代碼難以被了解和修改。
  • 字元串加密:OB混淆會将JavaScript代碼中的字元串進行加密,使得代碼難以被了解和修改。
  • 代碼結構混淆:OB混淆會将JavaScript代碼中的結構進行混淆,使得代碼難以被了解和修改。

3.OB混淆JavaScript三個方向詳解

變量、函數名随機重命名

OB混淆會将JavaScript代碼中的變量、函數名等進行随機重命名,使得代碼難以被了解和修改。這個過程可以通過以下步驟實作:

  • 周遊JavaScript代碼,擷取所有的變量、函數名等辨別符。
  • 生成随機的辨別符名稱,并将原有的辨別符名稱替換為随機名稱。
  • 更新代碼中所有引用該辨別符的地方,将其替換為新的随機名稱。

字元串加密

OB混淆會将JavaScript代碼中的字元串進行加密,使得代碼難以被了解和修改。這個過程可以通過以下步驟實作:

  • 周遊JavaScript代碼,擷取所有的字元串。
  • 将字元串進行加密,可以使用常見的加密算法,如Base64、AES等。
  • 更新代碼中所有引用該字元串的地方,将其替換為加密後的字元串。

代碼結構混淆

OB混淆會将JavaScript代碼中的結構進行混淆,使得代碼難以被了解和修改。這個過程可以通過以下步驟實作:

  • 将JavaScript代碼進行分塊,将每個塊中的代碼進行随機排序。
  • 将每個塊中的代碼進行随機組合,生成新的代碼結構。
  • 更新代碼中所有引用該塊的地方,将其替換為新的代碼結構。

總之,OB混淆是一種常見的JavaScript混淆方式,可以有效地增加代碼的安全性,防止被惡意篡改或者盜用。但是,OB混淆也會增加代碼的複雜度和維護成本,是以需要在實際應用中進行權衡。

第七章:cookie反爬處理

在爬蟲領域,網站通常會使用cookie來進行反爬處理,以識别爬蟲并限制其通路。是以,了解cookie反爬處理的原理和技巧對于爬蟲開發者來說非常重要。

1.cookie加解密原理

在HTTP協定中,cookie是通過Set-Cookie和Cookie頭來傳遞的。網站通常會對cookie進行加密或者編碼,以防止被惡意篡改或者竊取。常見的加密方式包括Base64、MD5、SHA1等。

2.cookie和session機制

cookie和session是Web開發中常用的兩種機制。cookie是一種存儲在用戶端的小型文本檔案,用于存儲使用者的身份資訊、浏覽曆史等。而session則是一種在伺服器端存儲的資料結構,用于存儲使用者的會話資訊。通常情況下,伺服器會将session ID存儲在cookie中,以便在後續的請求中識别使用者身份。

3.cookie hook技巧

cookie hook是一種常用的反爬技巧,它可以通過修改cookie的值來繞過網站的反爬機制。常見的cookie hook技巧包括:

  • 修改cookie的值,以繞過網站的限制。
  • 删除cookie,以避免被網站識别為爬蟲。
  • 僞造cookie,以模拟正常使用者的行為。

4.acw_sc_v2調試

在進行cookie反爬處理時,經常會遇到acw_sc_v2這個參數。這個參數是阿裡雲CDN的一種反爬機制,用于檢測請求是否來自于正常的浏覽器。如果請求中沒有正确的acw_sc_v2參數,CDN會傳回403錯誤。

為了解決這個問題,我們需要了解acw_sc_v2的生成方式和調試方法。

acw_sc_v2的生成方式

acw_sc_v2參數的生成方式比較複雜,需要使用一些加密算法。一般來說,生成acw_sc_v2參數需要以下步驟:

  • 擷取目前時間戳,機關為毫秒。
  • 将時間戳轉換為16進制字元串,并在前面補0,使其長度為13位。
  • 将13位時間戳字元串和一個随機字元串拼接起來,得到一個新的字元串。
  • 對新字元串進行MD5加密,得到一個32位的字元串。
  • 将32位字元串的前6位和後6位分别取出來,得到兩個6位的字元串。
  • 将兩個6位字元串拼接起來,得到12位的字元串,即為acw_sc_v2參數的值。

acw_sc_v2的調試方法

在進行cookie反爬處理時,我們需要調試acw_sc_v2參數的生成過程,以便正确地生成該參數。下面介紹幾種調試方法:

  • 使用浏覽器開發者工具

在浏覽器中打開目标網站,按下F12鍵打開開發者工具。在Network頁籤中找到一個請求,檢視該請求的請求頭資訊。一般來說,acw_sc_v2參數會出現在請求頭的Cookie字段中。将該Cookie字段複制下來,然後使用MD5加密算法對其進行加密,得到32位的字元串。最後按照上述步驟,将32位字元串轉換為acw_sc_v2參數的值。

  • 使用Python腳本

使用Python腳本可以自動化生成acw_sc_v2參數。下面是一個Python腳本示例:

import time
import random
import hashlib

def generate_acw_sc_v2():
      timestamp = str(int(time.time() * 1000))
      random_str = ''.join(random.sample('abcdefghijklmnopqrstuvwxyz0123456789', 6))
      new_str = timestamp + random_str
      md5_str = hashlib.md5(new_str.encode('utf-8')).hexdigest()
      acw_sc_v2 = md5_str[:6] + md5_str[-6:]
      return acw_sc_v2           

該腳本會生成一個随機的acw_sc_v2參數值。

  • 使用線上工具

在網上可以找到一些線上工具,可以幫助我們生成acw_sc_v2參數

第八章:AST抽象文法樹

AST(Abstract Syntax Tree)抽象文法樹是一種将代碼轉換為樹形結構的資料結構,它可以幫助我們更好地了解代碼的結構和含義。在JavaScript中,AST可以用于代碼分析、代碼優化、代碼混淆等方面。

下面從AST技術介紹、字元串和編碼還原、evaluate方法學習、JavaScript實戰解混淆幾個方向詳細介紹AST的應用。

1.AST技術介紹

AST是一種将代碼轉換為樹形結構的資料結構,它可以幫助我們更好地了解代碼的結構和含義。在JavaScript中,AST可以用于代碼分析、代碼優化、代碼混淆等方面。

AST的生成過程一般分為三個步驟:詞法分析、文法分析和AST建構。詞法分析将代碼分解為一個個的詞法單元,文法分析将詞法單元組合成文法樹,AST建構則是将文法樹轉換為AST。

2.字元串和編碼還原

在JavaScript中,代碼經過壓縮和混淆後,常常會将變量名、函數名等替換為無意義的字元串或者編碼。這時候,我們需要将這些字元串和編碼還原為原來的變量名、函數名等。

字元串還原可以通過正規表達式或者字元串替換的方式實作。編碼還原則需要根據具體的編碼方式進行解碼,常見的編碼方式有Unicode編碼、Base64編碼等。

AST字元串和編碼還原是指将AST轉換為字元串形式,并将字元串還原為AST的過程。這個過程在JavaScript代碼混淆和反混淆中非常重要。

下面是一個簡單的示例,展示如何将AST轉換為字元串:

const esprima = require('esprima');

const code = 'function add(a, b) { return a + b; }';
const ast = esprima.parseScript(code);

const astString = JSON.stringify(ast, null, 2);
console.log(astString);           

在這個示例中,我們使用了esprima庫将代碼解析為AST。然後,我們使用JSON.stringify方法将AST轉換為字元串,并将其列印到控制台上。

輸出結果如下:

{
   "type": "Program",
   "body": [
      {
        "type": "FunctionDeclaration",
         "id": {
            "type": "Identifier",
            "name": "add"
        },
       "params": [
           {
              "type": "Identifier",
              "name": "a"
           },
           {
              "type": "Identifier",
              "name": "b"
           }
   ],
   "body": {
       "type": "BlockStatement",
       "body": [
           {
              "type": "ReturnStatement",
              "argument": {
                  "type": "BinaryExpression",
                  "operator": "+",
                  "left": {
                     "type": "Identifier",
                     "name": "a"
                  },
                  "right": {
                     "type": "Identifier",
                     "name": "b"
                  }
              }
          }
       ]
     }
    }
   ],
  "sourceType": "script"
}           

我們可以看到,AST被轉換為了一個JSON字元串,其中每個節點都有一個type屬性,用于表示節點的類型。例如,FunctionDeclaration表示函數聲明,Identifier表示辨別符,BinaryExpression表示二進制表達式等等。

接下來,我們将介紹如何将字元串還原為AST。

const esprima = require('esprima');

const astString = `{
   "type": "Program",
   "body": [
      {
         "type": "FunctionDeclaration",
         "id": {
            "type": "Identifier",
            "name": "add"
         },
         "params": [
            {
            "type": "Identifier",
             "name": "a"
       },
      {
           "type": "Identifier",
           "name": "b"
      }
    ],
    "body": {
       "type": "BlockStatement",
       "body": [
          {
            "type": "ReturnStatement",
            "argument": {
            "type": "BinaryExpression",
            "operator": "+",
            "left": {
              "type": "Identifier",
              "name": "a"
            },
            "right": {
            "type": "Identifier",
            "name": "b"
           }
        }
      }
    ]
   }
  }
 ],
 "sourceType": "script"
}`;

const ast = JSON.parse(astString);
console.log(ast);           

在這個示例中,我們将AST字元串直接指派給一個變量。然後,我們使用JSON.parse方法将字元串轉換為AST對象,并将其列印到控制台上。

輸出結果與之前的示例相同,不再贅述。

總的來說,AST字元串和編碼還原是JavaScript代碼混淆和反混淆中非常重要的一環。掌握這個技術可以幫助我們更好地了解和處理混淆代碼。

3.evaluate方法學習

evaluate方法是JavaScript中的一個内置函數,它可以将字元串作為代碼執行。在AST中,我們可以通過evaluate方法執行AST節點中的代碼。

evaluate方法的使用非常簡單,隻需要将AST節點中的代碼轉換為字元串,然後傳入evaluate方法即可。需要注意的是,由于evaluate方法會執行任意的代碼,是以在使用時需要謹慎,避免執行惡意代碼。

4.JavaScript解混淆

在實際開發中,我們常常會遇到代碼混淆的情況。代碼混淆可以通過将代碼壓縮、變量名替換、字元串編碼等方式實作,進而使代碼難以閱讀和了解。

在解混淆過程中,AST可以幫助我們更好地了解代碼的結構和含義,進而更容易地還原出原始代碼。常見的解混淆方法包括字元串和編碼還原、變量名還原、函數還原等。

總之,AST是一種非常有用的技術,它可以幫助我們更好地了解和處理JavaScript代碼。在實際開發中,我們可以通過AST實作代碼分析、代碼優化、代碼混淆等功能,進而提高代碼的品質和安全性。

第九章:JS安全産品攻防

1.瑞數

2.acw_sc_v2

這兩個子產品,之前出了視訊,就不在贅述了,建議找到視訊自己觀看

專題文章較長,建議關注+收藏,以免找不到

關注公衆号擷取電子版+視訊:

關注+評論(python)或者私信(python)擷取

繼續閱讀