实验环境:WIN7虚拟机
软件:VC6

首先在VC6里面写一个空函数Fun();

F7编译运行一下,没有出错,接着在函数处使用F9下断点,使程序运行到Fun函数时停下。

接着F5开始运行这个程序

程序停在了Fun函数处,反汇编进去进行逆向分析


可以看到程序停在Fun函数的入口处,这里的call就是Fun函数的入口,F11跟进去进行分析。

原始堆栈图是这样的。

0040D408 call @ILT+5(_Fun) (0040100a)

F11,跟进这个call进行分析,进入函数之后编译器会将跳出函数之后下一个要执行的地址压入堆栈,即将0040D40D压入堆栈,同时esp-4,esp变成0012FEF8,这时的堆栈是这样的:

跟进来之后是一个jmp,F11直接跳转。

现在进到函数里面了

00401010 push ebp

首先将ebp压栈,就是将[ebp]压入堆栈,即将0012FF48压入堆栈,然后esp的位置向上提升一个变为0012FEF4。

查看检查寄存器进行验证:

00401011 mov ebp,esp

将esp的值赋给ebp,也就是将0012FEF4赋给ebp,这时的堆栈图是这样的

查看寄存器验证,这里可以看到esp和ebp的值相等,说明上面那个堆栈图没有问题

00401013 sub esp,40h

将esp减去40h,也就是将esp的位置提升到0012FEB4位置,这一步的作用是提升堆栈,这时的堆栈图是这样的

查看寄存器进行验证,看到esp的值为0012FEB4

00401016 push ebx

接着将ebx压栈,查看栈顶可以看到ebx被压入堆栈,同时esp的位置向上提升。


此时的堆栈是这样的:

00401017 push esi

将esi的值压入堆栈,此时的堆栈是这样的


查看寄存器进行验证:

00401018 push edi

接着将edi的值压入堆栈,此时的堆栈是这样的


查看寄存器验证:

00401019 lea edi,[ebp-40h]

将[ebp-40h]的地址存入edi中,也就是将0012FEB4存入edi。

查看寄存器验证,可以看到0012FEB4被存入edi中

0040101C mov ecx,10h

将10h存入ecx中,也就是将00000010存入ecx,查看寄存器验证:

00401021 mov eax,0CCCCCCCCh

将CCCCCCCC存入eax中,查看寄存器验证:

00401026 rep stos dword ptr [edi]

将eax的中的值存储到[edi]对应地址的内存中,并重复ecx次,也就是将CCCCCCCC存入地址0012FEB4对应的内存中,并重复10h次,rep每执行一次,[edi]会相应的加4(向下填充数值),ecx会相应的减4(减少执行次数)。

此时的堆栈是这样的:


查看寄存器验证一下,发现从0012FEF4到0012FEB4全部被填充为CCCCCCCC。

00401028 pop edi

将edi出栈,也就是将esp当前对应的值0012FF48赋给edi,同时esp加4变成0012FEAC,此时的堆栈


查看寄存器验证:

00401029 pop esi

将esi出栈,也就是将esp当前对应的值00000000赋给edi,同时esp加4变成0012FEB0,此时的堆栈


查看寄存器验证:

0040102A pop ebx

将ebx出栈,也就是将esp当前对应的值7FFDD000赋给ebx,同时esp加4变成0012FEB4,此时的堆栈


查看寄存器验证一下:

0040102B mov esp,ebp

将ebp的值赋给esp,这里的作用相当于降低堆栈,此时的堆栈是这样的


查看寄存器进行验证,esp的值和ebp的值相等

0040102D pop ebp

将ebp出栈,也就是将esp当前对应的值0012FF48赋给ebx,这时ebx又回到了一开始所在的位置,同时esp加4变成0012FEF8,此时的堆栈是这样的


查看寄存器验证一下

0040102E C3 ret

相当于pop eip,即将当前esp对应的值放入eip中,也就是将0040D40D放入eip中,同时ESP+4,esp变为0012FEFC,此时的堆栈是这样的


查看寄存器验证一下,至此堆栈恢复平衡,Fun函数执行完毕

逆向学习周记-C语言空函数的更多相关文章

  1. 空函数有参函数调用参数的注意事项Swift 1.1语言

    空函数有参函数调用参数的注意事项Swift 1.1语言 7.2.3  空函数 空函数有参函数调用参数的注意事项Swift 1.1语言空函数是函数中最简单的形式.在空函数中,函数只有一个空壳,里面是没有 ...

  2. IOS学习笔记07---C语言函数-printf函数

    IOS学习笔记07---C语言函数-printf函数 0 7.C语言5-printf函数 ------------------------- ----------------------------- ...

  3. IOS学习笔记06---C语言函数

    IOS学习笔记06---C语言函数 --------------------------------------------  qq交流群:创梦技术交流群:251572072              ...

  4. c语言学习笔记(8)——函数

    学完c语言的函数可以理解面向过程的语言 函数是c语言的重点 一.为什么需要函数? 1.避免了重复性操作 2.有利于程序的模块化(每一个功能可以用不同函数去实现) 二.什么叫做函数? 逻辑上:能够完成特 ...

  5. iOS学习之C语言函数

    一.函数的定义 返回值类型 函数名(参数类型 参数名, ...) { 功能语句; return 返回值; } 按照返回值和参数划分: 第一种: 无返回值 无参 void sayHello() { pr ...

  6. 【学习笔记】【C语言】函数

    一. 什么是函数 任何一个C语言程序都是由一个或者多个程序段(小程序)构成的,每个程序段都有自己的功能,我们一般称这些程序段为“函数”.所以,你可以说C语言程序是由函数构成的. 比如你用C语言编写了一 ...

  7. GO学习-(12) Go语言基础之函数

    Go语言基础之函数 函数是组织好的.可重复使用的.用于执行指定任务的代码块.本文介绍了Go语言中函数的相关内容. 函数 Go语言中支持函数.匿名函数和闭包,并且函数在Go语言中属于"一等公民 ...

  8. [java学习笔记]java语言核心----面向对象之构造函数

    1.构造函数概念 特点: 函数名与类名相同 不用定义返回值类型 没有具体的返回值 作用:                给对象进行初始化 注意: 默认构造函数 多个构造函数是以重载出现的 一个类中如果 ...

  9. 【C语言】函数和自定义函数

    函数,我之前也提到过一点点内容.其实函数是很好理解的,但是写起来又十分麻烦. 一.     函数引入 我们知道,C源程序是由函数组成的.请看下面的简单函数例子 #include <stdio.h ...

随机推荐

  1. Flume理论研究与实验

    一.理论研究 1.1 总览 Flume是一个分布式的可靠的日志收集系统,主要是用于从各种数据源收集.聚合并移动大批量的日志数据到存储系统:它本身具有许多故障转移和恢复机制,具有强大的容错能力:它使用下 ...

  2. v-if和v-show 的区别

    区别 1.手段:v-if是通过控制dom节点的存在与否来控制元素的显隐:v-show是通过设置DOM元素的display样式,block为显示,none为隐藏: 2.编译过程:v-if切换有一个局部编 ...

  3. 深入浅出分析 PriorityQueue

    一.摘要 在前几篇文章中,咱们了解到,Queue 的实现类有 ArrayDeque.LinkedList.PriorityQueue. 在上一章节中,陆续的介绍到 ArrayDeque 和 Linke ...

  4. oracle管理角色和权限

    介绍 这一部分主要看看oracle中如何管理权限和角色,权限和角色的区别在哪里. 当刚刚建立用户时,用户没有任何权限,也不能执行任何操作.如果要执行某种特定的数据库操作,则必需为其授予系统的权限:如果 ...

  5. Runtime - 关联对象使用方法及注意点

    大家都知道在分类里,可以间接的添加属性,运用runtime关联对象. 如下图,只是声明了btnClickedCount的set, get方法而已 并没有生成_btnClickedCount 成员变量, ...

  6. 《Java基础知识》Java多态和动态绑定

    在Java中,父类的变量可以引用父类的实例,也可以引用子类的实例. 请读者先看一段代码: public class Demo { public static void main(String[] ar ...

  7. sqlserver 行转列、字符串行转列、自动生产行转列脚本

    行转列,老生常谈的问题.这里总结一下网上的方法. 1.生成测试数据: CREATE TABLE human( name ), --姓名 norm ), --指标 score INT , --分数 gr ...

  8. RMAN 下NOARCHIVELOG和ARCHIVE模式的恢复

    恢复处于NOARCHIVELOG模式的数据库 当数据库处于NOARCHIVELOG模式时,如果出现介质故障 ,则最后一次备份之后对数据库所做的任何操作都将丢失.通过RMAN执行恢复时,只需要执行res ...

  9. Neo4j安装过程详解

    在安装neo4j之前,需要安装Java JRE,并配置Java开发环境,然后安装neo4j服务. 一.CentOS下安装 1.下载Neo4j 去官网下载最新的neo4j,选择社区版.地址:https: ...

  10. Paper | MFQE 2.0: A New Approach for Multi-frame Quality Enhancement on Compressed Video

    目录 1. 要点 2. 压缩视频特性分析 2.1 质量波动 2.2 帧间相关性 3. 方法 3.1 分类器 3.2 好帧运动补偿 3.3 质量增强网络 4. 实验 4.1 差帧质量提升效果 4.2 总 ...