12558网页游戏私服论坛

 找回密码
 立即注册
游戏开服表 申请开服
游戏名称 游戏描述 开服状态 游戏福利 运营商 游戏链接
攻城掠地-仿官 全新玩法,觉醒武将,觉醒技能 每周新区 经典复古版本,长久稳定 进入游戏
巅峰新版攻 攻城掠地公益服 攻城掠地SF 新兵种、新武将(兵种) 进入游戏
攻城掠地公 散人玩家的天堂 新开 进入游戏
改版攻城掠 上线即可国战PK 稳定新区 全新改版,功能强大 进入游戏
少年江山 高福利高爆率 刚开一秒 江湖水落潜蛟龙 进入游戏
太古封魔录 开服送10亿钻石 福利多多 不用充钱也可升级 进入游戏
神魔之道 签到送元宝 稳定开新区 送豪华签到奖励 进入游戏
神奇三国 统帅三军,招揽名将 免费玩新区 激情国战,征战四方 进入游戏
龙符 三日豪礼领到爽 天天开新区 助你征战无双 进入游戏
王者之师 免费领豪华奖励 免费玩新区 6元送6888元宝 进入游戏
查看: 197|回复: 0

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

[复制链接]

303

主题

303

帖子

616

积分

实习版主

Rank: 7Rank: 7Rank: 7

积分
616
发表于 2021-7-18 17:55:18 | 显示全部楼层 |阅读模式
继续更新个人的学习笔记,
其它笔记传送门
逆向基础笔记一 进制篇
逆向基础笔记二 数据宽度和逻辑运算
逆向基础笔记三 通用寄存器和内存读写
逆向基础笔记四 堆栈篇
逆向基础笔记五 标志寄存器
逆向基础笔记六 汇编跳转和比力指令
逆向基础笔记七 堆栈图(重点)
逆向基础笔记八 反汇编分析C语言
逆向基础笔记九 C语言内联汇编和调用协定
逆向基础笔记十 汇编寻找C步伐入口
逆向基础笔记十一 汇编C语言基本类型
逆向基础笔记十二 汇编 全局和局部 变量
逆向基础笔记十三 汇编C语言类型转换
逆向基础笔记十四 汇编嵌套if else
逆向基础笔记十五 汇编比力三种循环
逆向基础笔记十六 汇编一维数组
逆向基础笔记十七 汇编二维数组 位移 乘法
逆向基础笔记十八 汇编 布局体和内存对齐
逆向基础笔记十九 汇编switch比力if else
逆向基础笔记二十 汇编 指针(一)
逆向基础笔记二十二 汇编 指针(三)
逆向基础笔记二十三 汇编 指针(四)
逆向基础笔记二十四 汇编 指针(五) 系列完结
指针二

先前介绍了指针的一些基本的知识,但都没有提到地点的概念,下面承接之前的笔记,继续学习指针
下面要介绍三个相干的内容:获取变量的数据类型取变量地点取地点中存储的数据
获取变量的数据类型

在C语言中可以使用下面的方法获取一个变量的数据类型:
代码

#include "stdafx.h"#include void function(){                        char**** a;        printf("%s\n",typeid(a).name());}int main(int argc, char* argv[]){        function();        return 0;}运行结果


使用方式

通过上面的例子可以知道使用方式首先要包罗一个相干的头文件typeinfo
然后使用该头文件的方法typeid(变量).name()即可获得变量对应的数据类型
取变量地点

在C语言中可以在变量前加上&符号来获取一个变量的地点
首先看看取回来地点的类型
取地点的返回类型

#include "stdafx.h"#include void function(){                        char a;        short b;        int c;        char* d;        printf("%s\n",typeid(&a).name());        printf("%s\n",typeid(&b).name());                printf("%s\n",typeid(&c).name());        printf("%s\n",typeid(&d).name());}int main(int argc, char* argv[]){        function();        return 0;}运行结果


分析结果

不难发现,所有取地点返回的类型都为原本变量的类型后加个*,也契合了本笔记的主题——指针
取地点的内容

通过前面的分析得出了取出的地点类型是一个指针类型,现在要观察其存储的内容
代码

#include "stdafx.h"#include //为了方便观察地点 先声明为全局变量int a;void function(){    a=610;        int* b=&a;    printf("%x\n",b);}int main(int argc, char* argv[]){        function();        return 0;}运行结果


反汇编代码

11:       a=610;00401038   mov         dword ptr [a (00427c48)],262h12:       int* b=&a;00401042   mov         dword ptr [ebp-4],offset a (00427c48)13:       printf("%x\n",b);通过a的赋值语句可以看到a存储在00427c48这个内存地点中
11:       a=610;00401038   mov         dword ptr [a (00427c48)],262h再看下面的指针赋值语句
12:       int* b=&a;00401042   mov         dword ptr [ebp-4],offset a (00427c48)这里的offset a是vc6.0为了方便使用者检察天生的,实际上的语句为:
mov dword ptr ss:[ebp-0x4],0x427C48也就是直接将全局变量a的地点00427c48赋给b
代码二

前面声明的变量为全局变量,现在来看看局部变量的情况:
#include "stdafx.h"#include void function(){    //这里a声明为局部变量        int a=610;        int* b=&a;        printf("%x\n",b);}int main(int argc, char* argv[]){        function();        return 0;}运行结果二


此时的地点显然就是一个堆栈中的地点,对应了变量存储在堆栈中
反汇编代码二

11:       int a=610;00401038   mov         dword ptr [ebp-4],262h12:       int* b=&a;0040103F   lea         eax,[ebp-4]00401042   mov         dword ptr [ebp-8],eax13:       printf("%x\n",b);可以看到此时是通过lea指令将变量a的地点ebp-4传给eax,然后再将eax赋值给b
取地点中存储数据

前面讲了怎样获取一个变量的地点,那么在获取完地点后,再说说怎样获取这地点中存储的数据
在C语言中,在一个指针类型的变量前面加上*符号,即可取出该地点里所存储的内容
取地点数据的返回类型

如法炮制,观察取地点数据的返回类型
代码

#include "stdafx.h"#include void function(){        int***a=(int***) 610;        printf("%s\n",typeid(*a).name());        printf("%s\n",typeid(**a).name());        printf("%s\n",typeid(***a).name());}int main(int argc, char* argv[]){        function();        return 0;}运行结果


分析结果

不难发现,所有取地点数据返回的类型都为原本变量的类型后减个*,可以说是和&取地点恰好相反
不同的是对于多级指针,可以一次使用多个*来多次取地点中存储的数据
取地点数据的内容

前面相识了*符号的使用,现在来看个稍微复杂点的例子
代码

#include "stdafx.h"#include int a;void function(){        a=610;        int* b=&a;        int** c=&b;        int*** d=&c;        c=*d;        b=*c;        a=*b;    b=**d;    a=**c;       a=***d;}int main(int argc, char* argv[]){        function();        return 0;}反汇编代码

11:       a=610;00401038   mov         dword ptr [a (00427c50)],262h12:       int* b=&a;00401042   mov         dword ptr [ebp-4],offset a (00427c50)13:       int** c=&b;00401049   lea         eax,[ebp-4]0040104C   mov         dword ptr [ebp-8],eax14:       int*** d=&c;0040104F   lea         ecx,[ebp-8]00401052   mov         dword ptr [ebp-0Ch],ecx15:       c=*d;00401055   mov         edx,dword ptr [ebp-0Ch]00401058   mov         eax,dword ptr [edx]0040105A   mov         dword ptr [ebp-8],eax16:       b=*c;0040105D   mov         ecx,dword ptr [ebp-8]00401060   mov         edx,dword ptr [ecx]00401062   mov         dword ptr [ebp-4],edx17:       a=*b;00401065   mov         eax,dword ptr [ebp-4]00401068   mov         ecx,dword ptr [eax]0040106A   mov         dword ptr [a (00427c50)],ecx18:19:       b=**d;00401070   mov         edx,dword ptr [ebp-0Ch]00401073   mov         eax,dword ptr [edx]00401075   mov         ecx,dword ptr [eax]00401077   mov         dword ptr [ebp-4],ecx20:       a=**c;0040107A   mov         edx,dword ptr [ebp-8]0040107D   mov         eax,dword ptr [edx]0040107F   mov         ecx,dword ptr [eax]00401081   mov         dword ptr [a (00427c50)],ecx21:22:       a=***d;00401087   mov         edx,dword ptr [ebp-0Ch]0040108A   mov         eax,dword ptr [edx]0040108C   mov         ecx,dword ptr [eax]0040108E   mov         edx,dword ptr [ecx]00401090   mov         dword ptr [a (00427c50)],edx分析反汇编

首先将各变量信息整理出来,方便后面分析:
变量变量地点变量内容/地点的值(十六进制)a00427c50262(对应十进制为610)bebp-4 = 0012FF2800427C50cebp-8 = 0012FF240012FF28debp-0Ch = 0012FF200012FF24代码中涉及的变量较多,这里只拿最复杂的 a=***d来作分析,其它留作样例
22:       a=***d;00401087   mov         edx,dword ptr [ebp-0Ch]0040108A   mov         eax,dword ptr [edx]0040108C   mov         ecx,dword ptr [eax]0040108E   mov         edx,dword ptr [ecx]00401090   mov         dword ptr [a (00427c50)],edx1.这里的ebp-0Ch对应的是d的地点,此时就是将d赋值给edx
00401087   mov         edx,dword ptr [ebp-0Ch]
结合内存里的数据可以得到:d的地点=ebp-0Ch=0012FF20,d=[ebp-0Ch]=0012FF24
这里的代码相当于
00401087   mov         edx,0012FF24h(d)2.将前面edx地点里存储的数据赋值给eax,此时的[edx]存储的实在就是c
0040108A   mov         eax,dword ptr [edx]
结合内存里的数据可以得到:d=edx=0012FF24,[edx]=0012FF28=c
这里的代码相当于
0040108A   mov         eax,0012FF28(c)3.将前面eax地点里存储的数据赋值给ecx,此时的[eax]存储的实在就是b
0040108C   mov         ecx,dword ptr [eax]
结合内存里的数据可以得到:c=eax=0012FF28,b=[eax]=00427C50
这里的代码相当于
0040108C   mov         ecx,00427C50(b)4.将前面ecx地点里存储的数据赋值给edx,此时的[ecx]存储的实在就是a
0040108E   mov         edx,dword ptr [ecx]
结合内存里的数据可以得到:b=ecx=00427C50,a=[ecx]=262h=610
这里的代码相当于
0040108E   mov         edx,262h5.最后将edx赋值给a
00401090   mov         dword ptr [a (00427c50)],edx小总结

可以看到,被赋值变量 = * 赋值变量   在汇编中的形式为:mov 被赋值变量,[赋值变量]
如果有多个*,则多执行频频来取值
总结


  • 可以在变量前加上&符号来获取变量地点
  • 取地点返回的类型都为原本变量的类型后加个*,也就是个指针类型
  • 在一个指针类型的变量前面加上*符号,即可取出该地点里所存储的内容
  • 取地点数据返回的类型都为原本变量的类型后减个*,可以说是和&取地点恰好相反
  • 对于多级指针,可以一次使用多个*来多次取地点中存储的数据

来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

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

x
楼主热帖
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-14 18:00 , Processed in 0.093750 second(s), 31 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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