裸函数

编译器不会做出保存现场、提升堆栈、恢复现场等功能,在调用函数时只会生成CALL指令

一、普通函数

  • 声明

    int plus(int a, int b)
    {
       return a + b;
    }
    
  • 汇编表示

  1. 函数代码及断点设置

裸函数_windows逆向

  1. 调用普通函数时编译器的处理

参数处理
CALL调用
外平栈
返回值处理

裸函数_调用函数_02

  1. JMP跳转

裸函数_堆栈_03

  1. 函数内部处理

提升堆栈
保存现场
设置缓冲区
函数功能实现
恢复现场
函数返回

裸函数_功能实现_04

二、裸函数

  • 声明

    void __declspec(naked) plus(int a, int b)
    {
     
    }
    
  • 汇编表示

  1. 函数代码及断点设置

裸函数_堆栈_05

  1. 调用裸函数时编译器的处理

参数处理
CALL调用
堆栈平衡

裸函数_堆栈_06

  1. 执行call时发生错误

并未生成ret指令,导致函数无法返回

裸函数_调用函数_07


裸函数_堆栈_08


裸函数_调用函数_09

  1. 使用__asm{}手动添加汇编代码

裸函数_堆栈_10


裸函数_调用函数_11


裸函数_windows逆向_12

  1. 加上返回值与函数功能实现

裸函数_编译器_13


裸函数_windows逆向_14


裸函数_堆栈_15


裸函数_调用函数_16


裸函数_调用函数_17

三、总结

经过以上实验,不难看出,裸函数可以看作是不交由编译器自动处理的函数,可以说是编译器不管这个函数,其内部功能需要开发者手动编写