• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            tqsheng

            go.....
            隨筆 - 366, 文章 - 18, 評(píng)論 - 101, 引用 - 0
            數(shù)據(jù)加載中……

            庫(kù)函數(shù)的快速鑒別和識(shí)別技術(shù)

            標(biāo) 題: 庫(kù)函數(shù)的快速鑒別和識(shí)別技術(shù)
            翻 譯: 月中人
            時(shí) 間: 2006-09-07 15:20
            鏈 接: http://bbs.pediy.com/showthread.php?threadid=31636
            詳細(xì)信息:

             

             

            庫(kù)函數(shù)的快速鑒別和識(shí)別技術(shù)

            文檔編號(hào):

            S002-0017

            原作者:

            Ilfak Guilfanov [DataRescue.com]

            譯者:

            月中人 [PTG]

            審校:

             

            發(fā)布時(shí)間:

            2007-01-10

            原文標(biāo)題:

            Fast Library Identification and Recognition Technology

            關(guān)鍵詞:

            庫(kù)函數(shù),鑒別,識(shí)別,簽名,特征文件

            1. 原文版權(quán)聲明:

            (c) Copyright 1997 by Ilfak Guilfanov & DataRescue

            Reproduction strictly forbidden

            2. 譯文字典:

            Identification鑒別,即確定一個(gè)函數(shù)是什么;

            Recognition識(shí)別,即從程序中分離出屬于一個(gè)函數(shù)的那些代碼;

            misidentification錯(cuò)誤標(biāo)識(shí)

             

             

             

             


            1         目標(biāo)

            對(duì)于現(xiàn)代高級(jí)語(yǔ)言所寫(xiě)的程序,分離庫(kù)函數(shù)所費(fèi)的時(shí)間是反匯編的一個(gè)主要障礙。我們會(huì)因?yàn)闆](méi)有從中獲得新的知識(shí)而覺(jué)得時(shí)間被浪費(fèi)了:它只是我們深入分析程序和反映其意圖的算法之前一個(gè)必不可少的步驟。遺憾的是,每次反匯編一個(gè)新的程序都不得不重復(fù)這一步。

            有時(shí),了解一個(gè)庫(kù)函數(shù)的類(lèi)別能相當(dāng)大地減輕對(duì)程序的分析工作。這對(duì)于丟棄無(wú)用信息可能極有幫助。舉例來(lái)說(shuō),一個(gè)處理流數(shù)據(jù)的C++函數(shù)通常與程序的主要算法無(wú)關(guān)。

            請(qǐng)注意一個(gè)有意思的現(xiàn)象,每一高級(jí)語(yǔ)言程序都使用很多標(biāo)準(zhǔn)庫(kù)函數(shù),有時(shí)甚至達(dá)到所有被調(diào)用函數(shù)的95%是標(biāo)準(zhǔn)函數(shù)。使用某個(gè)眾所周知的編譯器編譯的“Hello, world!”程序中有:

                    庫(kù)函數(shù)        -    58個(gè)

                    函數(shù)main()    -    1個(gè)

            當(dāng)然,這是一個(gè)人為的例子,但我們的分析確實(shí)顯示,真實(shí)程序中的函數(shù)平均50%是庫(kù)函數(shù)。這就是為什么反匯編器的使用者不得不花費(fèi)他一半以上的時(shí)間來(lái)分離出那些庫(kù)函數(shù)。對(duì)一個(gè)未知程序進(jìn)行分析類(lèi)似于解答一個(gè)巨大的拼字智力游戲:我們確定的字母越多,就越容易猜測(cè)下一個(gè)字。反匯編過(guò)程中,在一個(gè)函數(shù)里面注解和有意義名字越多,意味著能夠更快地理解它的意圖。象OWLMFC以及其他一些標(biāo)準(zhǔn)庫(kù)的廣泛使用,甚至更增加了在目標(biāo)程序中標(biāo)準(zhǔn)函數(shù)所占的成分。

            使用現(xiàn)代技術(shù)(如,AppExpert或類(lèi)似的向?qū)В┯?span>C++編的一個(gè)中等尺寸的Win32程序,會(huì)從10002500個(gè)庫(kù)函數(shù)中調(diào)用任何函數(shù)。

            我們?cè)噲D創(chuàng)造一個(gè)識(shí)別標(biāo)準(zhǔn)庫(kù)函數(shù)的算法來(lái)輔助IDA用戶。我們希望它是一個(gè)實(shí)用而且有用的東西,因此必須接受一些限制:

            n         我們只考慮用C/C++編寫(xiě)的程序

            n         我們不企圖達(dá)成完美的函數(shù)識(shí)別:從理論上講這是不可能的。而且,對(duì)某些函數(shù)的識(shí)別可能導(dǎo)致不良后果。例如,對(duì)下面這個(gè)函數(shù)的識(shí)別將會(huì)誤導(dǎo)以致產(chǎn)生許多錯(cuò)誤標(biāo)識(shí)。

                            push    bp

                            mov     bp, sp

                            xor     ax, ax

                            pop     bp

                            ret

            這毫無(wú)意義,因?yàn)樵诂F(xiàn)代的C++庫(kù)中你會(huì)發(fā)現(xiàn)有許多不同名字的函數(shù)與它每個(gè)字節(jié)都完全相同。

            n         我們只識(shí)別和鑒別位于代碼段的函數(shù),而忽略數(shù)據(jù)段。

            n         當(dāng)一個(gè)函數(shù)已經(jīng)被成功鑒別的時(shí)候,我們給它指定一個(gè)名字和一個(gè)最終的注解。我們不打算提供關(guān)于函數(shù)參數(shù)或函數(shù)行為的信息。

            我們還要求做到以下幾點(diǎn)

            n         我們努力完全地避免假陽(yáng)性。我們認(rèn)為假陽(yáng)性(一個(gè)被錯(cuò)誤地鑒別的函數(shù))比假陰性(一個(gè)沒(méi)有鑒別出來(lái)的函數(shù))更糟。理想的情況應(yīng)該是根本不產(chǎn)生假陽(yáng)性。

            n         函數(shù)的識(shí)別需要你提供最低限度的處理器和存儲(chǔ)器資源。

            n         由于IDA的多價(jià)結(jié)構(gòu) - 它支持好幾十種非常不同的處理器 - 鑒別算法必須是獨(dú)立于平臺(tái)的,即它必須適用于為任何處理器編譯的程序。

            n         應(yīng)該鑒別main()函數(shù)并適當(dāng)?shù)丶右詷?biāo)注,因?yàn)槲覀儗?duì)庫(kù)的啟動(dòng)代碼不感興趣。

            2         難點(diǎn)

            存儲(chǔ)器的使用量

            識(shí)別和鑒別的主要障礙是函數(shù)的純數(shù)量及其占用存儲(chǔ)空間的大小。如果我們計(jì)算所有編譯器‘廠商’為不同存儲(chǔ)器‘模型’生產(chǎn)的所有庫(kù)所有‘版本’,所需儲(chǔ)存空間動(dòng)輒成百上千億字節(jié)之巨。

            如果我們?cè)噲D考慮OWLMFCMFC及類(lèi)似的庫(kù),情況更糟。所需要的儲(chǔ)存量是極大的。目前,個(gè)人電腦用戶不可能負(fù)擔(dān)得起劃撥成百上千兆字節(jié)的磁盤(pán)空間給一個(gè)簡(jiǎn)單的反匯編工具程序。因此,我們必須采用某種算法,如此便可以減少識(shí)別標(biāo)準(zhǔn)庫(kù)函數(shù)時(shí)所需信息的尺寸。當(dāng)然,由于必須被識(shí)別的函數(shù)個(gè)數(shù)多,我們需要一個(gè)有效率的識(shí)別算法:簡(jiǎn)單的暴力搜索并非一個(gè)可選方案。

             

            可變性

            另一個(gè)的困難在于程序中的‘變數(shù)’字節(jié)[_variant_ bytes]。有些字節(jié)在載入時(shí)被修正(被解決),而另一些字節(jié)在鏈接時(shí)變成常數(shù),但是大部份變數(shù)字節(jié)是來(lái)自引用的外部名字。在那種情況下,編譯器不知道被調(diào)用函數(shù)的地址,而且保留這些字節(jié)的值為零。這種所謂的“修正信息[fixup information]”通常被寫(xiě)到輸出文件[output file]的一個(gè)表(有時(shí)叫做“重定位表”或“重定位信息”)。下例包含有變數(shù)字節(jié)。

            B8 0000s                             mov     ax, seg _OVRGROUP_

            9A 00000000se                        call    _farmalloc

            26: 3B 1E 0000e                      cmp     bx, word ptr es:__ovrbuffer

             

            鏈接器將會(huì)試圖解決外部引用,使用所調(diào)用的函數(shù)的地址替換那些零,但是有些字節(jié)仍保留不變:程序中對(duì)動(dòng)態(tài)庫(kù)的引用或者包含絕對(duì)地址的那些字節(jié)。這些引用只能在載入時(shí)由系統(tǒng)裝載程序解決。它將會(huì)試圖解決所有的外部引用而且用絕對(duì)地址替換零。當(dāng)系統(tǒng)裝載程序不能夠解決某個(gè)外部引用時(shí),如同該程序引用一個(gè)未知DLL的情況一樣,程序就不運(yùn)行。

            某些鏈接器設(shè)置的優(yōu)化也會(huì)讓事情變復(fù)雜,因?yàn)槟切┕潭ǖ淖止?jié)有時(shí)會(huì)被改變。例如:

                           0000: 9A........        call    far ptr xxx

                         被替換成

                           0000: 90                nop

                           0001: 0E                push    cs

                           0002: E8....            call    near ptr xxx

             

            程序會(huì)照常運(yùn)行,但是鏈接器帶來(lái)的替換確實(shí)讓我們不可能利用函數(shù)模板做逐字節(jié)對(duì)比。一個(gè)程序中變數(shù)字節(jié)的出現(xiàn)使得不可能利用簡(jiǎn)單的檢驗(yàn)和來(lái)識(shí)別。如果函數(shù)沒(méi)有包含變數(shù)字節(jié),開(kāi)頭N字節(jié)的CRC[循環(huán)冗余校驗(yàn)碼]就足以鑒別和選擇在一個(gè)散列表中的一組函數(shù)。使用這種表會(huì)大大減少鑒別所需的信息大小:函數(shù)的名字、它的長(zhǎng)度以及檢驗(yàn)和就夠了。

            我們已經(jīng)用例子證明了,識(shí)別所有的標(biāo)準(zhǔn)庫(kù)函數(shù)是不可能的,或者甚至是不值得的。還有一個(gè)補(bǔ)充證明就是,某些函數(shù)是同一的,它們做的事完全相同,只是以不同的方式調(diào)用。例如,函數(shù)strcmp()fstrcmp()在大規(guī)模存儲(chǔ)器模型中是同一的。


            這里我們遇到一個(gè)左右為難的問(wèn)題:有些函數(shù)并非無(wú)足輕重,而且將它們標(biāo)注會(huì)對(duì)用戶有幫助,所以我們不想從識(shí)別過(guò)程中丟棄這些函數(shù),然而我們無(wú)法區(qū)別它們。

            更具體些:考慮這個(gè)

                            call    xxx

                            ret

                    或者

                            jmp     xxx

             

            乍一看,這些代碼片斷沒(méi)有特別之處。問(wèn)題是它們?cè)跇?biāo)準(zhǔn)庫(kù)中出現(xiàn),有時(shí)數(shù)量相當(dāng)多。Borland C++ 1.5OS/2編譯器使用的那些庫(kù)包含20個(gè)這種類(lèi)型的調(diào)用,出現(xiàn)在read()write()等重要的函數(shù)中。

            對(duì)這些函數(shù)的無(wú)格式比較不會(huì)有什么收獲。區(qū)別那些函數(shù)的唯一機(jī)會(huì)是發(fā)現(xiàn)它們調(diào)用其他的什么函數(shù)。通常,所有的短函數(shù)(只由2-3條指令組成)都難以識(shí)別,而且錯(cuò)誤識(shí)別的概率非常高。然而不識(shí)別它們是不好的,因?yàn)樗鼤?huì)導(dǎo)致級(jí)聯(lián)的識(shí)別失敗:如果我們不識(shí)別函數(shù)tolower(),我們可能就無(wú)法識(shí)別引用tolower()strlwr()

             

            版權(quán)

            最后,有一個(gè)明顯的版權(quán)問(wèn)題:就是一個(gè)反匯編器的分發(fā)可能不帶那些標(biāo)準(zhǔn)庫(kù)。

             


            3         要點(diǎn)

            為了解決以上提出的問(wèn)題,我們創(chuàng)建一個(gè)數(shù)據(jù)庫(kù),含有我們想要識(shí)別的所有庫(kù)的所有函數(shù)。于是對(duì)于反匯編出來(lái)的程序每個(gè)字節(jié),IDA Pro都檢查它能否標(biāo)志著某個(gè)標(biāo)準(zhǔn)庫(kù)函數(shù)的開(kāi)始。

            識(shí)別算法所需要的信息保存在一個(gè)特征[signature]文件中。每個(gè)函數(shù)表現(xiàn)為一個(gè)模式。模式是一個(gè)函數(shù)開(kāi)頭的32個(gè)字節(jié),其中所有變數(shù)字節(jié)用符號(hào)標(biāo)記。例如:

            558BEC0EFF7604..........59595DC3558BEC0EFF7604..........59595DC3 _registerbgidriver

            558BEC1E078A66048A460E8B5E108B4E0AD1E9D1E980E1C0024E0C8A6E0A8A76 _biosdisk

            558BEC1EB41AC55604CD211F5DC3.................................... _setdta

            558BEC1EB42FCD210653B41A8B5606CD21B44E8B4E088B5604CD219C5993B41A _findfirst

             

            其中變數(shù)字節(jié)顯示為“..”,有些函數(shù)開(kāi)始幾字節(jié)組成的序列相同。因此樹(shù)結(jié)構(gòu)好象很適合用來(lái)儲(chǔ)存它們:

            558BEC

                  0EFF7604..........59595DC3558BEC0EFF7604..........59595DC3 _registerbgidriver

                  1E

                    078A66048A460E8B5E108B4E0AD1E9D1E980E1C0024E0C8A6E0A8A76 _biosdisk

                  B4

                    1AC55604CD211F5DC3                                       _setdta

                    2FCD210653B41A8B5606CD21B44E8B4E088B5604CD219C5993B41A   _findfirst

             

            字節(jié)序列保存在樹(shù)的結(jié)點(diǎn)中。在這個(gè)例子中,樹(shù)的根包含序列“558BEC”,三個(gè)子樹(shù)起源于根,分別地以

            字節(jié)0E1EB4開(kāi)始。以B4開(kāi)始的子樹(shù)生出兩個(gè)子樹(shù)。每個(gè)子樹(shù)以葉子結(jié)束。關(guān)于函數(shù)的信息保存在那里(上述例子中只有名字是可見(jiàn)的)。

            [注意此處有誤:根據(jù)之前列出的4個(gè)模式來(lái)看,直接源于根的只有0E1E兩個(gè)子樹(shù),B4應(yīng)在1E之后]

            樹(shù)數(shù)據(jù)結(jié)構(gòu)同時(shí)達(dá)成兩個(gè)目標(biāo):

            n         存儲(chǔ)器需求減少了,因?yàn)槲覀冊(cè)跇?shù)結(jié)點(diǎn)儲(chǔ)存幾個(gè)函數(shù)共用字節(jié)。當(dāng)然,節(jié)省量與具有相同開(kāi)頭字節(jié)的函數(shù)數(shù)目成比例。

            n         它很適合于加快模式速配。將程序中某個(gè)特定位置與一個(gè)特征文件中所有函數(shù)進(jìn)行匹配所需的比較次數(shù)是以函數(shù)數(shù)目的對(duì)數(shù)增長(zhǎng)。

            單獨(dú)以函數(shù)開(kāi)頭的32個(gè)字節(jié)為基礎(chǔ)下結(jié)論不是很明智。正如前面所提到的,現(xiàn)代的真實(shí)庫(kù)包含一些以相同字節(jié)開(kāi)始的函數(shù):

            558BEC

                  56

                    1E

                      B8....8ED8

                               33C050FF7608FF7606..........83C406

                                                                  8BF083FEFF

                                0. _chmod   (20 5F33)

                                1. _access (18 9A62)

             

            當(dāng)兩個(gè)函數(shù)有相同的開(kāi)頭32個(gè)字節(jié)時(shí),它們被儲(chǔ)存在樹(shù)的同一個(gè)葉子中。為了解決這種情況,我們從位置33起開(kāi)始計(jì)算那些字節(jié)的CRC16直到遇到第一個(gè)變數(shù)字節(jié)為止。CRC被儲(chǔ)存在特征文件中。用于計(jì)算該CRC的字節(jié)數(shù)目也需要保存,因?yàn)檫@個(gè)數(shù)目因不同函數(shù)而不同。在上述例子中,計(jì)算_chmod函數(shù)(字節(jié)3352)的CRC16用了20字節(jié),而_access函數(shù)用18字節(jié)。

            當(dāng)然,有一種可能性是,第一個(gè)變數(shù)字節(jié)處在33d[十進(jìn)制數(shù)]位置。則用來(lái)計(jì)算CRC16的字節(jié)序列的長(zhǎng)度等于零。但實(shí)際上,這很少地發(fā)生,而且這個(gè)算法所引起錯(cuò)誤識(shí)別的次數(shù)非常低。

            有時(shí)函數(shù)有相同的起始32字節(jié)模式,而且有相同的CRC16,如下面的例子中

            05B8FFFFEB278A4606B4008BD8B8....8EC0

                      0. _tolower (03 41CB) (000C:00)

                      1. _toupper (03 41CB) (000C:FF)

             

            真抱歉:只有3個(gè)字節(jié)用來(lái)計(jì)算CRC16,而且兩個(gè)函數(shù)的CRC16是相同的。在這種情況下,我們將會(huì)嘗試尋找到某個(gè)位置,使得同一葉子的所有函數(shù)在那里有不同的字節(jié)。(在我們的例子中這個(gè)位置是32+3+000C[注意數(shù)的進(jìn)制]

            但是既使這個(gè)方法也不能識(shí)別所有的函數(shù)。看另外一個(gè)例子:

            ... (這里只顯示樹(shù)的一部分)

                            0D8A049850E8....83C402880446803C0075EE8BC7:

                              0. _strupr (04 D19F) (REF 0011: _toupper)

                              1. _strlwr (04 D19F) (REF 0011: _tolower)

             

            這些函數(shù)在非變數(shù)字節(jié)處完全相同,而只有它們調(diào)用的函數(shù)不同。在這個(gè)例子中區(qū)別兩函數(shù)的唯一方法是檢驗(yàn)偏移11處的那條指令所引用的名字。

            最后這個(gè)方法有一缺點(diǎn):函數(shù)_strupr()_ strlwr()的正確識(shí)別依賴于函數(shù)_toupper()_tolower()的識(shí)別。這意味著在因?yàn)槿鄙賹?duì)_toupper()_tolower()的引用而識(shí)別失敗的情況下,我們必須推遲識(shí)別并且稍后在找到_tolower()_toupper()后重做識(shí)別。這影響了算法的整體設(shè)計(jì):我們需要做第二趟以解決那些被推遲的識(shí)別。幸運(yùn)地,后一趟只應(yīng)用在程序中少數(shù)地方。

            最后,你會(huì)發(fā)現(xiàn)有的函數(shù)在非變數(shù)字節(jié)處完全相同,[而且變數(shù)字節(jié)]引用相同的名字,但是這些函數(shù)被以不同的名字調(diào)用。那些函數(shù)有相同的實(shí)現(xiàn)但有不同的名字。令人驚訝的是,在標(biāo)準(zhǔn)庫(kù)中,尤其在C++庫(kù)中,這是常見(jiàn)的情形。

            我們稱(chēng)這種情形為‘沖突’,即隸屬于同一葉子的一些函數(shù)無(wú)法通過(guò)上述方法相互區(qū)別。下面是一個(gè)典型的例子:

            558BEC1EB441C55606CD211F720433C0EB0450E8....5DCB................

               0. _remove (00 0000)

               1. _unlink (00 0000)

            或者

            8BDC36834702FAE9....8BDC36834702F6E9............................

               0. @iostream@$vsn            (00 0000)

               1. @iostream_withassign@$vsn (00 0000)

             

            人工智能是解決這些沖突的唯一辦法。因?yàn)楫?dāng)前目標(biāo)是效率和速度,所以我們決定把人工智能作為該算法的未來(lái)發(fā)展方向。


            4         實(shí)現(xiàn)

            IDA Pro 3.6版中,該算法的實(shí)際實(shí)現(xiàn)幾乎完全符合以上描述。我們已限制算法只使用于CC++語(yǔ)言編寫(xiě)的程序反匯編,但是未來(lái)絕對(duì)有可能為其他庫(kù)編寫(xiě)預(yù)處理器[pre-processors]

            為每個(gè)編譯器提供一個(gè)單獨(dú)的特征文件。這樣隔離降低了跨編譯器的鑒別沖突概率。一個(gè)特別的特征文件,名為啟動(dòng)特征文件[startup signature file],被應(yīng)用于所反匯編程序的入口以確定生成它所用的編譯器。一旦得以鑒別,我們就知道應(yīng)該使用哪個(gè)特征文件來(lái)反匯編其它部分。我們的算法成功地辨別市場(chǎng)上大多數(shù)常用的編譯器的啟動(dòng)模塊。

            既然我們以一個(gè)特征文件儲(chǔ)存適合于一個(gè)編譯器的所有函數(shù)簽名,所以就不必要區(qū)別這些編譯器的版本和/或庫(kù)的存儲(chǔ)器模型(小的、緊湊的、中等的、大的、極大的)。

            對(duì)于反匯編文件的每個(gè)格式,我們使用專(zhuān)門(mén)的啟動(dòng)特征文件。特征文件exe.sig用于MS DOS下運(yùn)行的程序,而lx.signe.sig用于OS/2下的,等等。

            為了降低短函數(shù)的錯(cuò)誤識(shí)別概率,我們必須完全地記錄任何一個(gè)對(duì)外部名字的引用--假如存在這樣的引用。這也許會(huì)在某種程度上降低函數(shù)識(shí)別成功的機(jī)會(huì),但是我們認(rèn)為事實(shí)證明采用這樣的方式是正確的。錯(cuò)誤地識(shí)別不如不識(shí)別。我們創(chuàng)建特征文件時(shí)不使用某些短函數(shù)(少于4字節(jié)),它們不包含對(duì)外部名字的引用,而且我們也不企圖去識(shí)別這類(lèi)函數(shù)。

            來(lái)自<ctype.h>的函數(shù)很短,但它們引用符號(hào)類(lèi)型數(shù)組,所以我們決定把對(duì)這個(gè)數(shù)組的引用作為一個(gè)例外:我們計(jì)算符號(hào)類(lèi)型數(shù)組的CRC16,并將它儲(chǔ)存特征文件中。

            沒(méi)有人工智能,我們用自然智能解決沖突。特征文件的創(chuàng)作人決定特征文件中函數(shù)的取舍。選擇函數(shù)是很容易的,而且實(shí)際上是編輯一個(gè)文本文件。

            函數(shù)的模式不是以它們的最初形式儲(chǔ)存在一個(gè)特征文件中(即,它們看起來(lái)不像例子那樣)。我們不使用那些形式的模式,而是儲(chǔ)存一些比特?cái)?shù)組,這些位用來(lái)確定某些字節(jié)的改變,即字節(jié)的數(shù)值被分離儲(chǔ)存。因此,除了函數(shù)的名字以外,特征文件沒(méi)有包含來(lái)自原始庫(kù)文件的字節(jié)。特征文件的創(chuàng)建包括兩個(gè)階段:庫(kù)的預(yù)處理和特征文件的創(chuàng)建。在第一個(gè)階段使用‘parselib’這個(gè)程序。它預(yù)處理*.obj*.lib文件以產(chǎn)生一個(gè)模式文件。模式文件包含函數(shù)的模式、它們的名字、它們的CRC16以及創(chuàng)建特征文件所需的所有其他信息。在第二個(gè)階段,‘sigmake’這個(gè)程序從模式文件建立特征文件。

            分為兩個(gè)階段允許sigmake工具程序與輸入文件的格式無(wú)關(guān)。因此未來(lái)將有可能為非*.obj*.lib格式的文件編寫(xiě)另外的預(yù)處理器。

            我們決定壓縮(使用InfoZip算法)所創(chuàng)建的特征文件以減少儲(chǔ)存它們所需的磁盤(pán)空間。

            為了方便用戶,我們?cè)噲D盡最大可能識(shí)別main()函數(shù)。鑒別這個(gè)函數(shù)的算法因編譯器不同而不同、因程序不同而不同。(DOS/OS2/Windows/GUI/Console...)。

            該算法作為一個(gè)文本字符串被寫(xiě)入一個(gè)特征文件中。遺憾的是,我們還不能自動(dòng)產(chǎn)生該算法。

             


            5         結(jié)果

            事實(shí)證明那些特征文件壓縮得很好;它們的壓縮系數(shù)可能大于2。這個(gè)壓縮率的理由是,一個(gè)特征文件大約95%是函數(shù)名字。(例子:用于MFC 2.x的特征文件在壓縮前是2.5MB,壓縮是700Kb。它包含33634個(gè)函數(shù)名字;平均每個(gè)函數(shù)用21字節(jié)儲(chǔ)存。通常,一個(gè)庫(kù)文件尺寸對(duì)一個(gè)特征文件尺寸的比率從100500不等。

            正確識(shí)別函數(shù)的百分比非常高。我們的算法識(shí)別出那個(gè)“Hello World”程序中除一個(gè)函數(shù)之外的所有函數(shù)。未被識(shí)別的函數(shù)只有一條指令:

                    jmp     off_1234

             

            尤其讓我們滿意的是沒(méi)有錯(cuò)誤識(shí)別。然而這并不意味著錯(cuò)誤永遠(yuǎn)不會(huì)發(fā)生。請(qǐng)注意,該算法只對(duì)函數(shù)工作。

            數(shù)據(jù)有時(shí)位于代碼段,而且因此我們需要把某些名字標(biāo)記為“數(shù)據(jù)名”,而非“函數(shù)名”。在一個(gè)現(xiàn)代的大型庫(kù)文件中檢驗(yàn)所有名字并標(biāo)記所有的數(shù)據(jù)名字是不容易的。

            我們計(jì)劃在未來(lái)某時(shí)實(shí)現(xiàn)這些數(shù)據(jù)名字的標(biāo)記。


            ©2000-2007 PEdiy.com All rights reserved.
            By PEDIY

            posted on 2008-01-24 12:05 tqsheng 閱讀(587) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            婷婷综合久久中文字幕蜜桃三电影| 亚洲精品无码久久久影院相关影片| 久久福利资源国产精品999| 99久久精品费精品国产| 国内精品久久久久久久久| 欧美久久一区二区三区| 国产亚洲精品久久久久秋霞| 久久精品麻豆日日躁夜夜躁| 88久久精品无码一区二区毛片 | 996久久国产精品线观看| 色综合久久88色综合天天 | 国内精品伊人久久久久av一坑 | 久久综合给合久久狠狠狠97色| 色婷婷综合久久久久中文 | 婷婷伊人久久大香线蕉AV| 好久久免费视频高清| 久久久国产精华液| 久久久久久A亚洲欧洲AV冫| 99久久99这里只有免费费精品| 久久精品成人影院| 久久综合久久综合久久| 日韩精品久久无码人妻中文字幕 | 久久久久亚洲AV无码专区体验| 久久精品国产亚洲麻豆| 一本色道久久综合亚洲精品| 久久性生大片免费观看性| 91精品国产9l久久久久| 久久久亚洲裙底偷窥综合| 人妻无码久久精品| 欧美日韩中文字幕久久久不卡| 国产精品熟女福利久久AV| 久久精品中文字幕无码绿巨人| 久久久精品国产免大香伊 | 亚洲天堂久久久| 婷婷久久综合九色综合绿巨人| 国产精品伊人久久伊人电影 | 久久人人超碰精品CAOPOREN| 亚洲国产精品久久久久婷婷软件 | 久久天天躁狠狠躁夜夜96流白浆| 久久无码AV中文出轨人妻| 国产香蕉97碰碰久久人人|