函数调用分析

目录

函数相关的汇编指令

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

图像分割方法

常见的图像分割方法有以下几种&#xff1a; 1.基于阈值的分割方法 灰度阈值分割法是一种最常用的并行区域技术&#xff0c;它是图像分割中应用数量最多的一类。阈值分割方法实际上是输入图像f到输出图像g的如下变换&#xff1a; 其中&#xff0c;T为阈值&#xff1b;对于物体的…

Django 路由配置(二)

一、路由 就是根据用户请求的URL链接来判断对应的出来程序&#xff0c;并返回处理结果&#xff0c;也是就是URL和django的视图建立映射关系. 二、Django请求页面的步骤 1、首先Django确定要使用的根URLconf模块&#xff0c;通过ROOT_URLCONF来设置&#xff0c;在settings.py配置…

试用无线调试器PowerDebugger小记

试用无线调试器PowerDebugger小记 文章目录 试用无线调试器PowerDebugger小记引言准备软硬件环境PowerDebugger 无线调试器EVB-YTM32B1LE0-Q64 开发板 开始调试小结参考文献 引言 多年前调试智能车时&#xff0c;抱着电脑连着小车在跑道上一边跑一边看数据的经历&#xff0c;让…

春秋云境靶场CVE-2022-30887漏洞复现(任意文件上传漏洞)

文章目录 前言一、CVE-2022-30887描述和介绍二、CVE-2021-41402漏洞复现1、信息收集2、找可能可以进行任意php代码执行的地方3、漏洞利用找flag 总结 前言 此文章只用于学习和反思巩固渗透测试知识&#xff0c;禁止用于做非法攻击。注意靶场是可以练习的平台&#xff0c;不能随…

深入解析SSD Wear Leveling磨损均衡技术:如何让你的硬盘更长寿?

SSD的存储介质是什么&#xff0c;它就是NAND闪存。那你知道NAND闪存是怎么工作的吗&#xff1f;其实&#xff0c;它就是由很多个晶体管组成的。这些晶体管里面存储着电荷&#xff0c;代表着我们的二进制数据&#xff0c;要么是“0”&#xff0c;要么是“1”。NAND闪存原理上是一…

Unity模拟薄膜干涉效果

Unity制作薄膜干涉效果&#xff0c;色彩斑斓的黑色石头 大家好&#xff0c;我是阿赵。   这次来做一个模拟薄膜干涉的彩色效果&#xff0c;Shader是使用ASE来连接&#xff0c;也算是ASE做复杂一点的效果的一个例子吧。 一、什么是薄膜干涉 以下解释来源于百度百科&#xff1…

白鳝:聊聊IvorySQL的Oracle兼容技术细节与实现原理

两年前听瀚高的一个朋友说他们要做一个开源数据库项目&#xff0c;基于PostgreSQL&#xff0c;主打与Oracle的兼容性&#xff0c;并且与PG社区版内核同步发布。当时我听了有点不太相信&#xff0c;瀚高的Highgo是在PG内核上增加了一定的Oracle兼容性的特性&#xff0c;一般也会…

#gStore-weekly | gBuilder功能详解之表单录入

gBuilder除了可以提供结构化数据映射以及非结构化数据抽取两种构建知识图谱的方式以外&#xff0c;还提供了表单录入的方式来构建知识图谱的数据&#xff0c;用户只需要根据设计好的schema将实体、属性以及关系通过填写表单的形式录入&#xff0c;再通过一键生成NT文件即可获得…

HTTP1.1升级HTTP2.0

HTTP1.1升级HTTP2.0 一&#xff0c;前言介绍 1.为什么要升级http2.0 HTTP2.0相比于HTTP1.x有以下几个优点&#xff1a; 二进制分帧&#xff1a;HTTP2.0将所有传输的信息分割为更小的消息和帧&#xff0c;并采用二进制格式对它们进行编码&#xff0c;这样可以更好地对数据进行…

国家开放大学平时作业训练题

卷代号&#xff1a;1400 机器人技术及应用 参考试题 一、单项选择题&#xff08;每小题3分&#xff0c;共45分&#xff09; 1.在变径轮和变形车轮的设计中&#xff0c;借鉴了&#xff08; &#xff09;的设计&#xff0c;使得车轮可以主动变形进行越障。 A.滑块机构 …

MR混合现实教学系统在汽车检修与维护课堂教学中的应用

传统的汽车检修与维护课堂教学主要依赖教师口头讲解和黑板演示&#xff0c;这种方式存在一定的局限性。首先&#xff0c;对于一些复杂的机械结构和操作过程&#xff0c;教师难以生动形象地展示给学生。其次&#xff0c;学生无法直接观察到实际操作中的细节和注意事项&#xff0…

Python CleverCSV指南,让CSV不再难搞

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;我是涛哥&#xff0c;今天为大家分享 Python CleverCSV指南&#xff0c;让CSV不再难搞&#xff0c;文章58000字&#xff0c;阅读大约15分钟&#xff0c;大家enjoy~~ CleverCSV是一个Python库&#xff0c;专注于提…

vue过渡,vue3组合式API详细介绍

7.过渡效果 vue提供了两个内置组件,可以帮助你制作基于状态变化的过渡和动画 Transition会在一个元素或组件进入和离开DOM时应用动画TransitionGroup会在一个v-for列表中的元素或组件被插入,移动,或移除时应用动画 7-1过渡效果 过渡模式 <Transition mode"out-in&q…

系列二、Lock接口

一、多线程编程模板 线程 操作 资源类 高内聚 低耦合 二、实现步骤 1、创建资源类 2、资源类里创建同步方法、同步代码块 三、12306卖票程序 3.1、synchronized实现 3.1.1、Ticket /*** Author : 一叶浮萍归大海* Date: 2023/11/20 8:54* …

python趣味编程-5分钟实现一个贪吃蛇游戏(含源码、步骤讲解)

Python 贪吃蛇游戏代码是用 Python 语言编写的。在这个贪吃蛇游戏中,Python 代码是增强您在创建和设计如何使用 Python 创建贪吃蛇游戏方面的技能和才能的方法。 Python Tkinter中的贪吃蛇游戏是一个简单干净的 GUI,可轻松玩游戏。游戏设计非常简单,用户不会觉得使用和理解…

车载毫米波雷达行业发展5——企业

5.1 博世 5.1.1 公司简介 博世集团创立于 1886 年&#xff0c;业务涵盖汽车与智能交通技术、工业技术、消费品、能源与建 筑技术四大领域&#xff0c;是德国最大的工业企业之一、全球最大的汽车零部件供应商、最早研究车载毫米波雷达的企业之一。博世在高级辅助驾驶和自动驾驶…

数据库管理工具,你可以用Navicat,但我选DBeaver!

大家好&#xff0c;我是豆小匠。数据库GUI工具哪家强&#xff0c;众人遥指Navicat。 可是Navicat老贵了。 如果公司有正版授权的还好&#xff0c;如果没有正版授权&#xff0c;还不给你用盗版&#xff0c;那才叫绝绝子。 好了&#xff0c;主角登场&#xff0c;DBeaver&#x…

国产高云FPGA:纯verilog实现视频图像缩放,提供6套Gowin工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐国产高云FPGA相关方案推荐国产高云FPGA基础教程 3、设计思路框架视频源选择OV5640摄像头配置及采集动态彩条跨时钟FIFO图像缩放模块详解设计框图代码框图2种插值算法的整合与选择 Video Frame Buffer 图像缓存DDR3 Memory Interface 4、Go…

cadence layout lvs时出现error

Error&#xff1a;Schematic export failed or was cancelled.Please consult the transcript in the viewer window. 解决办法同下&#xff1a; cadence layout lvs时出现error-CSDN博客

Ps:陷印

在准备图像进行专业印刷之前&#xff0c;陷印 Trap是一个重要的步骤。 在彩色印刷中&#xff0c;多种颜色的墨水通常分别印刷。陷印是一种叠印技术&#xff0c;它可避免打印时印版的微小偏差或移动而使打印图像出现微小的缝隙。 进行陷印处理以纠正未对齐现象 A. 未对齐现象&am…