From: http://blog.csdn.net/hgy413/article/details/7921776

__declspec(naked)是用来告诉编译器函数代码的汇编语言为自己的所写,不需要编译器添加任何汇编代码

注意点:

[cpp] view plain copy
  1. void __declspec(naked) funname()
  2. {
  3. _asm
  4. {
  5. ...
[cpp] view plain copy
  1. ret
  2. }
  3. }

注意,__declspec(naked)是编译器直接拿来用的汇编函数代码,所以一定要记得在开始的时候保存上下文标志位(压栈),在结束的时候要记得恢复上下文(出栈)。并且在结尾要加上ret命令

比较下面两段代码:(都是调用strcmp函数)

[cpp] view plain copy
  1. VOID __declspec(naked) MyNakedFunction()
  2. {
  3. strcmp(...);
  4. // __cdecl 函数是调用者清除参数堆栈,对于非内联汇编调用这类函数,编译器将自动平衡堆栈,加入 ADD ESP, 8
  5. }
  6. VOID __declspec(naked) MyNakedFunction()
  7. {
  8. //...
  9. __asm CALL strcmp;
  10. __asm ADD ESP, 8; // 内联汇编需要自己平衡堆栈
  11. }

对于jmp类型的hook, 如果自己的过程没有使用_declspec(naked),那么系统会自动给添加一些额外的代码,控制堆栈平衡,但是这些额外的代码会破坏被hook函数 的堆栈。对于call类型的hook,如果使用_declspec(naked)修饰的话,要注意自己恢复堆栈平衡。使用 __declspec(naked)关键字定义函数:

1,使用 naked 关键字必须自己构建 EBP 指针 (如果用到了的话,如果最后是JMP到原函数,要自己在开始构建push ebp mov ebp, esp pushad pushfd在最后加popfd popad mov esp, ebp, pop ebp jmp xxxx);

2,必须自己使用 RET 或 RET n 指令返回 (除非你不返回,比如JMP到原函数); 对于一般的汇编内嵌代码(没有使用_declspec(naked)),不必保存上下文了,保存也不会有事,但是不能再加ret命令,因为编译器也会为其加一个,ret命令不能同时执行两次。会导致越界错误

刚发现,在naked函数中不能出现如int i=0;这样的赋值

在标明naked的函数中是不可以使用任何赋值都是不允许的。如果非要想用可以另写一个函数进行处理,处理完成后将结果返回既可。如果使用VS会提示以下错误。

initialized auto or register variable not allowed at function scope in 'naked' function

其实原因也很好解释,因为naked和父函数共用一个ebp, 所以要子局部变量,就用esp,

naked函数就不要带参数了,带参数的没必要写成naked函数

转载于:https://www.cnblogs.com/ykmzy/articles/5306607.html

C++基础巩固__declspec(naked)相关推荐

  1. YJX基础44 __declspec(naked)

    (在写驱动时)如果函数前不加__declspec(naked) 编译时编译器会自作主张补上栈移动和return,这样会破坏栈平衡 void __declspec(naked) NTSTATUS _My ...

  2. 【Win32汇编】__declspec(naked)裸函数

    使用 __declspec(naked) 定义的函数,编译器只会负责参数压栈.执行CALL指令,和释放参数的内存(堆栈平衡),除此之外啥也没有,比如提升堆栈,寄存器的保存和恢复,或者是函数返回,这些都 ...

  3. __declspec(naked)详解

    __declspec(naked)是用来告诉编译器函数代码的汇编语言为自己的所写,不需要编译器添加任何汇编代码 注意点: [cpp] view plaincopy void __declspec(na ...

  4. __declspec(naked)和__asm编写实践总结

    __cdecl 和 __stdcall 压栈参数顺序是一致的,但平衡堆栈方式不一样. __cdecl调用函数方式是调用者,即函数外部平衡堆栈,一般是在函数外部调用add esp, xxxx,函数内部只 ...

  5. void __declspec(naked)解释

    __declspec(naked)是用来告诉编译器函数代码的汇编语言为自己的所写,不需要编译器添加任何汇编代码 void __declspec(naked)  mdt { __asm pushad p ...

  6. 裸函数 __declspec(naked)

    在C语言转化成汇编的过程中,编译器会自动处理堆栈,比如以下代码,即使add函数里面一条语句都没有,但是编译器在编译过程中 还是生成了很多指令(00F11380 - 00F1139C) 用于处理堆栈 v ...

  7. 裸函数 __declspec(naked),C语言是怎么变成汇编的,用裸函数加汇编实现一个最简单的加法函数

    裸函数: 普通函数会自动生成实现堆栈提升.堆栈的缓存区建立.堆栈平衡和函数返回的汇编代码,裸函数不会自动生成任何代码,全部要自己手动写汇编代码. 裸函数定义:__declspec(naked) 加汇编 ...

  8. __declspec(naked)是用来告诉编译器函数代码的汇编语言为自己的所写,不需要编译器添加任何汇编代码

    __declspec(naked)是用来告诉编译器函数代码的汇编语言为自己的所写,不需要编译器添加任何汇编代码 extern "C" void __declspec(naked) ...

  9. VC在X64模式下不支持__declspec(naked)

    2019独角兽企业重金招聘Python工程师标准>>> 1.将汇编代码独立出来,形成.asm文件. 2.可以生写一个包含原型的.c文件,然后用cl.exe /c /Fa xxx.c ...

最新文章

  1. 没听说过“羽毛球VR”计划?嗯?
  2. 在Apache上搭建pywebsocket提供html5的websocket服务
  3. 论文排版中页码的设置方法
  4. 洛谷精选 - 字符串合集
  5. 苹果的 Metal 工程
  6. 机器人防火墙:人机识别在应用安全及风控领域的一点实践
  7. SQL Server 默认跟踪报表
  8. 白鹭引擎制作滚动框,类似div的oveflow
  9. Android Studio单元测试入门
  10. 使用express重构博客项目
  11. word论文公式编号排版
  12. 推荐 9 个超赞的 JavaScript 库
  13. ESP8266教程4 — ESP8266 智能配网
  14. android高德地图热力图,没有编程基础也可通过高德地图完成炫酷的热力图分析...
  15. 计算机二级java复习资料
  16. 千兆网线与千兆水晶头接法
  17. NOI2010 航空管制
  18. springboot集成kettle, 访问不到ktr文件
  19. 视频教程-C语言核心编程-C/C++
  20. python 学籍管理系统的简单实现

热门文章

  1. php时间戳与date格式转换
  2. PS 选区时显示像素
  3. CSRF攻击、防止CSRF攻击原理及配置
  4. Latex论文排版——图片
  5. 《桃花源记》--歪解
  6. 使用gdb调试Android(aarch 64)可执行二进制文件
  7. ISO26262标准
  8. 参观计算机实验室后的感想,参观实验室心得体会.doc
  9. vuex简单入门:singer实例创建以及读写全过程
  10. PCB布局布线技巧总结