引擎保護方法和裝置與流程
2024-04-03 19:33:05 1

本公開涉及網絡安全領域,具體地,涉及一種引擎保護方法和裝置。
背景技術:
目前大部分瀏覽器引擎以及Java、Perl、Ruby、Flash等都使用了JIT編譯(Just-In-Time Compilation)技術來提高代碼執行效率。JIT編譯技術在為可執行對象分配內存時會直接分配可預期的、具有可讀寫可執行(Read、Write、Exeute,RWX)權限的內存地址,這樣違背了數據執行保護以及隨機地址分配的保護措施,使得可執行對象執行時其引擎很容易受到緩衝區溢出、堆噴射等惡意攻擊。因此,少數使用JIT編譯技術的引擎採取了實時修改內存地址權限的方法對其進行保護,將分配給可執行對象的內存地址的寫權限與可執行權限分開。但是這樣又會使其處理周期過長,造成使用JIT編譯技術的引擎效率降低。
技術實現要素:
本公開的目的是提供一種引擎保護方法,該方法能夠在一定程度上避免引擎在可執行對象執行時被非法惡意攻擊。
為了實現上述目的,本公開提供一種引擎保護方法,該方法包括:
按照第一預設規則給可執行對象分配內存地址;
按照第二預設規則為所分配的內存地址設置保護區,其中所述保護區的權限為不可寫。
可選的,所述按照第一預設規則給可執行對象分配內存地址包括:
根據默認內存地址分配規則給所述可執行對象分配內存地址。
可選的,所述按照第一預設規則給可執行對象分配內存地址包括:
獲取為所述可執行對象申請內存的內存申請函數中的申請內存大小、申請內存地址和申請內存權限;
當所述申請內存地址為空且所述申請內存權限為可讀寫可執行權限時,對所述申請內存地址進行隨機化處理以得到隨機化內存地址;
根據所述隨機化內存地址、所述申請內存大小和所述申請內存權限確定要分配給所述可執行對象的內存地址;
當所確定的內存地址屬於系統內存地址時,返回所述對所述申請內存地址進行隨機化處理以得到隨機化內存地址的步驟;
當所確定的內存地址不屬於系統內存地址時,將所確定的內存地址分配給所述可執行對象。
可選的,在所述獲取為所述可執行對象申請內存的內存申請函數中的申請內存大小、申請內存地址和申請內存權限之後,所述按照第一預設規則給可執行對象分配內存地址還包括:
判斷所述申請內存大小是否是2的冪次方;
當所述申請內存大小不是2的冪次方時,將所述申請內存大小增加至大於所述申請內存大小的最小的2的冪次方。
可選的,所述按照第二預設規則為所分配的內存地址設置保護區包括:
將所述保護區設置在從所分配的內存地址的首地址開始的預設大小的內存空間內;
將所分配的內存地址向後偏移,其中偏移的大小為所述預設大小。
本公開還提供一種引擎保護裝置,該裝置包括:
內存地址分配模塊,用於按照第一預設規則給可執行對象分配內存地址;
保護區設置模塊,用於按照第二預設規則為所分配的內存地址設置保護區,其中所述保護區的權限為不可寫。
可選的,所述內存地址分配模塊包括:
內存地址默認分配子模塊,用於根據默認內存地址分配規則給所述可執行對象分配內存地址。
可選的,所述內存地址分配模塊包括:
獲取子模塊,用於獲取為所述可執行對象申請內存的內存申請函數中的申請內存大小、申請內存地址和申請內存權限;
內存地址隨機化子模塊,用於當所述申請內存地址為空且所述申請內存權限為可讀寫可執行權限時,對所述申請內存地址進行隨機化處理以得到隨機化內存地址;
內存地址確定子模塊,用於根據所述隨機化內存地址、所述申請內存大小和所述申請內存權限確定要分配給所述可執行對象的內存地址;
內存地址判斷子模塊,用於判斷所述內存地址確定子模塊所確定的內存地址是否屬於系統內存地址,並當所確定的內存地址屬於系統內存地址時,通知所述內存地址隨機化子模塊重新對所述申請內存地址進行隨機化處理以得到隨機化內存地址;
內存地址分配子模塊,用於當所述內存地址判斷子模塊判斷所確定的內存地址不屬於系統內存地址時,將所確定的內存地址分配給所述可執行對象。
可選的,在所述獲取子模塊獲取為所述可執行對象申請內存的內存申請函數中的申請內存大小、申請內存地址和申請內存權限之後,所述內存地址分配模塊還包括:
申請內存大小判斷子模塊,用於判斷所述申請內存大小是否是2的冪次方;
申請內存大小增加子模塊,用於當所述申請內存大小不是2的冪次方時,將所述申請內存大小增加至大於所述申請內存大小的最小的2的冪次方。
可選的,所述保護區設置模塊包括:
保護區設置子模塊,用於將所述保護區設置在從所分配的內存地址的首地址開始的預設大小的內存空間內;
內存地址偏移子模塊,用於將所分配的內存地址向後偏移,其中偏移的大小為所述預設大小。
通過上述技術方案,先按照第一預設規則給可執行對象分配內存地址,然後按照第二預設規則為所分配的內存地址設置保護區,其中所述保護區的權限為不可寫,這樣就能夠在一定程度上保護所述內存地址,且避免其引擎在可執行對象執行時被非法惡意攻擊。
本公開的其他特徵和優點將在隨後的具體實施方式部分予以詳細說明。
附圖說明
附圖是用來提供對本公開的進一步理解,並且構成說明書的一部分,與下面的具體實施方式一起用於解釋本公開,但並不構成對本公開的限制。在附圖中:
圖1是根據本公開一種實施方式的引擎保護方法的流程圖。
圖2是根據本公開又一種實施方式的引擎保護方法的流程圖。
圖3是根據本公開又一種實施方式的引擎保護方法的流程圖。
圖4是根據本公開又一種實施方式的引擎保護方法的流程圖。
圖5是根據本公開又一種實施方式的引擎保護方法的流程圖。
圖6是根據本公開一種實施方式的引擎保護裝置的示意框圖。
圖7是根據本公開又一種實施方式的引擎保護裝置中的內存地址分配模塊的示意框圖。
圖8是根據本公開又一種實施方式的引擎保護裝置中的內存地址分配模塊的示意框圖。
圖9是根據本公開又一種實施方式的引擎保護裝置中的內存地址分配模塊的示意框圖。
圖10是根據本公開一種實施方式的引擎保護裝置中的保護區設置模塊的示意框圖。
附圖標記說明
100引擎保護裝置 10內存地址分配模塊
20保護區設置模塊 101內存地址默認分配子模塊
102獲取子模塊 103內存地址隨機化子模塊
104內存地址確定子模塊 105內存地址判斷子模塊
106內存地址分配子模塊 107申請內存大小判斷子模塊
108申請內存大小增加子模塊 201保護區設置子模塊
202內存地址偏移子模塊
具體實施方式
以下結合附圖對本公開的具體實施方式進行詳細說明。應當理解的是,此處所描述的具體實施方式僅用於說明和解釋本公開,並不用於限制本公開。
圖1是根據本公開一種實施方式的引擎保護方法的流程圖,如圖1所示,該方法包括步驟S101和步驟S102。
在步驟S101中,按照第一預設規則給可執行對象分配內存地址。
在步驟S102中,按照第二預設規則為所分配的內存地址設置保護區,其中所述保護區的權限為不可寫。
所述保護區的設置目的是為了保護所述內存地址,其保護的方法即將所述保護區的權限設置為不可寫。
通過上述技術方案,當需要給可執行對象分配內存時,先按照第一預設規則給可執行對象分配內存地址,然後按照第二預設規則為所分配的內存地址設置保護區,其中所述保護區的權限為不可寫,這樣就能夠在一定程度上保護所分配的內存地址,且避免其引擎在可執行對象執行時被非法惡意攻擊。
圖2是根據本公開又一種實施方式的引擎保護方法的流程圖,如圖2所示,該方法包括圖1中的步驟S102,還包括步驟S201。
在步驟S201中,根據默認內存地址分配規則給所述可執行對象分配內存地址。
上述步驟即為圖1中步驟S101中所述的第一預設規則的其中一種。
所述默認內存地址分配規則即按照現有技術中使用JIT編譯技術的引擎為可執行對象分配內存地址的規則,本公開對所述默認內存地址分配規則不作限定。
通過上述技術方案,先根據默認內存地址分配規則給所述可執行對象分配內存地址,然後按照第二預設規則為所分配的內存地址設置保護區,其中所述保護區的權限為不可寫,這樣提供了一種通過為所分配的內存地址設置保護區進而來保護引擎不受非法惡意攻擊的方法。
圖3是根據本公開又一種實施方式的引擎保護方法的流程圖,圖3所示的方法是圖1中步驟S101中所述的第一預設規則中的另外一種。如圖3所示,該方法包括步驟S301至步驟S307。
在步驟S301中,獲取為所述可執行對象申請內存的內存申請函數中的申請內存大小、申請內存地址和申請內存權限。
可執行對象申請內存時,會通過自己的內存申請函數來進行申請,所述內存申請函數中主要包括申請的內存大小,申請內存的首地址,以及所要申請的內存頁的權限等參數信息。
在步驟S302中,判斷所述申請內存地址是否為空且所述申請內存權限是否為可讀寫可執行權限,如果是,則轉至步驟S303,如果不是,則轉至步驟S304。
判斷所述申請內存地址是否為空且所述申請內存權限是否為可讀寫可執行權限即為判斷所述可執行對象申請的內存是否為有被非法惡意攻擊的危險的內存。
在步驟S303中,在申請內存地址為空且申請內存權限為可讀寫可執行權限時,對所述申請內存地址進行隨機化處理以得到隨機化內存地址,然後轉至步驟S305。
步驟S303的主要目的是只在申請內存地址為空且申請內存權限為RWX權限時對申請內存地址進行隨機化,這樣就不會過多的佔用系統時間,不會影響引擎(例如,使用JIT編譯技術的引擎)的運行效率。
其中,所述對所述申請內存地址進行隨機化處理可以通過利用George Marsaglia's MWC算法來進行隨機化處理。George Marsaglia's MWC算法是一種利用異或與移位運算來產生高偽隨機度的偽隨機數生成算法,易於軟體實現,而且在硬體上運行速度非常快,因此對所述申請內存地址進行隨機化處理的過程幾乎不會影響到引擎的運行效率。
在步驟S304中,根據所述申請內存大小、所述申請內存地址和所述申請內存權限給所述可執行對象分配內存地址。
當判斷所述申請內存地址不為空時,說明可執行對象的申請內存地址是具體的地址,針對這種申請內存地址,選擇不對其進行隨機化處理,而直接根據所述申請內存大小、所述申請內存地址和所述申請內存權限給所述可執行對象分配內存地址。
當申請內存地址為空,但所述申請內存權限不為可讀寫可執行權限時,即所述可執行對象申請的內存地址不是RWX權限的內存地址時,也選擇不對其進行隨機化處理,而直接根據所述申請內存大小、所述申請內存地址和所述申請內存權限給所述可執行對象分配內存地址。因為當所述可執行對象的申請內存權限不是RWX權限時,所述引擎收到非法惡意攻擊的危險程度相對並不高,在這種情況下就無需佔用過多的系統時間對引擎進行保護。
在步驟S305中,根據所述隨機化內存地址、所述申請內存大小和所述申請內存權限確定要分配給所述可執行對象的內存地址。
所述確定要分配給所述可執行對象的內存地址的過程常用的方法是調用一個系統內存分配函數來完成。在windows系統下,所述系統內存分配函數可以是VitualAlloc函數,當然也可以是其他系統內存分配函數,例如直接調用Windows堆函數或者CRT堆函數等。對於不同的系統,調用的內存分配函數可以不一樣。
在步驟S306中,判斷所確定的內存地址是否屬於系統內存地址,如果否,則轉至步驟S307,如果是,則轉至步驟S303。
在確定了要分配給所述可執行對象的內存地址之後,需要對所確定的內存地址進行是否屬於系統內存地址的判斷,這一步屬於常規判斷。如果屬於系統內存地址,因為系統內存地址不可用,則返回步驟S303對所確定的內存地址進行再一次的隨機化處理,直到判斷所確定的內存地址不屬於系統內存地址時,即此時所確定的內存地址屬於用戶可用地址空間,這時,再轉至步驟S307。
在步驟S307中,將所確定的內存地址分配給所述可執行對象。
在判斷所確定的內存地址屬於用戶可用地址空間後,就將所確定的內存地址通過賦值的過程真正分配給可執行對象。
通過上述的技術方案,首先獲取為所述可執行對象申請內存的內存申請函數中的申請內存大小、申請內存地址和申請內存權限,當所述申請內存地址為空且所述申請內存權限為可讀寫可執行權限時,對所述申請內存地址進行隨機化處理以得到隨機化內存地址,然後根據所述隨機化內存地址、所述申請內存大小和所述申請內存權限確定要分配給所述可執行對象的內存地址,當所確定的內存地址屬於系統內存地址時,返回所述對所述申請內存地址進行隨機化處理以得到隨機化內存地址的步驟,而當所確定的內存地址不屬於系統內存地址時,就將所確定的內存地址分配給所述可執行對象,這樣,如果攻擊者想要在分配給可執行對象的內存地址上執行惡意代碼,由於採取了以上的隨機化處理,給可執行對象分配的內存地址是隨機的,攻擊者很難獲取可執行對象的準確內存地址,這樣,就能在一定程度上防止所述引擎被非法惡意攻擊。
以下是針對圖3中的隨機化處理方法的有效性評估。
從表1中可以看出,沒有使用本公開中的隨機化處理方法時,使用JIT編譯技術的引擎給可執行對象分配的是連續的相差0x10000位元組的內存地址,因此攻擊者能夠猜測出可執行對象在內存中的準確位置。然而,使用本公開的隨機化處理方法之後,所述引擎給可執行對象分配的地址是完全隨機的,攻擊者很難獲取可執行對象在內存中的準確位置。
表1
圖4是根據本公開又一種實施方式的引擎保護方法的流程圖,是圖1中步驟S101中所述的第一預設規則中的又一種。如圖4所示,該方法在圖3的步驟S301之後,還包括步驟S401和步驟S402,以及接下來的步驟S302至步驟S307。
在步驟S401中,判斷所述申請內存大小是否是2的冪次方,如果否,則轉至步驟S402,如果是,則轉至步驟S302。
判斷所述申請內存大小是否是2的冪次方的原因,一是通常情況下給可執行對象分配內存時,所述內存大小都是以2的冪的形式對齊的;二是2的冪的大小的內存空間適合硬體操作,有利用提高運行效率。
在步驟S402中,將所述申請內存大小增加至大於所述申請內存大小的最小的2的冪次方。
如果判斷所述申請內存大小不是2的冪次方,則主動將所述申請內存大小增加至最接近原申請內存大小的2的冪次方,然後在進行內存分配工作。
通過上述的技術方案,在所述獲取為所述可執行對象申請內存的內存申請函數中的申請內存大小、申請內存地址和申請內存權限之後,先判斷所述申請內存大小是否是2的冪次方,當所述申請內存大小不是2的冪次方時,將所述申請內存大小增加至大於所述申請內存大小的最小的2的冪次方,然後再進行後續的內存分配,這樣,有利於提高引擎的運行效率。
圖5是根據本公開又一種實施方式的引擎保護方法的流程圖,如圖5所示,該方法包括步驟S501和步驟S502。
步驟S501,將所述保護區設置在從所分配的內存地址的首地址開始的預設大小的內存空間內。
所述保護區的大小相對於所述所分配的內存地址大小很小,例如,所述保護區的大小可以是8k。
將所述保護區設置在從所分配的內存地址的首地址開始的預設大小的內存空間內時,保護區的內存地址與所分配的內存地址會出現重合,此時執行步驟S502。
步驟S502,將所分配的內存地址向後偏移,其中偏移的大小為所述預設大小。
在設置好保護區的地址之後,為避免內存重合,將所分配的內存地址向後偏移所述保護區的大小,保證保護區的內存地址與所分配的內存的保護地址是連續且不重合的。
通過上述的技術方案,先將所述保護區設置在從所分配的內存地址的首地址開始的預設大小的內存空間內,然後將所分配的內存地址向後偏移,其中偏移的大小為所述預設大小,這樣就為可執行對象的內存地址空間設置了一個能夠起到保護作用的保護區,由於這個保護區的地址與可執行對象的內存地址空間是連續的,且所述保護區的權限是不可寫,因此,當所述引擎受到非法惡意攻擊例如緩衝區溢出等攻擊時,就能夠及時的反應報警,以使所述引擎終止程序的運行,從而起到保護所述引擎的功能。
本公開的發明人以JavaScript引擎V8、Tamarin以及Safari’s為例,編寫了一系列的測試用例,用來測試使用本公開內容後引擎對於非法惡意攻擊的防範效果。表中的JIT引擎即使用JIT編譯技術的引擎。如表2所示,測試中的三個引擎對於測試用攻擊樣例的攻擊,防範效果都是有效的。
表2
本公開的發明人還將本公開內容與使用JIT編譯技術的引擎常用的安全防範措施進行了調研比較,結果如表3所示,從表3中可以看出,目前大多數使用JIT編譯技術的引擎都沒有使用本公開中的發明內容。
表3
其中,所述內存權限限定的方法,即在背景技術中提到的,少數使用JIT編譯技術的引擎採取的實時修改內存地址權限的方法,將分配給可執行對象的內存地址的寫權限與可執行權限分開,在最初為可執行對象分配內存地址時分配的是具有RWX權限的內存地址,並將權限修改為RW,在可執行對象即將執行時,將其內存地址的權限修改為RX,執行結束後再將其內存地址的權限修改為RW,這樣處理非常消耗處理器周期,會降低引擎效率。
另外,引擎JagerMonkey是實現了內存權限限定功能的,但是在默認情況下此功能未被開啟,因此默認其不具有此功能。
本公開的發明人還針對不同的使用JIT編譯技術的引擎進行了10000次的內存分配操作,表4顯示了在使用和不使用本公開內容的情況下的所用時間以及系統開銷,如表4所示,使用本公開內容的引擎的系統開銷在10%以內,這是在可以接受的範圍內的;且所用時間的差距也在可以接收的範圍內。
表4
圖6是根據本公開一種實施方式的引擎保護裝置100的示意框圖。如圖6所示,該裝置包括:
內存地址分配模塊10,用於按照第一預設規則給可執行對象分配內存地址;
保護區設置模塊20,用於按照第二預設規則為所分配的內存地址設置保護區,其中所述保護區的權限為不可寫。
通過上述技術方案,當可執行對象申請內存時,內存地址分配模塊10先按照第一預設規則給可執行對象分配內存地址,然後保護區設置模塊20按照第二預設規則為所分配的內存地址設置保護區,其中所述保護區的權限為不可寫,這樣就能夠在一定程度上保護所述內存地址,且避免其引擎在可執行對象執行時被非法惡意攻擊。
圖7是根據本公開又一種實施方式的引擎保護裝置100中的內存地址分配模塊10的示意框圖。如圖7所示,所述內存地址分配模塊10包括:
內存地址默認分配子模塊101,用於根據默認內存地址分配規則給所述可執行對象分配內存地址。
通過上述技術方案,內存地址默認分配子模塊101先根據默認內存地址分配規則給所述可執行對象分配內存地址,然後保護區設置模塊20再按照第二預設規則為所分配的內存地址設置保護區,其中所述保護區的權限為不可寫,這樣提供了一種通過為所分配的內存地址設置保護區進而來保護引擎不受非法惡意攻擊的方法。
圖8是根據本公開又一種實施方式的引擎保護裝置100中的內存地址分配模塊10的示意框圖。如圖8所示,所述內存地址分配模塊10包括:
獲取子模塊102,用於獲取為所述可執行對象申請內存的內存申請函數中的申請內存大小、申請內存地址和申請內存權限;
內存地址隨機化子模塊103,用於當所述申請內存地址為空且所述申請內存權限為可讀寫可執行權限時,對所述申請內存地址進行隨機化處理以得到隨機化內存地址;
內存地址確定子模塊104,用於根據所述隨機化內存地址、所述申請內存大小和所述申請內存權限確定要分配給所述可執行對象的內存地址;
內存地址判斷子模塊105,用於判斷所述內存地址確定子模塊所確定的內存地址是否屬於系統內存地址,並當所確定的內存地址屬於系統內存地址時,通知所述內存地址隨機化子模塊重新對所述申請內存地址進行隨機化處理以得到隨機化內存地址;
內存地址分配子模塊106,用於當所述內存地址判斷子模塊105判斷所確定的內存地址不屬於系統內存地址時,將所確定的內存地址分配給所述可執行對象。
通過上述的技術方案,首先獲取子模塊102獲取為所述可執行對象申請內存的內存申請函數中的申請內存大小、申請內存地址和申請內存權限,內存地址隨機化子模塊103在當所述申請內存地址為空且所述申請內存權限為可讀寫可執行權限時,對所述申請內存地址進行隨機化處理以得到隨機化內存地址,然後內存地址確定子模塊104根據所述隨機化內存地址、所述申請內存大小和所述申請內存權限確定要分配給所述可執行對象的內存地址,內存地址判斷子模塊105在當所確定的內存地址屬於系統內存地址時,返回所述對所述申請內存地址進行隨機化處理以得到隨機化內存地址的步驟,而內存地址分配子模塊106在當所確定的內存地址不屬於系統內存地址時,將所確定的內存地址分配給所述可執行對象,這樣,如果攻擊者想要在分配給可執行對象的內存地址上執行惡意代碼,由於採取了以上的隨機化處理,給可執行對象分配的內存地址是隨機的,攻擊者很難獲取可執行對象的準確內存地址,這樣,就能在一定程度上防止所述引擎被非法惡意攻擊。
圖9是根據本公開又一種實施方式的引擎保護裝置100中的內存地址分配模塊10的示意框圖。如圖9所示,在獲取子模塊102獲取為所述可執行對象申請內存的內存申請函數中的申請內存大小、申請內存地址和申請內存權限之後,所述內存地址分配模塊10還包括:
申請內存大小判斷子模塊107,用於判斷所述申請內存大小是否是2的冪次方;
申請內存大小增加子模塊108,用於當所述申請內存大小不是2的冪次方時,將所述申請內存大小增加至大於所述申請內存大小的最小的2的冪次方。
通過上述的技術方案,在獲取子模塊102獲取為所述可執行對象申請內存的內存申請函數中的申請內存大小、申請內存地址和申請內存權限之後,申請內存大小判斷子模塊107判斷所述申請內存大小是否是2的冪次方,申請內存大小增加子模塊108在當所述申請內存大小不是2的冪次方時,將所述申請內存大小增加至大於所述申請內存大小的最小的2的冪次方,然後再進行後續的內存分配,這樣,有利於提高引擎的運行效率。
圖10是根據本公開一種實施方式的引擎保護裝置100中的保護區設置模塊20的示意框圖。如圖10所示,所述保護區設置模塊20包括:
保護區設置子模塊201,用於將所述保護區設置在從所分配的內存地址的首地址開始的預設大小的內存空間內;
內存地址偏移子模塊202,用於將所分配的內存地址向後偏移,其中偏移的大小為所述預設大小。
通過上述的技術方案,保護區設置子模塊201先將所述保護區設置在從所分配的內存地址的首地址開始的預設大小的內存空間內,然後內存地址偏移子模塊202將所分配的內存地址向後偏移,其中偏移的大小為所述預設大小,這樣就為可執行對象的內存地址空間設置了一個能夠起到保護作用的保護區,由於這個保護區的地址與可執行對象的內存地址空間是連續的,且所述保護區的權限是不可寫,因此,當所述引擎受到非法惡意攻擊例如緩衝區溢出等攻擊時,就能夠及時的反應報警,以使所述引擎終止程序的運行,從而起到保護所述引擎的功能。
以上結合附圖詳細描述了本公開的優選實施方式,但是,本公開並不限於上述實施方式中的具體細節,在本公開的技術構思範圍內,可以對本公開的技術方案進行多種簡單變型,這些簡單變型均屬於本公開的保護範圍。
另外需要說明的是,在上述具體實施方式中所描述的各個具體技術特徵,在不矛盾的情況下,可以通過任何合適的方式進行組合。為了避免不必要的重複,本公開對各種可能的組合方式不再另行說明。
此外,本公開的各種不同的實施方式之間也可以進行任意組合,只要其不違背本公開的思想,其同樣應當視為本公開所公開的內容。