zoukankan      html  css  js  c++  java
  • 滴水逆向-指针1

     

     

     

     相关练习和测试代码

    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
    ",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
    ",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
    ",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
    ",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
    ",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
    ",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
    ",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
    ",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
    ",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
    ",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
    ",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
    ",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
    ");    
        }        
        else        
        {        
            printf("8
    ");    
        }        
    }
    
    int main(int argc, char* argv[])
    {
        fun();
        return 0;
    }    
                    
    结论:
                        
    带*的变量,如果类型相同,可以做大小的比较。                
    
    
    课后练习
                        
    1.char类型占几字节?char*类型占几字节?int*****占几字节?    
                        
    char 占用1字节                        
    (32位下)char* 站用4字节                        
    (32位下)int***** 站用4字节                        
                            
                            
    2char** 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
    " (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个字节宽度进行计算,当定义一个*的时候按照结构体内部实际字节站用的计算
            
                            
                            
                            
    迷茫的人生,需要不断努力,才能看清远方模糊的志向!
  • 相关阅读:
    游戏开发系统功能(9)
    游戏开发创建游戏世界(8)
    游戏开发沟通和开会技巧(7)
    游戏开发策划工作(6)
    游戏开发了解测试工作(4)
    Django:学习笔记(9)——用户身份认证
    Django:学习笔记(8)——视图
    Django:学习笔记(7)——模型进阶
    Django:学习笔记(6)——模型
    Django:学习笔记(5)——会话
  • 原文地址:https://www.cnblogs.com/autopwn/p/15133910.html
Copyright © 2011-2022 走看看