<<加密與解密>>第14章的SMC(Self-Modifying Code)技術實現很有意思,這節的練習例子將SMC技術與其它一些反跟蹤技術結合起來,有一種海陸空聯合作戰的趕腳:單步跟蹤,軟斷點,硬件斷點都要中作者的陷阱,從而不是跑飛就是掉進系統DLL領空迷失,無法正確跟蹤到后面的源代碼,更別說分析了.
作者太高估咱們(異或是唯獨自己太蠢?)的水平,書上和例子代碼注釋都講解得不夠詳細,我冥思苦想了好大半天,翻出書來復習標志寄存器TF位,SEH執行流程等,才明白了那幾句代碼所謂的SEH暗樁是怎么回事:
0040112D |. 66:9C pushfw 0040112F |. 804C24 01 01 or byte ptr [esp+1], 1 00401134 |. 66:9D popfw 00401136 |. 90 nop
后來我查到這篇帖子,里面有作者的詳細講解了:
http://bbs.pediy.com/showthread.php?t=70444
不過我對作者的這句話的正確性表示懷疑:"如果試圖單步跟蹤這段代碼,誤入陷阱的話,在這里就是單步跟蹤到 popf 時,則不會再產生單步調試異常,直接運行到其后的 nop 指令處,由於沒有運行異常處理函數因而 EAX 和 EDX 寄存器值也就沒有交換,最后計算的密鑰也就是錯誤的。"
我參考王爽的<<匯編語言第二版>>第12章11節"單步中斷"以及<<C++反匯編與逆向分析技術揭秘>>第16章"OllyDbg的工作原理"后認識到,幾種類型的斷點實際上都是通過系統的SEH異常處理機制來達到下斷的.單步跟蹤時產生異常后,系統檢測到調試程序有附加調試器,故優先將處理權給了調試器,而不是程序自己設置的SEH handler,不是調試狀態的話,一切正常.總結SEH的處理流程就是這樣的:
(1)系統檢測到程序若有附加調試器,就把異常丟給調試器進行處理.
(2)否則執行線程中距離棧頂最近的SEH的異常處理函數(TEB的第一個數據成員指針指向其).
(3)若失敗,則依次嘗試執行SEH鏈表中后續的異常處理函數.(線程SEH處理實際上是分兩輪的,第二輪是unwind操作)
(4)若線程SEH鏈中所有handler都失敗,則執行進程級別SEH處理.(SetUnhandledExceptionFilter,謂之top level)
(5)若還是失敗,系統默認的SEH處理被執行:程序崩潰的對話框彈出.
關於這個SMC實現例子,我這個小菜鳥思考了一會兒,應該怎么破.它目的即是反追蹤,阻止你邊調試邊閱讀代碼?我想的是:我們先運行之,發現其功能是彈出消息框,查看導入函數有MessageBoxA,於是嘗試對該API下斷,F9運行后再Ctrl+A讓OD重新分析,就能讀到所有解密后的代碼了.但是我覺得不夠好,如果怎么能夠直接調試跟蹤整個程序流程,而又靈活的不踏入作者設下的陷阱里,像凌波微步一樣在里面穿行,才是最合我心意的.不過以我的水平,沒找到方法.
最近學了一些關於SEH機制及其ASM級實現原理的知識,認為這個東東確實是了不得,不但可以挪用來制造陷阱反追蹤,還可以利用它來溢出攻擊(見<<0day安全:軟件漏洞分析技術>>第6章1節),下面鏈接中的文章講到還能通過它進入Ring0!
http://bbs.pediy.com/showthread.php?t=154271
我現在有一種趕腳,學到越來越多的底層知識后,我似乎有一種主動的想把各個知識點聯系起來,像拼圖一樣逐漸完整自己對整個系統的理解的意圖,但是又不得其法,力不能及,一會兒腦子就像灌鉛了一樣鑽不開了.總結來說:想要融會貫通是很難的,得靠長時間的積累和沉淀~
最后,怎么感覺自己這篇隨筆跟題目對不上啊...沒事,咱是玩單機版博客的,自娛自樂挺有意思....