Source Insight可以說是一款程序員必備的開發/閱讀源碼工具,美中不足的是SI沒有標簽欄,多個源碼之間切換很不方便,於是我就乘閑暇之余寫了該作品sihook:標簽插件;不過嚴格意義上來說sihook並不算是插件,而是一個內掛:)
如何給Source Insight添加標簽欄呢?可以查看orbit的博客<<給Source Insight做個外掛>>系列;感謝orbit的分析,而且orbit再很早的時候就已經做了一個標簽插件,我也下載和試用了他的插件,不過orbit的像個外掛,而我的更像內掛:),由於很久沒寫win程序,對windows消息也不熟悉,手頭連spy++都沒有,開始以為要hook住SI的某個內部函數來掛鈎子窗口的創建和銷毀,看了orbit的博客后發現原來SI是個標准的MDI程序,子窗口的創建和銷毀都是WM_MDI*的消息,那事情就簡單了,只要替換原SI的wndproc就可以實現我們想要的事情.orbit的插件居然是用mfc做的dll,代碼中還有線程和定時器,用起來還要個loader來加載,使用起來不太方便,在線程中操作UI怎么看都覺得有點別扭,既然已經注入SI程序了,那我們就因該做的更徹底更底層一點:).
經過幾年的編程積累,也有點感悟,越來越覺得c++太繁雜了,而c的清晰精簡讓我越來越欣賞,一段c代碼能很好表達清楚的邏輯,c++開發者喜歡繞上一大圈來實現,更不提那些變形的VC和我從來沒搞懂過的MFC,幾年以前接觸MFC依葫蘆畫瓢的時候總是搞不懂MFC在干些什么,現在回過頭來看,MFC完全就是一個失敗的設計.好了,不吐槽c++和該死的VC+MFC了,這次sihook用c開發,gcc編譯,偷懶沒裝MSYS用CodeBlocks做IDE,Makefile都省了:)
下面我簡單介紹一下sihook的實現原理:
1,插件的自動加載msimg32
幾年前dll都是用CreateRemoteThread方法來加載,就是必須要有個exe的loader,而現在有了msimg32延遲加載漏洞,腰不酸了腿不疼了,加載外掛更方便了:),具體原理我就不多介紹了,網上一搜一大把.
2,肢解SI之siframe
SI主窗體是siframe,由於msimg32是延遲加載,由hook CreateWindowEx調試發現,當我們的dll載入的時候,siframe和mdiclient已經創建了,而si_sw未創建,那么我們直接得到當前進程的HWND就是siframe的HWND了,然后SetWindowLong替換窗口過程,只關心WM_SETTEXT消息,WM_SETTEXT設置標題的時候我們在后面加上"加強版"的字樣,然后以siframe為父窗體創建我們的systabcontrol32控件.
3,肢解SI之mdiclient
mdiclient是SI中最重要的一個窗口,它管理着源碼窗口的創建銷毀,首先用FindWindowEx得到mdiclinet的句柄,然后SetWindowLong替換窗口過程,這里面要處理的消息有WM_WINDOWPOSCHANGING;WM_MDICREATE;WM_MDIDESTROY;WM_MDIACTIVATE;
WM_WINDOWPOSCHANGING是窗口大小改變的消息,這時候要處理tab的大小和mdiclient自身的大小,要在oldwndproc執行之前處理;
WM_MDICREATE;WM_MDIDESTROY;WM_MDIACTIVATE;要在oldwndproc執行之后處理,這樣就可以直接拿到子窗口的句柄處理了.
WM_MDICREATE消息用FindWindowEx得到新創建的si_sw源碼窗口的句柄,替換窗口過程
WM_MDIDESTROY消息直接能拿到HWND,同步刪除tab標簽
WM_MDIACTIVATE也能直接拿到HWND,同步激活tab標簽
4,肢解SI之si_sw
si_sw子窗口就是源碼顯示窗口了,這個窗口我們只關心WM_SETTEXT消息,得到當前源碼的標題(包括標題的變更),直接顯示在tab上,這樣就不用一個定時器去不停的比較了;
5,tabctl控件
為了精簡,直接用sdk編程,只能用系統自帶的systabcontrol32控件來做標簽了,我封裝了一層接口方便上層調用,包括增加,刪除,雙擊關閉,改變選項卡顏色,調整位置高度等.說起來這是我第一次用systabcontrol32這個控件,做的很難看,如果有sdk美化高手知道怎么做的漂亮一點,可以給我留言,再此先表示感謝.另外雙擊關閉標簽的同時要關閉源碼窗口,看orbit的介紹要發WM_CLOSE消息,而且他的代碼確實是這么實現的,並且有效,但是我怎么試都不靈,最后用OD一調試,發現SI自己發的是WM_SYSCOMMAND消息,WPARAM參數是SC_CLOSE,於是我也用SC_CLOSE消息來關閉文檔:)
OK,基本原理就是上面幾點,理清楚了制作標簽內掛就很容易了,整個工程不算tabctl控件源碼不超過10個函數,以下是效果圖和插件下載包
sihookv1.0下載:[點我]
安裝:解壓sihook.zip兩個dll放到SI目錄即可
刪除:刪除SI目錄msimg32.dll和sihook.dll即可
源代碼地址:https://github.com/redxu/sihook
注:測試發現某些XP sp2裝了某些衛士的機器會無法使用此插件,msimg未加載,原因調查中