tags: (大模型生成,存檔備查)
JavaScript 反混淆與 Python 執(zhí)行
1. JavaScript 反混淆方法
JavaScript 反混淆是一個復(fù)雜的過程,因為混淆的目的是使代碼難以閱讀和理解。以下是一些常用的反混淆方法:
1.1. 代碼美化 (Code Beautification)
混淆后的代碼通常會刪除空格、換行符,并縮短變量名。代碼美化工具可以恢復(fù)代碼的可讀性,使其更易于分析。
示例 (混淆前):
function add(a, b) { return a + b; }
示例 (混淆后):
function _0x123456(a,b){return a+b}
示例 (美化后):
function _0x123456(a, b) {
return a + b;
}
1.2. 變量和函數(shù)重命名 (Variable and Function Renaming)
混淆器通常會將有意義的變量和函數(shù)名替換為無意義的短名稱(如 _0x123456)。手動或使用工具將這些名稱改回有意義的名稱可以大大提高可讀性。
1.3. 去除死代碼和無用代碼 (Dead Code and Obfuscation-Specific Code Removal)
混淆器可能會插入不會執(zhí)行的“死代碼”或?qū)iT用于混淆的復(fù)雜邏輯。識別并移除這些代碼可以簡化程序流程。
1.4. 字符串解密 (String Decryption)
許多混淆器會將字符串進(jìn)行編碼(如 Base64、Hex、Unicode 轉(zhuǎn)義等),并在運(yùn)行時解密。你需要找到解密函數(shù)并模擬其行為來獲取原始字符串。
示例:
// 混淆代碼中可能包含的字符串解密函數(shù)
function decryptString(encodedStr) {
// 假設(shè)這里是Base64解碼邏輯
return atob(encodedStr);
}
var message = decryptString("SGVsbG8gV29ybGQ="); // "Hello World"
1.5. 控制流平坦化 (Control Flow Flattening) 反轉(zhuǎn)
控制流平坦化將代碼的線性執(zhí)行流程轉(zhuǎn)換為一個大的 switch 語句,使得難以跟蹤執(zhí)行路徑。反轉(zhuǎn)這種混淆通常需要深入理解混淆器的邏輯,并可能需要編寫腳本來重建原始控制流。
1.6. 反調(diào)試和反篡改技術(shù)繞過 (Anti-Debugging and Anti-Tampering Bypass)
一些混淆代碼會檢測調(diào)試器或代碼修改。反混淆前可能需要繞過這些保護(hù)措施。
1.7. 抽象語法樹 (AST) 轉(zhuǎn)換
對于復(fù)雜的混淆,直接操作代碼字符串可能不夠。將代碼解析成抽象語法樹 (AST),然后在 AST 層面進(jìn)行轉(zhuǎn)換和優(yōu)化,最后再生成代碼,是更強(qiáng)大的反混淆方法。
2. 通過 Python 執(zhí)行混淆的 JS 文件并獲取運(yùn)行結(jié)果
Python 本身不能直接執(zhí)行 JavaScript 代碼。你可以通過調(diào)用外部 JavaScript 運(yùn)行時(如 Node.js)或使用 Python 庫來橋接 JavaScript 環(huán)境。
2.1. 使用 subprocess 模塊調(diào)用 Node.js (推薦)
這是最常用且可靠的方法,特別是當(dāng) JavaScript 代碼依賴于 Node.js 環(huán)境或瀏覽器 API(如 document.writeln,雖然 document 對象在 Node.js 中不存在,但可以通過模擬或修改 JS 代碼來適應(yīng))。
前提: 確保你的系統(tǒng)上安裝了 Node.js。
示例 (web.js):
// web.js (假設(shè)這是混淆后的JS文件,其中包含一個簡單的輸出)
var _0x516401 = "Hello from obfuscated JS!";
console.log(_0x516401);
// 如果web.js中包含document.writeln,你需要將其替換為console.log才能在Node.js中看到輸出
// 例如,將 document.writeln('...') 改為 console.log('...')
Python 代碼 (execute_js.py):
import subprocess
import os
def execute_js_with_nodejs(js_file_path):
try:
# 確保 Node.js 可執(zhí)行文件在 PATH 中,或者提供完整路徑
# 如果 web.js 中有 document.writeln,需要先手動修改為 console.log
command = ["node", js_file_path]
# 執(zhí)行命令并捕獲標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯誤
result = subprocess.run(
command,
capture_output=True,
text=True, # 以文本模式捕獲輸出,自動解碼
check=True # 如果命令返回非零退出碼,則拋出CalledProcessError
)
print("JS Output:")
print(result.stdout)
if result.stderr:
print("JS Error (stderr):")
print(result.stderr)
return result.stdout
except subprocess.CalledProcessError as e:
print(f"Error executing JS: {e}")
print(f"Stdout: {e.stdout}")
print(f"Stderr: {e.stderr}")
return None
except FileNotFoundError:
print("Error: Node.js not found. Please ensure Node.js is installed and in your system's PATH.")
return None
# 假設(shè) web.js 位于當(dāng)前腳本的同級目錄
js_file = os.path.join(os.path.dirname(__file__), 'web.js')
# 或者提供絕對路徑
# js_file = 'f:\\python code\\爬蟲\\論壇\\web.js'
if os.path.exists(js_file):
print(f"Executing {js_file}...")
js_output = execute_js_with_nodejs(js_file)
if js_output:
print("Successfully executed JS.")
else:
print(f"Error: JS file not found at {js_file}")
2.2. 使用 PyExecJS 庫
PyExecJS 是一個 Python 庫,它會自動尋找并使用可用的 JavaScript 運(yùn)行時(如 Node.js, PhantomJS, Nashorn, JScript 等)來執(zhí)行 JavaScript 代碼。它提供了一個更高級的接口。
安裝:
pip install PyExecJS
示例 (web.js):
// web.js (假設(shè)這是混淆后的JS文件,其中包含一個簡單的輸出)
var _0x516401 = "Hello from obfuscated JS!";
// 注意:PyExecJS 默認(rèn)不會直接捕獲 console.log 的輸出,除非你配置它。
// 通常,你需要讓JS代碼返回一個值,或者通過特定的方式將輸出傳遞回Python。
// 對于簡單的值,可以直接返回。
_0x516401;
Python 代碼 (execute_js_pyexecjs.py):
import execjs
import os
def execute_js_with_pyexecjs(js_file_path):
try:
with open(js_file_path, 'r', encoding='utf-8') as f:
js_code = f.read()
# 創(chuàng)建一個JS上下文
ctx = execjs.compile(js_code)
# 執(zhí)行JS代碼并獲取返回值
# 如果JS文件中有全局變量或函數(shù),你可以通過call方法調(diào)用它們
# 例如:result = ctx.call("myFunction", arg1, arg2)
# 對于簡單的JS文件,如果最后一行是一個表達(dá)式,它的值會被返回
result = ctx.eval("_0x516401") # 假設(shè) _0x516401 是一個全局變量或表達(dá)式
print("JS Execution Result:")
print(result)
return result
except execjs.RuntimeUnavailableError:
print("Error: No JavaScript runtime found. Please install Node.js or another compatible runtime.")
return None
except Exception as e:
print(f"Error executing JS with PyExecJS: {e}")
return None
# 假設(shè) web.js 位于當(dāng)前腳本的同級目錄
js_file = os.path.join(os.path.dirname(__file__), 'web.js')
# 或者提供絕對路徑
# js_file = 'f:\\python code\\爬蟲\\論壇\\web.js'
if os.path.exists(js_file):
print(f"Executing {js_file}...")
js_output = execute_js_with_pyexecjs(js_file)
if js_output:
print("Successfully executed JS.")
else:
print(f"Error: JS file not found at {js_file}")
注意: PyExecJS 在處理 console.log 或 document.writeln 等副作用時可能不如 subprocess 直接。如果你的 JavaScript 代碼主要通過這些方式輸出,你可能需要修改 JavaScript 代碼以返回所需的值,或者使用 subprocess 方法。
3. 在線 JavaScript 反混淆工具
以下是一些常用的在線 JavaScript 反混淆工具:
- JS Beautifier: <mcurl name="https://beautifier.io/" url="https://beautifier.io/"></mcurl> (主要用于代碼美化,對輕度混淆有效)
- de4js (Online JavaScript Deobfuscator): <mcurl name="https://de4js.net/" url="https://de4js.net/"></mcurl> (支持多種混淆類型,功能較強(qiáng)大)
-
Obfuscator.io Deobfuscator: <mcurl name="https://deobfuscate.io/" url="https://deobfuscate.io/"></mcurl> (專門針對
javascript-obfuscator工具生成的代碼) - Unminify: <mcurl name="https://unminify.com/" url="https://unminify.com/"></mcurl> (一個通用的代碼美化和格式化工具)
- Online JavaScript Deobfuscator (by dcode.fr): <mcurl name="https://www.dcode.fr/javascript-deobfuscator" url="https://www.dcode.fr/javascript-deobfuscator"></mcurl> (提供多種解碼和反混淆選項)
4. 常用混淆方案及其對應(yīng)的在線反混淆網(wǎng)址
JavaScript 混淆方案多種多樣,以下是一些常見的類型及其對應(yīng)的反混淆策略或工具:
| 混淆方案類型 | 特點 | 常見混淆器/工具 | 在線反混淆網(wǎng)址/策略 |
|---|---|---|---|
| 代碼壓縮/美化 | 移除空格、換行、注釋,縮短變量名,但代碼結(jié)構(gòu)不變。 | UglifyJS, Terser, Google Closure Compiler | <mcurl name="JS Beautifier" url="https://beautifier.io/"></mcurl>, <mcurl name="Unminify" url="https://unminify.com/"></mcurl> (直接美化即可) |
| 字符串編碼 | 將字符串轉(zhuǎn)換為 Base64, Hex, Unicode 轉(zhuǎn)義等形式,運(yùn)行時解密。 | 所有主流混淆器都支持 | 通常需要找到解密函數(shù)并手動模擬,或使用 <mcurl name="de4js" url="https://de4js.net/"></mcurl> 等工具嘗試自動識別和解密。 |
| 變量/函數(shù)名重命名 | 將有意義的名稱替換為短的、無意義的名稱(如 _0x...)。 |
所有主流混淆器都支持 | 代碼美化后,手動重命名或使用某些反混淆工具的輔助重命名功能。 |
| 控制流平坦化 | 將代碼的線性執(zhí)行流程轉(zhuǎn)換為一個大的 switch 語句,通過數(shù)組索引跳轉(zhuǎn)。 |
javascript-obfuscator |
<mcurl name="Obfuscator.io Deobfuscator" url="https://deobfuscate.io/"></mcurl> (專門針對此工具),<mcurl name="de4js" url="https://de4js.net/"></mcurl> (可能支持部分) |
| 自執(zhí)行匿名函數(shù) (IIFE) | 將代碼包裹在 IIFE 中,創(chuàng)建私有作用域,防止外部訪問。 | 常見模式 | 代碼美化后,結(jié)構(gòu)會更清晰,但核心邏輯仍需進(jìn)一步反混淆。 |
| 數(shù)組混淆 | 將字符串或其他常量存儲在一個數(shù)組中,通過索引訪問。 | javascript-obfuscator |
<mcurl name="Obfuscator.io Deobfuscator" url="https://deobfuscate.io/"></mcurl>,或手動提取數(shù)組并替換索引。 |
| 調(diào)試器檢測/反調(diào)試 | 插入代碼檢測調(diào)試器,如果檢測到則阻止代碼執(zhí)行或進(jìn)入無限循環(huán)。 | 常見于惡意腳本 | 需要在調(diào)試器中繞過或禁用這些檢測點。 |
| Domain Lock / Time Lock | 代碼只在特定域名或特定時間段內(nèi)執(zhí)行。 | 自定義混淆 | 需要修改或繞過檢查邏輯。 |
重要提示:
- 沒有一個通用的反混淆工具可以解決所有類型的混淆。對于復(fù)雜的混淆,通常需要結(jié)合多種工具、手動分析和逆向工程技術(shù)。
- 在線工具可能存在安全風(fēng)險,不要上傳包含敏感信息的代碼。
- 理解混淆原理是有效反混淆的關(guān)鍵。