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 return a + 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操作系统不允许别的程序去访问另一个程序的地址空间,所以要做外挂也必须使用注入的方式,除非你越过操作系统,这样难度可想而知。