JS逆向:AST 語法樹反混淆策略處理控制流平坦化

1、控制流

  • 控制流(Control Flow),指的是
  • 控制流基本語法包括兩種:
    -- 第一種:if / else 條件語句判斷
if(條件){  };
else{  };

-- 第二種:while / switch / case 條件語句判斷

while (option) {
    switch (args){
        case 1:console.log('case 1,xxx');
        case 2:console.log('case 2,xxx');
        case 3:console.log('case 3,xxx');
    }
}

2. 控制流平坦化

  • 控制流平坦化(Control Flow Flattening)是一種代碼混淆方式,其基本思想是讓所有的基本塊都有共同的前驅塊,而該前驅塊進行基本塊的分發,分發用switch語句,依賴於switch變量進行分發。
  • 具體是先爲每個基本塊進行值編號,每個基本塊就是一個case塊,如果基本塊有後繼塊,就替換每個基本塊的後繼塊,新的後繼塊更新switch變量爲後繼塊的值,然後跳轉到switch開始分發處,初始switch變量爲入口entry塊的值。
  • 現已有一些編譯器實現了控制流平坦化,Obfuscator-LLVM(簡稱 OLLVM)是一種基於 LLVM 框架的實現,這是目前比較主流的控制流平坦化實現方法;
  • 例如,有下面的代碼,正常形態下我們可以很容易看懂其邏輯:
// 正常形態
function test(a){
   var b = a;
   b += 1;
   b += 2;
   b += 3;
   b += 4;
   return a + b
  • 通過加密操作,得到下面的代碼,這樣看起來就會複雜得多,調試的時候如果此處下斷點,跳來跳去也會讓人覺得頭暈:
// 亂序形態
function test() {
    for (var s = 1; void 0 !== s; ) {
        var r = 3 & s
          , c = s >> 2
          , b = 3 & c;
        switch (r) {
        case 0:
            !function() {
                switch (b) {
                case 0:
                    k += "do",
                    s = 8;
                    break;
                case 1:
                    k += "Nt",
                    s = 2;
                    break;
                case 2:
                    s = k ? 4 : 2;
                    break;
                case 3:
                    s = void 0
                }
            }();
            break;
        case 1:
            var k = "e";
            s = k ? 0 : 8;
            break;
        case 2:
            k += "nerap",
            k = k.split("").reverse().join("");
            var i = kr[k];
            s = i ? 3 : 12;
            break;
        case 3:
            a.push(175528201),
            a.push(24898129191),
            a.push(2),
            a.push(0),
            e(13, 2, -1);
            var o = a.pop();
            i[o](kr),
            s = 12
        }
    }
}
  • 上面這段代碼以 switch-case 的方式實現使用了控制流平展混淆。相比於常規的控制流平展混淆的改進之處在於,它的 switch-case 結構不止一層,本例中嵌套了一層,理論上可以多層嵌套;
  • 針對不止一層switch-case結構的混淆變種,需要把原始方案作一個增強。我們採用樹形結構來表示原始的控制流結構。一層switch-case可看做只有兩層的樹。多層switch-case相當於在對應節點上的繼續延伸,從而形成三層、四層…的樹形結構;


3. AST 語法樹處理控制流平坦化

  • 首先將上面的代碼複製到 https://astexplorer.net/,得到下圖:
  • 通過分析,我們得出這段代碼包含兩側的 switch / case 嵌套,如下圖:


  • 之後,我們查找 switch 條件,分析條件參數;


  • 結合條件參數和執行邏輯邏輯,即可推導出最初的代碼;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章