12558网页游戏私服论坛

 找回密码
 立即注册
游戏开服表 申请开服
游戏名称 游戏描述 开服状态 游戏福利 运营商 游戏链接
攻城掠地-仿官 全新玩法,觉醒武将,觉醒技能 每周新区 经典复古版本,长久稳定 进入游戏
巅峰新版攻 攻城掠地公益服 攻城掠地SF 新兵种、新武将(兵种) 进入游戏
攻城掠地公 散人玩家的天堂 新开 进入游戏
改版攻城掠 上线即可国战PK 稳定新区 全新改版,功能强大 进入游戏
少年江山 高福利高爆率 刚开一秒 江湖水落潜蛟龙 进入游戏
太古封魔录 开服送10亿钻石 福利多多 不用充钱也可升级 进入游戏
神魔之道 签到送元宝 稳定开新区 送豪华签到奖励 进入游戏
神奇三国 统帅三军,招揽名将 免费玩新区 激情国战,征战四方 进入游戏
龙符 三日豪礼领到爽 天天开新区 助你征战无双 进入游戏
王者之师 免费领豪华奖励 免费玩新区 6元送6888元宝 进入游戏
三国霸业 战车-珍宝-觉醒-攻城掠地SF-全新玩法 免费玩新区 攻城掠地私服 进入游戏
手游私服盒子 各类免费游戏 0.1折送海量资源 各类手游私服 进入游戏
皇家MU2 《奇迹 2:传奇》韩国网禅公司《奇迹》正统续作。 3D锁视角Mmrpg 暗黑3+传奇+流放之路+奇迹 进入游戏
查看: 340|回复: 0

逆向基础笔记二十 汇编 指针(一)

[复制链接]

345

主题

345

帖子

700

积分

实习版主

Rank: 7Rank: 7Rank: 7

积分
700
发表于 2021-5-7 23:06:40 | 显示全部楼层 |阅读模式
继续更新个人的学习笔记,
其它笔记传送门
逆向底子笔记一 进制篇
逆向底子笔记二 数据宽度和逻辑运算
逆向底子笔记三 通用寄存器和内存读写
逆向底子笔记四 堆栈篇
逆向底子笔记五 标志寄存器
逆向底子笔记六 汇编跳转和比较指令
逆向底子笔记七 堆栈图(重点)
逆向底子笔记八 反汇编分析C语言
逆向底子笔记九 C语言内联汇编和调用协定
逆向底子笔记十 汇编探求C步伐入口
逆向底子笔记十一 汇编C语言基本范例
逆向底子笔记十二 汇编 全局和局部 变量
逆向底子笔记十三 汇编C语言范例转换
逆向底子笔记十四 汇编嵌套if else
逆向底子笔记十五 汇编比较三种循环
逆向底子笔记十六 汇编一维数组
逆向底子笔记十七 汇编二维数组 位移 乘法
逆向底子笔记十八 汇编 布局体和内存对齐
逆向底子笔记十九 汇编switch比较if else
逆向底子笔记二十一 汇编 指针(二)
逆向底子笔记二十二 汇编 指针(三)
逆向底子笔记二十三 汇编 指针(四)
逆向底子笔记二十四 汇编 指针(五) 系列完结
终于来到C语言中极其重要的部分——指针,由于指针的内容相对较多,于是将其拆分为好几个笔记,并且在指针结束之后该系列也差不多要完结了,下一系列暂定为PE的学习
指针

什么是指针

一般关于指针的解释都离不开地址。这里先暂且忘记这个概念
指针其实也是一种数据范例,和先前学习的int float等数据范例没有实质上的区别,只不过这个数据范例是在先前学习的全部数据范例后面加上多少个*号,如char *,int *等等,这种数据范例被称为指针

  • 任意范例后面都可以加上*号,使其成为新的指针数据范例
  • *可以是任意多个
指针的声明

指针的声明其着实前面先容什么是指针的时候就已经讲到了,例子如下:
struct S1{        int a;};void function(){                        char* a;        short** b;        int*** c;        long**** d;        _int64***** e;        float****** f;        double******* g;        S1******** s1;}可以看到全部的其它数据范例(包罗布局体)后面加上多少个*后就是所谓的指针了
推荐的声明方式如上
但也可以这样将*放在变量前面,但不推荐,由于这样相当于将这个数据范例拆开了,倒霉于理解
struct S1{        int a;};void function(){                        char *a;        short **b;        int ***c;        long ****d;        _int64 *****e;        float ******f;        double *******g;        S1 ********s1;}指针的赋值

在说指针的赋值之前先看看先前平凡变量的赋值
平凡变量的赋值貌似是直接使用 变量=值即可,但其实是编译器简化了赋值的步骤,实际上在赋值前本应该加上要赋值范例
例子如下:
void function(){                        int a;    a=610;    a=(int)610;}现在再来看指针的赋值
void function(){                        char* a;        a=(char*) 610;    int** b;    b=(int**) 610;}在要赋的值前面加上指针的范例即可,貌似宁静凡变量的赋值并无太大差别,此时也留意到这里的指针也和地址没有什么关联
指针的的范例转换这里暂且不提
指针的数据宽度

研究数据宽度方法

先前研究过其它基本变量的数据宽度,会发现char、short、int都是按照4字节来分配的(内存对齐),但实际使用的情况下则是按照其原本范例的数据宽度来赋值或举行其它操纵的
如:
void function(){                        char a;        short b;        int c;        a=1;        b=2;        c=3;}其对应的反汇编代码为:
11:   void function(){00401010   push        ebp00401011   mov         ebp,esp00401013   sub         esp,4Ch00401016   push        ebx00401017   push        esi00401018   push        edi00401019   lea         edi,[ebp-4Ch]0040101C   mov         ecx,13h00401021   mov         eax,0CCCCCCCCh00401026   rep stos    dword ptr [edi]12:       char a;13:       short b;14:       int c;15:       a=1;00401028   mov         byte ptr [ebp-4],116:       b=2;0040102C   mov         word ptr [ebp-8],offset function+20h (00401030)17:       c=3;00401032   mov         dword ptr [ebp-0Ch],318:   }00401039   pop         edi0040103A   pop         esi0040103B   pop         ebx0040103C   mov         esp,ebp0040103E   pop         ebp0040103F   ret可以留意到此时提拔的堆栈为4Ch,而默认(空函数时)提拔的堆栈为40h
00401013   sub         esp,4Ch于是此时为三个变量分配的空间是:4Ch-40h=0xC=12=3×4,即为char short int都分配了4个字节
但在这三个变量赋值的时候显现出来的就是其原本的数据范例宽度了
15:       a=1;00401028   mov         byte ptr [ebp-4],1在char范例的a中的赋值宽度是 byte,1字节
16:       b=2;0040102C   mov         word ptr [ebp-8],offset function+20h (00401030)在short范例的b中的赋值宽度是word,2字节
17:       c=3;00401032   mov         dword ptr [ebp-0Ch],3在int范例的c中的赋值宽度是dword,4字节
研究指针数据宽度

于是如法炮制,按照前面的方法来研究指针的数据宽度
在前面的数据范例后添加*,使其成为指针范例
void function(){                        char* a;        short* b;        int* c;        a=(char*)  1;        b= (short*) 2;        c=(int*)  3;}其对应的反汇编代码为
11:   void function(){00401010   push        ebp00401011   mov         ebp,esp00401013   sub         esp,4Ch00401016   push        ebx00401017   push        esi00401018   push        edi00401019   lea         edi,[ebp-4Ch]0040101C   mov         ecx,13h00401021   mov         eax,0CCCCCCCCh00401026   rep stos    dword ptr [edi]12:       char* a;13:       short* b;14:       int* c;15:       a=(char*)  1;00401028   mov         dword ptr [ebp-4],116:       b= (short*) 2;0040102F   mov         dword ptr [ebp-8],217:       c=(int*)  3;00401036   mov         dword ptr [ebp-0Ch],318:   }0040103D   pop         edi0040103E   pop         esi0040103F   pop         ebx00401040   mov         esp,ebp00401042   pop         ebp00401043   ret直接观察对应的赋值语句:
15:       a=(char*)  1;00401028   mov         dword ptr [ebp-4],116:       b= (short*) 2;0040102F   mov         dword ptr [ebp-8],217:       c=(int*)  3;00401036   mov         dword ptr [ebp-0Ch],3可以看到,全部赋值的宽度都为dowrd,阐明无论是char*、short、int\其数据宽度都为4字节
可以使用同样的方法研究float、double、struct等其它数据范例
并且在这里会留意到,指针范例的赋值和非指针范例的赋值在反汇编中并没有什么区别
总结

无论是什么范例,在其后面加上(无论加几个\都一样)后其数据宽度都变为4字节
指针的加减

例子

指针范例也支持加减的操纵,但不支持乘和除编译器决定的),来看例子:
#include "stdafx.h"void function(){                        char* a;        short* b;        int* c;        a=(char*)  1;        b= (short*) 2;        c=(int*)  3;        a++;        b++;        c++;        printf("a:%d\t b:%d\tc:%d\n",a,b,c);}int main(int argc, char* argv[]){        function();        return 0;}运行结果


分析

这里会观察到结果并不是想象中的2,3,4;而是2,4,7
细心的小伙伴肯定发现了:

  • 2 = 1 + 1  (char数据宽度为1字节)
  • 4 = 2 + 2  (short数据宽度为2字节)
  • 7 = 3 + 4  (int数据宽度为4字节)
结果是加上了原本各自的数据范例的宽度
拓展例子

前面只是都是一级指针,现在将指针换为二级指针:
void function(){                        char** a;        short** b;        int** c;        a=(char**)  1;        b= (short**) 2;        c=(int**)  3;        a++;        b++;        c++;        printf("a:%d\t b:%d\tc:%d\n",a,b,c);}运行结果


分析

此时的结果为:

  • 5= 1 + 4  (char* 数据宽度为4字节)
  • 6= 2 + 4  (short* 数据宽度为4字节)
  • 7 = 3 + 4  (int* 数据宽度为4字节)
结果为加上 去掉一个*后的数据宽度
拓展例子二

前面的加法操纵都只增长了1,现在再来查看增长大于1时的情况
void function(){                        char* a;        short* b;        int* c;        a=(char*)  1;        b= (short*) 2;        c=(int*)  3;        a=a+5;        b=b+5;        c=c+5;        printf("a:%d\t b:%d\tc:%d\n",a,b,c);}运行结果


分析

此时的结果为:

  • 6= 1 + 5*1 (char 数据宽度为1字节)
  • 12= 2 + 5*2  (short 数据宽度为2字节)
  • 23 = 3 + 5*4  (int 数据宽度为4字节)
结果为加上 去掉一个*后的数据宽度 × 增长的数值
总结

无论是指针的加亦或是减(这里只演示了加法,但减法同理),其加或减的单位为去掉一个*后的数据宽度
也就是实际增减的数值=去掉一个*后的数据宽度 × 增减的数值
指针范例相减

前面提到的指针的加减都是同一个指针里的加减,但指针之间其实也支持相减操纵(不支持相加
但指针之间的加减要求指针的范例必须一致,即char*范例只能和char*范例相加减,不能和char**或其它范例相加减
例子

void function(){                        char* a;        char* b;        short* c;        short* d;        int* e;        int* f;        a=(char*) 200;        b=(char*) 100;        c=(short*) 200;        d=(short*) 100;        e=(int*) 200;        f=(int*) 100;        printf("%d\n",a-b);        printf("%d\n",c-d);        printf("%d\n",e-f);}运行结果


分析

此时的结果为:

  • 100 =  (200 - 100)/1(char 数据宽度为1字节)
  • 50 =  (200 - 100)/2  (short 数据宽度为2字节)
  • 25 =   (200 - 100)/4 (int 数据宽度为4字节)
结果为相减完后再除以  原本各自的数据宽度
扩展例子

前面只是都是一级指针,现在将指针换为四级指针:
void function(){                        char**** a;        char**** b;        short**** c;        short**** d;        int**** e;        int**** f;        a=(char****) 200;        b=(char****) 100;        c=(short****) 200;        d=(short****) 100;        e=(int****) 200;        f=(int****) 100;        printf("%d\n",a-b);        printf("%d\n",c-d);        printf("%d\n",e-f);}运行结果


分析

此时的结果为:

  • 25 =  (200 - 100)/4(char*** 数据宽度为4字节)
  • 25 =  (200 - 100)/4  (short*** 数据宽度为4字节)
  • 25 =   (200 - 100)/4 (int*** 数据宽度为4字节)
结果为相减后再除以  去掉一个*后的数据宽度
总结

指针之间的减法,其结果为相减后再除以去掉一个*后的数据宽度
指针之间的比较

指针之间也支持相互比较,但也和上面指针范例相减一样,要求指针范例一致
例子

void function(){                        char**** a;        char**** b;        a=(char****) 200;        b=(char****) 100;        if (a>b)        {                printf("a>b\n");        }else{                printf("a

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
楼主热帖
回复

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|12558网页游戏私服论坛 |网站地图

GMT+8, 2024-11-24 19:26 , Processed in 0.078125 second(s), 32 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表