C/C++逆向:字符数组与字符串对比

ops/2024/10/25 11:40:12/

在逆向工程中,字符数组和字符串的处理是一个重要的方面。字符数组通常是由相同类型的数据元素组成的集合,存储在连续的内存空间中,而字符串则是字符数组的一种特殊形式,用于表示文本信息。字符数组和字符串的区别主要体现在它们的定义、使用方式以及内存管理上。从逆向工程的角度来看,字符数组和字符串的差异可以通过分析汇编代码、内存布局、以及程序运行时的行为来进一步理解。这种差异会在二进制级别影响程序的结构、数据操作方式和函数调用。下面我们先给出一个C代码例子:

#include<stdio.h>
#include<stdlib.h>
​
int main() {char arr[6] = { 'W', 'o', 'l', 'v', 'e', 'n' };char str[] = "wolven";system("pause");return 0;
}

接着我们对这个代码进行编译生成exe文件,接着使用IDA工具进行逆向分析。

字符数组

字符数组是一组连续的字符元素,存储在内存中的相邻位置。例如:

char arr[6] = {'W', 'o', 'l', 'v', 'e', 'n'};

arr 是一个字符数组,它包含 6 个字符,它不会自动添加空字符作为结束标志。字符数组在内存中按顺序存储字符元素。由于它不一定需要以空字符 \0 结尾,因此逆向工程时不能直接依赖 \0 来确定数组的结束位置。我们需要依靠上下文或程序中使用的索引来判断数组的长度。汇编代码中,字符数组的初始化通常是通过一个 mov 指令序列来逐个将字符放入内存地址。对上述程序进行逆向分析可以得到如下代码:

mov     [ebp+var_C], 57h ; 'W'
mov     [ebp+var_B], 6Fh ; 'o'
mov     [ebp+var_A], 6Ch ; 'l'
mov     [ebp+var_9], 76h ; 'v'
mov     [ebp+var_8], 65h ; 'e'
mov     [ebp+var_7], 6Eh ; 'n'

可以看到字符数组的初始化这里直接向内存地址写入字符,没有自动附加的终止符。

字符串

在 C 语言中,字符串是以空字符 \0 结尾的字符数组。字符串可以通过字符串常量来定义:

char str[] = "wolven";

在这个例子中,str 是一个字符串,它等价于一个包含 {'w', 'o', 'l', 'v', 'e', 'n','\0'} 的字符数组。字符串的结尾会自动由 \0 标记,这也是区别字符串和普通字符数组的关键。逆向时,当你遇到一个以 \0 结尾的字符序列时,可以确定这是一个字符串常量,这个是字符串的显著特征,在逆向过程中很容易识别。字符串的初始化常常通过块拷贝的方式进行,即一次性将整个字符串(包括 \0)写入内存。如上述的C代码对应的汇编代码可能会通过类似 mov 指令加载整个字符串:

mov     eax, dword ptr ds:aWolven ; "wolven"
mov     [ebp+var_1C], eax
mov     cx, word ptr ds:aWolven+4 ; "en"
mov     [ebp+var_18], cx
mov     dl, byte ptr ds:aWolven+6 ; ""
mov     [ebp+var_16], dl

这段汇编代码显示了字符串的初始化过程:从内存中的字符串 "wolven" 中提取内容,并将其存储在栈上的过程。mov eax, dword ptr ds:aWolven ; "wolven":从 ds 段(数据段)加载一个指针或常量值,该值是以 "wolven" 为起始的4字节(32位)数据,存入寄存器 eax;也就是将 "wolv" (4字节) 放入 eax 寄存器中。然后将eax中的内容再存入栈中。这就是一个拷贝的过程,接着就是将剩下的"en"\0(空)分别存入栈空间。这就是字符串初始化的分步拷贝的过程。


http://www.ppmy.cn/ops/128322.html

相关文章

VScode分文件编写C++报错 | 如何进行VScode分文件编写C++ | 不懂也能轻松解决版

分文件编写遇到的问题 分文件编写例子如下所示&#xff1a; 但是直接使用 Run Code 或者 调试C/C文件 会报错如下&#xff1a; 正在执行任务: C/C: g.exe 生成活动文件 正在启动生成… cmd /c chcp 65001>nul && D:\Librarys\mingw64\bin\g.exe -fdiagnostics-col…

云原生后端(Cloud-Native Backend)

云原生后端&#xff08;Cloud-Native Backend&#xff09;是指在云计算环境中&#xff0c;利用云原生技术&#xff08;如容器、微服务、服务网格等&#xff09;构建和部署后端应用程序的一种方法。这种方法的兴起得益于云计算和微服务架构的快速发展&#xff0c;以及企业对高效…

WebStorm EsLint报红色波浪线

如图左侧。 这个错误是由于 ESLint 和 Prettier 的配置不一致导致的。它建议你移除多余的空格。以下是一些解决方法&#xff1a; 安装 Prettier 插件&#xff1a; 确保你在 WebStorm 中安装了 Prettier 插件&#xff0c;并确保它配置正确。 调整 ESLint 配置&#xff1a; 检查…

通义千问API—让大模型使用工具

通义千问API—让大模型使用工具 引言 通义千问是阿里巴巴推出的一个强大的预训练语言模型&#xff0c;能够生成高质量的文本内容。为了让通义千问更加灵活和实用&#xff0c;我们推出了通义千问API&#xff0c;使开发者能够将大模型与各种工具和服务集成在一起。本文将详细介…

雷池WAF自动化实现安全运营实操案例终极篇

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…

依托微信小程序,畅享校园二手交易

作者介绍&#xff1a;✌️大厂全栈码农|毕设实战开发&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。 &#x1f345;获取源码联系方式请查看文末&#x1f345; 推荐订阅精彩专栏 &#x1f447;&#x1f3fb; 避免错过下次更新 Springboot项目精选实战案例 更多项目…

【linux开发-驱动】SPI驱动开发相关

一、什么是SPI SPI 全称是 SerialPerripheral Interface&#xff0c;也就是串行外围设备接口&#xff0c;SPI 以主从方式工作&#xff0c;通常是有一个主设备和一个或多个从设备&#xff0c;一般 SPI 需要4 根线&#xff0c;但是也可以使用三根线(单向传输)。 ①CS/SS&#x…

Acrel-1000变电站综合自动化系统及微机在化工企业中的应用方案

文&#xff1a;安科瑞郑桐 摘要&#xff1a;大型化工企业供配电具有的集约型特点&#xff0c;化工企业内35kV变电站和10kV变电所数量大、分布广&#xff0c;对于老的大多大型及中型化工企业而言&#xff0c;其变电站或变电所内高压电气设备为旧式继电保护装置&#xff0c;可靠…