日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C#不为人知的秘密-缓冲区溢出

發布時間:2023/12/19 C# 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#不为人知的秘密-缓冲区溢出 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
開場白

  各位朋友們,當你們看到網上傳播關于微軟windows、IE對黑客利用“緩沖區溢出”、0day漏洞攻擊的新聞,是否有過自己也想試試身手,可惜無從下手的感慨?本文將完全使用C#語言,探索那些不為人知的秘密。

  1.本文講述在C#中利用堆棧緩沖區溢出動態修改內存,達到改變應用程序執行流程的目的。

  2.如果你是高手,請指出本文的不足。

  3.為了讓本文通俗易懂,代碼將極盡精簡。

  現在開始

  我們知道,當數組下標越界時,.NET會自動拋出StackOverflowException,這樣便讓我們可以安全的讀寫內存,那么我們有沒有逾越這個自動檢測的屏障,達到我們非常操作的目的呢?答案是有的,而且我們可以修改一些關鍵變量如if、switch的判斷值,for循環變量i值,甚至方法返回值,當然理論上還可以注入代碼、轉移代碼執行區塊,前提是必須在unsafe代碼里。

  方法在被調用時,系統會進行以下幾項操作:將該方法入棧、參數入棧、返回地址入棧、控制代碼區入棧(EIP入棧)。我們想要訪問方法的棧內地址,常規的托管代碼是不行的,只能使用unsafe代碼,但也并不是說你非要精通C/C++語言和指針操作,本文的例子都非常簡單,完全可以將指針就認為是簡版C#數組。

  改變臨時變量的值

  先給出一段代碼,然后再詳細解釋原理。

?代碼

static? unsafe?void Main(string[] args)
??????? {
??????????? //在棧上申請一個只能保存一個int32的內存段 www.elivn.com
??????????? int* p =?stackalloc?int[1];

??????????? for (var i =?0; i <?30; i++)
??????????? {
??????????????? System.Threading.Thread.Sleep(200);

??????????????? Console.WriteLine("{0}\n", i);
??????????????? p[i] =?0;
??????????? }
???????????
??????????? Console.ReadLine();
??????? }

  這是一個既簡單,但是對于從沒有嘗試這樣寫過代碼的開發者來說,又頗耐人尋味,C#(包括C/C++)不會去檢查指針p的偏移量是否越界,那么這段代碼將會順利編譯并運行,那么for循環會順利執行30次嗎?還是......

  結論是,這將是一個死循環,因為p不斷的遞增1偏移,并將附近的內存的值全改為0,而局部變量i是靠p最近的變量,所有當p[i]的偏移地址等于i的地址時,代碼p[i]=0就等價于i=0,實際上我在測試中i=6的時候i的值就被覆蓋為0了,我在代碼中添加了Thread.Sleep(200)和Console.WriteLine("{0}\n", i)就是讓大家能更直觀的看到程序的執行過程,當然這里也可以改為p[i]=1,p[i]=2等數字

  搜索內存值并修改

  還是先給出代碼

代碼 static? unsafe?void Main(string[] args)
??????? {
??????????? Console.WriteLine(Change_Result());
??????????? Console.ReadLine();
??????? }

??????? static?unsafe?int Change_Result()
??????? {
???????????
??????????? int i =?0;
??????????? //變量result,默認的返回值
??????????? int result =?123;
??????????? //申請一段棧內存,大小可隨意設置
??????????? int* p =?stackalloc?int[1];
??????????? //從當前棧地址開始向下查找與函數返回值相匹配的地址,一旦匹配則修改為10000
??????????? while (true)
??????????? {
??????????????? if (p[++i] ==?123)
??????????????? {
??????????????????? p[i] =?10000;
??????????????????? break;
??????????????? }
??????????? };
??????????? return result;
??????? }

  變量result作為方法的返回值默認為123,并且沒有任何顯式修改其值的代碼,關鍵在這里

while (true)
{
if (p[++i] == 123)
{
p[i] = 10000;
break;
}
}

  這段代碼找到值為123的內存地址(也就可能是變量result的地址),然后將其值修改為10000,當然,函數返回值就肯定不會再是原先的123咯

  這就是經典的StackOverFlow的兩個例子,希望通俗易懂能讓大家所接受,另外緩沖區溢出并不只是改變內存的值,在高手的手里,他還可以執行任意代碼,因為方法執行的時候總會有一個指針指向方法即將執行的下一條指令,如果控制了這個指針,就控制了進程。

轉載于:https://www.cnblogs.com/seoxs/archive/2011/04/26/2028903.html

總結

以上是生活随笔為你收集整理的C#不为人知的秘密-缓冲区溢出的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。