IDA静态逆向工具规则解析

简介: IDA规则解析

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

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

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++);创建栈帧时最重要的步骤,是通过调用函数将参数存入栈中。【调用函数必须存储调用的参数!】

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

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

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

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

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

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

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

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

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

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

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

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

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

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

其他调用约定(调用约定特定于语言、编译器、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字节的缓冲区)
1
(stdcall或cdecl调用约定,它们的栈帧完全相同)

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

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

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

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

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

相关文章
|
机器学习/深度学习 人工智能 JSON
Resume Matcher:增加面试机会!开源AI简历优化工具,一键解析简历和职位描述并优化
Resume Matcher 是一款开源AI简历优化工具,通过解析简历和职位描述,提取关键词并计算文本相似性,帮助求职者优化简历内容,提升通过自动化筛选系统(ATS)的概率,增加面试机会。
1926 18
Resume Matcher:增加面试机会!开源AI简历优化工具,一键解析简历和职位描述并优化
|
存储 人工智能 API
离线VS强制登录?Apipost与Apifox的API工具理念差异深度解析
在代码开发中,工具是助手还是枷锁?本文通过对比Apipost和Apifox在断网环境下的表现,探讨API工具的选择对开发自由度的影响。Apifox强制登录限制了离线使用,而Apipost支持游客模式与本地存储,尊重开发者数据主权。文章从登录策略、离线能力、协作模式等方面深入分析,揭示工具背后的设计理念与行业趋势,帮助开发者明智选择,掌握数据控制权并提升工作效率。
1263 19
|
数据采集 存储 调度
BeautifulSoup VS Scrapy:如何选择适合的HTML解析工具?
在Python网页抓取领域,BeautifulSoup和Scrapy是两款备受推崇的工具。BeautifulSoup易于上手、灵活性高,适合初学者和简单任务;Scrapy则是一个高效的爬虫框架,内置请求调度、数据存储等功能,适合大规模数据抓取和复杂逻辑处理。两者结合使用可以发挥各自优势,例如用Scrapy进行请求调度,用BeautifulSoup解析HTML。示例代码展示了如何在Scrapy中设置代理IP、User-Agent和Cookies,并使用BeautifulSoup解析响应内容。选择工具应根据项目需求,简单任务选BeautifulSoup,复杂任务选Scrapy。
575 1
BeautifulSoup VS Scrapy:如何选择适合的HTML解析工具?
|
JSON 监控 物联网
WebSocket 调试全攻略:核心解析、工具选择与对比!
WebSocket 是一种全双工、实时交互的网络通信协议,适用于即时通信、实时数据流、多人协作、IoT 等场景。调试 WebSocket 时,工具应具备握手管理、实时消息收发、自定义 Header、消息大小告警、分组管理、多连接支持和断线重现等功能。主流调试工具如 Postman、ApiPost 和 ApiFox 各有优劣:Postman 界面友好适合基础调试;ApiPost 支持高级功能如消息分组和自动重连;ApiFox 则强化了多连接支持。选择工具时需根据具体需求和团队熟悉度决定。
|
数据可视化 测试技术 API
前后端分离开发:如何高效调试API?有工具 vs 无工具全解析
在前后端分离开发中,API调试至关重要。本文探讨有无调试工具时如何高效调试API,重点分析Postman、Swagger等工具优势及无工具代码调试方法。通过实际场景如用户登录接口,对比两者特性。同时介绍Apipost-Hepler(IDEA插件),将可视化与代码调试结合,提供全局请求头配置、历史记录保存等功能,优化团队协作与开发效率,助力API调试进入全新阶段。
|
数据可视化 项目管理
个人和团队都好用的年度复盘工具:看板与KPT方法解析
本文带你了解高效方法KPT复盘法(Keep、Problem、Try),结合看板工具,帮助你理清头绪,快速完成年度复盘。
1719 7
个人和团队都好用的年度复盘工具:看板与KPT方法解析
|
数据可视化 测试技术 API
前后端分离开发:如何高效调试API?有工具 vs 无工具全解析
在前后端分离的开发模式中,API 调试的效率直接影响项目的质量和交付速度。通过本文的对比分析,我们可以看到无工具调试模式虽具备灵活性和代码复用能力,但在操作便利性和团队协作上稍显不足。而传统的外部调试工具带来了可视化、高效协作与扩展性,却可能存在工具切换带来的开发链路断层问题。Apipost-Hepler 融合了两者的优势,让开发者无需离开熟悉的 IDEA 环境,就能享受可视化调试工具的强大功能。
638 5
|
JSON 监控 物联网
#WebSocket 调试全攻略:Postman、Apipost和Apifox核心解析、工具选择与对比!
WebSocket 是一种现代化的全双工通信协议,允许客户端和服务端通过持久连接实时双向传输数据。它适用于即时通讯、实时通知、金融行情、在线协作、物联网等场景。调试 WebSocket 时,工具应具备握手管理、实时消息收发、自定义 Header、消息大小监控、分组管理、多连接支持等功能。
1210 1
|
网络协议 Unix Linux
深入解析:Linux网络配置工具ifconfig与ip命令的全面对比
虽然 `ifconfig`作为一个经典的网络配置工具,简单易用,但其功能已经不能满足现代网络配置的需求。相比之下,`ip`命令不仅功能全面,而且提供了一致且简洁的语法,适用于各种网络配置场景。因此,在实际使用中,推荐逐步过渡到 `ip`命令,以更好地适应现代网络管理需求。
977 11
|
监控 数据可视化 数据挖掘
直播电商复盘全解析:如何通过工具提升团队效率
直播电商作为新兴商业模式,正改变传统零售格局。其成功不仅依赖主播表现和产品吸引力,更需团队高效协作与分工优化。复盘是提升执行力的关键环节,通过总结经验、发现问题、优化流程,结合在线工具如板栗看板,可提升复盘效率。明确团队角色、建立沟通机制、制定优化方案,确保数据驱动决策,从而在竞争中保持领先。

热门文章

最新文章

推荐镜像

更多
  • DNS