青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Shuffy

不斷的學習,不斷的思考,才能不斷的進步.Let's do better together!
posts - 102, comments - 43, trackbacks - 0, articles - 19

windows進程中的內存結構

Posted on 2007-04-13 22:49 Shuffy 閱讀(149) 評論(0)  編輯 收藏 引用 所屬分類: VC++/C/C++/C#瀏覽集合

信息來源:中國源碼下載站

接觸過編程的人都知道,高級語言都能通過變量名來訪問內存中的數據。那么這些變量在內存中是如何存放的呢?程序又是如何使用這些變量的呢?下面就會對此進行深入的討論。下文中的C語言代碼如沒有特別聲明,默認都使用VC編譯的release版。 
首先,來了解一下 C 語言的變量是如何在內存分部的。C 語言有全局變量(Global)、本地變量(Local),靜態變量(Static)、寄存器變量(Regeister)。每種變量都有不同的分配方式。先來看下面這段代碼: 
#include <stdio.h> 
int g1=0, g2=0, g3=0; 
int main() 

static int s1=0, s2=0, s3=0; 
int v1=0, v2=0, v3=0; 
//打印出各個變量的內存地址 
printf("0x%08x\n",&v1); //打印各本地變量的內存地址 
printf("0x%08x\n",&v2); 
printf("0x%08x\n\n",&v3); 
printf("0x%08x\n",&g1); //打印各全局變量的內存地址 
printf("0x%08x\n",&g2); 
printf("0x%08x\n\n",&g3); 
printf("0x%08x\n",&s1); //打印各靜態變量的內存地址 
printf("0x%08x\n",&s2); 
printf("0x%08x\n\n",&s3); 
return 0; 

編譯后的執行結果是: 
0x0012ff78 
0x0012ff7c 
0x0012ff80 
0x004068d0 
0x004068d4 
0x004068d8 
0x004068dc 
0x004068e0 
0x004068e4 
輸出的結果就是變量的內存地址。其中v1,v2,v3是本地變量,g1,g2,g3是全局變量,s1,s2,s3是靜態變量。你可以看到這些變量在內存是連續分布的,但是本地變量和全局變量分配的內存地址差了十萬八千里,而全局變量和靜態變量分配的內存是連續的。這是因為本地變量和全局/靜態變量是分配在不同類型的內存區域中的結果。對于一個進程的內存空間而言,可以在邏輯上分成3個部份:代碼區,靜態數據區和動態數據區。動態數據區一般就是“堆棧”。“棧(stack)”和“堆(heap)”是兩種不同的動態數據區,棧是一種線性結構,堆是一種鏈式結構。進程的每個線程都有私有的“棧”,所以每個線程雖然代碼一樣,但本地變量的數據都是互不干擾。一個堆棧可以通過“基地址”和“棧頂”地址來描述。全局變量和靜態變量分配在靜態數據區,本地變量分配在動態數據區,即堆棧中。程序通過堆棧的基地址和偏移量來訪問本地變量。 

├———————┤低端內存區域 
│ …… │ 
├———————┤ 
│ 動態數據區 │ 
├———————┤ 
│ …… │ 
├———————┤ 
│ 代碼區 │ 
├———————┤ 
│ 靜態數據區 │ 
├———————┤ 
│ …… │ 
├———————┤高端內存區域 

堆棧是一個先進后出的數據結構,棧頂地址總是小于等于棧的基地址。我們可以先了解一下函數調用的過程,以便對堆棧在程序中的作用有更深入的了解。不同的語言有不同的函數調用規定,這些因素有參數的壓入規則和堆棧的平衡。windows API的調用規則和ANSI C的函數調用規則是不一樣的,前者由被調函數調整堆棧,后者由調用者調整堆棧。兩者通過“__stdcall”和“__cdecl”前綴區分。先看下面這段代碼: 
#include <stdio.h> 
void __stdcall func(int param1,int param2,int param3) 

int var1=param1; 
int var2=param2; 
int var3=param3; 
printf("0x%08x\n",&para;m1); //打印出各個變量的內存地址 
printf("0x%08x\n",&para;m2); 
printf("0x%08x\n\n",&para;m3); 
printf("0x%08x\n",&var1); 
printf("0x%08x\n",&var2); 
printf("0x%08x\n\n",&var3); 
return; 

int main() 

func(1,2,3); 
return 0; 

編譯后的執行結果是: 
0x0012ff78 
0x0012ff7c 
0x0012ff80 
0x0012ff68 
0x0012ff6c 
0x0012ff70 

├———————┤<—函數執行時的棧頂(ESP)、低端內存區域 
│ …… │ 
├———————┤ 
│ var 1 │ 
├———————┤ 
│ var 2 │ 
├———————┤ 
│ var 3 │ 
├———————┤ 
│ RET │ 
├———————┤<—“__cdecl”函數返回后的棧頂(ESP) 
│ parameter 1 │ 
├———————┤ 
│ parameter 2 │ 
├———————┤ 
│ parameter 3 │ 
├———————┤<—“__stdcall”函數返回后的棧頂(ESP) 
│ …… │ 
├———————┤<—棧底(基地址 EBP)、高端內存區域 

上圖就是函數調用過程中堆棧的樣子了。首先,三個參數以從又到左的次序壓入堆棧,先壓“param3”,再壓“param2”,最后壓入“param1”;然后壓入函數的返回地址(RET),接著跳轉到函數地址接著執行(這里要補充一點,介紹UNIX下的緩沖溢出原理的文章中都提到在壓入RET后,繼續壓入當前EBP,然后用當前ESP代替EBP。然而,有一篇介紹windows下函數調用的文章中說,在windows下的函數調用也有這一步驟,但根據我的實際調試,并未發現這一步,這還可以從param3和var1之間只有4字節的間隙這點看出來);第三步,將棧頂(ESP)減去一個數,為本地變量分配內存空間,上例中是減去12字節(ESP=ESP-3*4,每個int變量占用4個字節);接著就初始化本地變量的內存空間。由于“__stdcall”調用由被調函數調整堆棧,所以在函數返回前要恢復堆棧,先回收本地變量占用的內存(ESP=ESP+3*4),然后取出返回地址,填入EIP寄存器,回收先前壓入參數占用的內存(ESP=ESP+3*4),繼續執行調用者的代碼。參見下列匯編代碼: 
;--------------func 函數的匯編代碼------------------- 
:00401000 83EC0C sub esp, 0000000C //創建本地變量的內存空間 
:00401003 8B442410 mov eax, dword ptr [esp+10] 
:00401007 8B4C2414 mov ecx, dword ptr [esp+14] 
:0040100B 8B542418 mov edx, dword ptr [esp+18] 
:0040100F 89442400 mov dword ptr [esp], eax 
:00401013 8D442410 lea eax, dword ptr [esp+10] 
:00401017 894C2404 mov dword ptr [esp+04], ecx 
……………………(省略若干代碼) 
:00401075 83C43C add esp, 0000003C ;恢復堆棧,回收本地變量的內存空間 
:00401078 C3 ret 000C ;函數返回,恢復參數占用的內存空間 
;如果是“__cdecl”的話,這里是“ret”,堆棧將由調用者恢復 
;-------------------函數結束------------------------- 

;--------------主程序調用func函數的代碼-------------- 
:00401080 6A03 push 00000003 //壓入參數param3 
:00401082 6A02 push 00000002 //壓入參數param2 
:00401084 6A01 push 00000001 //壓入參數param1 
:00401086 E875FFFFFF call 00401000 //調用func函數 
;如果是“__cdecl”的話,將在這里恢復堆棧,“add esp, 0000000C” 
聰明的讀者看到這里,差不多就明白緩沖溢出的原理了。先來看下面的代碼: 
#include <stdio.h> 
#include <string.h> 
void __stdcall func() 

char lpBuff[8]="\0"; 
strcat(lpBuff,"AAAAAAAAAAA"); 
return; 

int main() 

func(); 
return 0; 

編譯后執行一下回怎么樣?哈,“"0x00414141"指令引用的"0x00000000"內存。該內存不能為"read"。”,“非法操作”嘍!"41"就是"A"的16進制的ASCII碼了,那明顯就是strcat這句出的問題了。"lpBuff"的大小只有8字節,算進結尾的’\0’,那strcat最多只能寫入7個"A",但程序實際寫入了11個"A"外加1個’\0’。再來看看上面那幅圖,多出來的4個字節正好覆蓋了RET的所在的內存空間,導致函數返回到一個錯誤的內存地址,執行了錯誤的指令。如果能精心構造這個字符串,使它分成三部分,前一部份僅僅是填充的無意義數據以達到溢出的目的,接著是一個覆蓋RET的數據,緊接著是一段shellcode,那只要著個RET地址能指向這段shellcode的第一個指令,那函數返回時就能執行shellcode了。但是軟件的不同版本和不同的運行環境都可能影響這段shellcode在內存中的位置,那么要構造這個RET是十分困難的。一般都在RET和shellcode之間填充大量的NOP指令,使得exploit有更強的通用性。 

├———————┤<—低端內存區域 
│ …… │ 
├———————┤<—由exploit填入數據的開始 
│ │ 
│ buffer │<—填入無用的數據 
│ │ 
├———————┤ 
│ RET │<—指向shellcode,或NOP指令的范圍 
├———————┤ 
│ NOP │ 
│ …… │<—填入的NOP指令,是RET可指向的范圍 
│ NOP │ 
├———————┤ 
│ │ 
│ shellcode │ 
│ │ 
├———————┤<—由exploit填入數據的結束 
│ …… │ 
├———————┤<—高端內存區域

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美日韩第一区| 夜色激情一区二区| 久久久久久午夜| 夜夜嗨av一区二区三区四季av | 欧美日韩午夜| 巨乳诱惑日韩免费av| 一本久久综合亚洲鲁鲁| 欧美精品网站| 欧美激情在线| 亚洲综合999| 亚洲精品日韩欧美| 91久久精品国产91久久性色| 美女福利精品视频| 久久国产福利国产秒拍| 久久精品夜色噜噜亚洲aⅴ| 亚洲欧美日韩国产综合在线| 一区二区三区久久精品| 99热免费精品| 国产精品欧美一区二区三区奶水 | 亚洲在线免费视频| 亚洲午夜视频在线| 在线观看日产精品| 在线日韩视频| 亚洲精选大片| 亚洲午夜羞羞片| 校园春色综合网| 欧美福利视频| 亚洲色图综合久久| 欧美一区二区三区播放老司机| 久久久久久久网| 欧美日韩精品系列| 亚洲第一精品影视| 一区二区久久久久| 性欧美暴力猛交另类hd| 欧美 日韩 国产 一区| 亚洲激情第一区| 亚久久调教视频| 欧美激情在线观看| 国产九色精品成人porny| 亚洲国产cao| 亚洲欧美网站| 亚洲国产日韩欧美在线动漫| 亚洲一级黄色av| 久久精品中文字幕一区| 欧美精品www| 欧美国产先锋| 国语自产精品视频在线看| 99爱精品视频| 久久久亚洲影院你懂的| 亚洲免费观看在线观看| 欧美韩日一区二区| 久久av资源网| 国产精品s色| 亚洲国产精品一区二区尤物区| 亚洲深夜影院| 99精品热6080yy久久 | 99国产精品一区| 欧美呦呦网站| 久久久水蜜桃| 国产伦精品一区二区三区视频黑人 | 亚洲男人的天堂在线| 久久精品99久久香蕉国产色戒 | 久久精品在线视频| 国产日本欧洲亚洲| 亚洲欧美日韩国产综合精品二区| 日韩写真视频在线观看| 欧美日韩国产色视频| 亚洲美女在线视频| 国产精品ⅴa在线观看h| 欧美亚洲日本国产| 正在播放亚洲| 亚洲精品久久久久久下一站| 老鸭窝亚洲一区二区三区| 在线日本成人| 亚洲国产精品尤物yw在线观看 | 欧美jjzz| 欧美激情在线有限公司| 亚洲丝袜av一区| 亚洲视频在线看| 国产免费一区二区三区香蕉精| 久久激情中文| 美日韩精品免费观看视频| 91久久精品一区二区别| 日韩亚洲视频在线| 国产日韩精品一区二区浪潮av| 久久精品国产综合精品| 久久婷婷亚洲| 亚洲综合二区| 久久久精品日韩欧美| 亚洲剧情一区二区| 欧美一区二区三区婷婷月色 | 国产欧美一区二区白浆黑人| 久久久久九九九| 欧美高清视频在线| 欧美一区二区在线视频| 免费不卡在线观看| 亚洲欧美日韩一区在线| 久久综合网络一区二区| 亚洲愉拍自拍另类高清精品| 欧美在线免费观看视频| 亚洲精品在线观| 亚洲欧美美女| 亚洲视频第一页| 久久视频在线免费观看| 亚洲午夜羞羞片| 欧美不卡视频一区发布| 午夜精品在线| 欧美精品成人91久久久久久久| 欧美在线中文字幕| 欧美三日本三级三级在线播放| 久久精品国产精品亚洲综合 | 国产日韩欧美二区| 国产精品亚洲综合一区在线观看| 欧美激情综合色综合啪啪| 女人香蕉久久**毛片精品| 在线亚洲高清视频| 亚洲色图自拍| 亚洲国产精品99久久久久久久久| 欧美国产91| 欧美一区二区日韩| 欧美—级a级欧美特级ar全黄| 久久av在线| 欧美日韩在线视频一区| 女同性一区二区三区人了人一 | 欧美小视频在线| 久久夜色精品国产亚洲aⅴ| 国产精品久久久久久久浪潮网站| 亚洲欧美日韩精品久久奇米色影视| 久久噜噜噜精品国产亚洲综合| 性欧美xxxx视频在线观看| 欧美体内she精视频| 亚洲欧洲在线播放| 最新亚洲电影| 亚洲精品一线二线三线无人区| 国产精品蜜臀在线观看| av成人毛片| 亚洲欧洲综合另类| 久久久久久久久久久一区 | 你懂的视频一区二区| 国产亚洲精品久久飘花| 亚洲小视频在线观看| 亚洲女性喷水在线观看一区| 欧美日韩成人精品| 亚洲精选国产| 一本久久a久久精品亚洲| 欧美大色视频| 亚洲国产成人精品女人久久久 | 欧美承认网站| 亚洲高清二区| 一区二区三区久久| 国产精品久久久久久久浪潮网站| 亚洲天堂久久| 香蕉国产精品偷在线观看不卡| 国产精品入口尤物| 欧美在线亚洲在线| 欧美成ee人免费视频| 日韩视频一区二区三区在线播放 | 欧美一级大片在线观看| 欧美一级黄色网| 亚洲风情在线资源站| 国产精品自拍一区| 国产无一区二区| 最新国产の精品合集bt伙计| 亚洲尤物在线视频观看| 久久久久久成人| 亚洲高清电影| 毛片一区二区三区| 欧美午夜美女看片| 国产精品啊啊啊| 一色屋精品视频免费看| 性欧美videos另类喷潮| 欧美视频一区二区三区…| 一区二区三区鲁丝不卡| 欧美在线视频免费观看| 极品尤物av久久免费看 | 久久精品视频在线观看| 韩日午夜在线资源一区二区| 久久亚洲综合色| 夜久久久久久| 欧美成人精品高清在线播放| 在线一区亚洲| 在线免费高清一区二区三区| 欧美性jizz18性欧美| 久久手机免费观看| 亚洲综合色自拍一区| 亚洲激情另类| 久久精品30| 亚洲一区中文| 亚洲精品系列| 在线日韩av片| 国内一区二区三区| 国产精品免费看片| 欧美日韩在线大尺度| 欧美成人激情视频| 久久成人精品无人区| 一区二区三区欧美成人| 欧美激情第五页| 久久婷婷国产麻豆91天堂| 午夜在线电影亚洲一区| 中国亚洲黄色|