分析数组,结构体在反汇编中存储

2023-09-18 19:44:38

本文会在IDA中分析数组,结构体在内存中的存储

目录

IDA分析数组存储

IDA分析结构体存储

传递参数的方式


IDA分析数组存储

测试代码如下:

/************************************************************************/
/*@Author            : 玄都大法师
/*@Data              : 2023/09/11
/*@Description       : 汇编学习

/************************************************************************/

#include <stdio.h>

int main()
{
	int arr[5] = { 1, 2, 3, 4, 5 };
	int n = 2;
	arr[2] = 20;

	return 0;
}

去除main函数的栈帧汇编,留下有关数组的部分

.text:004143F5                 mov     [ebp+var_18], 1
.text:004143FC                 mov     [ebp+var_14], 2
.text:00414403                 mov     [ebp+var_10], 3
.text:0041440A                 mov     [ebp+var_C], 4
.text:00414411                 mov     [ebp+var_8], 5
.text:00414418                 mov     [ebp+var_24], 2
.text:0041441F                 mov     eax, 4
.text:00414424                 shl     eax, 1
.text:00414426                 mov     [ebp+eax+var_18], 14h

进入到main函数的堆栈空间查看

数组在内存堆栈中存储是一段连续的空间,数组名就是这段空间的首地址

得到数组地址是 0x00B5FEB4

在内存搜索

数组数据的存储是从首地址开始的

在IDA分析数组,这是在对数组初始化,[EBP-18h]就是数组的首地址

双击var_18进入main的堆栈空间,修改var_18的名字为arr

把这段数据转换为数组形式,需要设置整个数组的元素个数,从首地址开始转换

IDA数组部分汇编发生了变化

可以总结出来一个公式,访问数组的元素就是通过 数组首地址+偏移量 

&arr[n] = arr + 4*n   

分析如下:

.text:004143F5                 mov     [ebp+arr], 1    ; 数组第一个元素
.text:004143FC                 mov     [ebp+arr+4], 2  ; 数组第二个元素
.text:00414403                 mov     [ebp+arr+8], 3  ; 数组第三个元素
.text:0041440A                 mov     [ebp+arr+0Ch], 4 ; 数组第四个元素
.text:00414411                 mov     [ebp+arr+10h], 5 ; 数组第五个元素
.text:00414418                 mov     [ebp+var_24], 2 ; int n = 2;  给变量n赋值
.text:0041441F                 mov     eax, 4
.text:00414424                 shl     eax, 1          ; 配合上一条 4 = 0100 shL偏移一位
.text:00414426                 mov     [ebp+eax+arr], 14h ; 修改数组第三个元素   arr[2] = 20;
.text:0041442E                 xor     eax, eax        ; return 0

IDA分析结构体存储

测试代码

/************************************************************************/
/*@Author            : 玄都大法师
/*@Data              : 2023/09/11
/*@Description       : 汇编学习

/************************************************************************/

#include <stdio.h>

struct MyStruct
{
	int nNum;
	float fNum;
	char chA;
};

void Print(MyStruct stc)
{
	printf("int %d, y %f,z %c", stc.nNum, stc.fNum, stc.chA);
}


int main()
{
	MyStruct stc = {1, 2.2, 'A'};
	stc.fNum = 5.5;
	Print(stc);

	return 0;
}

分析和结构相关的汇编代码

.text:004143E0 ; int __cdecl main_0(int argc, const char **argv, const char **envp)
.text:004143E0 _main_0         proc near               ; CODE XREF: _main↑j
.text:004143E0
.text:004143E0 var_14          = byte ptr -14h
.text:004143E0 var_10          = dword ptr -10h
.text:004143E0 var_C           = dword ptr -0Ch
.text:004143E0 var_8           = dword ptr -8
.text:004143E0 argc            = dword ptr  8
.text:004143E0 argv            = dword ptr  0Ch
.text:004143E0 envp            = dword ptr  10h
.text:004143E0
.text:004143E0                 push    ebp
.text:004143E1                 mov     ebp, esp
.text:004143E3                 sub     esp, 0D4h
.text:004143E9                 push    ebx
.text:004143EA                 push    esi
.text:004143EB                 push    edi
.text:004143EC                 lea     edi, [ebp+var_14]
.text:004143EF                 mov     ecx, 5
.text:004143F4                 mov     eax, 0CCCCCCCCh
.text:004143F9                 rep stosd
.text:004143FB                 mov     ecx, offset unk_41C003
.text:00414400                 call    j_@__CheckForDebuggerJustMyCode@4 ; __CheckForDebuggerJustMyCode(x)
.text:00414405                 mov     [ebp+var_10], 1
.text:0041440C                 movss   xmm0, ds:dword_417BE0 ; 浮点数的存储应该和编译器有关
.text:00414414                 movss   [ebp+var_C], xmm0 ; 浮点数的赋值往往借助xmm0寄存器
.text:00414419                 mov     byte ptr [ebp+var_8], 41h ; 'A'
.text:0041441D                 movss   xmm0, ds:dword_417BE4 ; 字符的赋值也是往往借助xmm0寄存器
.text:00414425                 movss   [ebp+var_C], xmm0
.text:0041442A                 sub     esp, 0Ch        ; 这种函数传参也很有意思
.text:0041442D                 mov     eax, esp        ; 把esp给eax,通过eax来实现参数压入栈
.text:0041442F                 mov     ecx, [ebp+var_10]
.text:00414432                 mov     [eax], ecx      ; [eax]是对eax存储的地址引用,相当于 esp
.text:00414434                 mov     edx, [ebp+var_C]
.text:00414437                 mov     [eax+4], edx
.text:0041443A                 mov     ecx, [ebp+var_8]
.text:0041443D                 mov     [eax+8], ecx
.text:00414440                 call    sub_4113C0
.text:00414445                 add     esp, 0Ch
.text:00414448                 xor     eax, eax
.text:0041444A                 push    edx
.text:0041444B                 mov     ecx, ebp        ; Esp
.text:0041444D                 push    eax
.text:0041444E                 lea     edx, Fd         ; Fd
.text:00414454                 call    j_@_RTC_CheckStackVars@8 ; _RTC_CheckStackVars(x,x)
.text:00414459                 pop     eax
.text:0041445A                 pop     edx
.text:0041445B                 pop     edi
.text:0041445C                 pop     esi
.text:0041445D                 pop     ebx
.text:0041445E                 add     esp, 0D4h
.text:00414464                 cmp     ebp, esp
.text:00414466                 call    j___RTC_CheckEsp
.text:0041446B                 mov     esp, ebp
.text:0041446D                 pop     ebp
.text:0041446E                 retn
.text:0041446E _main_0         endp

结构体赋值

分析print函数调用,新的调用传参

.text:0041442A                 sub     esp, 0Ch        ; 这种函数传参也很有意思
.text:0041442D                 mov     eax, esp        ; 把esp给eax,通过eax来实现参数压入栈
.text:0041442F                 mov     ecx, [ebp+var_10]
.text:00414432                 mov     [eax], ecx      ; [eax]是对eax存储的地址引用,相当于 esp
.text:00414434                 mov     edx, [ebp+var_C]
.text:00414437                 mov     [eax+4], edx
.text:0041443A                 mov     ecx, [ebp+var_8]
.text:0041443D                 mov     [eax+8], ecx
.text:00414440                 call    sub_4113C0
.text:00414445                 add     esp, 0Ch

这种函数传参调用函数,没有通过esp,借助eax寄存器来寻址把参数入栈,实际上效果和原来一样,换汤不换药。

IDA中添加结构体

在IDA空白界面右击,选择 Add struct type  或者空白处摁下insert  如果想要创建标准结构体,就点击 add standard structure

输入名字

创建成功

在ends这一行,摁下d就可以创建结构体元素,在元素一行后面摁d可以修改大小

应用结构体

选到首个元素地址,摁下y,输入需要修改的结构体名称,然后重命名

IDA的变化

结构体的特征:给一段连续空间赋值,数组也有,但区别在于,两者寻址方式不一样,而且数组元素类型单一

传递参数的方式

方式一:

push 0x1;
push 0x2;
push 0x3;

方式二:

sub esp 0xC;
mov [esp+0x0],1;
mov [esp+0x4],2;
mov [esp+0x8],3;

方式三:

sub esp 0xC;
mov eax,esp;

mov [eax+0x0],1;
mov [eax+0x4],2;
mov [eax+0x8],3;

更多推荐

Linux常用命令—find命令大全

文章目录一、find命令常用功能1、find命令的基本信息如下。2、按照文件名搜索3、按照文件大小搜索4、按照修改时间搜索5、按照权限搜索举例:6、按照所有者和所属组搜索7、按照文件类型搜索8、逻辑运算符一、find命令常用功能1、find命令的基本信息如下。命令名称:find。英文原意:searchforfilesi

怎么设置IP白名单

IP白名单是一种网络安全机制,用于限制只允许特定的IP地址或IP地址范围通过访问控制。在本文中,我将详细解释IP白名单的概念、用途以及如何设置IP白名单。**1.什么是IP白名单?**IP白名单是一种访问控制列表,它允许或阻止特定的IP地址或IP地址范围对系统、应用程序或网络进行访问。只有在白名单中的IP地址被授权通过

C++ std::unique_lock 用法

文章目录1.创建std::unique_lock对象2.自动加锁和解锁3.延迟加锁与手动加解锁4.尝试加锁5.配合条件变量使用6.小结参考文献std::unique_lock是C++11提供的一个用于管理互斥锁的类,它提供了更灵活的锁管理功能,适用于各种多线程场景。1.创建std::unique_lock对象std::

【面试刷题】——Qt事件处理器级别的划分

在Qt中,事件处理器(EventHandler)可以分为不同的级别,以适应不同的需求和场景。以下是Qt事件处理器级别的划分:应用程序级别事件处理器:这是最高级别的事件处理器,通常用于处理应用程序范围内的事件,如全局快捷键、自定义应用程序级别的事件等。应用程序级别事件处理器可以通过继承QCoreApplication或使

浅谈电气防火保护器在地下商场的应用 安科瑞 缪阳扬

摘要:近年来,我国城市发展速度加速。很多城市大力建造地下建筑设施,比如地铁、地下停车场和地下商场等。地下商场属于人员密集型建筑,其防火设计一直令相关的专家头疼。由于人员密集,防火处理不好将酿成灾难性的后果。因此,防火十分重要。防火设计可以着重于疏散和火灾探查报警系统两个方面,而电气火灾监控系统在实际预警和报警过程中有着

vector的扩容机制—为何是1.5倍或者是2倍

文章目录前言一、Vector扩容过程二、为什么是1.5倍或者2倍?前言在C++编程中,Vector是一种常用的动态数组容器。其大小是可以动态调整的,而在扩容操作中,Vector通常会将容量增加为原来的两倍。本篇博客将详细介绍Vector扩容的原理、扩容过程,并解释为何选择两倍进行扩容。一、Vector扩容过程当向vec

QT用户登录注册,数据库实现

登录窗口头文件#ifndefLOGINUI_H#defineLOGINUI_H#include<QWidget>#include<QLineEdit>#include<QPushButton>#include<QLabel>#include<QMessageBox>#include<QSqlDatabase>//数据库

智能配电监控管理系统:高效、安全、绿色的电力管理

随着科技的快速发展,电力行业正在逐步实现智能化、数字化转型。其中,智能配电监控管理系统在优化电力资源配置、提升运营效率、保障用电安全等方面发挥着至关重要的作用。系统架构:力安科技电易云智能配电监控管理系统是在配电室(含高压柜、变压器、低压柜)、箱式变电站、配电箱及动力柜(箱)、智能终端箱实现智能化、网络化、数字化的基础

虹科CiA演讲回顾 | CAN(FD)总线协议转换原理及其在汽车行业的应用

2023年9月14日,CiA中国技术日直播活动在线上举行,该活动致力于开展与CAN总线相关领域的技术工作,演讲者都是CAN领域的专家。虹科首席工程师陈皓受邀参与活动,并带来以“CAN和CANFD总线协议转换”为主题的演讲。本次演讲内容主要分为三个部分:首先介绍了CAN和CANFD总线的区别,并以此为切入点讲解了两种总线

在已知的二维坐标里找到最接近的点

一、业务场景最近在研发的项目,在做可视化层,在全球地图上,对我们的国家的陆地地图经纬度按照步长为1的间隔做了二维处理。在得到一组整数的点位信息后,需要将我们已有的数据库数据(业务项目)按照地址的经纬度,映射到这些点位上,找到对应的id建立联系。简化后的处理逻辑如下:参考上图:纬度为y轴,跨度为35,间距为1经度为x轴,

李沐深度学习记录1:零碎知识记录、08线性回归

简要记录,以便查阅~一、零碎知识x.numel():看向量或矩阵里元素个数A.sum():向量或矩阵求和,axis参数可对某维度求和,keepdims参数设置是否保持维度不变A.cumsum:axis参数设置沿某一维度计算矩阵累计和x*y:向量的按元素乘法torch.dot(x,y):向量的点乘(点积or内积),结果是

热文推荐