堆溢出的DWORD Shoot核心原理-口语化
1、雙向鏈表上有a、b、c一共3個連續(xù)的堆塊,a、b、c三者之間的實際物理地址可能相差很大,但是絕對不會三者之間無其他字節(jié),如果無其他字節(jié),那表示他們三個可以合并成一個物理連接起來的大塊,堆管理系統(tǒng)很快會讓他們三者搞基成一個大個子堆塊,拆下來重新按照其尺寸重新鏈接到該去的鏈表位置去。。。而不會放縱其在鏈表上物理地址緊密鏈接的同時還分成3個堆塊串聯(lián)在鏈表上。
2、返回正題,拆下其中一個堆塊b時,會產生a、c之間的空缺,導致a、c無法相互知曉。所以堆管理系統(tǒng)會在拆b時,把a和c縫縫補補,連在一起,成為新鏈表,等待下次拆分、合并等等。
關鍵來了,
【1】雙向鏈表上a與b之間有從左往右的一條線(這條線體現(xiàn)在:每個堆塊都在距離自身堆塊塊首的相對第9~12字節(jié)保存他前方那個堆塊(遠離鏈表頭的方向)的塊數據的地址)連起來.
【2】又有從右往左的一條線連起來(這條線體現(xiàn)在:每個堆塊都在距離自身堆塊塊首相對13~16字節(jié)處保存他屁股后面那個堆塊(當前堆塊屁股位置是靠近鏈表頭地址的那邊)的塊數據的地址);
以此類推每2個相鄰堆塊之間由于雙向可循,由于每個堆塊上都記載著往該塊左邊或右邊方向走的下一個地址(即上述9~12、13~16字節(jié)數據均為地址值),所以斷掉一個塊(暫稱為塊b)時,該斷掉的塊的左右兩邊欲形成新連接,必須知道彼此的地址。這個重新知曉相互地址的任務由即將被拆下來的堆塊去處理,因為它才同時熟悉兩邊的鄰居,知道他們地址,知道他們聯(lián)系電話,QQ號,微信號。。。于是該堆塊(又叫節(jié)點)把他身上距離頭頂第9~12字節(jié)的4個字節(jié)的數據(實際上是他右鄰居堆塊的門牌號地址,舉例0x001A0038)抄下來,給到左鄰居。怎么給?在他身上距離頭頂第13~16字節(jié)處的4個字節(jié),就是他左鄰居的門牌號地址(這個數據肯定比他右鄰居的門牌號地址小,假設0x001A000A),我們于是按照這個左鄰居地址,在堆管理系統(tǒng)幫助下,把0x001A0038這個數值給到左鄰居家去:mov [0x001A000A],0x001A0038 ?? 。。。。都知道[]方括號的意思吧。等右鄰居的地址給了左鄰居后,再把左鄰居的地址按此方法給到右鄰居,他此時也就從鏈表上斷下來了,因為空表鏈表上已經沒有他存在的痕跡了。
而這個斷掉塊b過程之前,我們先通過字符串變量溢出,將字符串從其他塊溢出到塊b中,即覆蓋了他的第9~16字節(jié)數據,效果就是改了他身上所保管的左、右鄰居門牌號地址,一般就是右鄰門牌號覆蓋為shellcode入口地址,左鄰門牌號覆蓋為各種特殊地址,比如重要函數調用地址,棧幀中函數返回地址,棧幀中SEH的句柄。這樣,在塊b斷下來時,他會把shellcode地址賦值到某個經常調用的函數的地址上,或棧幀中當前函數返回地址上,或棧幀中距離當前棧最近的SEH異常處理最近的那個句柄。
然后堆塊這邊就沒他們什么事了,就等著某個函數被調用,錯誤跳轉到shellcode地址去執(zhí)行我們構造的code;等著棧幀中當前函數返回時執(zhí)行的卻是跳轉到shellcode地址去執(zhí)行我們構造的code;溢出發(fā)生了導致系統(tǒng)啟動異常處理,執(zhí)行了SEH異常處理相關函數,跳轉到shellcode地址去執(zhí)行我們構造的code。。。。。。
溢出并惡意執(zhí)行了我們的代碼。
現(xiàn)在回頭去看,堆塊斷下來時,把錯誤的右鄰居門牌號(子彈,shellcode入口地址,共計4個字節(jié),即為DWORD雙字),抄給左鄰居時(左鄰居的地址已經被改為目標地址,任何能被調用的地址),就是發(fā)生了子彈射擊,DWORD Shoot是也。
? --至于后面的把左鄰居地址給右鄰居地址的操作,會導致反射,影響shellcode,這個以后再分享了。
轉載于:https://www.cnblogs.com/taonull/p/3930054.html
總結
以上是生活随笔為你收集整理的堆溢出的DWORD Shoot核心原理-口语化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 加载指定路径下所有文件
- 下一篇: [架构] 分布式和集群的区别