hdwiki做网站/小红书kol推广
反汇编分析C语言
空函数反汇编
#include "stdafx.h"//空函数
void function(){}int main(int argc, char* argv[])
{//调用空函数function();return 0;
}
我们通过反汇编来分析这段空函数
函数外部
12: function();
00401048 call @ILT+5(function) (0040100a)
13: return 0;
0040104D xor eax,eax
14: }
0040104F pop edi
00401050 pop esi
00401051 pop ebx
00401052 add esp,40h
00401055 cmp ebp,esp
00401057 call __chkesp (004010e0)
0040105C mov esp,ebp
0040105E pop ebp
0040105F ret
函数内部
6: void function(){
00401010 push ebp
00401011 mov ebp,esp
00401013 sub esp,40h
00401016 push ebx
00401017 push esi
00401018 push edi
00401019 lea edi,[ebp-40h]
0040101C mov ecx,10h
00401021 mov eax,0CCCCCCCCh
00401026 rep stos dword ptr [edi]
7:
8: }
00401028 pop edi
00401029 pop esi
0040102A pop ebx
0040102B mov esp,ebp
0040102D pop ebp
0040102E ret
分析函数
函数调用
00401048 call @ILT+5(function) (0040100a)
先就是通过call来调用我们的function函数
函数内部
接着进到函数的内部
有了之前画堆栈图的经验,我们不难看出,尽管我们的函数是个空函数,但其汇编代码依然完成了以下流程:
提升堆栈
保护现场
初始化提升的堆栈
恢复现场
返回
提升堆栈
00401010 push ebp
00401011 mov ebp,esp
00401013 sub esp,40h
保护现场
00401016 push ebx
00401017 push esi
00401018 push edi
PS:前面的push ebp也是保护现场
初始化提升的堆栈
00401019 lea edi,[ebp-40h]
0040101C mov ecx,10h
00401021 mov eax,0CCCCCCCCh
00401026 rep stos dword ptr [edi]
恢复现场
00401028 pop edi
00401029 pop esi
0040102A pop ebx
0040102B mov esp,ebp
0040102D pop ebp
PS:这里的mov esp,ebp就是降低堆栈,与前面的提升堆栈相对应,所以也属于恢复现场的一部分
返回
0040102E ret
函数返回后
函数返回后不出意料地返回到了调用CALL地下一行语句,我们接着看
0040104D xor eax,eax
这里是将eax清零,注意到我们的语句为return 0 这里就是将eax作为返回值来传递
一般来说eax都是作为函数的返回值,但不绝对,有的函数返回值是存在内存里或其它情况,要具体情况具体分析
接着看下面的代码:
0040104F pop edi
00401050 pop esi
00401051 pop ebx
很明显,这里是在还原现场,别忘了我们的主程序main本身也是个函数,这是在还原调用main前保护的现场
接着往下走
00401052 add esp,40h
00401055 cmp ebp,esp
00401057 call __chkesp (004010e0)
这里首先是将esp减少了40h,然后比较ebp和esp,最后再调用一个chkesp函数
从名称就不难看出chkesp = check esp ,检查esp,这个函数就是用来检查堆栈是否平衡的
继续
0040105C mov esp,ebp
0040105E pop ebp
依旧是恢复现场
最后就是返回
0040105F ret
总结空函数分析
我们可以看到,即便一个空函数什么都没有做,但调用一个空函数所产生的汇编代码却不少
保护现场、恢复现场以及堆栈平衡的检查等等都没少,可谓麻雀虽小五脏俱全
简单加法函数反汇编
有了前面分析空函数的经验,我们再来分析分析一个简单的加法函数
#include "stdafx.h"
int Plus(int x,int y){return x+y;
}int main(int argc, char* argv[])
{//调用加法函数Plus(1,2);return 0;
}
函数外部
16: Plus(1,2);
004010A8 push 2
004010AA push 1
004010AC call @ILT+0(Plus) (00401005)
004010B1 add esp,8
17: return 0;
004010B4 xor eax,eax
18: }
004010B6 pop edi
004010B7 pop esi
004010B8 pop ebx
004010B9 add esp,40h
004010BC cmp ebp,esp
004010BE call __chkesp (004010e0)
004010C3 mov esp,ebp
004010C5 pop ebp
004010C6 ret
函数内部
10: int Plus(int x,int y){
00401060 push ebp
00401061 mov ebp,esp
00401063 sub esp,40h
00401066 push ebx
00401067 push esi
00401068 push edi
00401069 lea edi,[ebp-40h]
0040106C mov ecx,10h
00401071 mov eax,0CCCCCCCCh
00401076 rep stos dword ptr [edi]
11: return x+y;
00401078 mov eax,dword ptr [ebp+8]
0040107B add eax,dword ptr [ebp+0Ch]
12: }
0040107E pop edi
0040107F pop esi
00401080 pop ebx
00401081 mov esp,ebp
00401083 pop ebp
00401084 ret
分析函数
函数调用
004010A8 push 2
004010AA push 1
004010AC call @ILT+0(Plus) (00401005)
结合前面的空函数分析,我们可以明显发现这里的函数调用环节,多了两个push
就是将函数所需的参数压入堆栈,这里的参数为 2 和 1,注意压入的顺序是反着的(由调用协定决定,下篇笔记会详细说明)
函数内部
提升堆栈保护现场初始化
提升堆栈、保护现场、初始化部分和空函数如出一辙,这里就不再赘述
00401060 push ebp
00401061 mov ebp,esp
00401063 sub esp,40h
00401066 push ebx
00401067 push esi
00401068 push edi
00401069 lea edi,[ebp-40h]
0040106C mov ecx,10h
00401071 mov eax,0CCCCCCCCh
00401076 rep stos dword ptr [edi]
实际执行
00401078 mov eax,dword ptr [ebp+8]
0040107B add eax,dword ptr [ebp+0Ch]
这里的[ebp+8]就是我们前面压入的参数1,[ebp+c]就是前面压入的参数2
于是这两条语句其实就是
00401078 mov eax,1
0040107B add eax,2
将1+2的结果保存到eax中(此时eax又作为函数返回值的载体)
恢复现场和返回
接下来的内容就和空函数一样了,恢复现场和返回,也不再赘述
0040107E pop edi
0040107F pop esi
00401080 pop ebx
00401081 mov esp,ebp
00401083 pop ebp
00401084 ret
函数返回后
004010B1 add esp,8
17: return 0;
004010B4 xor eax,eax
18: }
004010B6 pop edi
004010B7 pop esi
004010B8 pop ebx
004010B9 add esp,40h
004010BC cmp ebp,esp
004010BE call __chkesp (004010e0)
004010C3 mov esp,ebp
004010C5 pop ebp
004010C6 ret
函数返回后我们会发现与先前的空函数相比多了这一行代码:
004010B1 add esp,8
这里是对应我们前面压入的两个参数1和2,压入参数后esp减少了8,这里我们函数调用结束后,就不再需要之前压入的两个参数了,于是将esp恢复到压入参数前,这其实也算在恢复现场里,用来平衡堆栈
我们可以发现,这条语句是在我们call调用完毕返回后执行的平衡堆栈操作,所以这种操作也被称为堆栈外平衡
与之相对就是堆栈内平衡:即在call里面就把堆栈平衡好了
相关文章:
![](https://img-blog.csdnimg.cn/52f9ccdd47744165b7124a4e8ce3b0f1.png)
Windows逆向安全(一)之基础知识(二)
反汇编分析C语言 空函数反汇编 #include "stdafx.h"//空函数 void function(){}int main(int argc, char* argv[]) {//调用空函数function();return 0; }我们通过反汇编来分析这段空函数 函数外部 12: function(); 00401048 call ILT5(func…...
![](https://img-blog.csdnimg.cn/7bad75e62e8e447f898d7720037c5a48.png)
Python 基础教程【2】:条件语句和循环语句
本文已收录于专栏🌻《Python 基础》文章目录1、流程控制语句1.1 顺序语句1.2 条件语句1.2.1 if语句注意事项1.2.2 三元运算符1.2.3 自动类型转换1.3 循环语句1.3.1 while 循环1.3.2 for-in 循环1.3.3 for...else 循环1.3.4 break 和 continue 的区别2、实践——猜数…...
![](https://www.ngui.cc/images/no-images.jpg)
【React避坑指南】useEffect 依赖引用类型
前言 如果你是一个入行不久的前端开发,面试中多半会遇到一个问题: 你认为使用React要注意些什么? 这个问题意在考察你对React的使用深度,因为沉浸式地写过一个项目就会发现,不同于一些替你做决定的框架,“…...
![](https://img-blog.csdnimg.cn/img_convert/eed4219f4cf28996fd6ad645d267e9d8.png)
Android binder通信实现进程间通信
一.binder通信原理Binder 是 Android 系统中用于跨进程通信的一种机制,它允许一个进程中的组件与另一个进程中的组件进行通信,从而实现进程间通信 (IPC)。Binder 机制是基于 Linux 内核提供的进程间通信机制 (IPC) 实现的。在 Binder 机制中,…...
![](https://img-blog.csdnimg.cn/9d232644271749c1b45f57c98445f4da.png)
2023年BeijngCrypt勒索病毒家族最新变种之.halo勒索病毒
目录 前言:简介 一、什么是.halo勒索病毒? 二、.halo勒索病毒是如何传播感染的? 三、感染.halo后缀勒索病毒建议立即做以下几件事情 四、中了.halo后缀的勒索病毒文件怎么恢复? 五、加密数据恢复情况 六、系统安全防护措施建…...
![](https://img-blog.csdnimg.cn/5d914fd07e434287821889ac51ee9156.png)
【LeetCode】BM1 反转链表、NC21 链表内指定区间反转
作者:小卢 专栏:《Leetcode》 喜欢的话:世间因为少年的挺身而出,而更加瑰丽。 ——《人民日报》 BM1 反转链表 描述: 给定一个单链表的头结点pHead(该头节点是有值的,…...
![](https://www.ngui.cc/images/no-images.jpg)
拼多多24届暑期实习真题
1. 题目描述: 多多开了一家自助餐厅,为了更好地管理库存,多多君每天需要对之前的课流量数据进行分析,并根据客流量的平均数和中位数来制定合理的备货策略。 2. 输入输出描述: 输入描述: 输入共两行&#x…...
![](https://img-blog.csdnimg.cn/b1657925fb8349d5b1b8abfb15422364.png)
JS高级知识总结
文章目录1. this指向问题2. 对象进阶2.1 对象的定义和使用2.2 对象访问器2.2.1 Getter2.2.2 Setter2.3 对象构造器2.4 对象原型2.4.1 prototype属性2.4.2 \_\_proto\_\_ 属性2.4.3 constructor属性2.4.4 原型链2.5 Object对象2.5.1 管理对象2.5.2 保护对象3. 函数进阶3.1 函数的…...
![](https://img-blog.csdnimg.cn/81660c688d724bd49a180f50dac7f60d.png)
Jenkins+Docker+Maven+gitlab实现自动构建、远程发布
前言 一个项目完整的生命周期是从开发的coding阶段和coding阶段的质量测试,再到多次发布投入使用。目前大部分的测试阶段并不是从coding结束后开始的,而是和coding同步进行的。可能今天早上coding完成一个功能,下午就要投入测试。在这期间&a…...
![](https://img-blog.csdnimg.cn/8f37f97c990e402ca7f6414cbe55b51f.png)
centos7克隆虚拟机完成后的的一些配置介绍
系列文章目录 centos7配置静态网络常见问题归纳_张小鱼༒的博客-CSDN博客 文章目录 目录 系列文章目录 前言 一、配置Hadoop要下载的压缩包 1、下载对应版本的Hadoop压缩包 2、我们如何查看自己电脑的端口号 3、下载jdk对应的版本 二、虚拟机centos7克隆虚拟机完成后的一些基本…...
![](https://img-blog.csdnimg.cn/a7efd4050bfd47ee86154fee1d8305ee.png)
C语言/动态内存管理函数
C程序运行时,内存将被划分为三个区域,而动态开辟的内存区间位于堆区。 文章目录 前言 一、内存划分 二、malloc函数 三、calloc函数 四、realloc函数 五、free函数 总结 前言 在使用C语言编写程序时,使用动态内存是不可避免的&#x…...
![](https://img-blog.csdnimg.cn/931571665af143c8a82e55b0127ddc74.png#pic_center)
华为OD机试题,用 Java 解【任务调度】问题
华为Od必看系列 华为OD机试 全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典使用说明 参加华为od机试,一定要注意不要…...
![](https://www.ngui.cc/images/no-images.jpg)
河南农业大学2023春蓝桥杯赛前训练第一场
A 滑板上楼梯 贪心 要求最少次数,尽量多跳三阶的,不能连续跳三阶,三阶后面一定要跟着一个一阶,相当于直接跳四阶 每次跳四阶都是两步(3、1),如果 % 4 之后,正好剩下 3 ,…...
![](https://www.ngui.cc/images/no-images.jpg)
docker-dockerfile
1.常用保留字指令 FROM : 基础镜像MAINTAINER: 维护者姓名和邮箱RUN : Run ["可执行文件",参数1]; Run [shell命令]EXPOSE: 暴露出的端口号WORKDIR: 登录后的位置USER: 执行用户,默认是rootENV: 构建过程的环境变量ADD: 将宿主机的文件拷贝到…...
![](https://img-blog.csdnimg.cn/img_convert/56e05aa45cab48aa8cca2e31564a612f.jpeg)
【JavaEE】浅识进程
一、什么是进程1.1 操作系统学习进程之前首先要了解我们的操作系统(OS),我们的操作系统实际上也是一款软件,属于系统软件的范畴,操作系统早期采用命令提示框与用户交互,我们启动某个软件,打开某…...
![](https://img-blog.csdnimg.cn/ca157bfbc9454e04b1becec54fc15095.png)
Java_Spring:1. Spring 概述
目录 1 spring 是什么 2 Spring 的发展历程 3 spring 的优势 4 spring 的体系结构 1 spring 是什么 Spring 是分层的 Java SE/EE 应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control:反转控制)和 AOP(Aspec…...
![](https://img-blog.csdnimg.cn/40cb46b038dd44e0939840635149459c.png)
使用Maven实现第一个Servlet程序
目录 前言: Maven 什么是Maven 创建Maven项目 Mevan目录介绍 Servlet程序 引入Servlet依赖 创建目录结构 编写代码 打包程序 部署程序 验证程序 idea集成Tomcat 下载Tomcat插件 配置Tomcat的路径 Smart Tomcat工作原理 小结: 前言&#…...
![](https://img-blog.csdnimg.cn/53e8bd270e9d4903b6a974f91a6999a6.png)
【MySQL】MySQL的优化(一)
目录 查看SQL执行频率 定位低效率执行SQL 定位低效率执行SQL-慢查询日志 定位低效率执行SQL-show processlist 查看SQL执行频率 MySQL 客户端连接成功后,通过 show [session|global] status 命令可以查看服务器状态信息。通 过查看状态信息可以查看对当…...
![](https://img-blog.csdnimg.cn/d6a179cd494e4cde946403fc9d9b284a.png)
win kubernetes dashbord部署springboot服务
文章目录前言一、新建springboot工程二、制作镜像1.编写dockerfile2.使用阿里云镜像仓库3.使用dashbord部署服务总结前言 使用win版docker desktop安装的k8s,kubenetes dashbord。 一、新建springboot工程 就是简单一个接口。没什么说的 二、制作镜像 1.编写dock…...
![](https://img-blog.csdnimg.cn/f5dfaa6439604a5397b2fd493cc037ac.png)
Linux之进程终止
本节目录1.进程终止2.exit与_exit函数1.进程终止 进程终止时,操作系统做了什么? 释放进程中申请的相关内核数据结构和对应的数据和代码。本质就是释放系统资源。 进程终止的常见方式 a.代码跑完,结果正确 b.代码跑完,结果不正确…...
![](https://img-blog.csdnimg.cn/3ab2acb883ac4ae1a1df9d4b6f305817.png)
全网独家首发|极致版YOLOv7改进大提升(推荐)网络配置文件仅24层!更清晰更方便更快的改进YOLOv7网络模型
有不少小伙伴和我交流YOLO改进的时候,都说YOLOv7的网络配置文件长达104层,改起来很费力,数层数都要数很久,还很容易出错,而且基于YOLOv5代码架构,Debug起来也确实比较费时,所以博主对YOLOv7网络…...
![](https://img-blog.csdnimg.cn/e08c2cde795e41f7b9adef8a8156eaf8.png)
C++入门 谁都能看懂的类和对象
类 C语言结构体中只能定义变量. 在C中,结构体内不仅可以定义变量,也可以定义函数。 //c语言 typedef struct ListNode {int val;struct ListNode* next; }LTN; //c struct ListNode {int val;//c中可以直接用这个,不用加structListNode* next…...
![](https://img-blog.csdnimg.cn/e716edc0965e4494a8c67f940baa210b.png)
C++ STL:string类的模拟实现
目录 前置说明 一. 构造函数和析构函数的模拟实现 1.1 构造函数 1.2 析构函数 二. string类对象容量及成员相关的函数 2.1 获取字符串有效字符数、容量及_str成员变量获取相关函数 2.2 扩容及变长相关函数 2.3 字符串清空和判空函数 三. 运算符重载函数 3.1 赋值运算…...
![](https://img-blog.csdnimg.cn/324013a192744744a2b1902d84223369.png)
并发编程---线程池(六)
阻塞队列的应⽤——线程池一 线程池基本概念二 线程池三种常⽤创建⽅式2.1.newFixedThreadPool线程池:2.2.newSingleThreadExecutor线程池:2.3.newCachedThreadPool线程池:2.4. 线程池代码演示三 线程池创建的七个参数四 线程池底层原理理解&…...
![](https://www.ngui.cc/images/no-images.jpg)
【Java实战】不会还有人用if else进行参数校验吧
当请求参数很多,几乎每一个参数都需要后端去兜底校验时,你还在写if else去判断参数是否为空吗??要校验为空的参数三四个还好,要是十几个,业务逻辑还没开始就写二三十行代码开始堆山了嘛,教给大家…...
![](https://www.ngui.cc/images/no-images.jpg)
深度学习部署(十六): CUDA RunTime API _vector-add 使用cuda核函数实现向量加法
1. 知识点 nthreads的取值,不能大于block能取值的最大值。一般可以直接给512、256,性能就是比较不错的 (input_size block_size - 1) / block_size;是向上取整 对于一维数组时,采用只定义layout的x维度,若处理的是二维ÿ…...
![](https://www.ngui.cc/images/no-images.jpg)
堆结构的两个应用
堆排序 堆结构很大的一个用处,就是用于堆排序了,堆排序的时间复杂度是O(n∗log2n)O(n*log_2n)O(n∗log2n)量级的,在众多排序算法中所处的地位也是高手级别的了。 但很多人在使用堆排序的时候,首先认为我必须得有一个堆数据结构…...
![](https://www.ngui.cc/images/no-images.jpg)
Java中的 static
1 static 静态变量 1.1 静态变量的使用 static变量也称作静态变量,也叫做类变量 静态变量被所有的对象所共享,在内存中只有一个副本 当且仅当在类初次加载时会被初始化 静态变量属于类 通过类名就可以直接调用静态变量 也可以通过对象名.静态变量…...
![](https://img-blog.csdnimg.cn/img_convert/9b3993e303c7d53528e17086aae89a7f.png)
基于Vision Transformer的图像去雾算法研究与实现(附源码)
基于Vision Transformer的图像去雾算法研究与实现 0. 服务器性能简单监控 \LOG_USE_CPU_MEMORY\文件夹下的use_memory.py文件可以实时输出CPU使用率以及内存使用率,配合nvidia-smi监控GPU使用率 可以了解服务器性能是否足够;运行时在哪一步使用率突然…...
![](https://www.ngui.cc/images/no-images.jpg)
服务器相关常用的命令
cshell语法 https://www.doc88.com/p-4985161471426.html domainname命令 1)查看当前系统域名 domainname2)设置并查看当前系统域名 domainname example.com3)显示主机ip地址 domainname -Iwhich命令 which 系统命令在 PATH 变量指定的…...
![](/images/no-images.jpg)
专业做简历的网站/莆田百度快照优化
001. 两数之和 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可…...
![](/images/no-images.jpg)
怎么去推广一个app/windows优化大师自动下载
假如你写过很多程序,你可能偶尔会碰到要确定字符或字符窜串否包含在一段文字中,在这篇文章中,我将讨论使用CHARINDEX和PATINDEX函数来搜索文字列和字符串。我将告诉你这两个函数是如何运转的,解释他们的区别。同时提供一些例子&am…...
![](/images/no-images.jpg)
中英双语营销型网站/下载班级优化大师app
最近业务需要:将图片转为base64格式。 so~~~;百度n多资料最后写成,还是有一点小bug就是生成的图片不太清晰; 文章最后还有代码的下载地址 参考资料: 微信小程序文档-wx.canvasGetImageData UPNG.js下载地址 代码…...
![](https://images2017.cnblogs.com/blog/1223777/201710/1223777-20171012221551934-1313285903.png)
服务周到的做网站/长尾词和关键词的区别
项目地址:https://gitee.com/670578767/XueShengXinXiGuanLiXiTong/tree/master 目前已完成学生管理系统学生部分,目前整个系统还存在一些不稳定的小问题,现阶段正在做程序的测试和调整,会尽快将程序完善。 转载于:https://www.cnblogs.com/s…...
![](/images/no-images.jpg)
介绍学校网站怎么做/seo泛目录培训
Android UVC 同时打开多路摄像头 前言 硬件环境 效果图 注意问题 代码分析(摄像头的打开步骤) 1.找到摄像头设备 打开摄像头 项目地址 前言 做项目用到了多路摄像头,但是原生固件最多支持两路同时打开(cameraID 0和1)&…...
![](/images/no-images.jpg)
全国b2b网站大全/外链推广
package demo;import java.util.Random;/*** ** author Weirdo-world* * java 实现多线程程序* 1)继承Thread类* 2)实现Runnble接口** 通过多线程模拟售票窗口* 各售票窗口不能售出同一张票* 打印售出的票号*/ public class Demo5 {public static void main(Str…...