0
点赞
收藏
分享

微信扫一扫

滴水逆向-指针1

滴水逆向-指针1_逆向

 

 滴水逆向-指针1_3c_02

 

滴水逆向-指针1_3c_03

 

滴水逆向-指针1_3c_04

 

滴水逆向-指针1_逆向_05

 

滴水逆向-指针1_逆向_06

 

 滴水逆向-指针1_逆向_07

 

 滴水逆向-指针1_#include_08

 

 相关练习和测试代码

C指针

1."带*类型" 的特征探测:宽度

宽度探测

带一个*的探测

源代码

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

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

printf("%d %d %d\n",a,b,c);
}

int main(int argc, char* argv[])
{
fun();
return 0;
}

反汇编代码

9: char* a = (char*)1;
0040B818 mov dword ptr [ebp-4],1
10: short* b = (short*)2;
0040B81F mov dword ptr [ebp-8],2
11: int* c =(int*)3;
0040B826 mov dword ptr [ebp-0Ch],3

上述显示都是站4个字节

带两个*的探测

源代码
#include "stdafx.h"
#include <string.h>

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

printf("%d %d %d\n",a,b,c);
}

int main(int argc, char* argv[])
{
fun();
return 0;
}

反汇编代码

9: char** a = (char**)1;
0040B818 mov dword ptr [ebp-4],1
10: short** b = (short**)2;
0040B81F mov dword ptr [ebp-8],2
11: int** c =(int**)3;
0040B826 mov dword ptr [ebp-0Ch],3

上述显示还是都站4个字节


带两个以上*的探测

源代码
#include "stdafx.h"
#include <string.h>

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

printf("%d %d %d\n",a,b,c);
}

int main(int argc, char* argv[])
{
fun();
return 0;
}


反汇编代码

9: char******* a = (char*******)1;
0040B818 mov dword ptr [ebp-4],1
10: short******* b = (short*******)2;
0040B81F mov dword ptr [ebp-8],2
11: int******* c =(int*******)3;
0040B826 mov dword ptr [ebp-0Ch],3

上述显示还是都站4个字节

结论:
不管什么类型,不管带多少个*,她们所站的字节大小都是4个字节;



2."带*类型"的特征探测:声明

上述1题目中已经探测了,任何类型都可以带*,加了*就是新类型,然后可以加很多个* ,而且写法是标准最好推荐的写法是类似:int* x; 这样方便阅读

结论:
(1)带有*的变量类型的标准写法:变量类型* 变量名
(2)任何类型都可以带* 加上*以后是新的类型
(3)*可以是任意多个


3."带*类型" 的特征探测:赋值

上述1题目已经探测了,测试赋值操作;
结论:

1.带*类型的变量赋值时只能使用"完整写法".

2.带*类型的变量宽度永远是4字节,无论类型是什么,无论有几个*.


4."带*类型" 的特征探测:++ --

带一个*的测试

源代码

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

void fun()
{
char* a;
short* b;
int* c;

a = (char*)100;
b = (short*)100;
c = (int*)100;


a++;
b++;
c++;

printf("%d %d %d\n",a,b,c);
}

int main(int argc, char* argv[])
{
fun();
return 0;
}

运行结果:101 102 104

反汇编代码

9: char* a;
10: short* b;
11: int* c;
12:
13: a = (char*)100;
0040B818 mov dword ptr [ebp-4],64h
14: b = (short*)100;
0040B81F mov dword ptr [ebp-8],64h
15: c = (int*)100;
0040B826 mov dword ptr [ebp-0Ch],64h
16:
17:
18: a++;
0040B82D mov eax,dword ptr [ebp-4]
0040B830 add eax,1
0040B833 mov dword ptr [ebp-4],eax
19: b++;
0040B836 mov ecx,dword ptr [ebp-8]
0040B839 add ecx,2
0040B83C mov dword ptr [ebp-8],ecx
20: c++;
0040B83F mov edx,dword ptr [ebp-0Ch]
0040B842 add edx,4
0040B845 mov dword ptr [ebp-0Ch],edx


带两个*的测试

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

void fun()
{
char** a;
short** b;
int** c;

a = (char**)100;
b = (short**)100;
c = (int**)100;


a++;
b++;
c++;

printf("%d %d %d\n",a,b,c);
}

int main(int argc, char* argv[])
{
fun();
return 0;
}

运行结果:104 104 104


反汇编代码

9: char** a;
10: short** b;
11: int** c;
12:
13: a = (char**)100;
0040B818 mov dword ptr [ebp-4],64h
14: b = (short**)100;
0040B81F mov dword ptr [ebp-8],64h
15: c = (int**)100;
0040B826 mov dword ptr [ebp-0Ch],64h
16:
17:
18: a++;
0040B82D mov eax,dword ptr [ebp-4]
0040B830 add eax,4
0040B833 mov dword ptr [ebp-4],eax
19: b++;
0040B836 mov ecx,dword ptr [ebp-8]
0040B839 add ecx,4
0040B83C mov dword ptr [ebp-8],ecx
20: c++;
0040B83F mov edx,dword ptr [ebp-0Ch]
0040B842 add edx,4
0040B845 mov dword ptr [ebp-0Ch],edx

带两个以上*的测试

源代码

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

void fun()
{
char********* a;
short********* b;
int********* c;

a = (char*********)100;
b = (short*********)100;
c = (int*********)100;


a++;
b++;
c++;

printf("%d %d %d\n",a,b,c);
}

int main(int argc, char* argv[])
{
fun();
return 0;
}

反汇编代码

9: char********* a;
10: short********* b;
11: int********* c;
12:
13: a = (char*********)100;
0040B818 mov dword ptr [ebp-4],64h
14: b = (short*********)100;
0040B81F mov dword ptr [ebp-8],64h
15: c = (int*********)100;
0040B826 mov dword ptr [ebp-0Ch],64h
16:
17:
18: a++;
0040B82D mov eax,dword ptr [ebp-4]
0040B830 add eax,4
0040B833 mov dword ptr [ebp-4],eax
19: b++;
0040B836 mov ecx,dword ptr [ebp-8]
0040B839 add ecx,4
0040B83C mov dword ptr [ebp-8],ecx
20: c++;
0040B83F mov edx,dword ptr [ebp-0Ch]
0040B842 add edx,4
0040B845 mov dword ptr [ebp-0Ch],edx

运行结果:104 104 104

结论:

1.不带*类型的变量,++或者-- 都是加1 或者减1
2.带*类型的变量,可是进行++ 或者 --的操作
3.带*类型的变量,++ 或者 -- 新增(减少)的数量是去掉一个*后变量的宽度


5."带*类型" 的特征探测:加上/减去 一个整数

带一个*的测试

源代码

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

void fun()
{
char* a;
short* b;
int* c;

a = (char*)100;
b = (short*)100;
c = (int*)100;

a = a + 6;
b = b + 6;
c = c + 6;


printf("%d %d %d\n",a,b,c);
}

int main(int argc, char* argv[])
{
fun();
return 0;
}

运行结果:106 112 124

反汇编代码

9: char* a;
10: short* b;
11: int* c;
12:
13: a = (char*)100;
0040B818 mov dword ptr [ebp-4],64h
14: b = (short*)100;
0040B81F mov dword ptr [ebp-8],64h
15: c = (int*)100;
0040B826 mov dword ptr [ebp-0Ch],64h
16:
17: a = a + 6;
0040B82D mov eax,dword ptr [ebp-4]
0040B830 add eax,6
0040B833 mov dword ptr [ebp-4],eax
18: b = b + 6;
0040B836 mov ecx,dword ptr [ebp-8]
0040B839 add ecx,0Ch
0040B83C mov dword ptr [ebp-8],ecx
19: c = c + 6;
0040B83F mov edx,dword ptr [ebp-0Ch]
0040B842 add edx,18h
0040B845 mov dword ptr [ebp-0Ch],edx


带两个*的测试

源代码

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

void fun()
{
char** a;
short** b;
int** c;

a = (char**)100;
b = (short**)100;
c = (int**)100;

a = a + 6;
b = b + 6;
c = c + 6;


printf("%d %d %d\n",a,b,c);
}

int main(int argc, char* argv[])
{
fun();
return 0;
}

运行结果:124 124 124

反汇编代码

9: char** a;
10: short** b;
11: int** c;
12:
13: a = (char**)100;
0040B818 mov dword ptr [ebp-4],64h
14: b = (short**)100;
0040B81F mov dword ptr [ebp-8],64h
15: c = (int**)100;
0040B826 mov dword ptr [ebp-0Ch],64h
16:
17: a = a + 6;
0040B82D mov eax,dword ptr [ebp-4]
0040B830 add eax,18h
0040B833 mov dword ptr [ebp-4],eax
18: b = b + 6;
0040B836 mov ecx,dword ptr [ebp-8]
0040B839 add ecx,18h
0040B83C mov dword ptr [ebp-8],ecx
19: c = c + 6;
0040B83F mov edx,dword ptr [ebp-0Ch]
0040B842 add edx,18h
0040B845 mov dword ptr [ebp-0Ch],edx



带两个以上*的测试

源代码

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

void fun()
{
char********* a;
short********* b;
int********* c;

a = (char*********)100;
b = (short*********)100;
c = (int*********)100;

a = a + 6;
b = b + 6;
c = c + 6;


printf("%d %d %d\n",a,b,c);
}

int main(int argc, char* argv[])
{
fun();
return 0;
}

运行结果:124 124 124

反汇编代码

9: char********* a;
10: short********* b;
11: int********* c;
12:
13: a = (char*********)100;
0040B818 mov dword ptr [ebp-4],64h
14: b = (short*********)100;
0040B81F mov dword ptr [ebp-8],64h
15: c = (int*********)100;
0040B826 mov dword ptr [ebp-0Ch],64h
16:
17: a = a + 6;
0040B82D mov eax,dword ptr [ebp-4]
0040B830 add eax,18h
0040B833 mov dword ptr [ebp-4],eax
18: b = b + 6;
0040B836 mov ecx,dword ptr [ebp-8]
0040B839 add ecx,18h
0040B83C mov dword ptr [ebp-8],ecx
19: c = c + 6;
0040B83F mov edx,dword ptr [ebp-0Ch]
0040B842 add edx,18h
0040B845 mov dword ptr [ebp-0Ch],edx


结论:

1.带*类型的变量可以加、减一个整数,但不能乘或者除.

2.带*类型变量与其他整数相加或者相减时:

带*类型变量 + N = 带*类型变量 + N*(去掉一个*后类型的宽度)
带*类型变量 - N = 带*类型变量 - N*(去掉一个*后类型的宽度)

所以计算结果就是:带*变量的值加上或者减去去掉一个*之后的类型宽度乘以一个整数;

例如:
上面测试加法的时候,两个以上*的计算操作:100+4x6=124
上面测试减法的时候,两个以上*的计算操作:100-4x6=76

6."带*类型" 的特征探测:求差值

带一个*的测试

源代码

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

void fun()
{
char* a;
char* b;

a = (char*)200;
b = (char*)100;

int c = a - b;


printf("%d\n",c);
}

int main(int argc, char* argv[])
{
fun();
return 0;
}

运行结果:100

反汇编代码

9: char* a;
10: char* b;
11:
12: a = (char*)200;
0040B818 mov dword ptr [ebp-4],0C8h
13: b = (char*)100;
0040B81F mov dword ptr [ebp-8],64h
14:
15: int c = a - b;
0040B826 mov eax,dword ptr [ebp-4]
0040B829 sub eax,dword ptr [ebp-8]
0040B82C mov dword ptr [ebp-0Ch],eax


带两个*的测试

源代码

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

void fun()
{
char** a;
char** b;

a = (char**)200;
b = (char**)100;

int c = a - b;


printf("%d\n",c);
}

int main(int argc, char* argv[])
{
fun();
return 0;
}

运行结果:25

反汇编代码

9: char** a;
10: char** b;
11:
12: a = (char**)200;
0040B818 mov dword ptr [ebp-4],0C8h
13: b = (char**)100;
0040B81F mov dword ptr [ebp-8],64h
14:
15: int c = a - b;
0040B826 mov eax,dword ptr [ebp-4]
0040B829 sub eax,dword ptr [ebp-8]
0040B82C sar eax,2
0040B82F mov dword ptr [ebp-0Ch],eax


带两个以上*的测试

源代码


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

void fun()
{
char************ a;
char************ b;

a = (char************)200;
b = (char************)100;

int c = a - b;


printf("%d\n",c);
}

int main(int argc, char* argv[])
{
fun();
return 0;
}

运行结果:25

反汇编代码

9: char************ a;
10: char************ b;
11:
12: a = (char************)200;
0040B818 mov dword ptr [ebp-4],0C8h
13: b = (char************)100;
0040B81F mov dword ptr [ebp-8],64h
14:
15: int c = a - b;
0040B826 mov eax,dword ptr [ebp-4]
0040B829 sub eax,dword ptr [ebp-8]
0040B82C sar eax,2
0040B82F mov dword ptr [ebp-0Ch],eax

结论:

1.两个类型相同的带*类型的变量可以进行减法操作.
2.想减的结果要除以去掉一个*的数据的宽度.

例如:
上面的计算操作:200-100=100 100/4=25

7."带*类型" 的特征探测:比较

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

void fun()
{
char************** a ;
char************** b ;

a = (char**************)200;
b = (char**************)100;

if(a>b)
{
printf("6\n");
}
else
{
printf("8\n");
}
}

int main(int argc, char* argv[])
{
fun();
return 0;
}

结论:

带*的变量,如果类型相同,可以做大小的比较。


课后练习

1.char类型占几字节?char*类型占几字节?int*****占几字节?

char 占用1字节
(32位下)char* 站用4字节
(32位下)int***** 站用4字节


2、char** arr[10] 占多少个字节?

4x10=40
(32位下)char*** arr[10]占用40个字节

3、自定义结构体如下:

struct Student
{
int x;
int y;
};


正常不带*测试代码

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

struct student
{
int x;
int y;
};


void fun()
{
student s;
s.x = 100;
s.y = 200;

printf("%d %d",s.x,s.y);
}

int main(int argc, char* argv[])
{
fun();
return 0;
}


带一个*的测试

源代码

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

struct student
{
int x;
int y;
};


void fun()
{
student* s;

s = (student*)100;

s++;

printf("%d",s);
}

int main(int argc, char* argv[])
{
fun();
return 0;
}

运算结果;108

反汇编代码:

4: #include "stdafx.h"
5: #include <string.h>
6:
7: struct student
8: {
9: int x;
10: int y;
11: };
12:
13:
14: void fun()
15: {
0040B800 push ebp
0040B801 mov ebp,esp
0040B803 sub esp,44h
0040B806 push ebx
0040B807 push esi
0040B808 push edi
0040B809 lea edi,[ebp-44h]
0040B80C mov ecx,11h
0040B811 mov eax,0CCCCCCCCh
0040B816 rep stos dword ptr [edi]
16: student* s;
17:
18: s = (student*)100;
0040B818 mov dword ptr [ebp-4],64h
19:
20: s++;
0040B81F mov eax,dword ptr [ebp-4]
0040B822 add eax,8
0040B825 mov dword ptr [ebp-4],eax
21:
22: printf("%d",s);
0040B828 mov ecx,dword ptr [ebp-4]
0040B82B push ecx
0040B82C push offset string "6\n" (0042001c)
0040B831 call printf (00401110)
0040B836 add esp,8
23: }
0040B839 pop edi
0040B83A pop esi
0040B83B pop ebx
0040B83C add esp,44h
0040B83F cmp ebp,esp
0040B841 call __chkesp (00401190)
0040B846 mov esp,ebp
0040B848 pop ebp
0040B849 ret


带两个*的测试

源代码

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

struct student
{
int x;
int y;
};


void fun()
{
student** s;

s = (student**)100;

s++;

printf("%d",s);
}

int main(int argc, char* argv[])
{
fun();
return 0;
}

运算结果:104

带两个以上*的测试

源代码

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

struct student
{
int x;
int y;
};


void fun()
{
student******* s;

s = (student*******)100;

s++;

printf("%d",s);
}

int main(int argc, char* argv[])
{
fun();
return 0;
}

运算结果:104

进行加上或者减去一个整数测试

带一个*测试

源代码

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

struct student
{
int x;
int y;
};


void fun()
{
student* s;

s = (student*)100;

s = s + 2;

printf("%d",s);
}

int main(int argc, char* argv[])
{
fun();
return 0;
}

运算结果:116

带两个*测试

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

struct student
{
int x;
int y;
};


void fun()
{
student** s;

s = (student**)100;

s = s + 2;

printf("%d",s);
}

int main(int argc, char* argv[])
{
fun();
return 0;
}

运算结果:108

带两个以上*测试

源代码

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

struct student
{
int x;
int y;
};


void fun()
{
student********* s;

s = (student*********)100;

s = s + 2;

printf("%d",s);
}

int main(int argc, char* argv[])
{
fun();
return 0;
}

加法:100+2x4=108
减法:100-2x4=92


相减进行测试

源代码

两个以上*测试

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

struct student
{
int x;
int y;
};


void fun()
{
student********* s1;
student********* s2;
int x;

s1 = (student*********)200;
s2 = (student*********)100;
x = s1 - s2;

printf("%d",x);
}

int main(int argc, char* argv[])
{
fun();
return 0;
}

运算结果:25

通过测试两个*的计算结果也是25

一个*测试

源代码

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

struct student
{
int x;
int y;
};


void fun()
{
student* s1;
student* s2;
int x;

s1 = (student*)200;
s2 = (student*)100;
x = s1 - s2;

printf("%d",x);
}

int main(int argc, char* argv[])
{
fun();
return 0;
}

运算结果:12

200-100=100 100/8=12.5 取12
8的由来是结构体里面两个整形int,所站字节数是8


结论:
结构体定义带*的操作跟其他类型一样,当定义两个*以上的类型,都按照4个字节宽度进行计算,当定义一个*的时候按照结构体内部实际字节站用的计算

 

迷茫的人生,需要不断努力,才能看清远方模糊的志向!


举报

相关推荐

0 条评论