C/C++逆向:数据类型识别

news2024/11/23 21:08:55

在逆向工程中,数据类型识别是理解程序逻辑的重要步骤,因为它直接影响对程序逻辑和功能的理解,识别出数据类型有助于确定变量的含义和函数的行为。在分析恶意软件或者寻找安全漏洞时,识别数据类型能够帮助发现代码中的潜在问题。例如,缓冲区溢出问题通常与错误的数据类型或者数组边界检查不当有关,了解变量的类型和大小有助于发现这类安全问题。那接下去我们就通过一个简单的例子来针对不同类型的数据进行特征分析。

逆向分析实例

下面是一个含有多种类型的数据变量的代码示例:

#include <stdio.h>
#include <stdlib.h>
​
int main() {
    short numA = 20;
    int numB = 10;
    long numC = 30;
    long long numD = 40;
    char letter = 'A';
    char text[] = "Hello, world!";
    float factor = 3.14;
    int * nPtr = &numB;
    long & nQuC = numC;
​
    printf("numA=%d\r\n", numA);
    printf("numB=%d\r\n", numB);
    printf("numC=%d\r\n", numC);
    printf("numD=%lld\r\n", numD);
    printf("Letter=%c\r\n", letter);
    printf("text=%s\r\n", text);
    printf("text=%f\r\n", factor);
    printf("text=%d\r\n", *nPtr);
    printf("text=%d\r\n", nQuC);
​
    system("pause");
    return 0;
}

此时使用Visual Studio对该代码进行编译,生成exe文件,对应的编译配置为Debug-x86

生成完成后放入x96dbg进行动态调试:

接着定位到main函数进行反汇编代码分析(定位main函数的方法请看笔者前面C/C++逆向:定位main函数文章);重点需要看的反汇编代码为红线以下部分,我们重点关注变量初始化部分,也就是方框中的代码。

①Short类型
mov eax,14
mov word ptr ss:[ebp-C],ax

mov eax, 14:将数值 20 加载到 eax 寄存器中。

mov word ptr ss:[ebp-C],ax:将 eax 的低 16 位(即 ax)的内容存储到内存地址 ss:[ebp-C],其中 [ebp-C] 通常表示函数栈帧中的一个局部变量。

word ptr是什么含义?

word ptr 是用于指示操作数的数据类型大小的指令修饰符
    word:表示 16 位的数据,即两个字节(2 bytes)。
    ptr(pointer):指针的缩写,意味着操作的对象是一个内存地址。

ss: 前缀

ss 表示 Stack Segment(堆栈段);在 x86 架构中,内存地址可以由段寄存器和偏移量共同构成,ss: 表明目标内存地址是相对于堆栈段的。

因为short类型占2个字节,即16位,所以在第一条指令将数值加载到 eax 寄存器以后,在将数值放入内存ss:[ebp-C]时的源操作数为eax寄存器的低16位ax。后续在逆向过程中遇到这种特征的代码就可以初步进行判断。

②int类型

相关代码:

mov dword ptr ss:[ebp-18],A

可以看到int类型的数据初始化就没有像short类型那样子弯绕,直接就将数值A(10)存入内存地址 ss:[ebp-18]。此时用于指示操作数的数据类型大小的指令修饰符为dword ptr也就是表示32位。

③long类型

相关代码:

mov dword ptr ss:[ebp-24],1E

long类型数据与int类型一样也是直接将将值1E(30)直接放入内存堆栈中,原因是因为在Windows环境中long的长度与int类型是一致的,长度都是4字节。所以此时用于指示操作数的数据类型大小的指令修饰符为dword ptr也就是表示32位。此外还有一个需要注意的点即长整型long在不用的操作系统中所占用的字节数不同,具体的占用字节如下图:

所以在写跨平台的应用时,如果使用到long型,需要考虑到精度丢失的问题,在写跨平台应用时也尽量避免使用long型。

④long long 类型

相关代码:

mov dword ptr ss:[ebp-34],28
mov dword ptr ss:[ebp-30],0

在 x86 体系结构中,long long 类型是一个 64 位(8 字节)的数据类型,而在 32 位程序中,通常使用两个 32 位(4 字节) 的存储单元来存储 long long 变量的高 32 位和低 32 位。因此,初始化 long long 类型数据会涉及到两个内存位置的赋值操作。

mov dword ptr ss:[ebp-34], 28:这条指令意味着 long long 变量的低 32 位被初始化为 28(40)

mov dword ptr ss:[ebp-30], 0[ebp-30] 是紧接着 [ebp-34] 的下一个 4 字节内存位置,用来存储 long long 变量的高 32 位;这里将高 32 位初始化为 0,此时我们可以查看内存窗口中的值:

可以发现确实是低 32 位被初始化为 28(40),高 32 位初始化为 0

如果此时代码的编译配置设置位x64,那么long long数据的初始化的反汇编代码就会是这样的:

mov         qword ptr [numD],28h  

⑤char类型

相关代码:

mov byte ptr ss:[ebp-3D],41

byte ptr 表示操作的数据大小是 8 位(1 字节),char 类型的数据在内存中占用 1 字节,因此汇编代码使用了 byte ptr 来进行操作。值 41(十六进制)对应于 ASCII 字符 'A',此时我们也可以通过查看内存来进行确定,在反汇编窗口中的对应反汇编代码中右击,选择在内存中转到:

接着选择地址(A)选项,然后此时内存窗口中就会将对该地址的值进行定位。

⑥字符串类型

相关代码:

mov eax,dword ptr ds:[FD7B30]
mov dword ptr ss:[ebp-58],eax
mov ecx,dword ptr ds:[FD7B34]
mov dword ptr ss:[ebp-54],ecx
mov edx,dword ptr ds:[FD7B38]
mov dword ptr ss:[ebp-50],edx
mov ax,word ptr ds:[FD7B3C]
mov word ptr ss:[ebp-4C],ax

这段汇编代码对应的是对一个字符串的逐步初始化过程。在 32 位系统中,由于寄存器和内存操作的限制,字符串数据是分块拷贝的。前面几条指令每次拷贝 4 字节,最后拷贝 2 字节。

char text[] = "Hello, world!";

这个字符串的初始化过程:

先将dword ptr ds:[FD7B30]值也就是6C6C6548(Hell)放入eax寄存器中;

然后将eax中的值转入dword ptr ss:[ebp-58]内存堆栈中,这就是第一个分块拷贝的过程,后续则是分别将内存中存储的字符串的值分别进行分块拷贝,因为过程都一样这边就不再一一列举了。这边主要说一下最后一个步骤:对于字符串Hello, world!来说应该需要做3次4字节+1次1字节的内存分块拷贝才对,为什么最后一个步骤使操作的指示符为word ptr两个字节呢?

mov ax,word ptr ds:[FD7B3C]
mov word ptr ss:[ebp-4C],ax

原因就是因为每个字符串都需要一个结束符号,所以最后两个字节应该是21(!) 00(结束符)

⑦float类型

相关代码

movss xmm0,dword ptr ds:[FD7BB0]
movss dword ptr ss:[ebp-64],xmm0

movss xmm0, dword ptr ds:[FD7BB0]:从数据段(ds)地址 [FD7BB0] 处读取一个 32 位(4 字节) 的单精度浮点数(float),并将其存储到 xmm0 寄存器中。

movss 指令用于移动单精度浮点数(即 32 位的 float),它与整数的 mov 不同,专门用于处理浮点数据;xmm0 是一个用于浮点运算的寄存器。

此时寄存器中的如下:

movss dword ptr ss:[ebp-64], xmm0:将 xmm0 寄存器中的单精度浮点数存储到栈帧中相对于基址指针 ebp 的偏移量 -64 处。

寄存器中XMM0中的十六进制值就是浮点型数据在内存中的存储形式,下面我们就来说一下十六进制的值与浮点数之间的转化是如何进行的,将十六进制数转换为浮点数涉及将其按照 IEEE 754 标准进行解码。IEEE 754 是计算机中用来表示浮点数的标准格式,其中单精度浮点数(float)占用 32 位(4 字节)。其转换的具体步骤如下:

IEEE 754 单精度(float)浮点数表示法

单精度浮点数的 32 位结构如下:

符号位(S):1 位,表示正负号(0 为正,1 为负)。
指数位(E):8 位,用于表示指数。
尾数位(M):23 位,用于表示有效数字(尾数)。

首先将十六进制数转化为二进制:0x4048F5C3 转换为二进制是:0100 0000 0100 1000 1111 0101 1100 0011对应到 IEEE 754 的结构中:

符号位(S):第 1 位是 0,表示正数。
指数位(E):接下来的 8 位是 10000000,对应十进制为 128。
尾数位(M):剩下的 23 位是 0100 1000 1111 0101 1100 0011。

接着需要解码浮点数:

符号位:S = 0,表示正数。
指数位:E = 128,所以实际的指数为:E - 127 = 1。
尾数位:M = 1.01001000111101011100011(添加隐含的 1)。相当于1+0.25+0.00390625+0.0009765625+⋯≈1.57

接着将数值代入公式中进行计算,具体表示公式为:

Value = 1^0 * 2^1 * 1.57 = 3.14

通过使用 IEEE 754 格式将 0x4048F5C3 转换为浮点数,得到的值是大约 3.14

IEEE 754 双精度(double)浮点数表示法
在 IEEE 754 双精度浮点数(double 类型)中,浮点数的表示和单精度有所不同。双精度使用 64 位来表示,其中包括符号位、指数位和尾数位,具体结构如下:

双精度浮点数的 64 位结构

符号位(S):1 位,用于表示正负号(0 表示正数,1 表示负数)。
指数位(E):11 位,用于表示指数,使用偏移量 1023,需要减去偏移量 1023 以得到实际的指数值。
尾数位(M):52 位,用于表示有效数字(尾数)。

双精度浮点数表示公式为:

计算方式都是一样的,这边就不做过多赘述。

⑧指针

相关代码

lea eax,dword ptr ss:[ebp-18]
mov dword ptr ss:[ebp-70],eax

leaLoad Effective Address指令,用于将操作数的有效地址加载到指定的寄存器中。

所以lea eax, dword ptr ss:[ebp-18] 的作用是将该偏移量的地址加载到 eax 寄存器中,而不是读取该地址的内容。这种用法通常用来获取某个变量的地址,因此 eax 寄存器中存储的是变量的地址,即指针值。

mov dword ptr ss:[ebp-70], eax:这条指令将 eax 寄存器的值(即之前计算出的地址)存储到栈中相对于基址指针 ebp 的偏移量 -70 处。

⑨引用类型

相关代码

lea eax,dword ptr ss:[ebp-24]
mov dword ptr ss:[ebp-7C],eax

在这边我们可以看到引用类型的初始化反汇编代码与指针类型的反汇编代码一致。lea eax, [ebp-24] 的作用是将该局部变量的地址加载到寄存器 eax 中。mov dword ptr ss:[ebp-7C], eax这条指令将寄存器 eax 中的值(也就是局部变量的地址)存储到栈中相对于基址指针 ebp 的偏移量 -7C 处。

指针和引用在 C++ 中虽然有不同的特性,但在底层的实现中,它们的初始化通常会生成类似的汇编代码。之所以出现这种情况,是因为引用和指针的本质上都是地址的操作,而汇编层面只关心数据的地址和访问方式。引用和指针的差异是由编译器层面决定和实现的,而不是在底层硬件或者汇编指令层面体现的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2182007.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CTFshow 命令执行 web29~web36(正则匹配绕过)

目录 web29 方法一&#xff1a;include伪协议包含文件读取 方法二&#xff1a;写入文件 方法三&#xff1a;通识符 web30 方法一&#xff1a;filter伪协议文件包含读取 方法二&#xff1a;命令执行函数绕过 方法三&#xff1a;写入文件 web31 方法一&#xff1a;filter伪…

等保测评:企业数字安全的坚实盾牌

1.1 企业数字化转型的浪潮 在当今时代&#xff0c;企业数字化转型的浪潮正以前所未有的速度席卷全球&#xff0c;据IDC预测&#xff0c;到2023年&#xff0c;全球数字化转型支出将达到惊人的2.3万亿美元。这一趋势不仅重塑了企业的运营模式&#xff0c;更对企业的信息安全提出…

redis面试-2024

1、Redis的基本数据结构类型 string、list、set、hash、zet。还有三种特殊类型&#xff1a;Geospatial、Hyperloglog、bitMap。 2、各数据类型对应的场景 3、redis快的原因 *基于内存 内存读写效率远高于磁盘读写&#xff0c;省去磁盘IO操作 *存储形式 Redis作为K-V键值对…

从一到无穷大 #36 Lindorm 宽表:东西互联,南北互联,AI一体

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作)&#xff0c;由 李兆龙 确认&#xff0c;转载请注明版权。 文章目录 引言索引列存索引全文索引向量索引二级索引 AI赋能时序宽表 LTS&#xff08;Lindorm …

面向MQTT基础物联网网络的Age-of-Information感知的保留消息策略

论文标题&#xff1a; 英文&#xff1a;AoI-aware Retained Message Policy in MQTT-based IoT Networks中文&#xff1a;面向MQTT基础物联网网络的Age-of-Information感知的保留消息策略 作者信息&#xff1a; Youngjun Kim 和 Yeunwoong Kyung工作单位&#xff1a;Youngju…

Unity3D播放GIF图片使用Animation来制作动画

系列文章目录 unity工具 文章目录 系列文章目录👉前言👉一、下载GIF动图,用PS制作导出帧动画图片👉二、使用Animation制作动画👉三、脚本控制动画播放👉壁纸分享👉总结👉前言 unity播放gif图片,本身是不支持的,但是可以使用其他方法来实现, 1.有一种使用System…

短链接生成-短链接-短网址-短链接生成接口-短链接转换接口-短网址URL生成-短链接地址-短网址-短域名-短链接【快证api】

短网址接口是指用于将长网址缩短为短网址的应用程序编程接口&#xff08;API&#xff09;。以下是关于短网址接口的详细介绍&#xff1a; 一、短网址接口的功能 短网址接口的主要功能是将冗长的网址缩短为简洁的短网址&#xff0c;便于在社交媒体、邮件、短信等渠道中分享和传…

Redis: 主从复制原理

主从复制原理剖析 1 &#xff09;配置 通过下面的从节点的配置项可以开启主从之间的复制功能slaveof 192.16.10.101 6379这里的复制包含全量复制和增量复制 2 &#xff09;主节点的主从配置信息解析 查看主从之间的信息&#xff0c;在主节点上 $ info replication 打印出来的…

系统实施方案(word2024原件参考模板)

软件实施方案 二、 项目介绍 三、 项目实施 四、 项目实施计划 五、 人员培训 六、 项目验收 七、 售后服务 八、 项目保障措施 软件开发全套资料获取&#xff1a;&#xff08;本文末个人名片也可直接获取&#xff09; 软件产品&#xff0c;特别是行业解决方案软件产品不同于一…

【RockyLinux 9.4】安装新版 QQ for Linux(不再是 QQ2008 那种老款了!)

总览 还记得两年之前的时候&#xff0c;当初用的还是那种 QQ2008 一样的 LinuxQQ 啥也干不了&#xff0c;还不如 QQ2008 最近寻思自己装个服务器玩&#xff0c;想下载一个 QQ 用来文件传输&#xff0c;没想到现在的 QQ Linux 这么棒&#xff01; 一、下载 1.下载网址 https…

C语言练手项目之通讯录

1.前言 使用我上期发布的泛型list去制作一个通讯录,实在是太So Easy了!!!(上期代码有改动,可通过我主页介绍的个人git仓库查看!!!) 2.代码截图 1.contact.h 2.main.c 3.contact.c 4.运行结果 3.结语 如果我的文章帮助到你,看到这里不妨点个小赞,加个收藏呗,你的点赞和收藏是我…

2024年9月总结及随笔之丢卡

1. 回头看 日更坚持了639天。 读《软件开发安全之道&#xff1a;概率、设计与实施》更新完成读《软件设计的要素》开更并更新完成读《构建可扩展分布式系统&#xff1a;方法与实践》开更并更新完成读《数据湖仓》开更并持续更新 2023年至2024年9月底累计码字1555996字&#…

Linux-基础篇-磁盘分区,挂载

Linux 分区 原理介绍 Linux 来说无论有几个分区&#xff0c;分给哪一目录使用&#xff0c;它归根结底就只有一个根目录&#xff0c;一个独立且唯一的文件结构 , Linux 中每个分区都是用来组成整个文件系统的一部分。 Linux 采用了一种叫 “ 载入 ” 的处理方法&#xff0c;…

【Linux-基础IO】如何理解Linux下一切皆文件磁盘的介绍

目录 如何理解Linux系统上一切皆文件 1.物理角度认识磁盘 2.对磁盘的存储进行逻辑抽象 磁盘寻址 3.磁盘中的寄存器 如何理解Linux系统上一切皆文件 计算机中包含大量外设&#xff0c;操作系统想要管理好这些外设&#xff0c;就必须对这些外设进行先描述再组织&#xff0c…

Emergency Stop (ES)

文章目录 1. 介绍2. Feature List3. 紧急停止信号触发方式3.1 Port触发紧急停止信号3.2 SMU事件触发紧急停止信号3.3 软件触发紧急停止信号 4. 应用场景4.1 Port4.2 MSC 1. 介绍 Emergency Stop (ES)是Ifx System Control Units (SCU)六大模块之一。详细信息可以参考Infineon-…

【牛客刷题记录】【JAVA】二分查找

(1) 二分查找 链接 二分查找需要序列是有序的&#xff0c;否则二分查找会失效。原理就是如果找的值比mid小&#xff0c;那么[mid,R]的内容就不需要再查找了&#xff0c;反之如果大于mid位置的值&#xff0c;则在[L,mid]内的值也不需要再查找。同时将L/R的值进行修改。注意循环…

计算机毕业设计 基于深度学习的短视频内容理解与推荐系统的设计与实现 Python+Django+Vue 前后端分离 附源码 讲解 文档

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

景联文科技入选《2024中国AI大模型产业图谱2.0版》数据集代表厂商

近日&#xff0c;大数据产业领域头部媒体数据猿携手上海大数据联盟联合发布了备受瞩目的《2024中国AI大模型产业图谱2.0版》。以大数据与AI为代表的智能技术为主要视角&#xff0c;聚焦全产业链&#xff0c;为业内提供更为专业直观的行业指导。 景联文科技凭借高质量数据集&…

第十一届蓝桥杯嵌入式省赛程序设计题解析(基于HAL库)(大学组)

一.题目分析 &#xff08;1&#xff09;.题目 &#xff08;2&#xff09;.题目分析 1.计时分析 只要遇到Vmin&#xff0c;就将计时时间重置为0&#xff0c;直到遇到Vmax结束计时 2.按键功能分析 a.B1显示和功能页面相互切换 b.B2每次按下Vmax加0.1&#xff0c;加到3.3V&a…

怀孕之天赋共享:其实人身体没变,完全是天赋共享

关于怀孕天赋共享&#xff0c;有人说&#xff0c;是不是怀孕导致身体变化&#xff1f; 并没有。下面这个就是案例。你总不能说&#xff0c;小孩生下来身体立即改变吧&#xff1f;