去控制流平坦化學習

2021-10-08 02:54:00 字數 2099 閱讀 3896

控制流平坦化是ollvm中使用到的一種**保護方式,它還有2個兄弟-虛假控制流和指令替換,這3種保護方式可以累加,對於靜態分析來說混淆後**非常複雜。

控制流平坦化的主要思想就是以基本塊為單位,通過乙個主分發器來控制程式的執行流程。

例如乙個常見的if-else分支結構的程式可以是這樣:

控制流平坦化在**上體現出來可以簡要地理解為是while+switch的結構,其中的switch可以理解為主分發器。這一點在ida的反彙編裡面可以很明顯地體現出來。

混淆前:

int __cdecl main

(int argc,

const

char

**ar**,

const

char

**envp)

else

return result;

}

混淆後:

int __cdecl main

(int argc,

const

char

**ar**,

const

char

**envp)

}else

if( v7 >

1633153877)}

else}}

else

if( v7 ==

-1424773164)}

}while

( v7 !=

-1883523171);

return v8;

}

從ida的流程圖中也可以很容易地識別出經過控制流平坦化的程式。

可以看到,經過平坦化之後的**塊大部分整齊地堆積在程式流圖的下方,而這部分**就是真正有意義的**塊,稱之為相關塊。

而去平坦化要做的就是在茫茫人海中識別出相關塊,然後理清楚這些相關塊之間的關係。

目前去控制流平坦化最有效的辦法是利用符號執行。具體的指令碼和使用我參考了

反混淆:恢復被ollvm保護的程式

而控制流平坦化的理論和去平坦化的演算法參考了

反混淆:恢復被ollvm保護的程式

file "default.py"

, line 32

, in statement_inspect

iflen(expressions)

!=0 and isinstance

(expressions[0]

, pyvex.expr.ite)

:typeerror: object of type 'generator' has no len

()

谷歌了一下,發現了和我遇到同樣問題的師傅

修復去除控制流平坦化工具deflat.py

這位師傅羅列了很多的報錯和修改方法,在參考並修改後執行成功。

上面的反混淆指令碼在處理控制流平坦化時只能解決簡單的while+switch套娃。如果輸入的資料能夠影響迴圈的走向,我們就不得不處理已經經過的分支,否則因為分支過多而爆記憶體…個人猜想可以通過手動patch的方法對程式執行的路徑樹進行「剪枝」,或者把乙個控制流平坦化流程圖分成2個。目前還沒有實際遇到過。以後遇到的時候再具體分析。

參考:

反混淆:恢復被ollvm保護的程式

利用符號執行去除控制流平坦化

修復去除控制流平坦化工具deflat.py

用angr去除o llvm控制流平坦化

更改這篇文章中最新版本的bug 和補充這篇文章的環境搭建 1.配置mac中docker環境 2 可以按照這篇文章中傳mac到docker檔案 3 安裝docker環境中的angr 但是注意不用第一步 1.sudo docker pull angr angr 2.sudo docker run it ...

180517 逆向 反控制流平坦化(符號執行指令碼)

正常流程如下 經混淆後的流程如下 破壞了 塊之間的關係後,整個程式的邏輯將很難辨認 符號執行的思路是遍歷所有路徑,將分發器等無用的 跳過,恢復 塊之間的聯絡 由於跳轉的 極有規律,因此在跨過分發器,找到 塊之間聯絡的基礎上修復控制流就難度不大了 符號執行反混淆的大體思路如上 可用指令碼 對於iscc...

控制流學習補充

5.控制流語句有if,else,elif,while,break,continue,for 6.if語句的條件為ture 時執行,為false時跳過。if語句組成 關鍵字if,條件ture或者false表示式,冒號 在下一行開始,縮排的 塊為if的子句。所有控制流語句都以冒號結尾,後面跟著乙個新的 ...