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