逆向_11指针类型分析
指针类型的宽度
- 无论原来类型的宽度是多少,在32位程序下,宽度均为4字节
- 无论多少个*,均为4个字节
指针类型的声明
- 带有
*
的变量类型的标准写法:变量类型*
变量名 - 任何类型都可以带
*
,加上*
以后是新的类型 *
可以是任意多个- 带
*
类型的变量,可以通过在其变量前加*
来获取其指向内存中存储的值. - 在带
*
类型的变量前面加*
,类型是其原来的类型减去一个*
.
指针类型的赋值
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***
指针类型的继续理解
题目为例
- 查找这些数据中,有几个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;
}
*(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的值
指针
- 指针 *
- 结构体指针 x —-> 结构体
- 指针的指针 x —-> 指针
- 指针数组 x —-> 数组每个元素存的是指针
- 数组指针 x —-> 数组
- 指针函数(返回值为指针)
- 函数指针 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" 转载请保留原文链接及作者。