Windows逆向安全(一)之基础知识(八)
if else嵌套
这次来研究if else嵌套在汇编中的表现形式,本次以获取三个数中最大的数这个函数为例子,分析if else的汇编形式
求三个数中的最大值
首先贴上代码:
#include "stdafx.h"int result=0;
int getMax(int i,int j,int k){if(i>j){if(i>k){return i;}else{return k;}}else{if(j>k){return j;}else{return k;}}
}int main(int argc, char* argv[])
{result=getMax(1,2,3);printf("%d\n",result);result=getMax(1,3,2);printf("%d\n",result);result=getMax(2,1,3);printf("%d\n",result);result=getMax(2,3,1);printf("%d\n",result);result=getMax(3,1,2);printf("%d\n",result);result=getMax(3,2,1);printf("%d\n",result);return 0;
}
先验证执行的结果是正确的:

确认可以函数是可以取出三个数的最大值的,于是开始分析该函数
为方便观看,将多余的验证删去,直接改为
getMax(1,2,3);

汇编代码
然后我们观察汇编代码
函数外部
28: getMax(1,2,3);
0040D7C8 push 3
0040D7CA push 2
0040D7CC push 1
0040D7CE call @ILT+10(func) (0040100f)
0040D7D3 add esp,0Ch
依次压入参数,然后调用函数,最后再堆栈外平衡,重点在函数内部,进去看看
函数内部
7: int getMax(int i,int j,int k){
0040D760 push ebp
0040D761 mov ebp,esp
0040D763 sub esp,40h
0040D766 push ebx
0040D767 push esi
0040D768 push edi
0040D769 lea edi,[ebp-40h]
0040D76C mov ecx,10h
0040D771 mov eax,0CCCCCCCCh
0040D776 rep stos dword ptr [edi]
8: if(i>j){
0040D778 mov eax,dword ptr [ebp+8]
0040D77B cmp eax,dword ptr [ebp+0Ch]
0040D77E jle getMax+32h (0040d792)
9: if(i>k){
0040D780 mov ecx,dword ptr [ebp+8]
0040D783 cmp ecx,dword ptr [ebp+10h]
0040D786 jle getMax+2Dh (0040d78d)
10: return i;
0040D788 mov eax,dword ptr [ebp+8]
0040D78B jmp getMax+42h (0040d7a2)
11: }else{
12: return k;
0040D78D mov eax,dword ptr [ebp+10h]
0040D790 jmp getMax+42h (0040d7a2)
13: }
14:
15: }else{
16: if(j>k){
0040D792 mov edx,dword ptr [ebp+0Ch]
0040D795 cmp edx,dword ptr [ebp+10h]
0040D798 jle getMax+3Fh (0040d79f)
17: return j;
0040D79A mov eax,dword ptr [ebp+0Ch]
0040D79D jmp getMax+42h (0040d7a2)
18: }else{
19: return k;
0040D79F mov eax,dword ptr [ebp+10h]
20: }
21: }
22: }
0040D7A2 pop edi
0040D7A3 pop esi
0040D7A4 pop ebx
0040D7A5 mov esp,ebp
0040D7A7 pop ebp
0040D7A8 ret
函数内部有不少代码是用来保护现场 初始化堆栈 恢复现场的,这里将其过滤掉,看判断语句:
判断语句
8: if(i>j){
0040D778 mov eax,dword ptr [ebp+8]
0040D77B cmp eax,dword ptr [ebp+0Ch]
0040D77E jle getMax+32h (0040d792)
9: if(i>k){
0040D780 mov ecx,dword ptr [ebp+8]
0040D783 cmp ecx,dword ptr [ebp+10h]
0040D786 jle getMax+2Dh (0040d78d)
10: return i;
0040D788 mov eax,dword ptr [ebp+8]
0040D78B jmp getMax+42h (0040d7a2)
11: }else{
12: return k;
0040D78D mov eax,dword ptr [ebp+10h]
0040D790 jmp getMax+42h (0040d7a2)
13: }
14:
15: }else{
16: if(j>k){
0040D792 mov edx,dword ptr [ebp+0Ch]
0040D795 cmp edx,dword ptr [ebp+10h]
0040D798 jle getMax+3Fh (0040d79f)
17: return j;
0040D79A mov eax,dword ptr [ebp+0Ch]
0040D79D jmp getMax+42h (0040d7a2)
18: }else{
19: return k;
0040D79F mov eax,dword ptr [ebp+10h]
20: }
21: }
22: }
参数分析

i>j
先来看看i>j的反汇编语句
0040D778 mov eax,dword ptr [ebp+8]
0040D77B cmp eax,dword ptr [ebp+0Ch]
0040D77E jle getMax+32h (0040d792)
比较第一个参数和第二个参数
jle:jump less equal,小于等于则跳转(有符号数)
跳转地址:0040d792
16: if(j>k){
0040D792 mov edx,dword ptr [ebp+0Ch]
i>k
9: if(i>k){
0040D780 mov ecx,dword ptr [ebp+8]
0040D783 cmp ecx,dword ptr [ebp+10h]
0040D786 jle getMax+2Dh (0040d78d)
比较第一个和第三个参数
jle:jump less equal,小于等于则跳转(有符号数)
跳转地址:0040d78d
11: }else{
12: return k;
0040D78D mov eax,dword ptr [ebp+10h]
0040D790 jmp getMax+42h (0040d7a2)
可以分析出,如果第一个参数小于等于第三个参数则跳转到0040D78D,并将第三个参数赋值给eax作为返回值,这条线路为(k>i>j)
否则执行返回指令,将第一个参数赋给eax作为返回值,这条线路为(i>j且i>k)
10: return i;
0040D788 mov eax,dword ptr [ebp+8]
0040D78B jmp getMax+42h (0040d7a2)
j>k
16: if(j>k){
0040D792 mov edx,dword ptr [ebp+0Ch]
0040D795 cmp edx,dword ptr [ebp+10h]
0040D798 jle getMax+3Fh (0040d79f)
比较第二个和第三个参数
jle:jump less equal,小于等于则跳转(有符号数)
跳转地址:0040d79f
18: }else{
19: return k;
0040D79F mov eax,dword ptr [ebp+10h]
可以分析出,如果第二个参数小于等于第三个参数则跳转到0040D79F,并将第三个参数赋值给eax作为返回值,这条线路为(i<=j<=k)
否则返回执行返回命令,将第二个参数赋值给eax作为返回值,这条线路为(i<=j且k<=j)
17: return j;
0040D79A mov eax,dword ptr [ebp+0Ch]
0040D79D jmp getMax+42h (0040d7a2)
总结
不难发现,三个数求最大值,只需两两比较就可以得出结果
分析if else的关键在于观察涉及的参数和jcc语句
此案例中就是直接采取了cmp 外加 jle来进行分支的选择和跳转
因为不符合条件的才要跳转走,所以在条件比较中,是大于的比较如i>j,所使用的汇编为jle 小于等于的比较
不按套路比较
此次案例并不能代表所有情况,实际分析要具体看情况来采取分析,有的程序可能就是不按套路出牌,先看看按套路出牌的程序,然后我们自己来模拟个不按套路的
正常套路
拿两个数的比较为例
#include "stdafx.h"
int getMax2(int i,int j){if(i>j){return i;}else{return j;}
}
int main(int argc, char* argv[])
{getMax2(1,2);return 0;
}
先看一般的汇编代码:
9: if(i>j){
0040D778 mov eax,dword ptr [ebp+8]
0040D77B cmp eax,dword ptr [ebp+0Ch]
0040D77E jle getMax2+25h (0040d785)
10: return i;
0040D780 mov eax,dword ptr [ebp+8]
0040D783 jmp getMax2+28h (0040d788)
11: }else{
12: return j;
0040D785 mov eax,dword ptr [ebp+0Ch]
13: }
14: }
依旧是采用cmp 和 jle来进行判断,和套路一致
不按套路
完整代码
#include "stdafx.h"
int __declspec(naked) myGetMax(int i,int j){__asm{ //保留调用前堆栈push ebp//提升堆栈mov ebp,espsub esp,0x40//保护现场push ebxpush esipush edi//初始化提升的堆栈,填充缓冲区mov eax,0xCCCCCCCCmov ecx,0x10lea edi,dword ptr ds:[ebp-0x40]rep stosd//函数核心功能//取出参数mov eax,dword ptr ds:[ebp+8]//比较参数cmp eax,[ebp+0xC]jge _retmov eax,[ebp+0xC]
_ret://恢复现场pop edipop esipop ebx//降低堆栈mov esp,ebppop ebp //返回ret }
}
int main(int argc, char* argv[])
{int result=myGetMax(1,2);printf("%d\n",result);result=myGetMax(4,3);printf("%d\n",result);return 0;
}
功能代码分析
这里截取出我们自己实现比较的那段代码
//函数核心功能//取出参数mov eax,dword ptr ds:[ebp+8]//比较参数cmp eax,[ebp+0xC]jge _retmov eax,[ebp+0xC]
_ret://恢复现场pop edipop esipop ebx//降低堆栈mov esp,ebppop ebp //返回ret
首先我们这里将第一个参数赋值给eax
然后比较eax和第二个参数,也就是比较第一个参数和第二个参数
这边使用的就不是jle而是jge了
jge:jump greater equal,即大于等于则跳转
前面已经将第一个参数赋值给了eax,而eax又是作为返回值来传递的
当第一个参数大于等于第二个参数时,就可以直接返回了
如果不是则不跳转,执行下面的将第二个参数赋值给eax作为返回值
这里注意到我在汇编中自己定义了一个段:_ret,来作为跳转的地址来使用
最后测试一下结果:

可以正确得到两个数中的最大值
相关文章:
Windows逆向安全(一)之基础知识(八)
if else嵌套 这次来研究if else嵌套在汇编中的表现形式,本次以获取三个数中最大的数这个函数为例子,分析if else的汇编形式 求三个数中的最大值 首先贴上代码: #include "stdafx.h"int result0; int getMax(int i,int j,int k)…...
PyCharm+PyQt5+pyinstaller打包labelImg.exe
0 开头 labelImg是一款标注软件,作为一个开源项目,它的源码可以在github上找到。官方仓库地址为: https://github.com/heartexlabs/labelImg 小白安装时的最新版本编译出来的界面长这样: 之前在小白的博客里,也教过…...
JavaScript里实现继承的几种方式
JavaScript 中的继承可以通过以下几种方式来实现: 1、原型链继承:通过将子类的原型对象指向父类的实例来实现继承。这种方式的优点是实现简单,缺点是父类的私有属性和方法子类是不能访问的。 function Parent() {this.name parent;this.ag…...
前端:运用HTML+CSS+JavaScript实现迷宫游戏
最近感到挺无聊的,于是想到了大学期间关于栈的应用知识,于是就写了这篇博客! 运用HTML+CSS+JavaScript实现迷宫游戏 1. 运行结果2. 实现思路3. 参考代码1. 运行结果 前端:做个迷宫玩玩,不会迷路吧! 2. 实现思路 如果有一个迷宫,有入口,也有出口,那么怎样找到从入口到出…...
NoSQL数据库简介
NoSQL代表“不仅是SQL”,指的是一种数据库管理系统,旨在处理大量非结构化和半结构化数据。与使用具有预定义架构的表格格式的传统SQL数据库不同,NoSQL数据库是无模式的,并且允许灵活和动态的数据结构。 NoSQL数据库是必需的&…...
面试马铭泽
为什么报考这个岗位 首先,我对军人从小有崇敬之情,梦想着穿着庄严的军装,更对祖国有强烈的热爱之心。我的大舅是一名现役军人,老舅也曾服过兵役,从他们的谈吐以及教育中,让我对部队一直充满向往之情&#…...
查看AWS S3的目录
要查看AWS S3存储桶(Bucket)的目录,您可以通过AWS管理控制台或AWS CLI(命令行界面)来实现。 在AWS管理控制台中查看: 登录AWS管理控制台。选择S3服务。在S3存储桶列表中选择要查看的存储桶。在对象列表中…...
分布式系统概念和设计-操作系统中的支持和设计
分布式系统概念和设计 操作系统支持 中间件和底层操作系统的关系,操作系统如何满足中间件需求。 中间件需求:访问物理资源的效率和健壮性,多种资源管理策略的灵活性。 任何一个操作系统的目标都是提供一个在物理层(处理器,内存&a…...
【redis】bitmap、hyperloglog、GEO案例
【redis】bitmap、hyperloglog、GEO案例 文章目录 【redis】bitmap、hyperloglog、GEO案例前言一、面试题二、统计的类型聚合统计排序统计问题:思路 二值统计 0和1基数统计 三、hyperloglog1、名词理解UV 独立访客PV 页面浏览量DAU 日活跃用户MAU 月活跃度 2、看需求…...
第二章:集合与区间
1.集合 1.内容概述 1.了解集合的意义2.了解常见集合符号的含义3.云用常见的集合符号来表示集合之间的关系、元素与集合之间的关系2.基本概念 1.集合:把一些确定的对象看成一个整体就形成了一个集合。集合一般使用大写字母A、B、C…来表示2.元素:集合中每一个对象叫做这个集合…...
Mysql8.0版本安装
一,使用yum方式安装 1,配置mysql安装源: sudo rpm -Uvh https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm2,安装mysql8.0: sudo yum --enablerepo=mysql80-community inst...
开放式耳机真的比封闭式强很多吗?推荐几款主流的开放式耳机
开放式耳机,顾名思义,就是通过骨头振动来传导声音的耳机。相比于传统耳机,它的声音传输更加开放,不会对耳膜造成压迫感,也不会对耳膜旁的内毛细胞造成损害。因此开放式耳机既是运动蓝牙耳机,又是音乐蓝牙…...
Doris(7):数据导入(Load)之Routine Load
例行导入功能为用户提供了义中自动从指定数据源进行数据导入的功能 1 适用场景 当前仅支持kafka系统进行例行导入。 2 使用限制 支持无认证的 Kafka 访问,以及通过 SSL 方式认证的 Kafka 集群。支持的消息格式为 csv 文本格式。每一个 message 为一行,…...
linux 安装php8.1 ZipArchive和libzip最新版扩展安装
1、概述 安装前咱们先看下我本地环境 [rootelk php8]# cat /etc/redhat-release Red Hat Enterprise Linux Server release 7.9 (Maipo) [rootelk php8]# [rootelk php8]# ./bin/php -v PHP 8.1.18 (cli) (built: Apr 17 2023 13:15:17) (NTS) Copyright (c) The PHP Group Z…...
大数据 | 实验一:大数据系统基本实验 | 熟悉常用的HBase操作
文章目录 📚HBase安装🐇安装HBase🐇伪分布式模式配置🐇测试运行HBase🐇HBase java API编程环境配置 📚实验目的📚实验平台📚实验内容🐇HBase Shell 编程命令实现以下指定…...
Linux command(split)
原理 在split.c中,首先处理传递给split命令的参数,包括需要拆分的文件、拆分大小/行数等选项。然后,通过调用open()函数打开需要拆分的文件,并获取文件信息。接着根据选项计算每个拆分文件的大小/行数,并根据需要创建输…...
开放式耳机好用吗,盘点几款口碑不错的开放式耳机
开放式耳机作为一种全新的耳机形态,已经成为了当前市场上非常火爆的一款产品。由于无需入耳佩戴,可以很好的避免了耳膜受到损伤,而且也能够让我们在佩戴眼镜时也能够正常使用。加上开放式耳机的音质和舒适度都要优于其他类型的耳机…...
法规标准-ISO 16787标准解读
ISO 16787是做什么的? ISO 16787全称为智能运输系统-辅助泊车系统(APS)-性能要求和测试程序,其中主要描述了对APS系统的功能要求及测试规范 APS类型 根据目标停车位类型将APS系统分为两类: 1)APS类型I&a…...
脑力劳动-英文单词
标题 前言必学场景词汇及用法会议简报电话出差市场调研广告与媒介电脑情境常用单词会议简报电话市场调研广告与媒介电脑前言 加油 必学场景词汇及用法 会议 1meeting [ˈmitɪŋ] n.会议hold / have / call off a meeting举办/取消会议be in a meeting在开会The meeting w…...
机器学习中的三个重要环节:训练、验证、测试
本文重点 模型训练、验证和测试是机器学习中的三个重要环节。这三个环节之间存在着紧密的关系,它们相互作用,共同构建出一个完整的机器学习模型。在本文中,我们将详细介绍模型训练、验证和测试之间的关系。 模型训练、验证和测试之间的关系 模型训练是机器学习中最基本的…...
mkcert 命令文档 - 本地 HTTPS 开发证书生成工具详解
1. 命令简介mkcert 是一个用 Go 语言编写的、零配置的本地开发用自签名证书生成工具。它能够自动创建并安装本地证书颁发机构(CA)到系统的信任存储中,并生成受本地信任的开发证书,大幅简化 HTTPS 本地开发环境的搭建过程ÿ…...
Phi-3-mini-4k-instruct-gguf开发者案例:为微信小程序后端提供的轻量API服务
Phi-3-mini-4k-instruct-gguf开发者案例:为微信小程序后端提供的轻量API服务 1. 项目背景与需求 在开发微信小程序时,我们经常需要为前端提供智能文本处理能力,比如自动生成商品描述、智能客服回复、内容摘要等。传统方案要么需要调用第三方…...
系统架构设计师常见高频考点总结之数据库
1. 局部数据库缓存1.1. 如何避免单点故障?(高可用设计)只要题目提到“避免单点故障”或“高可靠性”,标准答案只有一套组合拳:冗余(Redundancy):一台不够就两台。热备(Ho…...
OLED多级菜单移植与设计实战
1. 低成本嵌入式项目的OLED多级菜单设计 第一次接触OLED多级菜单是在一个智能温控器的DIY项目里。当时为了给设备做个简单的交互界面,我试过各种方案,最后发现0.96寸的OLED屏配上多级菜单是最经济实惠的选择。这种组合特别适合预算有限但又需要基本人机交…...
YOLOv8鹰眼目标检测问题解决:常见部署错误与使用技巧汇总
YOLOv8鹰眼目标检测问题解决:常见部署错误与使用技巧汇总 1. 引言:为什么选择YOLOv8鹰眼目标检测 YOLOv8作为当前计算机视觉领域最先进的目标检测模型之一,以其卓越的实时性和准确性赢得了广泛认可。鹰眼目标检测镜像基于Ultralytics官方YO…...
PCIe金手指设计避坑指南:从硬件选型到PCB布局的5个关键细节
PCIe金手指设计避坑指南:从硬件选型到PCB布局的5个关键细节 在高速数字系统设计中,PCIe金手指接口的可靠性直接决定了扩展卡的识别成功率和数据传输稳定性。许多工程师在完成原理图设计和PCB布局后,常会遇到设备频繁识别失败、链路训练不通过…...
无人值守智能图书借阅系统 Java 后端开发实战
在无人值守智能图书借阅系统的Java后端开发实战中,需围绕系统架构设计、核心功能实现、关键技术选型及部署优化等核心环节展开,以下为具体开发方案:一、系统架构设计分层架构体系:采用经典的四层架构设计,包括表现层、…...
Kandinsky-5.0-I2V-Lite-5s效果展示:建筑图纸→镜头平移漫游视频生成案例
Kandinsky-5.0-I2V-Lite-5s效果展示:建筑图纸→镜头平移漫游视频生成案例 1. 惊艳效果预览 Kandinsky-5.0-I2V-Lite-5s带来的建筑漫游视频生成效果令人印象深刻。想象一下,你有一张静态的建筑设计图纸,通过这个模型,只需简单描述…...
teler IDS v3前瞻:eBPF技术与teler-waf集成带来的革命性变革
teler IDS v3前瞻:eBPF技术与teler-waf集成带来的革命性变革 【免费下载链接】teler Real-time HTTP Intrusion Detection 项目地址: https://gitcode.com/gh_mirrors/te/teler teler IDS作为一款实时HTTP入侵检测系统,在网络安全领域已经建立了坚…...
LANDrop局域网文件传输:3分钟快速上手跨平台文件共享神器
LANDrop局域网文件传输:3分钟快速上手跨平台文件共享神器 【免费下载链接】LANDrop Drop any files to any devices on your LAN. 项目地址: https://gitcode.com/gh_mirrors/la/LANDrop 还在为不同设备间传输文件而烦恼吗?🤔 LANDrop…...
