0%

13-指针

指针

指针1

大纲:

  1. 宽度
  2. 声明
  3. 赋值
  4. ++ –
  5. 加/减 一个整数
  6. 求差值
  7. 比较

这些我都学过了,c语言基础相对较好,略过

1
2
3
4
5
char**** a;
char**** b;
a = (char****)200;
b = (char****)100;
int x=a-b;

结果就是砍掉一个*,在除以数据宽度就行

总结:

  1. 带有 * 的变量类型的标准写法:变量类型* 变量名
  2. 任何类型都可以带 * 加上 * 以后是新的类型
  3. *可以是任意多个
  4. 带 * 类型的变量赋值时只能使用“完整写法”.
  5. 带 * 类型的变量宽度永远是4字节、无论类型是什么,无论有几个*.
  6. 不带*类型的变量,++或者– 都是假1 或者减1
  7. 带*类型的变量,可是进行++ 或者 –的操作
  8. 带 * 类型的变量,++ 或者 – 新增(减少)的数量是去掉一个*后变量的宽度
  9. 带*类型的变量可以加、减一个整数,但不能乘或者除.
  10. 带*类型变量与其他整数相加或者相减时:
    • 带 * 类型变量 + N = 带 * 类型变量 + N(去掉一个后类型的宽度)
    • 带 * 类型变量 - N = 带 * 类型变量 - N(去掉一个后类型的宽度)
  11. 两个类型相同的带 * 类型的变量可以进行减法操作.
  12. 想减的结果要除以去掉一个 * 的数据的宽度.
  13. 带 * 的变量,如果类型相同,可以做大小的比较。

练习

练习全都是针对32位程序

  1. char类型占几字节?char类型占几字节?int****占几字节?
  2. char** arr[10] 占多少个字节?

练习1解答

1个字节,char* 4个字节,int* 4个字节

练习2解答

40个字节,就是定义了一个数组,存的类型为char**,所以就是10 × 4

练习3解答

带*结构体的加减法

1
2
3
4
5
6
7
8
9
10
11
12
13
struct Student
{
int x;
int y;
}
void test()
{
Student**** s;
s = (Student****)100;
s++;//s=?
s = s + 2;//s=?
s = s - 3;//s=?
}

先盲猜下,第一个s=104,第二个s=112.第三个s=100

1
2
3
4
5
6
7
8
9
void test1()
{
Student**** s1;
Studnet**** s2;
int x;
s1 = (Student****)200;
s2 = (Student****)100;
x = s1 - s2; //x=?
}

先盲猜,x=(200-100)/4=25

1
2
3
4
5
6
7
8
void test2()
{
Student* s;
s = (Student*)100;
s++; //s=?
s = s + 2; //s=?
s = s - 3; //s=?
}

盲猜,s=108, s=124,s=100

1
2
3
4
5
6
7
8
9
void test3()
{
Student* s1;
Student* s2;
int x;
s1 = (Student*)200;
s2 = (Student*)100;
x = s1 - s2;
}

盲猜, x=(200-100)/8=12

大胆猜想,小心论证,结果是正确的,没毛病

指针2

大纲:

  1. 类型转换
  2. &符号的使用
  3. “带 * 类型” 求值
  4. 用指针操作数组
  • &是地址符,类型是其后面的类型加一个“*”,任何变量都可以使用&来获取地址,但不能用在常量上。
  • 带 * 类型的变量,可以通过在其变量前加*来获取其指向内存中存储的值
  • 在带类型的变量前面加,类型是其原来的类型减去一个 *.

练习

分析下列c代码的反汇编

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

void func()
{
char a = 10;
short b = 0x20;
int c = 30;

char* pa = &a;
short* pb = &b;
int* pc = &c;

char** ppa = &pa;
short** ppb = &pb;
int** ppc = &pc;
}

利用堆栈图,分析下,相对不怎么难,二级**而已

分析下列代码反汇编

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void func1()
{
int******* p7;
int****** p6;
int***** p5;
int**** p4;
int*** p3;
int** p2;
int* p1;
int p = 10;

p1= &p;
p2 = &p1;
p3 = &p2;
p4 = &p3;
p5 = &p4;
p6 = &p5;
p7 = &p6;

}

结果就是p7->p6->p5->p4->p3->p2->p1->p

p7存p6地址,p6存p5地址,一直存下去

还行,逆向起来好像并不怎么复杂

完成代码,实现数组值的互换

1
2
3
4
5
6
7
8
9
10
11
void Function()
{
int arr[5]={1,2,3,4,5};
//添加代码,使用指针,将数组得到值倒置

//打印,不需要修改
for(int k=0; k<5; k++)
{
printf("%d\n", *(p+k));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void Function()
{
int arr[5]={1,2,3,4,5};
//添加代码,使用指针,将数组得到值倒置
int *p = arr;
int *q = &arr[4];
while(p<q)
{
//交换数值
int temp = *p;
*p = *q;
*q = temp;
//自增
p++;
q--;
}
p = arr;//恢复指针位置
//打印,不需要修改
for(int k=0; k<5; k++)
{
printf("%d\n", *(p+k));
}
}

指针3

编写一个函数,能够打印任意整形数组的值。

1
2
3
4
5
6
7
void PrintArray(int arr[],int nLength)
{
for(int i=0;i<nLength;i++)
{
printf("%d\n",arr[i]);
}
}

观察反汇编

通过这个顺便复习了for循环

练习

模拟实现CE的数据搜索功能:这一堆数据中存储了角色的血值信息,假设血值的类型为int类型,值为100(10进制)

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

char data[]= {
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

};
// type: byte num: data
void search(int type, int num)
{
char *start = data;
int length = sizeof(data)/sizeof(data[0]);
int i=0;
while(i< length-type)
{
if(type == 4)
{
if(*(int*)&data[i] == num)
{
printf("address:%x , data:%d\n",&data[i],(int)num);
}
}else if(type == 2)
{
if(*(short*)&data[i] == (short)num)
{
printf("address:%x , data:%d\n",&data[i],(short)num);
}
}else
{
if(*(char*)&data[i] == (char)num)
{
printf("address:%x , data:%d\n",&data[i],(char)num);
}
}
i += 1;

}
}


int main(int argc, char* argv[])
{
printf("data start from:%x\n", data);
search(4,100);
return 0;
}

对其进行解耦,接口不改变

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
char data[]= {
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

};
// type: byte num: data
void search_int(int num, int length)
{
int i=0;
while(i<length-4)
{
if(*(int*)&data[i] == num)
{
printf("address:%x , data:%d\n",&data[i],(int)num);
}
i++;
}
}
void search_short(int num, int length)
{
int i=0;
while(i<length-2)
{
if(*(short*)&data[i] == num)
{
printf("address:%x , data:%d\n",&data[i],(short)num);
}
i++;
}
}

void search_char(int num, int length)
{

int i=0;
while(i<length-1)
{
if(*(char*)&data[i] == num)
{
printf("address:%x , data:%d\n",&data[i],(char)num);
}
i++;
}
}
void search(int type, int num)
{
int length = sizeof(data)/sizeof(data[0]);
int i=0;
typedef void (*funcptr)(int,int);
funcptr p;
if(type == 4)
{
p = search_int;
}
else if(type == 2)
{
p = search_short;
}else
{
p = search_char;
}
p(num,length);
}


int main(int argc, char* argv[])
{
printf("data start from:%x\n", data);
search(4,0x64);
return 0;
}

指针4

1
2
char* x = "china"; //china存在常量区
char y[] = "china";

常见字符串操作,学过了

练习

模拟实现CE的数据搜索功能:这一堆数据中存储了角色的名字信息(WOW),请列出角色名的内存地址.

1
2
3
4
5
6
7
8
9
10
11
12
13
char data[]=
{
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,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
}
  1. 编写函数,返回角色名字信息的地址,如果没有返回0
    • char* FindRoleNameAddr(char* pData,char* pRoleName)
  2. 编写函数,遍历上面数据中所有角色名字.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include "string.h"
char data[]=
{
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,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
};

char* FindRoleNameAddr(char* pData,char* pRoleName)
{
int length = strlen(pRoleName);
int all = sizeof(data)/sizeof(pData[0]);
int i=0;
while(i < all -length)
{
if(strncmp(&pData[i],pRoleName,length) == 0)
{
return &pData[i];
break;
}

i++;
}
return NULL;
}

int main(int argc, char* argv[])
{
char *result = FindRoleNameAddr(data,"WOW");
if(result != NULL)
printf("%p\n", result);
else
printf("not found\n");
return 0;
}

指针5

练习

  1. 创建一个int* arr[5] 数组,并为数组赋值(使用&)
  2. 创建一个字符指针数组,存储所有的C的关键词(查资料找),并全部打印出来.

练习1解答

1
2
3
4
5
void test()
{
int array[5] = {1,2,3,4,5};
int* arr[5] = {&array[0],&array[1],&array[2],&array[3],&array[4]};
};

练习2解答

1
2
3
4
5
6
7
8
9
10
11
12
void test1()
{
char* arr[5] ={
"auto",
"break",
"case",
"char",
"const"
};
for(int i=0; i<5; i++)
printf("%s", arr[i]);
}

练习3

查找这些数据中,有几个id=1 level=8的结构体信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
typedef struct TagPlayer
{
int id;
int level;
}Player;
char data[]={
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
};

代码编写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
typedef struct TagPlayer
{
int id;
int level;
}Player;

char data[]={
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
};

void search_Struct()
{
int i=0;
int length = sizeof(data)/sizeof(data[0]);
while(i<length-8)
{
Player* temp = (Player*) &data[i];
if(temp->id == 1 && temp->level == 8)
{
printf("address:%x id=%d, level=%d\n",&data[i], temp->id, temp->level);
}
i++;
}
}
int main(int argc, char* argv[])
{
search_Struct();
return 0;
}

跟前面的差不多,强转成struct就行

指针6

反汇编并分析下列结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
void test()
{
char* p1;

char** p2;

char*** p3;

char**** p4;

char***** p5;

char****** p6;

char******* p7;

//反汇编 了解*的反汇编

printf("%d\n",*p1);


//反汇编:*p1 = *(p1+0)

printf("%d\n",*(p1+0));

//反汇编:*(p1+0) = p1[0]

printf("%d %d\n",*(p1+0),p1[0]);

printf("%d %d\n",*(p1+2),p1[2]);

//反汇编:了解**的反汇编

//

printf("%d\n",*p2);

printf("%d\n",*(*p2));

printf("%d %d\n",*(*(p2+0)),*(*(p2+0)+0));

printf("%d\n",*(*(p2+1)));

printf("%d\n",*(*(p2+1)+1));

printf("%d\n",*(*(p2+2)+3));

printf("%d %d\n",*(*(p2+0)+0),p2[0][0]);

//反汇编 了解***的反汇编

printf("%d\n",*p3);

printf("%d\n",*(*p3));

printf("%d\n",*(*(*p3)));

printf("%d %d\n",*(*(*p3)),*(*(*(p3+0)+0)+0));


printf("%d\n",*(*(*(p3+1)+2)+3));

printf("%d %d\n",*(*(*(p3+1)+2)+3),p3[1][2][3]);
}

这个挺好玩的,挺有意思

*(p+i) = p[i]
* (*(p+i)+k) = p[i][k]
*(*(*(p+i)+k)+m) = p[i][m]
*(*(*(*(*(p+i)+k)+m)+w)+t) = p[i][k][m][w][t]
*() 与 []可以相互转换

练习

  1. () 与 []是可以互换的,也就是说: * ( (p+1)+2) 相当与 p[1][2],那*(p+1)[2] 是否一定等于p[1][2]呢? 通过反汇编进行论证。
  2. 使用数组指针遍历一个一维数组.

练习1

不一定,这里有c语言结合顺序的问题

1
2
3
4
5
void test()
{
char **p;
printf("%d %d\n", *(p+1)[2], p[1][2], (*(p+1))[2]);
}

这个就是一样的,而原来的那个,结合顺序是优先数组((p+1)[2]) 首先是p+1,char *, +1 就是加上他当砍掉一个*的数据类型,也就是+4, 而p+1是char **类型,所以(p+1)[2]实际就是char *类型 +2 也就是+8,所以实际合起来就是+0xc,也就是p+1+2 ,猜想归猜想,实践证明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
0040D8B8   mov         eax,dword ptr [ebp-4]
0040D8BB mov ecx,dword ptr [eax+4]
0040D8BE movsx edx,byte ptr [ecx+2]
0040D8C2 push edx
0040D8C3 mov eax,dword ptr [ebp-4]
0040D8C6 mov ecx,dword ptr [eax+4]
0040D8C9 movsx edx,byte ptr [ecx+2]
0040D8CD push edx
0040D8CE mov eax,dword ptr [ebp-4]
0040D8D1 mov ecx,dword ptr [eax+0Ch]
0040D8D4 movsx edx,byte ptr [ecx]
0040D8D7 push edx
0040D8D8 push offset string "%d %d\n" (00422fb4)
0040D8DD call printf (0040d720)

你看它的取法,就是直接+0xc,也就是一样的说法,而结合顺序对的话,结果就是对的

练习2

1
2
3
4
5
6
7
8
9
10
11
void test()
{
int array[] = {12345678,345678,3456,56,78,12,34,0};

int (*p)[2];

p = (int (*)[2])array;
for(int i=0; i<4; i++)
printf("%d\n", (*p)[i]);

}

easy的一件事,注意的是,*p 还是个地址,至于为什么,请看滴水p32 指针第7讲

指针7

大纲:

  1. 数组指针
  2. 函数指针

练习

  1. 下列说法是否正确?为什么?
    • 指针的指针:就是指向指针的指针
    • 结构指针:就是指向结构的指针
    • 数组指针:就是指向数组的指针
    • 函数指针:就是指向函数的指
  2. 将一个函数存储到数据区,通过指针进行访问.

练习1解答

不正确,前面的指针练习已经说明了,结构指针不一定也得指向结构,他可以指向随便一个地址,强制转换后按结构来解析

练习2解答

1
2
3
4
5
6
7
8
9
10
11
12
13
unsigned char array[]= { 0x55, 0x8b,0xec,0x83,0xec,0x40,0x53,0x56,0x57,0x8d,0x7d,0xc0,0xb9,0x10,0x00,0x00,0x00,0xb8,0xcc,0xcc,0xcc,0xcc,0xf3,0xab,0xb8,0x01,0x00,0x00,0x00,0x5f,0x5e,0x5b,0x8b,0xe5,0x5d,0xc3};
int test(int a)
{
return 1;
}

int main(int argc, char* argv[])
{
int (*p)(int x);
p = (int (__cdecl *)(int))&array;
printf("%d", p(1));
return 0;
}

有点小疑惑,为啥要取地址才能搞定,经过测试后,发觉他们的汇编是一样的,而编译器却不通过,array是char []类型也就是char *类型,而&array是数组指针,也就是char (*p)[len]; 至于编译器为什么不通过,这里我也不得而知

练习3解答

3、char数组内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
char data[] = {		
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
};

不运行说出下面的结果: 指针定义如下:

*(*(px+0)+0) int (*px)[2];

*(*(px+1)+0) int (*py)[2][3];

*(*(px+2)+3) char (*pz)[2];

*(*(*(py+1)+2)+3) char (*pk)[2][3];

*(*(pz+2)+3)

*(*(*(pk+2)+3)+4)

这个也挺简单的

px+0

px+(2*4*1)

px+(2*4*2)+(3*4)

py+(2*3*4*1) + (3*4*2) + (4*3)

pz+(2*1*2)+3

pk+(2*3*1*2)+(3*1*3)+(1*4)

论证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
0040D428 8B 45 FC             mov         eax,dword ptr [ebp-4]
0040D42B 8B 08 mov ecx,dword ptr [eax]
0040D42D 89 4D EC mov dword ptr [ebp-14h],ecx
0040D430 8B 55 FC mov edx,dword ptr [ebp-4]
0040D433 8B 42 08 mov eax,dword ptr [edx+8]
0040D436 89 45 EC mov dword ptr [ebp-14h],eax
0040D439 8B 4D FC mov ecx,dword ptr [ebp-4]
0040D43C 8B 51 1C mov edx,dword ptr [ecx+1Ch]
0040D43F 89 55 EC mov dword ptr [ebp-14h],edx
0040D442 8B 45 F8 mov eax,dword ptr [ebp-8]
0040D445 8B 48 3C mov ecx,dword ptr [eax+3Ch]
0040D448 89 4D EC mov dword ptr [ebp-14h],ecx
0040D44B 8B 55 F4 mov edx,dword ptr [ebp-0Ch]
0040D44E 0F BE 42 07 movsx eax,byte ptr [edx+7]
0040D452 89 45 EC mov dword ptr [ebp-14h],eax
0040D455 8B 4D F0 mov ecx,dword ptr [ebp-10h]
0040D458 0F BE 51 19 movsx edx,byte ptr [ecx+19h]
0040D45C 89 55 EC mov dword ptr [ebp-14h],edx

实际确实如此,反汇编结果发觉,居然跟char **额外的相似

本文作者:NoOne
本文地址https://noonegroup.xyz/posts/b8c9efd6/
版权声明:转载请注明出处!