現在的木馬後門種類非常之多,其中有些木馬專門以Office 文檔為竊取目標 ,我最近做了一些Anti這些木馬的工作,在工作中我基本上實現了阻止未知程序 利用Office自動化接口竊取Word內容,但限於公司利益我只能寫一些基本上已經 比較成熟和公開的技術,當然其中了包含我的設計思想,我想多多少少會讓你有 所收獲,你可任意轉載文章,但請注明作者和出處,謝謝!
首先我們知道Ole拖放是由DoDragDrop啟動的,為此你可以事先要准備一些參 數給DoDragDrop使用,最開始我的想法是直接阻止DoDragDrop調用,後來我發現 這樣做會使Word文檔窗口內部的拖放操作失效,這會給人一種很不好的感覺,好 的保護軟件應該在客戶沒有感覺到不方便的情況提供保護,而後我又仔細看了 DoDragDrop的參數想發現有沒有什麼可以利用的地方,我發現它有四個參數:
IDataObject * pDataObject;
IDropSource * pDropSource;
DWORD dwOKEffect;
DWORD * pdwEffect;
後兩個參數基本上沒有什麼利用價值,我想到Hook IDataObject的GetData函 數,可是在Ole Drop客戶端編程時,通常當我調用COleDataObject的相關成員函 數時拖放已經差不多完成,鼠標已經在我的程序窗口上了。
而我現在的想法是在拖放操作剛離開Word的文檔窗口,還沒有到達外部程序 窗口時就讓它失效,這樣Hook IDataObject的虛函數肯定不行,我只有再研究一 下最後一個沒有研究過的參數pDropSource,它是一個IDropSource類型指針,我 發現它有一個虛函數QueryContinueDrag查看了一下MSDN發現它似乎就是我要找 的。
我的理解是這個函數是讓Ole拖放的服務端在調用DoDragDrop啟動Ole拖放操 作後,有機會取消拖放操作而設的一個CallBack,於是我寫了一段代碼Hook住 DoDragDrop並從DoDragDrop中進一步Hook住IDropSource的QueryContinueDrag虛 函數,我發現它會全程跟蹤整個拖放操作,只要這個CallBack一返回 DRAGDROP_S_CANCEL整個拖放操作就會被取消,這樣我只要知道當前鼠標下的窗 口是否是文檔窗口就可以了,一旦離開了文檔窗口我就讓這個CallBack返回 DRAGDROP_S_CANCEL取消整個拖放操作。
這樣做就可以不影響文檔窗口內部的拖放操作,又可以阻止將文檔窗口內部 的東西拖放到其它程序中,基本上不會讓客戶感到不方便,這很有意思!不是嗎 ?
那麼從鼠標位置得到窗口句柄可能嗎?答案是肯定的! GetCursorPos函數可 以返回一個POINT變量,它指示當前的鼠標位置,而WindowFromPoint則可以返回 某一個POINT位置下的窗口句柄。寫到這裡我想差不多已經說完了我的思路,不 知道你是否看得明白。
總結一下,用ATL向導生成一個COM框架,增加一個ATL簡單對象,在這個對象 上實現_IDTExtensibility2接口,在_IDTExtensibility2的OnConnection中Hook 住DoDragDrop API,在Word調用DoDragDrop時記錄下當前的文檔窗口句柄,並 Hook住第二個參數pDropSource的QueryContinueDrag虛函數,在 QueryContinueDrag裡跟蹤當前鼠下的窗口是否還是文檔窗口(比較句柄是否等於 DoDragDrop時記錄下的文檔窗口句柄),如果不是則返回DRAGDROP_S_CANCE取消 拖放操作,並彈出一個警告信息的MessageBox,否則執行原有的操作(讓拖放操 作正常進行)。
最後,別忘了注冊你的Word插件(用Regsvr32。exe),詳細的鍵值和代碼細節 見源程序吧!
2005年10月15日夜
參考資料:
MSDN October 2001
Microsoft Office 2000/Visual Basic Programmer''s Guide
ATL Internals
Inside C++ Object Model
本文配套源碼