天天看點

[轉載]運作中的DLL自更新

  最近手頭有個需求:dll需要注入到某個程序常駐,該dll具備自我更新能力,當發現新的可用版本時,立即Free自己,加載新的。下面是一個實作方案:

    開啟一個監聽線程,從網絡上拉新的可用版本,下載下傳放到一個臨時目錄,如果發現需要更新,則立即FreeLibrary自身,然後執行更新過程。

    由于FreeLibrary之後目前子產品的記憶體區域已經無效,是以更新的過程使用一個單獨的線程,并将要更新過程的代碼通過shellcode的形式寫到配置設定的記憶體中執行。更新過程中将會使用一些系統API函數,這裡不能直接通過函數名來調用,因為這樣會通路導入表,而DLL此時已經Free掉了。是以事先通過準備一個參數傳遞給該線程,該參數有更新線程要用到的一些資料和位址:

[轉載]運作中的DLL自更新

    下面看看更新監聽線程如何工作以及如何準備這些參數:

[轉載]運作中的DLL自更新

    建立好更新線程後,自己得及時退出并Free自己(這樣更新線程才能把自己删掉):

[轉載]運作中的DLL自更新

    下面看看更新線程如何工作:

[轉載]運作中的DLL自更新

    同Free自己子產品一樣,最後VirtualFree參數和目前代碼所占記憶體頁面後,不能再回來,通過建構棧參數的形式,結束目前線程。這個函數編譯後的二進制指令儲存到全局數組中:

[轉載]運作中的DLL自更新

下面是測試的效果(XP、Win7 32 &64均測試通過):

[轉載]運作中的DLL自更新

最後有幾個地方要說明的是:

1、  加載新的dll前要把臨時目錄下的檔案删除掉,防止出現遞歸循環更新過程。

2、  執行更新過程前需要判斷dll的版本資訊,同樣是為防止出現遞歸循環過程。