我先跳做 code obfuscation (程式模糊化) 的目的, 假設大家都知道 why (為何而戰), 這裡只筆記 what and how?
根據 [1], 我們可以做三種模糊化:
- Data Obfuscation
- Layout Obfuscation
- Control Obfuscation
Data obfuscation 是我們最熟悉的模糊化方式, 它是指對於變數名稱, 或者資料型態做修改. 事實上, 只要把 binary 中的 symbol strip 掉, 基本上名稱就變得亂七八糟了. 做法有二:
(1) compiler option [2]. 最厲害是 gcc 下開到 --strip=all
. For object modules, this option removes all debug, comments, notes and symbols from the ELF file. For executables, this option works the same as --no_linkview
.
(2) 用 command line 程式 off line 做 strip [3]. 最厲害也是開到 strip --strip=all
, 不過以我粗淺地觀察, command line 多了針對特定 section 的操作, 而不是只把 section 分為 debug, comment, localsymbol, note…這幾種而已, 例如:
-R sectionname
--remove-section=sectionname
附帶一提, section 的用法可以參照 ELF (Executable and Linkable format or Extensible Linking format) [4]. 一個 ELF (*.o, *.so) 理所當然有一個 ELF header, 底下又分成 program header table, section, section header table 三個部分. 在 section header table 裡面就會記錄每一筆 section 在 image 中的那個位置 (offset).
至於對 data 的混淆, 個人有一點經驗可以分享. 上個世紀我做過 reverse engineering, 有一次我看到 binary 中有一串數字
5FFD:07D7 46 17 5D 74 D1 45 C7 3F dd 3FC745D1745D1746h ; 2/11
5FFD:07DF 1C C7 71 1C C7 71 CC 3F dd 3FCC71C71C71C1Ch ; 2/9
5FFD:07E7 92 24 49 92 24 49 D2 3F dd 3FD2492492492492h ; 2/7
5FFD:07EF 9A 99 99 99 99 99 D9 3F dd 3FD999999999999Ah ; 2/5
5FFD:07F7 55 55 55 55 55 55 E5 3F dd 3FE5555555555555h ; 2/3
5FFD:07FF 00 00 00 00 00 00 00 40 dd 4000000000000000h ; 2
因為太有規律了, 所以可以看出是 2/(2N+1) 的序列, 也就是:
2 * (1+1/3+1/5+1/7...)
此時搭配引用這段數字的代碼, 就可以看出是在計算:
2 * (x + x^3/3 + x^5/5 + x^7/7 + ....)
= ln(1+x) - ln(1-x)
= ln ((1+x)/(1-x))
諸如此類. 如果當初原作者把參數打亂一下, 我想破頭也很難想出來.
Layout Obfuscation 是指修改 source code 的長相, 例如調整排縮 (indentation), 亂加 comment, 對 symbol 取怪名, 隨意插入不影響執行的關鍵字 [5]. 這對於已經編成 ELF 的程式當然沒用, 但是對於程式碼可直接執行的 java script 就有幫助.
Control Obfuscation 是指修改 code 的 statement 表示方式. 例如加入執行不到的 dead code, 該 call function 時把它的內容整個貼上來, 只用一個 function 但是把整包 library 塞進去. 看來這個手法主要是在 binary 的狀況下適用.
基本上, 如果做 binary release 可以用手法 1 和 3. 做 source code release 可以用手法 2. 不過接手這種 source code 的人應該心中 OOXX 吧…
[Note]
- Introduction to Code Obfuscation
- http://www.keil.com/support/man/docs/armclang_ref/armclang_ref_pge1362128923577.htm
- https://sourceware.org/binutils/docs/binutils/strip.html
- https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
- https://codeobfus.files.wordpress.com/2010/04/layout-obfuscations.pdf