函数调用分析

目录

函数相关的汇编指令

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.mzph.cn/news/153712.shtml

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

相关文章

Windows环境VSCode配置OpenCV-项目配置(二)

修改c_cpp_properties.json {"configurations": [{"name": "windows-gcc-x64","includePath": ["${workspaceFolder}/**","D:/mingw64/mingw64/include","D:/openCV_win/build/install/include","…

系列十二、线程池

一、线程池 1.1、为什么需要线程池 10年前单核CPU电脑&#xff0c;假的多线程&#xff0c;像马戏团小丑玩多个球&#xff0c;CPU需要来回切换。现在是多核电脑&#xff0c;多个线程各自跑在独立的CPU上&#xff0c;不用切换效率高。 1.2、优势 线程池做的主要工作是控制运行的…

天猫超市电商营销系统:无代码开发实现API连接集成

无代码开发实现天猫超市与电商系统的高效连接 天猫超市&#xff0c;作为天猫推出的网络零售超市&#xff0c;为广大网购消费者提供了一站式的购物服务。而通过无代码开发的方式&#xff0c;天猫超市能够实现与各种电商系统的连接和集成&#xff0c;这种方式无需进行繁琐的API开…

ESP32 http 请求

目录 参考教程1.使用的http连接2.使用Vscode-IDF创建http_request例程3.修改http_request_example_main.c函数4.已经获取到响应的数据 参考教程 ESP-IDF HTTP获取网络时间 1.使用的http连接 http://api.m.taobao.com/rest/api3.do?apimtop.common.getTimestamp请求可以得到…

【Python测试开发】:切换窗口和表单

一、多窗口切换 浏览器打开的窗口其实会有一个叫做句柄的概念。 句柄就类似于每一个标签页的ID一样&#xff0c;具有唯一性。 1.1 语法 获取当前窗口句柄&#xff0c;注意后面没有括号哦~ driver.current_window_handle获取所有窗口句柄&#xff0c;结果以列表格式存储&am…

ModBus TCP/RTU 报文解析

Modbus Tcp https://gitee.com/szwzhsz/Modbus-TCP-client-server-DotNetty.?_fromgitee_search 固定协议格式 事务标识(2byte)&#xff1a;00 00&#xff0c;可变(递增) 协议标识(2byte)&#xff1a;00 00&#xff0c;固定 长度(2byte)&#xff1a;00 06&#xff0c;可变 单…

PySide6 Tutorials (一)表格小部件魔改

前言 Pyside6官方教程给了一个使用表格显示颜色的教程&#xff0c;原教程地址如下&#xff1a;源地址&#xff0c; 结合前面button信号的学习&#xff0c;就魔改添加了如下功能&#xff1a;增加一列按钮&#xff0c;可以修改该行的颜色值&#xff0c;通过点击按钮生成指定的颜…

深度学习之生成唐诗案例(Pytorch版)

主要思路&#xff1a; 对于唐诗生成来说&#xff0c;我们定义一个"S" 和 "E"作为开始和结束。 示例的唐诗大概有40000多首&#xff0c; 首先数据预处理&#xff0c;将唐诗加载到内存&#xff0c;生成对应的word2idx、idx2word、以及唐诗按顺序的字序列。…

万字解析设计模式之代理模式

一、代理模式 1.1概述 代理模式是一种结构型设计模式&#xff0c;它允许通过创建代理对象来控制对其他对象的访问。这种模式可以增加一些额外的逻辑来控制对原始对象的访问&#xff0c;同时还可以提供更加灵活的访问方式。 代理模式分为静态代理和动态代理两种。静态代理是在编…

Day01 嵌入式 -----流水灯

一、简单介绍 嵌入式系统中的流水灯是一种常见的示例项目&#xff0c;通常用于演示嵌入式系统的基本功能和控制能力。流水灯由多个发光二极管&#xff08;LED&#xff09;组成&#xff0c;这些LED按照一定的顺序依次点亮和熄灭&#xff0c;形成一种像水流一样的流动效果。 二、…

单/三相dq解耦控制与特定次谐波抑制

1. 单相整流器dq坐标系下建模 单相整流器的拓扑如图所示&#xff0c;可知 u a b u s − L d i s d t − R i s {u_{ab}} {u_{s}} - L\frac{{d{i_s}}}{{dt}} - R{i_s} uab​us​−Ldtdis​​−Ris​。   将电压和电流写成dq的形式。 { u s U s m sin ⁡ ( ω t ) i s I …

选择「程序员」职业的8个理由

软件开发人员是具有创建软件程序的创意和技术技能的专业人员&#xff0c;是一个具有高回报和挑战性的职业选择。如今&#xff0c;软件开发人员几乎在每个行业工作。随着世界变得越来越数字化&#xff0c;越来越需要具有技术背景的人来创建特定的软件应用程序。 如果您考虑做一…

纯JS,RSA,AES,公钥,私钥生成及加解密

通过网络找的JS源文件&#xff0c;修改后使用&#xff0c;包含RSA 密匙对生成 及AES 加解密 涉及的JS源文件 下载 GitHub - cgrlancer/RSA-AES: 纯js,RSA,AES前端加解密 前端引用 import {generateRsaKeyWithPKCS8,encryptByRSA,decryptByRSA,encrypt,decrypt,testRsa} fr…

文心一言-情感关怀之旅

如何让LLM更有温度。 应用介绍

【精选】XML技术知识点合计

XML概述 概念 XML&#xff08;Extensible Markup Language&#xff09;&#xff1a;可扩展标记语言 可扩展&#xff1a;标签都是自定义的。 发展历程 HTML和XML都是W3C&#xff08;万维网联盟&#xff09;制定的标准&#xff0c;最开始HTML的语法过于松散&#xff0c;于是W…

企业要满足什么条件才能实施CRM系统?

CRM的作用相信大家也所有了解&#xff0c;但并不是所有的企业都适合实施CRM。或者说&#xff0c;大部分企业实施CRM并不会100%的成功。那么&#xff0c;企业实施CRM的条件是什么&#xff1f;下面我们就来说一说。 1、业务规模 如果您的客户数量较少&#xff0c;没有复杂的客户…

二分查找——34. 在排序数组中查找元素的第一个和最后一个位置

文章目录 1. 题目2. 算法原理2.1 暴力解法2.2 二分查找左端点查找右端点查找 3. 代码实现4. 二分模板 1. 题目 题目链接&#xff1a;34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣&#xff08;LeetCode&#xff09; 给你一个按照非递减顺序排列的整数数组 nums&#…

苹果手机数据迁移,简单方法送给大家!

当我们准备更换新的苹果手机时&#xff0c;最令人头疼的问题就是如何将旧手机的数据迁移到新手机上。无论是什么手机&#xff0c;数据迁移确实是一个比较繁琐的过程。 但是&#xff0c;只要我们掌握了正确的方法&#xff0c;那么这个过程就会变得简单许多。苹果手机数据迁移的…

护眼灯亮度多少合适?亮度适合学生的护眼台灯推荐

护眼灯亮度满足国AA级标准就好了。可以肯定的是&#xff0c;护眼灯一般可以达到护眼的效果。 看书和写字时&#xff0c;光线应适度&#xff0c;不宜过强或过暗&#xff0c;护眼灯光线较柔和&#xff0c;通常并不刺眼&#xff0c;眼球容易适应&#xff0c;可以防止光线过强或过…

数据质量校验

1.事实表包含昨日数据 2.昨日同比趋势分析 圆通业务量较为平稳 &#xff0c;每日数据量和昨日比差距不足20%&#xff0c;会做数据量的昨日环比差距分析