首页
社区
课程
招聘
[原创]《学习笔记》指针有啥难?
发表于: 2020-1-16 22:42 6267

[原创]《学习笔记》指针有啥难?

2020-1-16 22:42
6267

今天下雪了,所以我来看雪!!!

最近两个月我木有发帖,学校里的事比较多哈。。。第14届安徽省大学生职业规划大赛(金奖)主题就是软件逆向工程师(评委:这是啥???)。然后就是国家奖学金等。不亏,给

钱让我上大学。。。


好的,装0xD完了。进入正题。

首先我要解释一个梗:指针就是地址??? 不完全是! 

指针难么?



首先我们来看指针的宽度是啥。

char a=1;

char* b=(char*)1; //下面解释        

char** c=(char**)1;

a的宽度是1个字节

b的宽度是4个字节(32位)

二级指针 c也是4???

啥是二级指针 ?指向一级指针的东西???弄弄弄! 不一定是

继续,

short y;//宽度2字节

int z;//宽度4字节(32位机)

float f;//宽度4(32位机)

double d;//宽度8

加个*会怎样???

char* x;   

short* y; 

int* z;      

float* f;   

double* d;       

2020年我国全面进入小康社会,所有屌丝都有女朋友!!!人人平等!

咳咳,跑题了。。。它们的宽度都是4个字节,不信?你看!

14:   char* x=(char*)10;

00401048 C7 45 FC 0A 00 00 00 mov         dword ptr [ebp-4],0Ah

15:

16:   short* y=(short*)10;

0040104F C7 45 F8 0A 00 00 00 mov         dword ptr [ebp-8],0Ah

17:

18:   int* z=(int*)10;

00401056 C7 45 F4 0A 00 00 00 mov         dword ptr [ebp-0Ch],0Ah

19:

20:   float* f=(float*)10;

0040105D C7 45 F0 0A 00 00 00 mov         dword ptr [ebp-10h],0Ah

21:

22:   double* d=(double*)10;

00401064 C7 45 EC 0A 00 00 00 mov         dword ptr [ebp-14h],0Ah

:

那么,二级指针是啥?恩。。。

14:   char** x=(char**)10;

00401048 C7 45 FC 0A 00 00 00 mov         dword ptr [ebp-4],0Ah

15:

16:   short** y=(short**)10;

0040104F C7 45 F8 0A 00 00 00 mov         dword ptr [ebp-8],0Ah

17:

18:   int** z=(int**)10;

00401056 C7 45 F4 0A 00 00 00 mov         dword ptr [ebp-0Ch],0Ah

19:

20:   float** f=(float**)10;

0040105D C7 45 F0 0A 00 00 00 mov         dword ptr [ebp-10h],0Ah

21:

22:   double** d=(double**)10;

00401064 C7 45 EC 0A 00 00 00 mov         dword ptr [ebp-14h],0Ah

恩,也是4个字节!  你爹有5个亿,你有女票。我爹是画家,我也有女票!

总结:普通类型的指针宽度都是4个字节。多级指针也是4个字节。

下面我们看看一些奇葩的指针。

1. 指针数组(是指针的数组,是数组!)

为啥?  char[10]的宽度是10个字节,因为char宽度*10,那么char* [10]的宽度就是10个char*的宽度。也就是40。

人人平等,人人都有女票!

也是40个字节

那么 两个星呢?

恩,也是40个字节。

2 结构体指针

也是4个字节。 为啥? 因为这个指针通常指向了结构体变量的首地址(这个不能乱用)

3 函数指针

16:   int (*pf)(int)=f;

00401088 C7 45 FC 0F 10 40 00 mov         dword ptr [ebp-4],offset @ILT+10(f) (0040100f)

0040108F 8B 45 FC             mov         eax,dword ptr [ebp-4]

00401092 89 45 FC             mov         dword ptr [ebp-4],eax

宽度也是4,因为它现在指向了函数的首地址(其实是跳转表)。


指针运算

指针在做运算时,要拿砍掉一个星后的宽度然后在算。这样的运算规则便于开发寻址。

a的类型char* 宽度 砍掉一个*,变成了char。然后char的宽度是1。100+1*5=105.

以此类推。

自加

减法同理

指针与指针的运算

指针主要是用于寻址的。所以,我们假设a指向了一个变量,b也指向了一个变量,所以相减就是他们的地址差。指针与指针的运算应该先减,然后除以砍掉一个*的宽度。

同理,a-b=100,100/int的宽度4字节,最后得25。

多级指针与多级指针的运算

因为普通类型的指针宽度都是4个字节(32位机),所以我就举着一个例子吧。。

引用&的用法

引用的本质就是取地址,比如:

10:   char a = 10;

00401048 C6 45 FC 0A          mov         byte ptr [ebp-4],0Ah

11:   short b = 20;

0040104C 66 C7 45 F8 14 00    mov         word ptr [ebp-8],offset main+20h (00401050)

12:   int c = 30;

00401052 C7 45 F4 1E 00 00 00 mov         dword ptr [ebp-0Ch],1Eh

13:

14:   char* pa = (char*)&a;

00401059 8D 45 FC             lea         eax,[ebp-4]

0040105C 89 45 F0             mov         dword ptr [ebp-10h],eax

15:   short* pb = (short*)&b;

0040105F 8D 4D F8             lea         ecx,[ebp-8]

00401062 89 4D EC             mov         dword ptr [ebp-14h],ecx

16:   int* pc = (int*)&c;

00401065 8D 55 F4             lea         edx,[ebp-0Ch]

00401068 89 55 E8             mov         dword ptr [ebp-18h],edx

指针与引用正常情况下可以看成是一对,也就是间接寻址的引用。

比如说

10:   char a = 10;

00401048   mov         byte ptr [ebp-4],0Ah

11:

12:

13:   char* pa = (char*)&a;//取地址

0040104C   lea         eax,[ebp-4]

0040104F   mov         dword ptr [ebp-8],eax

14:

15:

16:   printf("%d ",*pa);

00401052   mov         ecx,dword ptr [ebp-8]//取ebp-8的数据 然后把它当成地址来取里面的值。

00401055   movsx       edx,byte ptr [ecx]

00401058   push        edx

00401059   push        offset string "%d " (0042e01c)

0040105E   call        printf (00408160)

00401063   add         esp,8

17:

说的简单粗暴点就是:变量前面加一个*就是把这个变量里面的值当成地址,然后取这个地址里面的值(相当于砍掉一个*)。 变量前面加一个&就是取这个变量的地址(相当于加一个星)。

例题:

打印数组

char arr[10];   

char* p = &arr[0]; //取数组第一个元素的地址   

for(int k=0;k<10;k++)                         

{                          

         printf("%d\n",*(p+k));      //取地址里的值     

}       

对应反汇编

12:   char* p = &arr[0]; //取数组第一个元素的地址

00401048   lea         eax,[ebp-0Ch]

0040104B   mov         dword ptr [ebp-10h],eax

13:   for(int k=0;k<10;k++)

0040104E   mov         dword ptr [ebp-14h],0

00401055   jmp         main+30h (00401060)

00401057   mov         ecx,dword ptr [ebp-14h]

0040105A   add         ecx,1

0040105D   mov         dword ptr [ebp-14h],ecx

00401060   cmp         dword ptr [ebp-14h],0Ah

00401064   jge         main+4Fh (0040107f)

14:   {

15:       printf("%d\n",*(p+k));  //取地址里的值

00401066   mov         edx,dword ptr [ebp-10h]//数组首地址

00401069   add         edx,dword ptr [ebp-14h]//k变量

0040106C   movsx       eax,byte ptr [edx]//寻址

0040106F   push        eax

00401070   push        offset string "%d\n" (0042e01c)

00401075   call        printf (00408180)

0040107A   add         esp,8

16:   }

0040107D   jmp         main+27h (00401057)

17:            

指针类型

虽然指针的宽度都是4字节,但是用的时候还是与区别的.

char类型的指针一次访问内存一个字节。

Short 类型的指针一次访问内存两个字节

Int 类型的指针一次访问内存4个字节

比如:

反汇编代码:

11:   int i=300;

00401048   mov         dword ptr [ebp-4],12Ch

12:   char* b=(char*)&i;

0040104F   lea         eax,[ebp-4]

00401052   mov         dword ptr [ebp-8],eax

13:

14:   printf("%d",*b);

00401055   mov         ecx,dword ptr [ebp-8]

00401058   movsx       edx,byte ptr [ecx] //这里 ,只取了1个byte

300的二进制是100101100   而char*只能取1个字节的数据,所以取低8位,也就是101100

=42。

例题

模拟实现CE的数据搜索功能:                                                                   

         这一堆数据中存储了角色的血值信息,假设血值的类型为int类型,值为100(10进制)                                                            

         请列出所有可能的值以及该值对应的地址.                                                               

         0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x07,0x09,                                                                

         0x00,0x20,0x10,0x03,0x03,0x0C,0x00,0x00,0x44,0x00,                                                               

         0x00,0x33,0x00,0x47,0x0C,0x0E,0x00,0x0D,0x00,0x11,                                                               

         0x00,0x00,0x00,0x02,0x64,0x00,0x00,0x00,0xAA,0x00,                                                               

         0x00,0x00,0x64,0x10,0x00,0x00,0x00,0x00,0x00,0x00,                                                                

         0x00,0x00,0x02,0x00,0x74,0x0F,0x41,0x00,0x00,0x00,                                                                

         0x01,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0A,0x00,                                                               

         0x00,0x02,0x74,0x0F,0x41,0x00,0x06,0x08,0x00,0x00,                                                                

         0x00,0x00,0x00,0x64,0x00,0x0F,0x00,0x00,0x0D,0x00,                                                                

         0x00,0x00,0x23,0x00,0x00,0x64,0x00,0x00,0x64,0x00                                                        

答案

                  void f(char a[],int l)                    

         {                          

for(int i=0;i<l;i++)                                         


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2020-3-18 22:05 被AMask编辑 ,原因:
上传的附件:
收藏
免费 5
支持
分享
打赏 + 1.00雪花
打赏次数 1 雪花 + 1.00
 
赞赏  天水姜伯约   +1.00 2020/01/20 加油。
最新回复 (20)
雪    币: 43
活跃值: (1084)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
哇,这么多图片挂了。。。 大哥大姐们直接下我发的word看吧。。。要不要重新发???
2020-1-16 22:48
0
雪    币: 47147
活跃值: (20415)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
3
加油
2020-1-16 22:53
0
雪    币: 43
活跃值: (1084)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
kanxue 加油[em_63]
恩,谢谢老大
2020-1-16 22:54
0
雪    币: 1722
活跃值: (201)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
2020-1-17 12:51
0
雪    币: 573
活跃值: (1004)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
现在的精华文对比五年前我是真看不懂了。
2020-1-17 13:51
2
雪    币: 43
活跃值: (1084)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
ChengQing 现在的精华文对比五年前我是真看不懂了。
.
最后于 2020-1-17 16:11 被AMask编辑 ,原因:
2020-1-17 13:58
0
雪    币: 142
活跃值: (121)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
8
好好上学吧...
2020-1-17 17:37
0
雪    币: 729
活跃值: (383)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
对比前几年的CHM精华离线版,我也是看不懂了。
2020-1-17 19:05
0
雪    币: 43
活跃值: (1084)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
gaoliangk 对比前几年的CHM精华离线版,我也是看不懂了。[em_39]
啥呀?慢慢来
2020-1-18 00:51
0
雪    币: 43
活跃值: (1084)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
11
落花满怀 好好上学吧...
学校、、、还是逆向好玩。。
2020-1-18 00:52
0
雪    币: 43
活跃值: (1084)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
12
ChengQing 现在的精华文对比五年前我是真看不懂了。


最后于 2020-10-19 20:34 被AMask编辑 ,原因:
2020-1-18 05:08
0
雪    币: 43
活跃值: (1084)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
13
gaoliangk 对比前几年的CHM精华离线版,我也是看不懂了。[em_3。
最后于 2020-10-19 20:34 被AMask编辑 ,原因:
2020-1-18 05:08
0
雪    币: 4094
活跃值: (4205)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
14
这都能弄一篇精华?
2020-1-18 21:14
0
雪    币: 43
活跃值: (1084)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
15
昵称好麻烦 这都能弄一篇精华?[em_2]


最后于 2020-10-19 20:35 被AMask编辑 ,原因:
2020-1-19 19:13
0
雪    币: 729
活跃值: (383)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
AMask 啥呀?慢慢来
没有针对你,我是说现在对精华的判断有点不太懂了,难道是图多就是精华吗?
2020-1-19 19:17
0
雪    币: 43
活跃值: (1084)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
17
gaoliangk 没有针对你,我是说现在对精华的判断有点不太懂了,难道是图多就是精华吗?[em_13]
我不是精华呀
2020-1-19 19:21
0
雪    币: 4694
活跃值: (4639)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
中间指针取低8位写错了,应该是44,即执行结果。好文章,学习啦,谢谢分享
2020-1-29 22:44
1
雪    币: 2119
活跃值: (1890)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
19
用心了
2020-1-30 03:02
0
雪    币: 43
活跃值: (1084)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
20
洪七公. 用心了
谢谢
2020-2-11 14:21
0
雪    币: 43
活跃值: (1084)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
21
cxbcxb 中间指针取低8位写错了,应该是44,即执行结果。好文章,学习啦,谢谢分享
可能是笔误。。
2020-2-11 14:22
0
游客
登录 | 注册 方可回帖
返回
//