看到《
C是否能指定函數在特定記憶體, 執行後抹除?》這問題我覺得有趣, 想試試看能不能辦到?
想法就是找出 function 的位址以及長度, 然後用 memset 填 0 即可, 原理很簡單, 實作就麻煩了不只一點。
ref:
How to get the length of a function in bytes?
首先要怎麼得到被刪除的 function address, size?
function address 很簡單, 就是 function 名稱, function 名稱本身就是位址, 沒問題, 問題在怎麼取得這個 function 的 size。
一開始我用了 list 1 L37 的方法, 把 f2 - f1 得到的 size 當作 f1() 的長度, 但是這有個前提, 編譯器產生的程式碼得把 f2 緊緊接在 f1 之後, 這是有保證的嗎? 我不確定, 不過要是擔心的話, 可以用 objdump 反組譯確認, 我當然是確認過了。
另外一個作法麻煩點, 相依於編譯器開發工具, 我修改了內建的 linker script, 插入 list 2 L24 ~ L31 的 linker script 指令, 計算出 f1 真正的長度, 這是最保險的方式, 可惜沒有可攜性。再使用 list 1 L29 ~L32 取得 f1() 長度。
有了長度, 位址, 把它傳給 memset 就結束了嗎? 還沒, 我們在 linux os 的控制下, 記憶體不是 user mode 程式要幹麻就能幹麻, 得把這個記憶體設定為可執行、可讀取、可寫入, 才可以用 memset, 這是 list 1 L47 在做的事情, 還沒完, 在這之前, 得先要算出 page align 的位址才可以, 因為 mprotect 需要傳入 page align 的位址。list 1 L38 ~ L42 就是在計算這個位址, 好了, 真的結束了, 在 list 1 L58 之後, 會發出 segment fault 的錯誤, 因為 f1 不再存在了。
這樣的功能有實用性嗎?
skype 為了避免被反組譯出來, 就用了類似的技巧, 將自己初始化的函式消去。
沒有留言:
張貼留言
使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。
我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。