IDA静态逆向工具详解二

2023-11-01

1.栈帧

  1. 栈帧(stack frame)栈帧是在程序的运行时栈中分配的内存块,专门用于特定的函数调用。

  2. 栈帧(激活记录)调用函数的详细步骤

    2.1.调用方将被调用函数所需的参数放入到该函数所采用的调用约定指定的位置。如果参数被放到运行时栈上,该操作可能导致程序的栈指针发生改变。

    2.2.调用方将控制权转交给被调用的函数,这个过程常由X86 CALL或MIPS JAL等指令执行。然后,返回地址被保存到程序栈或CPU寄存器中。

    2.3.如果有必要,被调用的函数会配置一个栈指针,并保存调用方希望保持不变的任何寄存器值。

    2.4.被调用的函数为它可能需要的任何局部变量分配空间。一般通过调整程序栈指针运行时栈上保留空间来完成这一任务。

    2.5.被调用的杉树执行其操作,可能会生成一个结果。在执行操作的过程中,被调用的函数可能会访问调用函数传递给他的参数。如果函数返回一个结果,此结果通常被放置到一个特定的寄存器中,或者放置到函数返回后调用可立即访问的寄存器中。

    2.6.一旦函数完成其操作,任何为局部变量保留的栈空间即被释放。通常,逆向执行第4步中的操作,即可完成这个任务。

    2.7.如果某个寄存器的值还未调用方保存(第3步)着,那么将其恢复到原始值。这包括恢复调用方得帧指针寄存器。

    2.8.被调用的函数将控制权返还给调用方。实现这一操作的主要指令包括X86 RET和 MIPS JR。根据所使用的调用约定,这一操作可能还会从程序栈中清除一个或多个参数。

    2.9.调用方一旦重新获得控制权,它可能需要删除程序栈中的参数,这时可能需要对栈进行调整,以将程序栈指针恢复到第1步以前的值。

2.调用约定

1.常见的X86编译器(MV C/C++或GUN的GCC/G++);创建栈帧时最重要的步骤,是通过调用函数将参数存入栈中。【调用函数必须存储调用的参数!】

  1. C调用约定(C/C++程序中常用的_cdecl修饰符会迫使编译器利用C调用约定。)
    (调用方按从右到左的顺序将函数参数放入栈,在被调用的函数完成操作时,调用方负责从栈中清除参数。)

    (从右到左在战中放入参数的结果是,如果函数被调用,最左面的(第一个)参数将始终位于栈顶。这样,无论该函数需要多少个参数,我们都可轻易的找到第一个参数【因此,cdecl调用约定非常适用于那些参数数量可变的函数(Printf)】)

    (要求调用函数从栈中删除参数,意味着:指令在由被调用的函数返回后,会立即对程序栈指针进行调整。如果函数能够接受数量可变的参数,则调用方非常适于进行这种调整。【因为它清除的指导,它向函数传递了多少个参数,因此能够轻松的调整。被调用方不知道自己会收多少个参数,因此很难对栈做出必要的调整】)

    (无论采用哪一种方法,在调用函数时,栈指针都会指向最左面的参数)

  2. 标准调用约定(微软为自己的调用约定起的名称叫_stdcall)
    (调用约定按从右到左的顺序将函数参数放在程序栈上。【区别在于:函数结束执行时,应由被调用的函数负责删除栈中的函数参数,只有参数数量固定不变才有可能】)

    (优点:在每次函数调用之后,不需要通过代码从栈中清除参数,因而能生成体积稍小、速度稍快的程序。【如果你正尝试为谋个共享库(DLL)组件生成函数原型或与二进制兼容的替代者,一定要记住这一点!】)

  3. X86 fastcall约定(fastcall是stdcall约定的一个变体,它向CPU寄存器(而非程序栈)最多传递两个参数)
    (MV C/C++和GUN GCC/G++编译器能够识别函数声明中的fastcall修饰符!)

    (如果指定使用fastcall约定,则传递给函数的前两个参数将分别位于ECX和EDX寄存器中。剩余的其他参数则以类似于stdcall约定的方式从右到左放入栈上。)

    (与stdcall约定相似的是,在返回其调用方时,fastcall函数负责从栈中删除参数。)

    (由于有两个参数被传递到寄存器中,被调用的函数仅仅需要从栈中清除8个字节,即使该函数拥有4个参数【fastcall只清理参数y和z】)

  4. C++调用约定(需要this指针,该指针指向用于调用函数的对象)
    (用于调用函数的对象的地址必须由调用方提供,因此,它在调用非静态成员函数时作为参数提供。)

    (C++语言标准并未规定应如何向非静态成员函数传递this指针,因此,不同的编译器使用不同的技巧传递this指针)

    (VC++提供thiscall调用约定,它将this传递到ECX寄存器中,并且和在stdcall中一样,它要求非静态成员函数清除栈中的参数)

    (GUN G++编译器将this看成是任何非静态成员函数的第一个隐含参数,而在所有其他方面与使用cdecl约定相同【因此,对使用g++ 编译的代码来说,在调用非静态成员函数之前this被放置到栈顶,且调用方负责在函数返回时删除栈中的参数(至少有一个参数)】)

  5. 其他调用约定(调用约定特定于语言、编译器、CPU的,如果遇到由更少见的编译器生成的代码,可能需要你自己进行一番研究【注意:优化代码、定制汇编语言代码和系统调用】)
    (如果输出函数(如库函数)是为了供其他程序员使用,必须遵守调用约定。;如果函数仅供内部程序使用,则该函数需要采用只有函数的程序才了解的调用约定,【VC++中使用/GL选项,以及在GUN gcc/g++中使用regparm关键字】)

    (如果程序员不嫌麻烦,使用了汇编语言,那么,他们就能够完全控制如何向他们的创建的函数传递参数。吹飞他们希望创建供其他程序员使用的函数。否则,汇编语言程序员能够以任何他们认为适当的方式传递参数。【因此,在分析自定义汇编代码时注意:模糊例程(obfuscation routine)和Shellcode常见的自定义汇编代码】)

    (系统调用是一种特殊的函数调用,用于请求一项操作系统服务。通常,系统调用会造成状态转换,由用户模式进入内核,以便操作系统内核执行用户的请求。)

    (启动系统调用的方式因操作系统和CPU而异。例如:Linux X86系统调用使用int 0x80指令启动,其他x86操作系统可能使用Sysenter指令)

    (在许多x86系统上(Linux例外)系统调用的参数位于运行时栈上,并在启动系统调用之前,在EAX寄存器中放入一个系统调用编号。【Linux系统调用接受位于特定寄存器中的参数,有时候,如果可用寄存器无法存储所有的参数,它也接受位于程序栈上的参数】)
    }

3.栈帧详解

C++代码
Void bar(int j, int k);
void demo_stackframe(int a, int b, int c)
{
int x;
char buffer[64];
int y;
int z;
bar(z,y);
}

(计算的出,局部变量最少需要76个字节的空间:3个4字节的证书和1个64字节的缓冲区)

(stdcall或cdecl调用约定,它们的栈帧完全相同)

(在分析使用栈指针引用栈帧变量的函数时,你必须小心,注意栈指针任何变化,并对所有未来的变量偏移量进行相应调整。使用栈指针引用所有栈帧变量的好处在于:所有其他寄存器仍可用于其他目的。)

(在弹出返回地址之前,需要从栈顶删除局部变量,以便于在ret指令执行时,栈指针正确的指向所保存的返回地址)
(由于专门使用一个寄存器作为帧指针,并通过一段代码在函数入口点配置了帧指针,因此,计算局部变量的偏移量的工作变的更加轻松。)

(在X86程序中,EBP(extended [ik’stendid]扩展 base pointer)扩展基址指针,寄存器通常专门用作栈帧指针。)

(栈帧中并没有用于储存被保存寄存器的标准位置)
(一旦EBP被保存,就可以修改,使他指向当前的栈位置,用mov完成,它将栈指针的当前值复制到EBP中)
(使用一个专用的帧指针,所有变量相对于帧指针寄存器的偏移量得以计算出来:正偏移量用于访问函数参数,而负偏移量则用于访问局部变量。【使用专用的帧指针,我们可以自由更改栈指针,而不影响帧内其他变量的偏移量】)

mov esp, ebp |
pop ebp |(由于这项操作十分常见,因此,x86体系结构提供了leave指令完成) “leave
ret | ret "

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

IDA静态逆向工具详解二 的相关文章

  • 线性布局中的layout_weight属性

    作者 华清远见讲师 layout weight属性是线性布局的特有属性 当需要去按比例分配某一行或某一列上的控件时 通常会想到使用权重这个属性去解决 一般在使用该属性时 要把控件的layout width或layout height设置成0
  • VMware创建虚拟机时出现 network bot from intel e1000

    准备在vmware 上 创建虚拟机 点击启动时 却出现 network bot from intel e1000 operating system not found 首先查看一下是否安装使用了iso镜像 查询步骤如图 选中使用即可 如果还
  • selenium测试框架快速搭建(ui自动化测试)

    一 介绍 selenium目前主流的web自动化测试框架 支持多种编程语言Java pythan go js等 selenium 提供一系列的api 供我们使用 因此在web测试时我们要点页面中的某一个按钮 那么我们只需要获取页面 然后根据
  • cmake:aux_source_directory

    理论 aux source directory 查找在某个路径下的所有源文件 aux source directory lt dir gt lt variable gt 搜集所有在指定路径 lt dir gt 下的源文件的文件名 将输出结果
  • 禅道的测试模块(编写用例)

    建用例 用测试人员1的账号登录

随机推荐

  • PCI配置空间访问机制 及 地址域转换过程

    访问配置空间的总线事务通过ID进行寻址 ID号由总线号 Bus 设备号 Device 功能号 Function 组成 总线号 HOST主桥遍历PCI总线时确定 PCI总线可以通过PCI桥来扩展 并形成PCI总线树 在PCI总线树上 有几片P
  • LinearGradient线性渲染

    java view plain copy import android content Context import android graphics Canvas import android graphics Color import
  • 深度学习Apex库的安装以及一些问题的解决

    深度学习Apex库的介绍 APEX是英伟达开源的 完美支持PyTorch框架 用于改变数据格式来减小模型显存占用的工具 其中最有价值的是amp Automatic Mixed Precision 将模型的大部分操作都用Float16数据类型
  • Java dom4j生成XML文件的方法分享

    转自 Java dom4j生成XML文件的方法分享 下文讲述使用dom4j生成XML文件的方法分享 如下所示 dom4j创建xml的方法分享 1 创建一个文档模型 Document document DocumentHelper creat
  • Java手动释放对象

    伪代码 public void updateUser BufferedWriter writer BufferedReader reader List
  • Object.entries()的使用

    Object entries的使用方法 场景 数据形式 场景 假如你要去做一个本地保存 键名相同 但是要做很多取值赋值 取值赋值 那你就可以使用Object entries 和for of搭配去实现一个简单的代码 数据形式 首先我们假定一个
  • 正则表达式中'.*?'和'.*+'的理解

    首先我们了解一下都有哪些限定符 字符 描述 匹配前面的子表达式零次或多次 例如 zo 能匹配 z 以及 zoo 等价于 0 匹配前面的子表达式一次或多次 例如 zo 能匹配 zo 以及 zoo 但不能匹配 z 等价于 1 匹配前面的子表达式
  • ChatGpt同类产品及其集成产品大全

    觉得好用帮忙点个赞吧 可以关注一下 后续会持续更新添加网站 ChatGpt是什么 Chat GPT 是一个基于 GPT 3 5 架构训练的大型语言模型 可以用于各种自然语言处理任务 例如文本生成 对话系统 语言翻译等 1 文心GPT 此网站
  • 【PMP】三点估算结合正态分布图

    贝塔分布公式 最乐观 4 最可能 最悲观 6 标准差公式 最悲观 最乐观 6 贝塔分布 是 PMOK 中三点估算的缺省 默认公式 三点估算结合正态分布图 68 26 的结果数据位于均值的 1 西格玛内 95 46 的结果数据位于均值的 2
  • 黄仁勋管理万亿英伟达的疯狂方法:没有计划、没有汇报、没有层级

    丰色 发自 凹非寺量子位 公众号 QbitAI 今年最为风头无两的半导体公司 无疑是市值已超1万亿的英伟达 让人没想到的是 老黄居然有着特别 甚至说是近乎疯狂的管理方式 没有计划 没有汇报 没有明确层级 曝光称 他直接管理40名下属 信奉扁
  • C语言中关于malloc(0)问题

    首先来解释malloc 0 的问题 这个语法是对的 而且确实也分配了内存 但是内存空间是0 就是说返回给你的指针是不能用的 感觉奇怪吧 但是从操作系统的原理来解释就不奇怪了 这要涉及操作系统维护内存的方法来说了 在内存管理中 内存被分为2部
  • wamp You don't have permission to access / on this server等问题的解决.

    Forbidden You don t have permission to access index phpon this server 然后也是找了很多 多是说什么allow from all等等的问题 但无论怎么设置都是这个问题 几经
  • [代码案例] 快速入手matlab绘图基本指令

    主要内容 Matlab绘图指令基本语法 涵盖画布位置大小 坐标调整 图例标签 子图绘制等 part 1 生成绘图数据据 part 2 绘图基本指令 part 3 多条曲线绘制 part 4 子图分块绘制方法 part 5 指定画布绘制 代码
  • ADworld reverse wp - babymips

    i i 4 32 i 其实是对v5数组进行操作 i 4是v5起始地址 观察栈帧得知 之后对比fdata的5个字节数据 再进入sub 4007F0进行检查 分别处理奇偶两种情况 奇数 v1 a1 i gt gt 2 a1 i lt lt 6
  • 孔乙己:参数的⑨种写法

    孔乙己 参数的 种写法 这里客串一下 using Ty int 1 Ty 2 const Ty Ty const 3 const Ty Ty const 4 Ty 5 Ty 6 Ty 7 const Ty Ty const 8 Ty con
  • 区间预测

    区间预测 MATLAB实现QRDNN深度神经网络分位数回归时间序列区间预测 目录 区间预测 MATLAB实现QRDNN深度神经网络分位数回归时间序列区间预测 效果一览 基本介绍 模型描述 程序设计 参考资料 效果一览 基本介绍 MATLAB
  • 基于正交试验的钢丝绳探伤仪结构参数优化

    目录 理论基础 比尔萨法定律 磁路欧姆定律 编辑 标题 摘要 结论 标题 摘要 结论 研究背景 大背景 小背景 研究内容 成果 内容 结论 成果 潜在研究点 疑问 理论基础 比尔萨法定律 磁路欧姆定律 标题 摘要 结论 标题 基于正交试验的
  • Celery(一)Celery介绍、安装和基本使用

    目录 1 Celery介绍 1 1 Celery是什么 1 2 架构图 2 安装 2 1 linux安装 2 2 windows安装 3 基本使用 3 1 启动worker 3 2 添加任务 3 4 扩展 3 3 停止worker 1 Ce
  • 前后端交互,修改密码校验

    1 思路分析 1 1 前端校验 1 gt 输入的原密码 新密码 确认密码 都不能为空 2 gt 原密码与新密码不能相同 3 gt 新密码与确认密码必须相同 1 2 后端校验 1 gt 后端接收前端发送的原密码和新密码 2 gt 验证输入的原
  • IDA静态逆向工具详解二

    文章目录 1 栈帧 2 调用约定 3 栈帧详解 1 栈帧 栈帧 stack frame 栈帧是在程序的运行时栈中分配的内存块 专门用于特定的函数调用 栈帧 激活记录 调用函数的详细步骤 2 1 调用方将被调用函数所需的参数放入到该函数所采用