函数调用分析

news2024/11/16 1:47:16

目录

函数相关的汇编指令

JMP指令

call指令

ret指令

VS2019正向分析main函数

总结调用函数堆栈变化规律

x64dbg分析调用函数

IDA分析调用函数


函数相关的汇编指令

JMP指令

JMP 指令表示的是需要跳转到哪个内存地址,相当于是间接修改了 EIP

call指令

call 指令也是用来修改 EIP 寄存器的
call 0x401000

相当于

push 0x401000+5
jmp 0x401000

调用函数前地址

执行后 进入函数执行代码段,call指令地址 00831f83+0x5 = 00831f88 压入堆栈

 

ret指令

相当于

mov eip,[esp];      ESP地址内存的地址(call 函数后下一条指令地址)给EIP
add esp,0x4;        

EIP存储的是一个地址,这个地址,这个地址的空间存储的是汇编指令

VS2019正向分析main函数

测试代码

#include <stdio.h>

int m = 999;

int add(int a, int b)
{
	int c = a + b;
	return c;
}

int main()
{
	int x = 3;
	int y = 4;
	int z = add(x, y);

	printf("add()返回值是%d  int m = %d", z, m );
	
	return 0;
}

调用堆栈

invoke main函数调用了main函数,main函数有3个参数

    static int __cdecl invoke_main()
    {
        return main(__argc, __argv, _get_initial_narrow_environment());
    }

main()函数汇编代码分析


int main()
{
00542560 55                   push        ebp  
00542561 8B EC                mov         ebp,esp  
00542563 81 EC E4 00 00 00    sub         esp,0E4h  
00542569 53                   push        ebx  
0054256A 56                   push        esi  
0054256B 57                   push        edi  
0054256C 8D 7D DC             lea         edi,[ebp-24h]  
0054256F B9 09 00 00 00       mov         ecx,9  
00542574 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
00542579 F3 AB                rep stos    dword ptr es:[edi]  
0054257B B9 03 C0 54 00       mov         ecx,offset _5899AD65_test@cpp (054C003h)  
00542580 E8 87 ED FF FF       call        @__CheckForDebuggerJustMyCode@4 (054130Ch)  
	int x = 3;
00542585 C7 45 F8 03 00 00 00 mov         dword ptr [x],3  
	int y = 4;
0054258C C7 45 EC 04 00 00 00 mov         dword ptr [y],4  
	int z = add(x, y);
00542593 8B 45 EC             mov         eax,dword ptr [y]  
00542596 50                   push        eax  
00542597 8B 4D F8             mov         ecx,dword ptr [x]  
0054259A 51                   push        ecx  
0054259B E8 1B EE FF FF       call        add (05413BBh)  
005425A0 83 C4 08             add         esp,8  
005425A3 89 45 E0             mov         dword ptr [z],eax  

	printf("add()返回值是%d  int m = %d", z, m);
005425A6 A1 28 A0 54 00       mov         eax,dword ptr [m (054A028h)]  
005425AB 50                   push        eax  
005425AC 8B 4D E0             mov         ecx,dword ptr [z]  
005425AF 51                   push        ecx  
005425B0 68 CC 7B 54 00       push        offset string "add()\xb7\xb5\xbb\xd8\xd6\xb5\xca\xc7%d" (0547BCCh)  
005425B5 E8 E8 ED FF FF       call        _printf (05413A2h)  
005425BA 83 C4 0C             add         esp,0Ch  

	return 0;
005425BD 33 C0                xor         eax,eax  
}
005425BF 5F                   pop         edi  
005425C0 5E                   pop         esi  
005425C1 5B                   pop         ebx  
005425C2 81 C4 E4 00 00 00    add         esp,0E4h  
005425C8 3B EC                cmp         ebp,esp  
005425CA E8 61 EC FF FF       call        __RTC_CheckEsp (0541230h)  
005425CF 8B E5                mov         esp,ebp  
005425D1 5D                   pop         ebp  
005425D2 C3                   ret  

开辟栈帧

int main()
{
00542560 55                   push        ebp  
00542561 8B EC                mov         ebp,esp 

给函数的局部变量开辟空间,0E4h个空间

00542563 81 EC E4 00 00 00    sub         esp,0E4h 

保存寄存器值 

00542569 53                   push        ebx  
0054256A 56                   push        esi  
0054256B 57                   push        edi 

给24h(36个字节)初始化,每个字节为0xCC,范围是EBP(0x009bfdb0) - 0x009bfd8C

具体细节:

  1. REP STOS 指令的作用是将一个指定的值写入字符串中的每个字节或字。
  2. EAC存储要初始化的值,0XCC ,是 int 3 截断告警(防止代码执行到此)
  3. ECX存储次数,9次,每次4个字节,一共36个字节
  4. lea取地址给EDI,目标
  5. rep stos根据DF寄存器决定赋值的方向,DF=0,低->高;高->低
0054256C 8D 7D DC             lea         edi,[ebp-24h]  
0054256F B9 09 00 00 00       mov         ecx,9  
00542574 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
00542579 F3 AB                rep stos    dword ptr es:[edi] 

初始化完成

VS2019系统函数

0054257B B9 03 C0 54 00       mov         ecx,offset _5899AD65_test@cpp (054C003h)  
00542580 E8 87 ED FF FF       call        @__CheckForDebuggerJustMyCode@4 (054130Ch)  

局部变量赋值

	int x = 3;
00542585 C7 45 F8 03 00 00 00 mov         dword ptr [x],3  
	int y = 4;
0054258C C7 45 EC 04 00 00 00 mov         dword ptr [y],4 

取地址查看

转到对应内存空间

maiin函数执行到最后一条语句,EAX是返回值,要清0

	return 0;
005425BD 33 C0                xor         eax,eax 

恢复易失性寄存器

005425BF 5F                   pop         edi  
005425C0 5E                   pop         esi  
005425C1 5B                   pop         ebx

恢复函数局部变量空间,函数外平栈

005425C2 81 C4 E4 00 00 00    add         esp,0E4h

检查堆栈有无异常,VS2019函数,无需关注

005425C8 3B EC                cmp         ebp,esp  
005425CA E8 61 EC FF FF       call        __RTC_CheckEsp (0541230h)

恢复栈帧,具体细节如下:

  1. MOV ESP,EBP   
  2. pop ebp      恢复原先栈帧的栈底
  3. ret         恢复原先栈帧的栈顶
005425CF 8B E5                mov         esp,ebp  
005425D1 5D                   pop         ebp  
005425D2 C3                   ret 

main函数调用已经分析完毕,中间还调用了add函数

	int z = add(x, y);
00542593 8B 45 EC             mov         eax,dword ptr [y]  
00542596 50                   push        eax  
00542597 8B 4D F8             mov         ecx,dword ptr [x]  
0054259A 51                   push        ecx  
0054259B E8 1B EE FF FF       call        add (05413BBh)  
005425A0 83 C4 08             add         esp,8  
005425A3 89 45 E0             mov         dword ptr [z],eax

具体细节:

函数参数压入堆栈

00542593 8B 45 EC             mov         eax,dword ptr [y]  
00542596 50                   push        eax  
00542597 8B 4D F8             mov         ecx,dword ptr [x]  
0054259A 51                   push        ecx

调用函数,并且下一条指令压入堆栈

0054259B E8 1B EE FF FF       call        add (05413BBh)

查看add函数汇编

int add(int a, int b)
{

开辟栈帧

00542EA0 55                   push        ebp  
00542EA1 8B EC                mov         ebp,esp  

开辟局部变量空间

00542EA3 81 EC CC 00 00 00    sub         esp,0CCh  

保存易失性寄存器

00542EA9 53                   push        ebx  
00542EAA 56                   push        esi  
00542EAB 57                   push        edi

初始化局部变量的堆栈
  
00542EAC 8D 7D F4             lea         edi,[ebp-0Ch]  
00542EAF B9 03 00 00 00       mov         ecx,3  
00542EB4 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
00542EB9 F3 AB                rep stos    dword ptr es:[edi] 

VS2019的函数
 
00542EBB B9 03 C0 54 00       mov         ecx,offset _5899AD65_test@cpp (054C003h)  
00542EC0 E8 47 E4 FF FF       call        @__CheckForDebuggerJustMyCode@4 (054130Ch) 

加法运算
 
	int c = a + b;
00542EC5 8B 45 08             mov         eax,dword ptr [a]  
00542EC8 03 45 0C             add         eax,dword ptr [b] 
00542ECB 89 45 F8             mov         dword ptr [c],eax  

c作为函数返回值,把值给eax寄存器

	return c;
00542ECE 8B 45 F8             mov         eax,dword ptr [c]  
}

恢复寄存器

00542ED1 5F                   pop         edi  
00542ED2 5E                   pop         esi  
00542ED3 5B                   pop         ebx  

平栈局部变量

00542ED4 81 C4 CC 00 00 00    add         esp,0CCh  

VS2019函数,检查堆栈是否有异常

00542EDA 3B EC                cmp         ebp,esp  
00542EDC E8 4F E3 FF FF       call        __RTC_CheckEsp (0541230h)  

恢复原栈帧的栈底

00542EE1 8B E5                mov         esp,ebp  
00542EE3 5D                   pop         ebp  

恢复原栈帧的栈顶,并且恢复程序执行流程

00542EE4 C3                   ret

到此栈还未回复完全,还有函数参数

平栈函数参数

005425A0 83 C4 08             add         esp,8 

把函数返回值给z

005425A3 89 45 E0             mov         dword ptr [z],eax 

总结调用函数堆栈变化规律

  1. 把函数参数压入栈
  2. call 函数   下一条指令地址压入堆栈(之后都是被调函数的引起的变化)
  3. 把原栈帧的栈帧基址(EBP)压入堆栈
  4. 开辟栈帧   
  5. 开辟局部变量空间
  6. 保存寄存器
  7. 给局部变量空间初始化
  8. 函数有返回值一半保存给eax
  9. 恢复寄存器
  10. 平栈 函数局部变量空间
  11. 恢复栈帧

x64dbg分析调用函数

定位到main函数

add函数

main函数

IDA分析调用函数

IDA其实和x64dbg一样

.text:00412560 ; int __cdecl main(int argc, const char **argv, const char **envp)
.text:00412560 main            proc near               ; CODE XREF: j_main↑j
.text:00412560
.text:00412560 var_24          = byte ptr -24h
.text:00412560 var_20          = dword ptr -20h
.text:00412560 var_14          = dword ptr -14h
.text:00412560 var_8           = dword ptr -8
.text:00412560 argc            = dword ptr  8
.text:00412560 argv            = dword ptr  0Ch
.text:00412560 envp            = dword ptr  10h
.text:00412560
.text:00412560                 push    ebp
.text:00412561                 mov     ebp, esp
.text:00412563                 sub     esp, 0E4h
.text:00412569                 push    ebx
.text:0041256A                 push    esi
.text:0041256B                 push    edi
.text:0041256C                 lea     edi, [ebp+var_24]
.text:0041256F                 mov     ecx, 9
.text:00412574                 mov     eax, 0CCCCCCCCh
.text:00412579                 rep stosd
.text:0041257B                 mov     ecx, offset unk_41C003
.text:00412580                 call    sub_41130C
.text:00412585                 mov     [ebp+var_8], 3
.text:0041258C                 mov     [ebp+var_14], 4
.text:00412593                 mov     eax, [ebp+var_14]
.text:00412596                 push    eax
.text:00412597                 mov     ecx, [ebp+var_8]
.text:0041259A                 push    ecx
.text:0041259B                 call    sub_4113BB
.text:004125A0                 add     esp, 8
.text:004125A3                 mov     [ebp+var_20], eax
.text:004125A6                 mov     eax, dword_41A028
.text:004125AB                 push    eax
.text:004125AC                 mov     ecx, [ebp+var_20]
.text:004125AF                 push    ecx
.text:004125B0                 push    offset unk_417BCC
.text:004125B5                 call    sub_4113A2
.text:004125BA                 add     esp, 0Ch
.text:004125BD                 xor     eax, eax
.text:004125BF                 pop     edi
.text:004125C0                 pop     esi
.text:004125C1                 pop     ebx
.text:004125C2                 add     esp, 0E4h
.text:004125C8                 cmp     ebp, esp
.text:004125CA                 call    sub_411230
.text:004125CF                 mov     esp, ebp
.text:004125D1                 pop     ebp
.text:004125D2                 retn
.text:004125D2 main            endp

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

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

相关文章

NX二次开发UF_CAM_ask_blank_matl_db_object 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;里海NX二次开发3000例专栏 UF_CAM_ask_blank_matl_db_object Defined in: uf_cam.h int UF_CAM_ask_blank_matl_db_object(UF_CAM_db_object_t * db_obj ) overview 概述 This function provides the database object which …

使ros1和ros2的bag一直互通

很多文章都是先source ros1 然后source ros2,再play bag source /opt/ros/noetic/setup.bash source /opt/ros/foxy/setup.bash ros2 bag play -s rosbag_v2 kitti_raw00.bag 但实测会出问题: 为使ros1和ros2的bag一直互通 sudo apt update sudo apt install ros-foxy-ro…

axios的原理及实现一个简易版axios

面试官&#xff1a;你了解axios的原理吗&#xff1f;有看过它的源码吗&#xff1f; 一、axios的使用 关于axios的基本使用&#xff0c;上篇文章已经有所涉及&#xff0c;这里再稍微回顾下&#xff1a; 发送请求 import axios from axios;axios(config) // 直接传入配置 axio…

hdfsClient_java对hdfs进行上传、下载、删除、移动、打印文件信息尚硅谷大海哥

Java可以通过Hadoop提供的HDFS Java API来控制HDFS。通过HDFS Java API&#xff0c;可以实现对HDFS的文件操作&#xff0c;包括文件的创建、读取、写入、删除等操作。 具体来说&#xff0c;Java可以通过HDFS Java API来创建一个HDFS文件系统对象&#xff0c;然后使用该对象来进…

PPT幻灯片里的图片,批量提取

之前分享过如何将PPT文件导出成图片&#xff0c;今天继续分享PPT技巧&#xff0c;如何提取出PPT文件里面的图片。 首先&#xff0c;我们将PPT文件的后缀名&#xff0c;修改为rar&#xff0c;将文件改为压缩包文件 然后我们将压缩包文件进行解压 最好是以文件夹的形式解压出来…

车载毫米波雷达行业发展1——概述

1.1 毫米波雷达定义及产品演进 1.1.1 毫米波雷达定义 毫米波雷达(mmWave Radar)是指工作在毫米波波段的雷达&#xff0c;其频域介于 30&#xff5e;300GHz&#xff0c;波长1~10mm。毫米波雷达稳定性高&#xff0c;抗干扰能力强&#xff0c;可穿透雾、烟、灰尘环境&#xff0…

发币成功,记录一下~

N年前就听说了这样一种说法——“一个熟练的区块链工程师&#xff0c;10分钟就可以发出一个新的币” 以前仅仅是有这么一个认识&#xff0c;但当时并不特别关注这个领域。 最近系统性学习中&#xff0c;今天尝试发币成功啦&#xff0c;记录一下&#xff5e; 发在 Sepolia Tes…

CentOS7安装部署Kafka with KRaft

文章目录 CentOS7安装部署Kafka with KRaft一、前言1.简介2.架构3.环境 二、正文1.部署服务器2.基础环境1&#xff09;主机名2&#xff09;Hosts文件3&#xff09;关闭防火墙4&#xff09;JDK 安装部署 3.单机部署1&#xff09;下载软件包2&#xff09;修改配置文件3&#xff0…

[Genode] ARM TrustZone

这是关于读文章ARM TrustZone的记录&#xff0c;原文是英文&#xff0c;刚开始会有点反应不过来&#xff0c;这里大部分是对文章的翻译与提取。 ARM信任区技术 ARM信任区是在 热烈讨论关于X86平台上的可信平台模块&#xff08;TPM&#xff09; 时引入的。。 就像TPM芯片神奇…

◢Django 分页+搜索

1、搜索数据 从数据库中获取数据&#xff0c;并进行筛选&#xff0c;xx__contains q作为条件&#xff0c;查找的是xx列中有q的所有数据条 当有多个筛选条件时&#xff0c;将条件变成一个字典&#xff0c;传入 **字典 &#xff0c;ORM会自行翻译并查找。 筛选电话号码这一列…

【Java】volatile-内存可见性问题

1、什么是内存可见性问题&#xff1f; &#xff08;1&#xff09;实例 要明白什么是内存可见性&#xff0c;我们首先来看一段代码 public class demo1 {public static int isQuit 0;public static void main(String[] args) {Thread thread1 new Thread(()->{while (is…

【每日刷题——语音信号篇】

思考与练习 练习2.1 语音信号在产生的过程中&#xff0c;以及被感知的过程中&#xff0c;分别要经过人体的哪些器官&#xff1f; 1.产生过程&#xff1a; 肺部空气 → \rightarrow →冲击声带 → \rightarrow →通过声道&#xff08;可以调节&#xff09; → \rightarrow →…

【小呆的力学笔记】有限元专题之循环对称结构有限元原理

文章目录 1. 循环对称问题的提出2. 循环对称条件2.1 节点位移的循环对称关系2.2 节点内力的循环对称关系 3. 在平衡方程中引入循环对称条件 1. 循环对称问题的提出 许多工程结构都是其中某一扇面的n次周向重复&#xff0c;也就是是周期循环对称结构。如果弹性体的几何形状、约…

【洛谷 P3743】kotori的设备 题解(二分答案+递归)

kotori的设备 题目背景 kotori 有 n n n 个可同时使用的设备。 题目描述 第 i i i 个设备每秒消耗 a i a_i ai​ 个单位能量。能量的使用是连续的&#xff0c;也就是说能量不是某时刻突然消耗的&#xff0c;而是匀速消耗。也就是说&#xff0c;对于任意实数&#xff0c;…

java学习part06数组工具类

1比较内容 2输出信息 3值填充 4快速排序 5二分查找 负数没找到&#xff0c;其他表示下标

SVG圆形 <circle>的示例代码

本专栏是汇集了一些HTML常常被遗忘的知识&#xff0c;这里算是温故而知新&#xff0c;往往这些零碎的知识点&#xff0c;在你开发中能起到炸惊效果。我们每个人都没有过目不忘&#xff0c;过久不忘的本事&#xff0c;就让这一点点知识慢慢渗透你的脑海。 本专栏的风格是力求简洁…

【MySql】13- 实践篇(十一)

文章目录 1. 自增主键为什么不是连续的&#xff1f;1.1 自增值保存在哪儿&#xff1f;1.2 自增值修改机制1.2.1 自增值的修改时机1.2.2 自增值为什么不能回退? 1.3 自增锁的优化1.3.1 自增锁设计历史 2. Insert语句为何很多锁?2.1 insert … select 语句2.2 insert 循环写入2…

记录--alova组件使用方法(区别axios)

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 在我们写项目代码时&#xff0c;应该更加专注于业务逻辑的实现&#xff0c;而把定式代码交给js库或工程化自动处理&#xff0c;而我想说的是&#xff0c;请求逻辑其实也是可以继续简化的。 你可能会说…

npm install 下载不下来依赖解决方案

背景 最近在构建 前端自动化部署 的方案中发现了一个问题&#xff0c;就是我在npm install的时候&#xff0c;有时候成功&#xff0c;有时候不成功&#xff0c;而且什么代码也没发生更改&#xff0c;报错也就是那么几个错&#xff0c;所以在此也整理了一下遇到这种情况&#xf…

音视频同步笔记 - 以音频时间为基

音视频同步 - 以音频时间为基 上图介绍&#xff1a; 该图是以音频的时间为基&#xff0c;对视频播放时间的延迟控制方案&#xff0c;只调整视频的播放延时。delayTime是视频播放的延迟时间&#xff0c;初始值是1 / FPS * 1000 (ms)&#xff0c;如果FPS为25帧率&#xff0c;初始…