程序基址與變量地址偏移初探
1.這個程序是我對程序基地址和偏移量的一個測試程序,先上代碼,代碼運行的主要任務是打印各種變量和函數的地址
1 #include<stdlib.h> 2 #include<stdio.h> 3 #include<windows.h> 4 5 int number; 6 int mmpe; 7 int qq; 8 int qo = 100; 9 10 11 int add(int a, int b) 12 { 13 printf("%p\n", &a); 14 printf("%p\n", &b); 15 returna + b; 16 17 } 18 19 void main() 20 { 21 int x = 100; 22 int y = 0; 23 printf("%p\n", &number); 24 printf("%p\n", &x); 25 printf("%p\n", &y); 26 printf("%p\n", main); 27 printf("%p\n", add); 28 y = add(12, 15) + 100; 29 printf("%d\n", y); 30 while (number < 1000) 31 { 32 number++; 33 Sleep(1000); 34 } 35 36 }
2.我運行了三次程序,昨天運行了一次,今天運行了兩次,這兩次間隔時間比較短,中間沒有關機,程序基地址會改變,也就是說程序基地址是會變的,下面三張圖
是我用PCHunter捕獲的程序地址
3.下面三張圖是對應的運行結果截圖,後面一個截圖是對三張圖地址的說明
4.計算地址偏移量:
@1第一次全局變量number對基地址的偏移:337c,第二次:337c,第三次:337c,可見全局變量對基地址偏移量是確定的,
@2main中局部變量X,Y的地址三次都不同,且不在程序地址範圍,大於地址程序空間編號,它是存儲在堆棧中,隨機分配,用完立即釋放,y地址相對於x偏移8
@3main函數入口地址對基地址偏移第一次:1030,第二次1030,第三次1030,確定的
@4add函數入口地址第一次偏移:1000,第二次1000,第三次1000,確定的
@5add中a,b局部變量地址也不再程序地址範圍,大於地址程序空間編號,它是存儲在堆棧中,隨機分配,用完立即釋放,a地址大於b地址8個字節
@6對x,y,a,b對應地址:0X00ECFF34,0x00ECFF3C,0X00ECFF40,0X00ECFF38,所以由地址從小到大排序為x,b,y,a,其他兩張圖也遵從這個順序
5.下面是我稍微改變了的代碼去掉了
6 int mmpe;
7 int qq;
這兩行
1 #include<stdlib.h> 2 #include<stdio.h> 3 #include<windows.h> 4 5 int number; 6 int qo = 100; 7 8 9 int add(int a, int b) 10 { 11 printf("%p\n", &a); 12 printf("%p\n", &b); 13 return a + b; 14 15 } 16 17 void main() 18 { 19 int x = 100; 20 int y = 0; 21 printf("%p\n", &number); 22 printf("%p\n", &x); 23 printf("%p\n", &y); 24 printf("%p\n", main); 25 printf("%p\n", add); 26 y = add(12, 15) + 100; 27 printf("%d\n", y); 28 while (number < 1000) 29 { 30 number++; 31 Sleep(1000); 32 } 33 34 }
7.再次運行,捕獲截圖,可見與上面程序基地址馬上不同
8.再來看打印地址結果number地址偏移:337c,main函數:1030,add函數:1000,規則不變
9.我調換一下number和qo‘順序,分兩種一種初始化qo一種不初始化qo
10.再次測試,基地址均發生改變
11.運行打印結果,
第一張圖,初始化qo,最後一個為新添加的qo地址:偏移:3018,number地址偏移:3384,main和add依然偏移不變
第二張圖不初始化qo,最後一個為新添加的qo地址:偏移:337c,number地址偏移:3380,main和add依然不變
12.總結:不同類型變量分配地址不同,全局變量對程序基地址有一個確定的偏移,這個偏移與變量定義的位置順序有關,還與變量的類型有關,程序裏的函數入口對基地址偏移量也是確定值,與函數位置有關,所以找到一個程序基地址並不難,但是要計算一個變量的地址偏移量就比較難了,因為代碼稍微改動一下偏移量就變了,除非你知道源碼,如果要修改的是局部變量就更難計算偏移量了,這與它的特新有關,但是我們可以使用內存檢索來查詢一個變量的地址或者函數入口地址,windows操作系統不允許別的程序去訪問另一個程序的地址空間,所以要做外掛也必須使用註入的方式,除非你越過操作系統,這樣難度可想而知。
程序基址與變量地址偏移初探