• 滴水逆向-指针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个字节宽度进行计算,当定义一个*的时候按照结构体内部实际字节站用的计算
            
                            
                            
                            
    迷茫的人生,需要不断努力,才能看清远方模糊的志向!
  • 相关阅读:
    Oracle 推出 ODAC for Entity Framework 和 LINQ to Entities Beta版
    Entity Framework Feature CTP 5系列文章
    MonoDroid相关资源
    MSDN杂志上的Windows Phone相关文章
    微软学Android Market推出 Web Windows Phone Marketplace
    使用 Visual Studio Agent 2010 进行负载压力测试的安装指南
    MonoMac 1.0正式发布
    Shawn Wildermuth的《Architecting WP7 》系列文章
    使用.NET Mobile API即51Degrees.mobi检测UserAgent
    MongoDB 客户端 MongoVue
  • 原文地址:https://www.cnblogs.com/autopwn/p/15133910.html
Copyright © 2020-2023  润新知