天天看點

開源代碼分析技巧之——高效Windows源碼分析

 以下筆者結合自己的近來的經驗就Windows源碼分析做下解讀。

一、了解Windows的代碼特點

      相比于Linux源碼,封裝的特性在Windows下展現的尤為突出。尤其MFC下的程式開發,我們需要常備MSDN,了解函數接口的定義、傳回值、參數(in或out)的含義。

      熟悉MFC的消息映射和傳遞機制。對于現成的實作,我們可參考使用不同的API,不必要重複造輪子。

二、通過文檔了解代碼實作

      項目中一般團隊開發,對于已有的實作會有前期的需求分析文檔、總體設計文檔、詳細或微型設計文檔。對一個新人來講,通過文檔了解版本中已經實作的功能、采用的技術、實作的流程圖等是很高效的方法。

      衡量你對實作功能了解的标準就是:你能給一個對該領域陌生的人講解明白大緻實作的原理。

三、自頂向下,分解開來

      雖然已有的代碼量非常龐大,但對個人而言不可能面面俱到,我們往往是根據項目組的安排維護其中的一個或大或小的子產品的代碼量,在其中修改已有代碼邏輯或新增新的功能。有了文檔的大局觀還需要自頂向下,将代碼分解開來,直到細化到你所維護的代碼的每一行。

      Windows下的自頂向下無非是:工程—>子產品-->類-->函數-->代碼行。

四、分析源碼邏輯

       對于自己負責子產品的功能實作,我們要了解新增功能的代碼的添加位置?代碼的前後邏輯及執行流程是怎麼樣的?新加後會不會對已有代碼邏輯構成影響?

       筆者案例:在代碼中新增序列号未開啟的功能,用于實作當客戶購買裝置當尚未購買該新增功能的序列号時是沒有權限執行後續的操作的。這個時候就需要我負責的用戶端的子產品接收裝置端的子產品的回報消息,并以彈窗的形式醒目的提示給客戶。上面提到的添加位置、流程、構成影響三個問題便都出現。我的實作如下:

      第一步:充分跟讀已有的代碼邏輯,知道原有代碼對初始登入出現錯誤(如網絡異常)是如何提示使用者的,大緻确定添加的位置;

      第二步:考慮如何從對端(裝置端)擷取提示資訊;

      第三步:在第一步的位置新增第二步擷取的代碼,并做不同場景下的測試,確定第一步位置的正确性以及新增代碼邏輯不會對已有代碼構成影響。

五、改動源碼的前提是已經對已有邏輯了然如胸

      差別于以前自己寫的小程式,代碼邏輯簡單、不與其他代碼或邏輯關聯,很容易定位出錯原因。實際項目開發中大家團隊作戰、各司其職。修改一處的代碼有可能“牽一發而動全身”。并且代碼bug出現有的是必現的,有的和環境、場景有關為非必現的。非必現bug很難排查。

      筆者案例:在開發中筆者需要動态加載DLL,以調用其中提供的函數接口。筆者想當然以為,動态加載隻要加上DLL的路徑就沒有問題。當時本機調試也沒有問題,但經理說要在虛拟機看下執行效果時,将Release版本可執行程式拷貝過去至虛拟機後,發現根本不能執行。即:在本機執行沒有任何bug,為什麼換台機器後就不能執行了呢?這種問題是如何出現的以及如何調試解決的呢?(該問題正是一年前360面試官問過我的題目)。筆者排查如下:

      第一步:通讀新增代碼,看有沒有邏輯bug。如果有修改之再測試;如果沒有,則思考至第二步。

      第二步:為什麼會換台機器就運作不了了?猜測多半和場景有關,基本聯想到新增的動态連結庫,在兩台機器的安裝路徑不一緻。

      第三步:基本确立DLL加載的問題,思考如何避免。檢視原有代碼邏輯對DLL進一步封裝為COM接口,加載COM接口不需要路徑,僅一個ID值就能識别,換成COM方式加載後就避免了上述問題。

      足現對已有代碼熟悉的重要性。

六、多調試而不是去猜bug原因會事半功倍

       如下調試要常備:GetLastError之ErrorCode、單步Debug調試、asm –int 3調試(内聯宏彙編,int表示觸發軟中斷,3是中斷号,這個依賴于具體的作業系統。解決正常斷點調試解決不了的問題,如對EXE、DLL調試,如1000次循環在999次挂掉的調試)。

       筆者曾遇到Http通路能正确擷取頁面資訊,但是換成Https頁面就不可以的bug。通路Https擷取頁面内容bug的解決就是通過GetLastError的錯誤碼,得知需要繞過SSL認證擷取頁面資訊,并進一步添加Flag标記變量将SSL認證回避掉。

       以VC6.0為例,是可以通過View-->Debug Windows --> Call Stacks 檢視調用堆棧的。如下圖所示:

開源代碼分析技巧之——高效Windows源碼分析

   對于複雜的功能實作,有了函數調用堆棧會加快我們的分析。

七、僅在必要的時候和原作者聯系

      即便一個項目組中,因為工作了大家都比較忙,各自手裡都有任務量,盡量自己去解決。即便非得去向原作者咨詢問題,也要事先将待問問題的思路、自己的想法在本上都記錄好,確定高效。

      個人體會:工作了,非在學校,大家的時間都特别寶貴,如果你耽誤了别人的時間很可能導緻别人進度的延誤。而在學校,筆者曾經幫别人用6個小時多的時間解決word2010,2007,2003解除安裝不幹淨的問題。工作後會發現6個小時,是工作一天的3/4的時間,忒寶貴了!

       2014-1-12 pm17:40思于家中床前

推薦閱讀:

【1】開源代碼分析技巧之一——列印調用邏輯

http://blog.csdn.net/laoyang360/article/details/12676131

【2】開源代碼分析技巧之二——gdb單步調試

http://blog.csdn.net/laoyang360/article/details/14102181

【3】開源代碼分析技巧之三——老外如是說

http://blog.csdn.net/laoyang360/article/details/16897117

【4】開源代碼分析技巧之四——國外技術社群提問

http://blog.csdn.net/laoyang360/article/details/16897827

繼續閱讀