逆向_11指针类型分析

指针类型的宽度

  • 无论原来类型的宽度是多少,在32位程序下,宽度均为4字节
  • 无论多少个*,均为4个字节

指针类型的声明

  1. 带有*的变量类型的标准写法:变量类型* 变量名
  2. 任何类型都可以带*,加上*以后是新的类型
  3. *可以是任意多个
  4. *类型的变量,可以通过在其变量前加*来获取其指向内存中存储的值.
  5. 在带*类型的变量前面加*,类型是其原来的类型减去一个*.

指针类型的赋值

int* a;
char* b;
short* c;

a = (int*)1;
b = (char*)2;
c = (short*)3;

&符号说明

  • &是地址符,类型是其后面的类型加一个“*”,任何变量都可以使用&来获取地址,但不能用在常量上

指针类型的++、–

int* a;
char* b;
short* c;

a = (int*)1;
b = (char*)2;
c = (short*)3;
a++;//+4
b++;//+1
c++;//+2
  • ++/–,加/减的是去掉一个*的宽度

指针类型的加减

int* a;
char* b;
short* c;

a = (int*)1;
b = (char*)2;
c = (short*)3;
//a+5 = 21 = 1+4*5
//b+5 = 7 = 2+1*5
//c+5 = 13 = 3+2*5
  • +A/-A,加/减的是(去掉一个*的宽度xA)

指针类型的求差值

int* a1;
char* b1;
short* c1;
int* a2;
char* b2;
short* c2;

a1 = (int*)200;
b1 = (char*)200;
c1 = (short*)200;
a2 = (int*)100;
b2 = (char*)100;
c2 = (short*)100;

//a1-a2 = 25
//b1-b2 = 100
//c1-c2 = 50
  • 数据类型务必一样
  • 算出的数值要除以去掉一个*的宽度

指针类型的比较

int*** a1;
int*** a2;
a1 = (int***)200;
a2 = (int***)100;
if(a1>a2){
    printf("1");
}else{
    printf("2");
}
//输出为1
  • 可以做大小比较

类型转换

  • 基本类型之间转换是可以的
  • 指针类型之间不能相互转换,但是可以强转

&符号的使用

  • &是地址符,类型是其后面的类型加一个“*”,任何变量都可以使用&来获取地址,但不能用在常量上

带*类型的特征探测

int* px;
int** px2;
int*** px3;
int**** px4;
//*(px) 是什么类型? int
//*(px2) 是什么类型? int*
//*(px3) 是什么类型? int**
//*(px4) 是什么类型? int***

指针类型的继续理解

题目为例

  1. 查找这些数据中,有几个id=1 level=8的结构体信息。
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x07,0x09,                    
0x00,0x20,0x10,0x03,0x03,0x0C,0x00,0x00,0x44,0x00,                    
0x00,0x33,0x01,0x00,0x00,0x08,0x00,0x00,0x00,0x00,                    
0x00,0x00,0x00,0x02,0x64,0x00,0x00,0x00,0xAA,0x00,                    
0x00,0x00,0x64,0x01,0x00,0x00,0x00,0x08,0x00,0x00,                    
0x00,0x00,0x02,0x00,0x74,0x0F,0x41,0x00,0x00,0x00,                    
0x01,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0A,0x00,                    
0x00,0x02,0x57,0x4F,0x57,0x00,0x06,0x08,0x00,0x00,                    
0x00,0x00,0x00,0x64,0x00,0x0F,0x00,0x00,0x0D,0x00,                    
0x00,0x00,0x23,0x00,0x00,0x64,0x00,0x00,x64,0x00    

结构体定义如下:                    

typedef struct TagPlayer                    
{                    
    int id;                
    int level;                
}Player;                    

题目解析

// 结构体搜索.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdlib.h>

char a[100]={
    0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x07,0x09,                    
    0x00,0x20,0x10,0x03,0x03,0x0C,0x00,0x00,0x44,0x00,                    
    0x00,0x33,0x01,0x00,0x00,0x08,0x00,0x00,0x00,0x00,                    
    0x00,0x00,0x00,0x02,0x64,0x00,0x00,0x00,0xAA,0x00,                    
    0x00,0x00,0x64,0x01,0x00,0x00,0x00,0x08,0x00,0x00,                    
    0x00,0x00,0x02,0x00,0x74,0x0F,0x41,0x00,0x00,0x00,                    
    0x01,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0A,0x00,                    
    0x00,0x02,0x57,0x4F,0x57,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                    

};
typedef struct TagPlayer        
{        
    int id;    
    int level;    
}Player;
int _tmain(int argc, _TCHAR* argv[])
{
    char *b = a;
    Player *pPlayer;
    pPlayer = (Player *)b;
    int i = 0;
    while (i<100-7)
    {
        if (pPlayer->id == 1 && pPlayer->level == 8)
        {
            printf("%X\n",pPlayer);
        }
        pPlayer = (Player *)++b;
        i++;
    }
    system("pause");
    return 0;
}
  1. 指针寻址的理解

*(p+0) = *p = p[0];
*(p+1) = p[1];
*(p+2) = p[2];
*(p+3) = p[3];
*(p+i) = p[i];
  • 多级*结构

    char* p1;
    char** p2;
    char*** p3;
    char**** p4;
    char***** p5;
    *(*(p2+2)+3) = p2[2][3];
    *(*(p2+i)+j) = p2[i][j];
    *(*(*(p3+i)+j)+k) = p3[i][j][k];
    *(*(*(*(p4+i)+j)+k)+m) = p4[i][j][k][m];
    *(*(*(*(*(p5+i)+j)+k)+m)+n) = p4[i][j][k][m][n];
  • 多级指针理解

    int i = 100;
    int* p1;
    int** p2;
    int*** p3;
    p1 = &i;
    p2 = &p1;
    printf("%d\n",*p2); //打印p1的地址
    printf("%d\n",*(*(p2))); //打印i的值
    printf("%d\n",p2[0][0]); //打印i的值
    printf("%d\n",p3[0][0][0]); //打印i的值
    printf("%d\n",*(*(*(p3)))); //打印i的值
  • 指针

    1. 指针 *
    2. 结构体指针 x —-> 结构体
    3. 指针的指针 x —-> 指针
    4. 指针数组 x —-> 数组每个元素存的是指针
    5. 数组指针 x —-> 数组
    6. 指针函数(返回值为指针)
    7. 函数指针 x —-> 函数

重点探讨数组指针

  • 宽度

    • 宽度为4
  • 解析

    • 指向一个数组的指针
  • px和*px的关系

    int arr[5] = {1,2,3,4,5};
    int (*px)[5];
    px = (int (*)[5])arr;//px和*px初始是一样的,其实就是px+0 = *(px+0)
    • 但是px++和(*px)++是不一样的
    • px++,加的是5*4,(*px)++加的是4
    • px存的是arr数组的首地址,然后*px也是数组的首地址,但是*p相当于arr数组了

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 787772394@qq.com

文章标题:逆向_11指针类型分析

本文作者:二豆子·pwnd0u

发布时间:2020-11-01, 20:11:35

最后更新:2023-05-18, 09:49:55

原始链接:http://blog.codefat.cn/2020/11/01/%E9%80%86%E5%90%91-11%E6%8C%87%E9%92%88%E7%B1%BB%E5%9E%8B%E5%88%86%E6%9E%90/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏

/*爱心代码*/ /*雪花效果*/ /*百度代码自动提交*/