首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

VBScript 微軟 Script Encoder 加解密完整實現:Encoder 物件編碼與手工解碼算法還原

     編輯:更多程式設計知識

微軟 Scripting.Encoder 物件提供 VBScript/JScript 原始碼「加密」(實為編碼混淆),生成 .vbe/.jse 檔案。本文提供官方編碼器封裝腳本,並深度解析手工解碼算法還原原始碼的完整 VBScript 實現。

一、官方編碼器使用(生成 .vbe)

' === encode.vbs:將 .vbs 編碼為 .vbe ===
If LCase(Right(WScript.FullName, 11)) = "wscript.exe" Then WScript.Quit(0)

If WScript.Arguments.Count < 2 Then
    WScript.Echo "Usage: cscript //nologo encode.vbs source.vbs target.vbe"
    WScript.Quit(1)
End If

srcFile = WScript.Arguments(0)
dstFile = WScript.Arguments(1)

Set fso = CreateObject("Scripting.FileSystemObject")
Set src = fso.OpenTextFile(srcFile, 1) ' ForReading
content = src.ReadAll
src.Close

' 核心:Scripting.Encoder.EncodeScriptFile
encoded = CreateObject("Scripting.Encoder").EncodeScriptFile(".vbs", content, 0, "VBScript")

fso.OpenTextFile(dstFile, 2, True).Write encoded ' ForWriting, Create
WScript.Echo "Encoded: " & dstFile

使用方式

cscript //nologo encode.vbs myscript.vbs myscript.vbe

二、手工解碼算法完整實現

解碼器不依賴 Scripting.Encoder,純 VBScript 還原編碼邏輯,適用於無法使用 COM 物件的環境。

' === decode.vbs:將 .vbe 還原為原始碼 ===
Option Explicit

Dim oArgs, srcFile
Set oArgs = WScript.Arguments
If oArgs.Count = 0 Then
    WScript.Echo "Usage: cscript //nologo decode.vbs encoded.vbe"
    WScript.Quit(1)
End If
srcFile = oArgs(0)

Dim fso, file, content
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FileExists(srcFile) Then
    WScript.Echo "File not found: " & srcFile
    WScript.Quit(2)
End If

Set file = fso.OpenTextFile(srcFile, 1)
content = file.ReadAll
file.Close

' === 核心解碼邏輯 ===
Const TAG_START = "#@~^"
Const TAG_END   = "==^#~@"

Dim posStart, posEnd
Do
    posEnd = 0
    posStart = InStr(content, TAG_START)
    If posStart > 0 Then
        ' 檢查標記後 10 字元是否為 "=="
        If (InStr(posStart, content, "==") - posStart) = 10 Then
            posEnd = InStr(posStart, content, TAG_END)
            If posEnd > 0 Then
                ' 提取編碼區塊:跳過 TAG_START(4) + 長度標記(8) = 12 字元
                ' 結束前 6 字元為 TAG_END
                Dim encodedBlock
                encodedBlock = Mid(content, posStart + 12, posEnd - posStart - 12 - 6)
                ' 解碼並替換
                content = Left(content, posStart - 1) & DecodeBlock(encodedBlock) & Mid(content, posEnd + 6)
            End If
        End If
    End If
Loop Until posEnd = 0

WScript.Echo content

' === 解碼核心函數 ===
Function DecodeBlock(encoded)
    Dim se, i, c, j, index, temp
    Dim decodeMap(127)
    Const COMB = "1231232332321323132311233213233211323231311231321323112331123132"
    
    ' 1. 建構反向映射表:利用 Encoder 編碼已知字元推導對應關係
    Set se = CreateObject("Scripting.Encoder")
    For i = 9 To 127
        decodeMap(i) = "JLA"  ' 佔位,長度 3
    Next
    
    For i = 9 To 127
        ' 編碼 3 個相同字元 chr(i),提取編碼後的 3 字元(位置 13-15)
        temp = Mid(se.EncodeScriptFile(".vbs", String(3, Chr(i)), 0, ""), 13, 3)
        For j = 1 To 3
            c = Asc(Mid(temp, j, 1))
            ' 將第 j 位映射回 chr(i)
            decodeMap(c) = Left(decodeMap(c), j-1) & Chr(i) & Mid(decodeMap(c), j+1)
        Next
    Next
    
    ' 修正已知 Bug:')' (42) 可能被誤解碼為 '>' (62)
    decodeMap(42) = Left(decodeMap(42), 1) & ")" & Right(decodeMap(42), 1)
    Set se = Nothing
    
    ' 2. 預處理特殊轉義序列
    encoded = Replace(Replace(encoded, "@&", Chr(10)), "@#", Chr(13)) ' LF, CR
    encoded = Replace(Replace(encoded, "@*", ">"), "@!", "<")        ' >, <
    encoded = Replace(encoded, "@$", "@")                           ' @ 本身
    
    ' 3. 逐字元解碼
    index = -1
    For i = 1 To Len(encoded)
        c = Asc(Mid(encoded, i, 1))
        If c < 128 Then index = index + 1
        
        ' 僅處理可列印字元與 Tab,跳過 < > @ (已轉義)
        If (c = 9) Or ((c > 31) And (c < 128)) Then
            If (c <> 60) And (c <> 62) And (c <> 64) Then
                ' COMB 序列決定使用 decodeMap 中第幾個字元 (1/2/3)
                Dim combIndex
                combIndex = Mid(COMB, (index Mod 64) + 1, 1)
                encoded = Left(encoded, i-1) & Mid(decodeMap(c), combIndex, 1) & Mid(encoded, i+1)
            End If
        End If
    Next
    
    DecodeBlock = encoded
End Function

三、編碼格式結構分析

' 編碼後檔案結構範例:
' #@~^AwQAAA==...編碼內容...==^#~@

' 標記結構:
' #@~^          : 固定起始標記 (4 bytes)
' AwQAAA==      : 長度/校驗資訊 (8 bytes, Base64-like)
' ...編碼資料... : 實際編碼腳本內容
' ==^#~@        : 固定結束標記 (6 bytes)

四、算法原理解析

階段操作關鍵點
編碼逐字元 XOR 混淆 + Base64 類似編碼 + 特殊字元轉義非加密,無金鑰,純混淆
解碼映射表建構窮舉 ASCII 9-127 編碼 3 字元,觀察輸出建構反向查找表利用 Encoder 確定性特性,無需逆向算法
COMB 序列"123123233232..." 決定每字元使用映射表第 1/2/3 位周期 64,增加靜態分析難度
特殊轉義@& → LF, @# → CR, @* → >, @! → <, @$ → @避免編碼區塊中出現標記衝突字元

五、安全性評估與現代替代

定性:Script Encoder 屬於源碼混淆,非加密。無金鑰、算法公開、可完全逆向。
用途:防止誤修改、隱藏邏輯細節、簡單授權檢查繞過門檻。
不可用於:保護機密演算法、金鑰儲存、知識產權核心邏輯。

現代替代方案

  • VBScript/JScript:棄用,遷移至 PowerShell / JavaScript (Node.js) / C#。
  • PowerShell:ConvertTo-SecureString + ConvertFrom-SecureString (DPAPI 機器/用戶級加密);模組簽名 (Authenticode)。
  • Node.js:pkg 打包為二進制、bytenode V8 bytecode 編譯、javascript-obfuscator 混淆。
  • .NET:Dotfuscator、ConfuserEx 混淆;核心邏輯編譯為 Native (AOT) 或放入 Azure Key Vault / HSM。

六、批次處理封裝

' === batch_decode.vbs:批次解碼資料夾所有 .vbe ===
Dim fso, folder, file
Set fso = CreateObject("Scripting.FileSystemObject")
Set folder = fso.GetFolder(".")

For Each file In folder.Files
    If LCase(fso.GetExtensionName(file.Name)) = "vbe" Then
        WScript.Echo "Decoding: " & file.Name
        Dim content, decoded
        Set file = fso.OpenTextFile(file.Path, 1)
        content = file.ReadAll
        file.Close
        ' 呼叫上述 DecodeBlock 邏輯(需複製函數體)
        decoded = DecodeFullContent(content)
        fso.OpenTextFile(fso.GetBaseName(file.Name) & ".vbs", 2, True).Write decoded
    End If
Next
WScript.Echo "Batch decode completed."
法律提醒:逆向工程、解碼他人受保護腳本可能違反軟體授權協議、DMCA 反繞過條款或當地法律。僅對自有代碼、授權代碼、安全研究(經許可)使用本工具。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved