花指令初认识

0x01 花指令简介

​ 花指令是企图隐藏掉不想被逆向工程的代码块 (或其它功能) 的一种方法, 在真实代码中插入一些垃圾代码的同时还保证原有程序的正确执行, 而程序无法很好地反编译, 难以理解程序内容, 达到混淆视听的效果。花指令会使得 IDA 在分析过程中出现问题,可能产生堆栈不平衡。

0x02 堆栈不平衡

​ IDA 中产生堆栈不平衡的原因可能是由于不同的函数调用约定,也可能是在实现代码保护插入了代码混淆(特指使用 push/push+ret 实现函数调用)。

关于函数调用约定:

​ 函数的调用约定,顾名思义就是对函数调用的一个约束和规定(规范),描述了函数参数是怎么传递和由谁清除堆栈的。它决定以下内容:(1)函数参数的压栈顺序,(2)由调用者还是被调用者把参数弹出栈,(3)以及产生函数修饰名的方法。
​ 主要需要了解三种调用约定:__cdecl、__stdcall、__fastcall。

1、__cdecl

​ cdecl(C declaration,即C声明)是源起C语言的一种调用约定,也是C语言的事实上的标准。在x86架构上,其内容包括:

  1. 函数实参在线程栈上按照从右至左的顺序依次压栈。
  2. 函数结果保存在寄存器 EAX / AX / AL 中
  3. 浮点型结果存放在寄存器 ST0 中
  4. 编译后的函数名前缀以一个下划线字符
  5. 调用者负责从线程栈中弹出实参(即清栈)
  6. 8 比特或者 16 比特长的整形实参提升为32比特长。
  7. 受到函数调用影响的寄存器(volatile registers):EAX, ECX, EDX, ST0 - ST7, ES, GS
  8. 不受函数调用影响的寄存器: EBX, EBP, ESP, EDI, ESI, CS, DS
  9. RET指令从函数被调用者返回到调用者(实质上是读取寄存器EBP所指的线程栈之处保存的函数返回地址并加载到IP寄存器)

2、__stdcall

​ stdcall是由微软创建的调用约定,是Windows API的标准调用约定。非微软的编译器并不总是支持该调用协议

  1. 函数实参在线程栈上按照从右至左的顺序依次压栈。
  2. 由被调用者负责清栈
  3. 编译后的函数后缀以符号“@”
  4. 寄存器EAX, ECX和EDX被指定在函数中使用,返回值放置在EAX中
  5. 其他方面与 __cdecl 一样

3、__fastcall。

​ 此约定还未被标准化,不同编译器的实现也不一致。

Microsoft/GCC fastcall
Microsoft 或 GCC 的 fastcall 约定(也即 msfastcall )把第一个(从左至右)不超过32比特的参数通过寄存器ECX/CX/CL传递,第二个不超过32比特的参数通过寄存器EDX/DX/DL,其他参数按照自右到左顺序压栈传递。

Borland fastcall
从左至右,传入三个参数至EAX, EDX和ECX中。剩下的参数推入栈,也是从左至右。 在32位编译器Embarcadero Delphi中,这是缺省调用约定,在编译器中以register形式为人知。 在i386上的某些版本Linux也使用了此约定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值