专栏首页有趣的django滴水逆向初级-C语言(二)

滴水逆向初级-C语言(二)

2.1.C语言的汇编表示

c语言代码

int plus(int x,int y)
{
	return 0;
}

void main()
{

	__asm
	{
		mov eax,eax
	}

	//调用函数
	plus(1,2);

	return;
}

汇编代码

1:
2:    int plus(int x,int y)
3:    {
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,40h
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-40h]
0040102C   mov         ecx,10h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
4:        return 0;
00401038   xor         eax,eax
5:    }
0040103A   pop         edi
0040103B   pop         esi
0040103C   pop         ebx
0040103D   mov         esp,ebp
0040103F   pop         ebp
00401040   ret
--- No source file  -------------------------------------------------------------------------------------------------------------------------------------
00401041   int         3
00401042   int         3
00401043   int         3
00401044   int         3
0040104F   int         3
--- C:\Program Files\Microsoft Visual Studio\MyProjects\11\test.cpp  ------------------------------------------------------------------------------------
6:
7:    void main()
8:    {
00401050   push        ebp
00401051   mov         ebp,esp
00401053   sub         esp,40h
00401056   push        ebx
00401057   push        esi
00401058   push        edi
00401059   lea         edi,[ebp-40h]
0040105C   mov         ecx,10h
00401061   mov         eax,0CCCCCCCCh
00401066   rep stos    dword ptr [edi]
9:        plus(1,2);    //调用函数
00401068   push        2
0040106A   push        1
0040106C   call        @ILT+0(plus) (00401005)
00401071   add         esp,8
10:
11:       return;
12:   }
00401074   pop         edi
00401075   pop         esi
00401076   pop         ebx
00401077   add         esp,40h
0040107A   cmp         ebp,esp
0040107C   call        __chkesp (004010a0)
00401081   mov         esp,ebp
00401083   pop         ebp
00401084   ret
--- No source file  -------------------------------------------------------------------------------------------------------------------------------------
00401085   int         3

2.2.参数传递与返回值

1、函数定义

返回类型函数名(参数列表)
{
	return
}

例子:
int plus(int x,int y)
{
    return x+y;
}

2.画堆栈图

int plus(int x,int y)
{
	return x+y;
}

void main()
{
	__asm
	{
		mov eax,eax     //断点调试   F7,F5,右键Go To Disassembly. F10单步,call按F11
	}

	plus(1,2);    

	return;
}

3.汇编代码

1:
2:    int plus(int x,int y)
3:    {
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,40h                       //提升堆栈
00401026   push        ebx
00401027   push        esi
00401028   push        edi                           //保存要用到的寄存器的值
00401029   lea         edi,[ebp-40h]
0040102C   mov         ecx,10h                       //ecx=10h,ecx是计数器  
00401031   mov         eax,0CCCCCCCCh                //eax=CCCCCCCC
00401036   rep stos    dword ptr [edi]              //把eax的值写到[edi],写的次数:ecx的值
4:        return x+y;
00401038   mov         eax,dword ptr [ebp+8]         //第一个参数的值,eax=1
0040103B   add         eax,dword ptr [ebp+0Ch]       //第一个参数+第二个参数  eax=1+2
5:    }
0040103E   pop         edi
0040103F   pop         esi
00401040   pop         ebx                           
00401041   mov         esp,ebp
00401043   pop         ebp                            //还原堆栈
00401044   ret                                        //eip=00401083,  esp+4
--- No source file  -------------------------------------------------------------------------------------------------------------------------------------
00401045   int         3
00401046   int         3

--- C:\Program Files\Microsoft Visual Studio\MyProjects\11\test.cpp  ------------------------------------------------------------------------------------
6:
7:    void main()
8:    {
00401050   push        ebp
00401051   mov         ebp,esp
00401053   sub         esp,40h
00401056   push        ebx
00401057   push        esi
00401058   push        edi
00401059   lea         edi,[ebp-40h]
0040105C   mov         ecx,10h
00401061   mov         eax,0CCCCCCCCh
00401066   rep stos    dword ptr [edi]
9:        __asm
10:       {
11:           mov eax,eax
00401068   mov         eax,eax
12:       }
13:
14:       plus(1,2);
0040106A   push        2								//通过堆栈传参数				
0040106C   push        1
0040106E   call        @ILT+0(plus) (00401005)
00401073   add         esp,8                           //还原堆栈
15:
16:       return;
17:   }
00401076   pop         edi
00401077   pop         esi
00401078   pop         ebx
00401079   add         esp,40h
0040107C   cmp         ebp,esp
0040107E   call        __chkesp (004010a0)
00401083   mov         esp,ebp
00401085   pop         ebp
00401086   ret
--- No source file  -------------------------------------------------------------------------------------------------------------------------------------
00401087   int         3
00401088   int         3

3、参数是如何传递的 C语言中参数传递:堆栈传参数从右到左

4、返回值存在哪里?返回值用了吗? C语言中,返回值存储在EAX中

2.3.变量

1、声明变量 变量类型变量名; 变量类型用来说明宽度是多大 int 4个字节 short 2个字节 char 1个字节

变量名的命名规则: 1、只能以字母、数字、下划线组成,且第一个字母必须是字母或下划线 2、区分大小写 3、不能使用C语言的关键字

2、全局变量: 1)编译的时候就已经确定了内存地址和宽度,变量名就是内存地址的别名。 2)如果不重写编译,全局变量的内存地址不变。游戏外挂中的找“基址”,其实就 是找全局变量。| 3)全局变量中的值任何程序都可以改,是公用的。 例子: CE搜索基址

C语言代码

#include <windows.h>
#include <stdio.h>

int x;

void main()
{
	x = 1234567;

	while(1)
	{
		Sleep(3000);
		printf("%d\n",x);
	}

	return;
}

3、局部变量 1)局部变量是函数内部申请的,如果函数没有执行,那么局部变量没有内存空间。 2)局部变量的内存是在堆栈中分配的,程序执行时才分配。我们无法预知程序何时 执行,这也就意味着,我们无法确定局部变量的内存地址。 3)因为局部变量地址内存是不确定的,所以,局部变量只能在函数内部使用,其他 函数不能使用。

2.4.变量与参数的内存布局

c语言代码

int plus(int x,int y)
{
	int z = x + y;
	return z;
}

void main()
{
	int r;
	r = plus(1,2);
	return;
} 

汇编代码

1:
2:    int plus(int x,int y)
3:    {
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,44h
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-44h]
0040102C   mov         ecx,11h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
4:        int z = x + y;
00401038   mov         eax,dword ptr [ebp+8]
0040103B   add         eax,dword ptr [ebp+0Ch]
0040103E   mov         dword ptr [ebp-4],eax            //[ebp-4]存放局部变量
5:        return z;
00401041   mov         eax,dword ptr [ebp-4]
6:    }
00401044   pop         edi
00401045   pop         esi
00401046   pop         ebx
00401047   mov         esp,ebp
00401049   pop         ebp
0040104A   ret
--- No source file  -----------------------------------------------------------------------------------------------
0040104B   int         3
0040104C   int         3

--- C:\Program Files\Microsoft Visual Studio\MyProjects\11\test.cpp  ----------------------------------------------
7:
8:    void main()
9:    {
00401060   push        ebp
00401061   mov         ebp,esp
00401063   sub         esp,44h
00401066   push        ebx
00401067   push        esi
00401068   push        edi
00401069   lea         edi,[ebp-44h]
0040106C   mov         ecx,11h
00401071   mov         eax,0CCCCCCCCh
00401076   rep stos    dword ptr [edi]
10:       int r;
11:       r = plus(1,2);
00401078   push        2
0040107A   push        1
0040107C   call        @ILT+0(plus) (00401005)
00401081   add         esp,8
00401084   mov         dword ptr [ebp-4],eax
12:       return;
13:   }
00401087   pop         edi
00401088   pop         esi
00401089   pop         ebx
0040108A   add         esp,44h
0040108D   cmp         ebp,esp
0040108F   call        __chkesp (004010b0)
00401094   mov         esp,ebp
00401096   pop         ebp
00401097   ret
--- No source file  -----------------------------------------------------------------------------------------------
00401098   int         3
00401099   int         3

堆栈图

1.5.函数嵌套调用的内存布局

C语言代码

#include<stdio.h>

int plus1(int x,int y)
{
	return x+y;
}

int plus(int x,int y,int z)
{
	int m = plus1(x,y);
	return m+z;
}

void main()
{
	int r;
	r = plus(1,2,3);
	printf("%d",r);
	return;
}

汇编代码

1:    #include<stdio.h>
2:
3:    int plus1(int x,int y)
4:    {
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,40h
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-40h]
0040102C   mov         ecx,10h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
5:        return x+y;
00401038   mov         eax,dword ptr [ebp+8]
0040103B   add         eax,dword ptr [ebp+0Ch]
6:    }
0040103E   pop         edi
0040103F   pop         esi
00401040   pop         ebx
00401041   mov         esp,ebp
00401043   pop         ebp
00401044   ret
--- No source file  -----------------------------------------------------------------------------------------------
00401045   int         3
00401046   int         3

7:
8:    int plus(int x,int y,int z)
9:    {
00401060   push        ebp
00401061   mov         ebp,esp
00401063   sub         esp,44h
00401066   push        ebx
00401067   push        esi
00401068   push        edi
00401069   lea         edi,[ebp-44h]
0040106C   mov         ecx,11h
00401071   mov         eax,0CCCCCCCCh
00401076   rep stos    dword ptr [edi]                 
10:       int m = plus1(x,y);
00401078   mov         eax,dword ptr [ebp+0Ch]
0040107B   push        eax
0040107C   mov         ecx,dword ptr [ebp+8]
0040107F   push        ecx
00401080   call        @ILT+10(plus) (0040100f)
00401085   add         esp,8
00401088   mov         dword ptr [ebp-4],eax
11:       return m+z;
0040108B   mov         eax,dword ptr [ebp-4]
0040108E   add         eax,dword ptr [ebp+10h]
12:   }
00401091   pop         edi
00401092   pop         esi
00401093   pop         ebx
00401094   add         esp,44h
00401097   cmp         ebp,esp
00401099   call        __chkesp (004010b0)
0040109E   mov         esp,ebp
004010A0   pop         ebp
004010A1   ret
--- No source file  -----------------------------------------------------------------------------------------------
004010A2   int         3
004010A3   int         3

13:
14:   void main()
15:   {
0040B500   push        ebp
0040B501   mov         ebp,esp
0040B503   sub         esp,44h
0040B506   push        ebx
0040B507   push        esi
0040B508   push        edi
0040B509   lea         edi,[ebp-44h]
0040B50C   mov         ecx,11h
0040B511   mov         eax,0CCCCCCCCh
0040B516   rep stos    dword ptr [edi]     
16:       int r;
17:       r = plus(1,2,3);
0040B518   push        3
0040B51A   push        2
0040B51C   push        1                  //传三个参数
0040B51E   call        @ILT+15(plus) (00401014)
0040B523   add         esp,0Ch
0040B526   mov         dword ptr [ebp-4],eax
18:       printf("%d",r);
0040B529   mov         eax,dword ptr [ebp-4]
0040B52C   push        eax
0040B52D   push        offset string "%d" (0041f10c)
0040B532   call        printf (0040b770)
0040B537   add         esp,8
19:       return;
20:   }
0040B53A   pop         edi
0040B53B   pop         esi
0040B53C   pop         ebx
0040B53D   add         esp,44h
0040B540   cmp         ebp,esp
0040B542   call        __chkesp (004010b0)
0040B547   mov         esp,ebp
0040B549   pop         ebp
0040B54A   ret
--- No source file  -----------------------------------------------------------------------------------------------
0040B54B   int         3
0040B54C   int         3

堆栈图

2.5.整数类型

1、整数类型的宽度:

char、short、 int、 long

char 8BIT 1字节 0~ 0xFF short 16BIT 2字节 0~ 0xFFFF int 32BIT 4字节 0 ~ 0xFFFFFFFF long 32BIT 4字节 0 ~ 0xFFFFFFFF

特别说明: int在16计算机中与short宽度-样,在32以上的计算机中与long同

2、存储格式: charx=1; //0000 0001 0x01 charx= 1; //1111 1111 0xFF

3、有符号与无符号数(signed、 unsigned) 1)什么时候使用有符号、无符号 2)有符号与无符号的区别: <1>正确理解有符号数与无符号数 <2>拓展时与比较时才有区别

2.6.if语句

C语言代码

#include<stdio.h>
#include<windows.h>

void main()
{
	int x = 10;
	int y = 20;

	if(x>y)
	{
		printf("+++++\n");
	}
	else
	{
		printf("------\n");
	}

	return;
} 

汇编代码

1:    #include<stdio.h>
2:    #include<windows.h>
3:
4:    void main()
5:    {
00401010   push        ebp
00401011   mov         ebp,esp
00401013   sub         esp,48h
00401016   push        ebx
00401017   push        esi
00401018   push        edi
00401019   lea         edi,[ebp-48h]
0040101C   mov         ecx,12h
00401021   mov         eax,0CCCCCCCCh
00401026   rep stos    dword ptr [edi]
6:        int x = 10;
00401028   mov         dword ptr [ebp-4],0Ah
7:        int y = 20;
0040102F   mov         dword ptr [ebp-8],14h
8:
9:        if(x>y)
00401036   mov         eax,dword ptr [ebp-4]
00401039   cmp         eax,dword ptr [ebp-8]
0040103C   jle         main+3Dh (0040104d)
10:       {
11:           printf("+++++\n");
0040103E   push        offset string "+++++\n" (00420028)
00401043   call        printf (00401090)
00401048   add         esp,4
12:       }
13:       else
0040104B   jmp         main+4Ah (0040105a)
14:       {
15:           printf("------\n");
0040104D   push        offset string "------\n" (0042001c)
00401052   call        printf (00401090)
00401057   add         esp,4
16:       }
17:
18:       return;
19:   }
0040105A   pop         edi
0040105B   pop         esi
0040105C   pop         ebx
0040105D   add         esp,48h
00401060   cmp         ebp,esp
00401062   call        __chkesp (00401110)
00401067   mov         esp,ebp
00401069   pop         ebp
0040106A   ret
--- No source file  -----------------------------------------------------------------------------------------------
0040106B   int         3
0040106C   int         3

2.7.switch语句

当分支条件比较多得时候switch比if语句高效很多。

case条件按顺序时候的汇编代码

C语言代码

#include<stdio.h>
#include<windows.h>

void Myprint(int x)
{
	switch(x)
	{
	case 1:
		printf("A\n");
		break;
	case 2:
		printf("B\n");
		break;
	case 3:
		printf("C\n");
		break;
	case 4:
		printf("D\n");
		break;
	case 5:
		printf("E\n");
		break;
	}
}

void main()
{
	Myprint(3);

	return ;
} 

汇编语言代码

1:    #include<stdio.h>
2:    #include<windows.h>
3:
4:    void Myprint(int x)
5:    {
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,44h
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-44h]
0040102C   mov         ecx,11h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
6:        switch(x)
7:        {
00401038   mov         eax,dword ptr [ebp+8]
0040103B   mov         dword ptr [ebp-4],eax
0040103E   mov         ecx,dword ptr [ebp-4]
00401041   sub         ecx,1
00401044   mov         dword ptr [ebp-4],ecx
00401047   cmp         dword ptr [ebp-4],4
0040104B   ja          $L42195+0Dh (004010a0)
0040104D   mov         edx,dword ptr [ebp-4]
00401050   jmp         dword ptr [edx*4+4010B1h]
8:        case 1:
9:            printf("A\n");
00401057   push        offset string "A\n" (0042002c)
0040105C   call        printf (00401130)
00401061   add         esp,4
10:           break;
00401064   jmp         $L42195+0Dh (004010a0)
11:       case 2:
12:           printf("B\n");
00401066   push        offset string "B\n" (00420028)
0040106B   call        printf (00401130)
00401070   add         esp,4
13:           break;
00401073   jmp         $L42195+0Dh (004010a0)
14:       case 3:
15:           printf("C\n");
00401075   push        offset string "C\n" (00420024)
0040107A   call        printf (00401130)
0040107F   add         esp,4
16:           break;
00401082   jmp         $L42195+0Dh (004010a0)
17:       case 4:
18:           printf("D\n");
00401084   push        offset string "D\n" (00420020)
00401089   call        printf (00401130)
0040108E   add         esp,4
19:           break;
00401091   jmp         $L42195+0Dh (004010a0)
20:       case 5:
21:           printf("E\n");
00401093   push        offset string "E\n" (0042001c)
00401098   call        printf (00401130)
0040109D   add         esp,4
22:           break;
23:       }
24:   }
004010A0   pop         edi
004010A1   pop         esi
004010A2   pop         ebx
004010A3   add         esp,44h
004010A6   cmp         ebp,esp
004010A8   call        __chkesp (004011b0)
004010AD   mov         esp,ebp
004010AF   pop         ebp
004010B0   ret
004010B1   push        edi
004010B2   adc         byte ptr [eax],al
004010B5   adc         byte ptr [eax],al
004010B9   jne         Myprint+0ABh (004010cb)
004010BB   inc         eax
004010BC   add         byte ptr [eax+edx+10930040h],al
004010C3   inc         eax
004010C4   add         ah,cl
--- No source file  -----------------------------------------------------------------------------------------------
004010C6   int         3
004010C7   int         3

case条件不按顺序时候的汇编代码

c语言代码

#include<stdio.h>
#include<windows.h>

void Myprint(int x)
{
	switch(x)
	{
	case 1:
		printf("A\n");
		break;
	case 2:
		printf("B\n");
		break;
	case 4:
		printf("C\n");
		break;
	case 7:
		printf("D\n");
		break;
	case 8:
		printf("E\n");
		break;
	}
}

void main()
{
	Myprint(3);

	return ;
} 

汇编代码

:    #include<stdio.h>
2:    #include<windows.h>
3:
4:    void Myprint(int x)
5:    {
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,44h
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-44h]
0040102C   mov         ecx,11h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
6:        switch(x)
7:        {
00401038   mov         eax,dword ptr [ebp+8]
0040103B   mov         dword ptr [ebp-4],eax
0040103E   mov         ecx,dword ptr [ebp-4]
00401041   sub         ecx,1
00401044   mov         dword ptr [ebp-4],ecx
00401047   cmp         dword ptr [ebp-4],7
0040104B   ja          $L42196+0Dh (004010a0)
0040104D   mov         edx,dword ptr [ebp-4]
00401050   jmp         dword ptr [edx*4+4010B1h]
8:        case 1:
9:            printf("A\n");
00401057   push        offset string "A\n" (0042002c)
0040105C   call        printf (00401130)
00401061   add         esp,4
10:           break;
00401064   jmp         $L42196+0Dh (004010a0)
11:       case 2:
12:           printf("B\n");
00401066   push        offset string "B\n" (00420028)
0040106B   call        printf (00401130)
00401070   add         esp,4
13:           break;
00401073   jmp         $L42196+0Dh (004010a0)
14:       case 4:
15:           printf("C\n");
00401075   push        offset string "C\n" (00420024)
0040107A   call        printf (00401130)
0040107F   add         esp,4
16:           break;
00401082   jmp         $L42196+0Dh (004010a0)
17:       case 7:
18:           printf("D\n");
00401084   push        offset string "D\n" (00420020)
00401089   call        printf (00401130)
0040108E   add         esp,4
19:           break;
00401091   jmp         $L42196+0Dh (004010a0)
20:       case 8:
21:           printf("E\n");
00401093   push        offset string "E\n" (0042001c)
00401098   call        printf (00401130)
0040109D   add         esp,4
22:           break;
23:       }
24:   }
004010A0   pop         edi
004010A1   pop         esi
004010A2   pop         ebx
004010A3   add         esp,44h
004010A6   cmp         ebp,esp
004010A8   call        __chkesp (004011b0)
004010AD   mov         esp,ebp
004010AF   pop         ebp
004010B0   ret
004010B1   push        edi
004010B2   adc         byte ptr [eax],al
004010B5   adc         byte ptr [eax],al
004010B9   mov         al,[75004010]
004010BE   adc         byte ptr [eax],al
004010C1   mov         al,[A0004010]
004010C6   adc         byte ptr [eax],al
004010C9   test        byte ptr [eax],dl
004010CB   inc         eax
004010CC   add         byte ptr [ebx-33FFBFF0h],dl
--- No source file  -----------------------------------------------------------------------------------------------
004010D2   int         3
004010D3   int         3

case条件中间不连续(3,5,6)的地方,会填充为default的地址,

2.8.for循环

C语言代码

#include<stdio.h>
#include<windows.h>

void Myprint()
{
	int i;
	for(i=0;i<10;i++)
	{
		printf("%d\n",i);
	}
}

void main()
{
	Myprint();

	return ;
} 

汇编代码

1:    #include<stdio.h>
2:    #include<windows.h>
3:
4:    void Myprint()
5:    {
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,44h
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-44h]
0040102C   mov         ecx,11h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
6:        int i;
7:        for(i=0;i<10;i++)
00401038   mov         dword ptr [ebp-4],0
0040103F   jmp         Myprint+2Ah (0040104a)
00401041   mov         eax,dword ptr [ebp-4]
00401044   add         eax,1
00401047   mov         dword ptr [ebp-4],eax
0040104A   cmp         dword ptr [ebp-4],0Ah
0040104E   jge         Myprint+43h (00401063)
8:        {
9:            printf("%d\n",i);
00401050   mov         ecx,dword ptr [ebp-4]
00401053   push        ecx
00401054   push        offset string "E\n" (0042001c)
00401059   call        printf (00401130)
0040105E   add         esp,8
10:       }
00401061   jmp         Myprint+21h (00401041)
11:   }
00401063   pop         edi
00401064   pop         esi
00401065   pop         ebx
00401066   add         esp,44h
00401069   cmp         ebp,esp
0040106B   call        __chkesp (004011b0)
00401070   mov         esp,ebp
00401072   pop         ebp
00401073   ret
--- No source file  ---------------------------------------------------------------------------------------------------------------------
00401074   int         3
00401075   int         3

2.9.数组

C语言代码

#include<stdio.h>
#include<windows.h>


void main()
{
	int age[5]={1,2,3,4,5};
	int x,y;
	x = age[0];
	age[1]=6;
	y = age[1];
	printf("%d\n%d",x,y);
	return ;
} 

汇编代码

1:    #include<stdio.h>
2:    #include<windows.h>
3:
4:
5:    void main()
6:    {
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,5Ch
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-5Ch]
0040102C   mov         ecx,17h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
7:        int age[5]={1,2,3,4,5};
00401038   mov         dword ptr [ebp-14h],1
0040103F   mov         dword ptr [ebp-10h],2
00401046   mov         dword ptr [ebp-0Ch],3
0040104D   mov         dword ptr [ebp-8],4
00401054   mov         dword ptr [ebp-4],5
8:        int x,y;
9:        x = age[0];
0040105B   mov         eax,dword ptr [ebp-14h]
0040105E   mov         dword ptr [ebp-18h],eax
10:       age[1]=6;
00401061   mov         dword ptr [ebp-10h],6
11:       y = age[1];
00401068   mov         ecx,dword ptr [ebp-10h]
0040106B   mov         dword ptr [ebp-1Ch],ecx
12:       printf("%d\n%d",x,y);
0040106E   mov         edx,dword ptr [ebp-1Ch]
00401071   push        edx
00401072   mov         eax,dword ptr [ebp-18h]
00401075   push        eax
00401076   push        offset string "%d\n%d" (0042001c)
0040107B   call        printf (00401130)
00401080   add         esp,0Ch
13:       return ;
14:   }
00401083   pop         edi
00401084   pop         esi
00401085   pop         ebx
00401086   add         esp,5Ch
00401089   cmp         ebp,esp
0040108B   call        __chkesp (004011b0)
00401090   mov         esp,ebp
00401092   pop         ebp
00401093   ret
--- No source file  ---------------------------------------------------------------------------------------------------------------------
00401094   int         3
00401095   int         3

2.10.多维数组

C语言代码

#include<stdio.h>
#include<windows.h>


void main()
{
	int arr[3][4] = 
	{
		{1,2,3,4},
		{5,6,7,8},
		{9,10,11,12}
	};

	return ;
} 

汇编代码

1:    #include<stdio.h>
2:    #include<windows.h>
3:
4:
5:    void main()
6:    {
00401010   push        ebp
00401011   mov         ebp,esp
00401013   sub         esp,70h
00401016   push        ebx
00401017   push        esi
00401018   push        edi
00401019   lea         edi,[ebp-70h]
0040101C   mov         ecx,1Ch
00401021   mov         eax,0CCCCCCCCh
00401026   rep stos    dword ptr [edi]
7:        int arr[3][4] =
8:        {
9:            {1,2,3,4},
00401028   mov         dword ptr [ebp-30h],1
0040102F   mov         dword ptr [ebp-2Ch],2
00401036   mov         dword ptr [ebp-28h],3
0040103D   mov         dword ptr [ebp-24h],4
10:           {5,6,7,8},
00401044   mov         dword ptr [ebp-20h],5
0040104B   mov         dword ptr [ebp-1Ch],6
00401052   mov         dword ptr [ebp-18h],7
00401059   mov         dword ptr [ebp-14h],8
11:           {9,10,11,12}
00401060   mov         dword ptr [ebp-10h],9
00401067   mov         dword ptr [ebp-0Ch],0Ah
0040106E   mov         dword ptr [ebp-8],0Bh
00401075   mov         dword ptr [ebp-4],0Ch
12:       };
13:
14:       return ;
15:   }
0040107C   pop         edi
0040107D   pop         esi
0040107E   pop         ebx
0040107F   mov         esp,ebp
00401081   pop         ebp
00401082   ret
--- No source file  ---------------------------------------------------------------------------------------------------------------------
00401083   int         3
00401084   int         3

2.11.结构体

结构体类型的定义:

struct类型名{
	//可以定义多种类型
	inta;
	char b;
	short c;
};

<1> char/int/数组等是编译器已经认识的类型:内置类型 <2>结构体是编译器不认识的,用的时候需要告诉编译器-声:自定义类型 <3>.上面的代码仅仅是告诉编译器我们自己定义的类型是什么样的,本身并不占用内存。

定义结构体类型的时候,直接定义变量

struct stPoint{
	int x;
	int y;
}point1 ,point2,point3;

//这种方式是分配内存的,因为不仅仅是定义新的类型,还定义了3个全局变量

2.12.字节对齐

1.什么是字节对齐呢? char X; short y;| intz;

字节对齐: 一个变量占用n个字节,则该变量的起始地址必须是n的整数倍,即:存放起始地址% n=0。

如果是结构体,那么结构体的起始地址是其最宽数据类型成员的整数倍。

2.结构体字节对齐占用空间大小

#include<stdio.h>
#include<windows.h>

struct test1{
	char a;
	int b;
};

struct test2{
	char c;
	double d;
};

int check()
{
	printf("%d\n",sizeof(test1));    //8
	printf("%d\n",sizeof(test2));    //16
	return 0;
}


void main()
{
	check();
	getchar();
	return ;
} 

3.当对空间要求较高的时候,可以通过#pragma pack(n)来改变结构体成员的对齐方式

#pragma pack(1)
structTest{
	char a;
	int b;
};
#pragma pack()

<1> #pragma pack(n)中n用来设定变量以n字节对齐方式,可以设定的值包括: 1、2、4、8,VC编译器默认是8。 <2>若需取消强制对齐方式,则可用命令#pragma pack()

<3>结构体大总大小: N = Min(最大成员,对齐参数)是N的整数倍

2.13.指针类型

1、定义带“*”类型的变量

1、带有**的变量类型的标准写法:变量类型* * 变量名。 2、任何类型都可以带* 加上* 以后是新的类型,统称“指针类型”。 3、*可以是任意多个。

2、指针宽度

指针类型的变量宽度永远是4字节、无论类型是什么,无论有几个*。

char* a
short* b
int* c

3、指针类型的自加和自减 1、不带类型的变量,++或者-都是加1或者减1 2、带类型的变量,++或者-新增(减少)的数量是去掉-一个*后变量的宽度

#include<stdio.h>
#include<windows.h>

void main()
{

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

	a = (char*)100;
	b = (short*)100;
	c = (int*)100;
	a++;   //减掉一个*后就是char的宽度,1
	b++;   //减掉一个*后就是short的宽度,2
	c++;   //减掉一个*后就是int的宽度,4
	printf("%d %d %d\n",a,b,c);   //101 102 104
		
	system("pause");
	return ;
} 
#include<stdio.h>
#include<windows.h>

void main()
{

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

	a = (char**)100;
	b = (short**)100;
	c = (int**)100;
	a++;   //减掉一个*后就是char*的宽度,4
	b++;   //减掉一个*后就是short*的宽度,4
	c++;   //减掉一个*后就是int*的宽度,4
	printf("%d %d %d\n",a,b,c);   //104 104 104
		
	system("pause");
	return ;
} 

4、指针类型的加减运算 1、指针类型的变量可以加、减-一个整数,但不能乘或者除. 2、指针类型变量与其他整数相加或者相减时: 指针类型变量+N = 指针类型变量+ N * (去掉-一个* 后类型的宽度) 指针类型变量-N = 指针类型变量- N * (去掉-一个 * 后类型的宽度)

#include<stdio.h>
#include<windows.h>

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

	a = (char*)100;
	b = (short*)100;
	c = (int*)100;
	a = a + 5;     // a = 100+(1x5)
	b = b + 5;     // b = 100+(2x5)
	c = c + 5;     // c = 100+(4x5)
	printf("%d %d %d\n",a,b,c);   //105 110 120
		
	system("pause");
	return ;
} 
#include<stdio.h>
#include<windows.h>

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

	a = (char**)100;
	b = (short**)100;
	c = (int**)100;
	a = a + 5;     // a = 100+(4x5)
	b = b + 5;     // b = 100+(4x5)
	c = c + 5;     // c = 100+(4x5)
	printf("%d %d %d\n",a,b,c);   //120 120 120
		
	system("pause");
	return ;
} 

5、指针类型可以做大小比较

#include<stdio.h>
#include<windows.h>

void main()
{

	char* a;
	char* b;

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

	if(a>b)
	{
		printf("1\n");     //1
	}
	else
	{
		printf("2\n");
	}
		
	system("pause");
	return ;
} 

2.14.&的使用

&是取地址符,任何变量都可以使用&来获取地址,但不能用在常量上。

指针变量赋值

#include<stdio.h>
#include<windows.h>

void main()
{

	char x;
	char* p1;
	char** p2;
	char*** p3;
	char**** p4;

	p1 = &x;        //char*
	p2 = &p1;		//char**
	p3 = &p2;		//cahr***
	p4 = &p3;		//char****
	
	system("pause");
	return ;
} 

2.15.取值运算符

1、 * 指针类型 的类型

*加指针类型 的类型是 指针类型减去一个 *

#include<stdio.h>
#include<windows.h>

void main()
{
	int*** a;
	int** b;
	int* c;

	int x = *(a);		//a是int***类型,*(a)是int**类型 
	int y = *(b);		//b是int**类型,*(b)是int*类型
	int z = *(c);		//c是int*类型,*(c)是int类型
		
	system("pause");
	return ;
} 

取值运算符举例

C语言代码

#include<stdio.h>
#include<windows.h>

int x = 1;
int* p1;
int** p2;
int*** p3;

void main()
{
	p1 = &x;
	p2 = &p1;
	p3=&p2;

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

	system("pause");
	return ;
} 

汇编代码

1:    #include<stdio.h>
2:    #include<windows.h>
3:
4:    int x = 1;
5:    int* p1;
6:    int** p2;
7:    int*** p3;
8:
9:    void main()
10:   {
00401010   push        ebp
00401011   mov         ebp,esp
00401013   sub         esp,44h
00401016   push        ebx
00401017   push        esi
00401018   push        edi
00401019   lea         edi,[ebp-44h]
0040101C   mov         ecx,11h
00401021   mov         eax,0CCCCCCCCh
00401026   rep stos    dword ptr [edi]
11:       p1 = &x;
00401028   mov         dword ptr [p1 (004255ec)],offset x (00424a30)
12:       p2 = &p1;
00401032   mov         dword ptr [p2 (004255f0)],offset p1 (004255ec)
13:       p3=&p2;
0040103C   mov         dword ptr [p3 (004255f4)],offset p2 (004255f0)
14:
15:       int r = *(*(*(p3)));
00401046   mov         eax,[p3 (004255f4)]
0040104B   mov         ecx,dword ptr [eax]
0040104D   mov         edx,dword ptr [ecx]
0040104F   mov         eax,dword ptr [edx]
00401051   mov         dword ptr [ebp-4],eax
16:       printf("%d\n",r);
00401054   mov         ecx,dword ptr [ebp-4]
00401057   push        ecx
00401058   push        offset string "%d\n" (00422024)
0040105D   call        printf (004011b0)
00401062   add         esp,8
17:
18:       system("pause");
00401065   push        offset string "pause" (0042201c)
0040106A   call        system (004010a0)
0040106F   add         esp,4
19:       return ;
20:   }
00401072   pop         edi
00401073   pop         esi
00401074   pop         ebx
00401075   add         esp,44h
00401078   cmp         ebp,esp
0040107A   call        __chkesp (00401230)
0040107F   mov         esp,ebp
00401081   pop         ebp
00401082   ret
--- No source file  --------------------------------------------------------------------------------------------------------------------------------
00401083   int         3

2.16.数组参数传递

1、数组作为参数:****

1.传递的是数组的首地址(也就是数组 第一个元素的地址)

2.应该传递数组的长度

C语言代码

#include<stdio.h>
#include<windows.h>

void PrintArray(int arr[], int nLength)
{
	for(int i=0;i<nLength;i++)
	{
		printf("%d\n",arr[i]);
	}
}

void main()
{
	int arr[5] = {1,2,3,4,5};
	PrintArray(arr,5);
	
	system("pause");
	return ;
} 

汇编代码

1:    #include<stdio.h>
2:    #include<windows.h>
3:
4:    void PrintArray(int arr[], int nLength)
5:    {
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,44h
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-44h]
0040102C   mov         ecx,11h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
6:        for(int i=0;i<nLength;i++)
00401038   mov         dword ptr [ebp-4],0
0040103F   jmp         PrintArray+2Ah (0040104a)
00401041   mov         eax,dword ptr [ebp-4]
00401044   add         eax,1
00401047   mov         dword ptr [ebp-4],eax
0040104A   mov         ecx,dword ptr [ebp-4]
0040104D   cmp         ecx,dword ptr [ebp+0Ch]
00401050   jge         PrintArray+4Bh (0040106b)
7:        {
8:            printf("%d\n",arr[i]);
00401052   mov         edx,dword ptr [ebp-4]
00401055   mov         eax,dword ptr [ebp+8]
00401058   mov         ecx,dword ptr [eax+edx*4]
0040105B   push        ecx
0040105C   push        offset string "%d\n" (0042201c)
00401061   call        printf (00401120)
00401066   add         esp,8
9:        }
00401069   jmp         PrintArray+21h (00401041)
10:   }
0040106B   pop         edi
0040106C   pop         esi
0040106D   pop         ebx
0040106E   add         esp,44h
00401071   cmp         ebp,esp
00401073   call        __chkesp (004011a0)
00401078   mov         esp,ebp
0040107A   pop         ebp
0040107B   ret
--- No source file  --------------------------------------------------------------------------------------------------------------------------------
0040107C   int         3

--- c:\program files\microsoft visual studio\myprojects\11\test.cpp  -------------------------------------------------------------------------------
11:
12:   void main()
13:   {
004010A0   push        ebp
004010A1   mov         ebp,esp
004010A3   sub         esp,54h
004010A6   push        ebx
004010A7   push        esi
004010A8   push        edi
004010A9   lea         edi,[ebp-54h]
004010AC   mov         ecx,15h
004010B1   mov         eax,0CCCCCCCCh
004010B6   rep stos    dword ptr [edi]
14:       int arr[5] = {1,2,3,4,5};
004010B8   mov         dword ptr [ebp-14h],1
004010BF   mov         dword ptr [ebp-10h],2
004010C6   mov         dword ptr [ebp-0Ch],3
004010CD   mov         dword ptr [ebp-8],4
004010D4   mov         dword ptr [ebp-4],5
15:       PrintArray(arr,5);
004010DB   push        5
004010DD   lea         eax,[ebp-14h]
004010E0   push        eax
004010E1   call        @ILT+0(PrintArray) (00401005)
004010E6   add         esp,8
16:
17:       system("pause");
004010E9   push        offset string "pause" (00422020)
004010EE   call        system (004011e0)
004010F3   add         esp,4
18:       return ;
19:   }
004010F6   pop         edi
004010F7   pop         esi
004010F8   pop         ebx
004010F9   add         esp,54h
004010FC   cmp         ebp,esp
004010FE   call        __chkesp (004011a0)
00401103   mov         esp,ebp
00401105   pop         ebp
00401106   ret
--- No source file  --------------------------------------------------------------------------------------------------------------------------------
00401107   int         3

2、用指针来操作数组

数组作为参数时,传递的人是地址

C语言代码

#include<stdio.h>
#include<windows.h>

void PrintArray(int* p, int nLength)
{
	for(int i=0;i<nLength;i++)
	{
		printf("%d\n",*(p+i));
	}
}

void main()
{
	int arr[5] = {1,2,3,4,5};
	PrintArray(&arr[0],5);
	
	system("pause");
	return ;
} 

汇编代码

1:    #include<stdio.h>
2:    #include<windows.h>
3:
4:    void PrintArray(int* p, int nLength)
5:    {
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,44h
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-44h]
0040102C   mov         ecx,11h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
6:        for(int i=0;i<nLength;i++)
00401038   mov         dword ptr [ebp-4],0
0040103F   jmp         PrintArray+2Ah (0040104a)
00401041   mov         eax,dword ptr [ebp-4]
00401044   add         eax,1
00401047   mov         dword ptr [ebp-4],eax
0040104A   mov         ecx,dword ptr [ebp-4]
0040104D   cmp         ecx,dword ptr [ebp+0Ch]
00401050   jge         PrintArray+4Bh (0040106b)
7:        {
8:            printf("%d\n",*(p+i));
00401052   mov         edx,dword ptr [ebp-4]
00401055   mov         eax,dword ptr [ebp+8]
00401058   mov         ecx,dword ptr [eax+edx*4]
0040105B   push        ecx
0040105C   push        offset string "%d\n" (0042201c)
00401061   call        printf (00401120)
00401066   add         esp,8
9:        }
00401069   jmp         PrintArray+21h (00401041)
10:   }
0040106B   pop         edi
0040106C   pop         esi
0040106D   pop         ebx
0040106E   add         esp,44h
00401071   cmp         ebp,esp
00401073   call        __chkesp (004011a0)
00401078   mov         esp,ebp
0040107A   pop         ebp
0040107B   ret
--- No source file  --------------------------------------------------------------------------------------------------------------------------------
0040107C   int         3
--- C:\Program Files\Microsoft Visual Studio\MyProjects\11\test.cpp  -------------------------------------------------------------------------------
11:
12:   void main()
13:   {
004010A0   push        ebp
004010A1   mov         ebp,esp
004010A3   sub         esp,54h
004010A6   push        ebx
004010A7   push        esi
004010A8   push        edi
004010A9   lea         edi,[ebp-54h]
004010AC   mov         ecx,15h
004010B1   mov         eax,0CCCCCCCCh
004010B6   rep stos    dword ptr [edi]
14:       int arr[5] = {1,2,3,4,5};
004010B8   mov         dword ptr [ebp-14h],1
004010BF   mov         dword ptr [ebp-10h],2
004010C6   mov         dword ptr [ebp-0Ch],3
004010CD   mov         dword ptr [ebp-8],4
004010D4   mov         dword ptr [ebp-4],5
15:       PrintArray(&arr[0],5);
004010DB   push        5
004010DD   lea         eax,[ebp-14h]
004010E0   push        eax
004010E1   call        @ILT+10(PrintArray) (0040100f)
004010E6   add         esp,8
16:
17:       system("pause");
004010E9   push        offset string "pause" (00422020)
004010EE   call        system (004011e0)
004010F3   add         esp,4
18:       return ;
19:   }
004010F6   pop         edi
004010F7   pop         esi
004010F8   pop         ebx
004010F9   add         esp,54h
004010FC   cmp         ebp,esp
004010FE   call        __chkesp (004011a0)
00401103   mov         esp,ebp
00401105   pop         ebp
00401106   ret
--- No source file  --------------------------------------------------------------------------------------------------------------------------------
00401107   int         3

2.17.指针与字符串

1、字符串的几种表示方式有什么区别?

char str[6] = {'A','B','C','D',E','0'};	//结尾要 '\O'或者0
char str[] = "ABCDE", 	//编译器末尾填0
char* str= "ABCDE";		//常量区

//打印
print("%s\n" ,str);

2、常用的字符串函数

1、int strlen (char* s)
返回值是字符串s的长度。不包括结束符'/0'。

2、char* strcpy (char* dest, char* src);
复制字符串src到dest中。返回指针为dest的值。

3、char* strcat (char* dest, char* src);
将字符串src添加到dest尾部。返回指针为dest的值。

4、int strcmp ( char* s1, char* s2);
一样返回0 不一样返回非0

2.18.指针取值的两种方式

1、一级指针和多级指针

c语言代码

#include<stdio.h>
#include<windows.h>

void main()
{
	int i = 100;

	int* p1 = &i;
	int** p2 = &p1;
	int*** p3 = &p2;
	int**** p4 = &p3;
	int***** p5 = &p4;
	int****** p6 = &p5;
	int******* p7 = &p6;

	int y = *******p7;  //y=1

	int z= p7[0][0][0][0][0][0][0]; //z=1 

	
	system("pause");
	return ;
} 

汇编代码

1:    #include<stdio.h>
2:    #include<windows.h>
3:
4:    void main()
5:    {
00401010   push        ebp
00401011   mov         ebp,esp
00401013   sub         esp,68h
00401016   push        ebx
00401017   push        esi
00401018   push        edi
00401019   lea         edi,[ebp-68h]
0040101C   mov         ecx,1Ah
00401021   mov         eax,0CCCCCCCCh
00401026   rep stos    dword ptr [edi]
6:        int i = 100;
00401028   mov         dword ptr [ebp-4],64h
7:
8:        int* p1 = &i;
0040102F   lea         eax,[ebp-4]
00401032   mov         dword ptr [ebp-8],eax
9:        int** p2 = &p1;
00401035   lea         ecx,[ebp-8]
00401038   mov         dword ptr [ebp-0Ch],ecx
10:       int*** p3 = &p2;
0040103B   lea         edx,[ebp-0Ch]
0040103E   mov         dword ptr [ebp-10h],edx
11:       int**** p4 = &p3;
00401041   lea         eax,[ebp-10h]
00401044   mov         dword ptr [ebp-14h],eax
12:       int***** p5 = &p4;
00401047   lea         ecx,[ebp-14h]
0040104A   mov         dword ptr [ebp-18h],ecx
13:       int****** p6 = &p5;
0040104D   lea         edx,[ebp-18h]
00401050   mov         dword ptr [ebp-1Ch],edx
14:       int******* p7 = &p6;
00401053   lea         eax,[ebp-1Ch]
00401056   mov         dword ptr [ebp-20h],eax
15:
16:       int y = *******p7;  //y=1
00401059   mov         ecx,dword ptr [ebp-20h]
0040105C   mov         edx,dword ptr [ecx]
0040105E   mov         eax,dword ptr [edx]
00401060   mov         ecx,dword ptr [eax]
00401062   mov         edx,dword ptr [ecx]
00401064   mov         eax,dword ptr [edx]
00401066   mov         ecx,dword ptr [eax]
00401068   mov         edx,dword ptr [ecx]
0040106A   mov         dword ptr [ebp-24h],edx
17:
18:       int z= p7[0][0][0][0][0][0][0]; //z=1
0040106D   mov         eax,dword ptr [ebp-20h]
00401070   mov         ecx,dword ptr [eax]
00401072   mov         edx,dword ptr [ecx]
00401074   mov         eax,dword ptr [edx]
00401076   mov         ecx,dword ptr [eax]
00401078   mov         edx,dword ptr [ecx]
0040107A   mov         eax,dword ptr [edx]
0040107C   mov         ecx,dword ptr [eax]
0040107E   mov         dword ptr [ebp-28h],ecx
19:
20:
21:       system("pause");
00401081   push        offset string "pause" (0042201c)
00401086   call        system (004010d0)
0040108B   add         esp,4
22:       return ;
23:   }
0040108E   pop         edi
0040108F   pop         esi
00401090   pop         ebx
00401091   add         esp,68h
00401094   cmp         ebp,esp
00401096   call        __chkesp (004011e0)
0040109B   mov         esp,ebp
0040109D   pop         ebp
0040109E   ret
--- No source file  --------------------------------------------------------------------------------------------------------------------------------
0040109F   int         3

2、总结:

*(p+i)= p[i]
*(*(p+i)+k) = p[i][k]
*(*(*(p+i)+k)+m) = p[i][k][m]
(*(p+i)+k)+m)+W)+t) = p[jIk]Im][W[t]

*()与[]可以相互转换

2.19.结构体指针

通过结构体指针读取和修改值

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>

Point{
	int x;
	int y;
}

void main()
{
	Point p = {1,2};

	Point* px = &p;
	
	int x = px->x;        //x=1
	px->y =100;
	int u = px->y;		  //y=100

	system("pause");
	return ;
} 

2.20.指针数组和数组指针

1、指针数组的定义

char arr[10];   	 //10 char
char* arr[10];		 //10 指针(char*)	 每个成员4字节
Point* arr[10];		 //10 指针(Point*) 每个成员4字节
int******* arr[10];	  // //10 指针(int*******) 每个成员4字节

2、指针数组的赋值

char* a = "hello";  //a存的是地址,里面存放的值是 “hello”
char* b = "你好";

//汇编代码
7:        char* a = "hello";
00401028   mov         dword ptr [ebp-4],offset string "hello" (004230cc)
8:        char* b = "你好";
0040102F   mov         dword ptr [ebp-8],offset string "\xc4\xe3\xba\xc3" (004230c4)
char* arr1[2] = {a,b};    //存放两个地址a和b

char* arr2[2] = {"hello","你好"};   //存放的也是两个地址
    
//汇编代码
7:        char* a = "hello";
00401028   mov         dword ptr [ebp-4],offset string "hello" (0042202c)
8:        char* b = "你好";
0040102F   mov         dword ptr [ebp-8],offset string "\xc4\xe3\xba\xc3" (00422024)
9:
10:       char* arr1[2] = {a,b};
00401036   mov         eax,dword ptr [ebp-4]
00401039   mov         dword ptr [ebp-10h],eax
0040103C   mov         ecx,dword ptr [ebp-8]
0040103F   mov         dword ptr [ebp-0Ch],ecx
11:       char* arr2[2] = {"hello","你好"};
00401042   mov         dword ptr [ebp-18h],offset string "hello" (0042202c)
00401049   mov         dword ptr [ebp-14h],offset string "\xc4\xe3\xba\xc3" (00422024)

3、结构体指针数组

struct Point
{
    int x;
    int y;
};

Point p;	//8字节
Point arr[10];	//8x10字节
Point* arrPoint[10;	//4x10字节

4、数组指针的定义

int(*px)[5];
char(*px)[5];	//一维数组指针

int(*px)[5][4];	//二维数组指针

5、数组指针的宽度与赋值

int(*px1) [5];	//一维数组指针
char(*px2) [3];
int(*px3) [2][2];	//二维数组指针
char(*px4) [3][3][3);	//三维数组指针
print("%d %d %d %d \n" ,sizeof(px1),sizeof(px2),sizeof(px3),sizeof(px4));   //4 4 4 4
                  
px1 = (int (*)[5])1;
px2 = (char (*)[(3])2;
px3 = (int (*)[2][2])3;
px4 = (char (*)[3][3][3])4;

6、数组指针的使用

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>

void main()
{
	int arr[] = {1,2,3,4,5,6,7,8,9,0};

	int(*px)[10] = &arr;

	printf("%d\n",(*px)[0]);	// 1

	system("pause");
	return ;
} 
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>

void main()
{
	int arr[3][3] = 
	{
		{1,2,3},
		{4,5,6},
		{7,8,9}
	};
	
	int(*px)[3] = &arr[0];

	printf("%d %d\n",(*px)[0],(*px)[2]);    //1  3

	px++;

	printf("%d %d\n",(*px)[0],(*px)[2]);	//4  6

	system("pause");
	return ;
} 

2.21.常见的几种调用约定:

三种常见调用约定

调用约定			参数压栈顺序			  平衡堆栈
cdecl			   从右至左入栈		   调用者清理栈

stdcall			   从右至左入栈		   自身清理堆栈

_ _fastcall     ECX/EDX传送前两个          自身清理堆栈
                剩下:从右至左入栈

2.22.函数指针

1、函数指针类型变量的定义 函数指针变量定义的格式:

返回类型(调用约定 *变量名)(参数列表);
如:
int ( _cdecl *pFun)(int,int);

2、通过函数指针绕过断点

<1>函数指针变量的定义
int (__stdcall *pFun)(int,int,int,int,int);

<2>正常调用
MessaleBox(0,0,0,0);

<3>通过函数指针绕过断点
pFun = (int (__stdcall *)(int,int,int,int,int))0x77D5055C;
pFun(0,0,0,0,0);

2.23.预处理之宏定义

1、什么是预处理: 预处理一般是指在程序源代码被转换为二进制代码之前,由预处理器对程序源代码文本进行处理处理后的结再由编译器进- -步编译。 预处理功能主要包括宏定义,文件包含,条件编译三部分

2、宏定义

<1>简单宏: #define 标识符字符序列
# define FALSE 0
# define NAME "测试"
# define_ IN
# define__ OUT

<2>带参数的宏: #define 标识符(参数表)字符序列
#define MAX(A,B) ((A)> (B)?(A):(B))

注意事项: 1、只作字符序列的替换工作,不作任何语法的检查,在编译前处理。 2、宏名标识符与左圆括号之间不允许有空白符,应紧接在- -起。 3、为了避免出错,宏定义中给形参加上括号。 4、多行声明时,回车换行前要加上字符‘\’,即“[enter]" ,注意字符 ‘\’ 后要紧跟回车键,中间不能有空格或其他字符。 5、末尾不需要分号。

2.24.条件编译与文件包含

1、什么是条件编译?

#if 0
	printf("------")
#endif        

2、预处理指令:条件编译是通过预处理指令实现的

3、文件包含有两种格式 分别是: #include "file"和#include 1.使用双引号,系统首先到当前目录下查找被包含的文件,如果没找到,再到系 统指定的"包含文件目录" (由用户在配置环境时设置)去找。 2.使用尖括号:直接到系统指定的"包含文件目录"去查找。 总结: 系统文件用<> 自己定义的文件用””

4、如何解决重复包含问题

  • 条件编译
  • 前置声明

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 滴水逆向初级-C++(三)

    1、什么是封装: 将函数定义到结构体内部,就是封装。 2、什么是类: 带有函数的结构体,称为类。 3、什么是成员函数: 结构体里面的函数,称为成员函数...

    zhang_derek
  • 滴水逆向初级-win32(四)

    1、什么是Win32 API?有哪些?在哪里? 主要是存放在C:\WINDOWS\system32下面所有的dll 几个重要的DLL: <1> Kerne...

    zhang_derek
  • 滴水逆向初级-汇编(一)

    进制的定义: 八进制的定义:由八个符号组成,分别是01234567逢八进一。 十进制的定义:由十个符号组成,分别是0123456789逢十进一。 N进制的...

    zhang_derek
  • 【读者投稿】几年安全学习经验杂谈

    我属于11年左右才开始入行的小菜鸟,听着前辈们经常讲着在10年之前,注入分分钟拿站,到10年开始慢慢出现waf,作为一个新人,waf当年的确是个不错的ideas...

    信安之路
  • 一周极客热文:2014年最值得学习的编程语言

    经过数据分析和研究Jobs Tractor的45000个开发人员招聘职位数据,我们得到了上图的结果: 自上一年,主要的变化如下:

    钱曙光
  • 滴滴面试

    牛客网
  • HTTPS和SSL/TLS协议

    前言 要说清楚 HTTPS 协议的实现原理,至少需要如下几个背景知识。 1. 大致了解几个基本术语(HTTPS、SSL、TLS)的含义 2. 大致了解 HTTP...

    用户1467662
  • 【老炮儿白硕开讲】区块链可替AI对抗数据寡头

    ---- 新智元专栏 作者:白硕 【新智元导读】目前最火的两个领域——人工智能和区块链的完整知识结构长在同一个人的脑子里,这是不常见的,白硕就是这样一...

    新智元
  • 通过游戏外挂.学习逆向技术指超级马里奥.

      逆向就是在没有源代码的情况下.通过汇编.反汇编来逆向一个成品的Exe(也可以是别的.举例是EXE)这样叫做逆向.

    IBinary
  • 聊聊 HTTPS 和 SSL/TLS 协议

    要说清楚 HTTPS 协议的实现原理,至少需要如下几个背景知识。 大致了解几个基本术语(HTTPS、SSL、TLS)的含义 大致了解 HTTP 和 TCP 的...

    程序员宝库
  • HTTPS和SSL/TLS协议

    要说清楚 HTTPS 协议的实现原理,至少需要如下几个背景知识。 1. 大致了解几个基本术语(HTTPS、SSL、TLS)的含义 2. 大致了解 HTTP ...

    菲宇
  • Elasticsearch-快问快答

    Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎,能够解决不断涌现出的各种用例。作为 Elastic Stack 的核心,它集...

    HLee
  • 中科院步态识别技术:不看脸 50米内在人群中认出你!

    如果你觉得好的话,不妨分享到朋友圈。 导语:新华社北京10月2日电(记者董瑞丰)中国科学院自动化所的专家日前介绍了一种新兴的生物特征识别技术——步态识别:只看走...

    IT派
  • 一个贯穿图像处理与数据挖掘的永恒问题

    作者: 左飞 著有《算法之美——隐匿在数据结构背后的原理(C++版)》 原文 http://blog.csdn.net/baimafujinji/articl...

    机器学习AI算法工程
  • 2分钟,完整回顾2017腾讯安全国际技术峰会

    导读:由腾讯安全科恩实验室主办的“2017腾讯安全国际技术峰会(TenSec 2017)”于8月31日落下帷幕,本次峰会聚焦安全行业前沿技术,覆盖时下最热的安全...

    腾讯技术工程官方号
  • 大数据和云计算技术周报(第105期)

    本文从7个角度理解Gossip协议,Gossip协议是一个通信协议,一种传播消息的方式,也是一种最终一致性协议

    大数据和云计算技术
  • TMD寒冬中前进,光凭流量能讲出一个好故事吗?

    当初在西栅河边侃侃而谈的张一鸣、王兴和程维三人,怎么也没想到TMD会在2018年面临最大的变局。

    用户2908108
  • Chameleon跨端框架—一个与Flutter比肩的开源作品

    在跨平台方案上除了有Flutter外,滴滴也出了一个Chameleon变色龙,一种适应不同环境的跨端整体解决方案,了解看看。

    苏南
  • 微信小程序创业向二三线城市持续的流量下沉将会成为主要战场

    自2017年1月小程序正式上线,小程序便一直稳步,持续的发展。2018年7月,根据公开数据显示,微信小程序总量达100w个,用户6亿,日活1.7亿,开发者150...

    速成应用小程序开发平台

扫码关注云+社区

领取腾讯云代金券