__declspec(naked)详解
__declspec(naked)是用来告诉编译器函数代码的汇编语言为自己的所写,不需要编译器添加任何汇编代码
注意点:
- void __declspec(naked) funname()
- {
- _asm
- {
- ...
- ret
- }
- }
注意,__declspec(naked)是编译器直接拿来用的汇编函数代码,所以一定要记得在开始的时候保存上下文标志位(压栈),在结束的时候要记得恢复上下文(出栈)。并且在结尾要加上ret命令
比较下面两段代码:(都是调用strcmp函数)
- VOID __declspec(naked) MyNakedFunction()
- {
- strcmp(...);
- // __cdecl 函数是调用者清除参数堆栈,对于非内联汇编调用这类函数,编译器将自动平衡堆栈,加入 ADD ESP, 8
- }
- VOID __declspec(naked) MyNakedFunction()
- {
- //...
- __asm CALL strcmp;
- __asm ADD ESP, 8; // 内联汇编需要自己平衡堆栈
- }
对于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函数
__declspec(naked)详解相关推荐
- 【转】__declspec用法详解
__declspec用法详解 __declspec用于指定所给定类型的实例的与Microsoft相关的存储方式.其它的有关存储方式的修饰符如static与extern等是C和 C++语言的ANSI规范 ...
- __declspec(dllexport)、__declspec(dllimport)详解
在Visual studio中新建DLL项目时编译器会自动生成下面这样的宏定义: #ifdef DLL_EXPORTS #define DLL_API __declspec(dllexport) #e ...
- pragma comment的使用 pragma预处理指令详解
pragma comment的使用 pragma预处理指令详解 #pragma comment( comment-type [,"commentstring"] ) 该宏放置一个注 ...
- #pragma comment和#pragma 预处理指令详解
该宏放置一个注释到对象文件或者可执行文件. 例如,#pragma comment(lib,"Ws2_32.lib")表示链接Ws2_32.lib这个库. 和在工程设置里写上链入 ...
- #pragma 详解
#pragma 求助编辑 pragma - 必应词典 美[p'ræɡmə]英[p'ræɡmə] n.[计]杂注 网络编译指示:显示编译指示:特殊指令 百科名片 在所有的预处理指令中,#Pragma 指 ...
- vs cpp生成h文件_lib 和 dll 的区别、生成以及使用详解
(给CPP开发者加星标,提升C/C++技能) 来源:tenoshttps://www.cnblogs.com/TenosDoIt/p/3203137.html [导读]:在日常开发中,我们只需要知道l ...
- JNI详解---从不懂到理解
Chap1:JNI完全手册... 3 Chap2:JNI-百度百科... 11 Chap 3:javah命令帮助信息... 16 Chap 4:用javah产生一个.h文件... 17 Chap ...
- OpenGL,GLUT,FreeGLUT,GLFW,GLEW,GLAD,GL3W,GLAD,GLM,GLSL的区别详解
OpenGL,GLUT,FreeGLUT,GLFW,GLEW,GLAD,GL3W,GLAD,GLM,GLSL的区别详解 很多同学在初学计算机图形学时,都要去配置OpenGL环境,其中涉及多个库的选择和 ...
- C++11、C++14、C++17、C++20新特性总结(5万字详解)
文章目录 C++ 11是什么,C++ 11标准的由来 C++ auto类型推导完全攻略 auto 类型推导的语法和规则 auto 的高级用法 auto 的限制 auto 的应用 使用 auto 定义迭 ...
最新文章
- koa2 mysql sequelize_Vue2+Koa2+Typescript前后端框架教程--05Sequelize(ORM)的使用实现基础的班级增删...
- Log4j配置文件以及配置方法
- mysql 设置中文 重启_如何启动/停止/重启MySQL + 进入MYSQL-Go语言中文社区
- C++打印0到N的Catalan数卡特兰数(附完整源码)
- OpenStack部署之小结
- 程序的灵魂-----算法
- sql2005 无法解决 equal to 操作Chinese_PRC_CI_AS 和 Chinese_PRC_CS_AS 之间的排序
- OJ1159: 最大的两个数(指针专题)(C语言)
- 二分法08:寻找旋转排序数组中的最小值
- asp.net core web api token验证和RestSharp访问
- 电脑广告太多,请避免安装这些软件
- 面试——嵌入式面试内容和注意事项
- Maven读书笔记之七(生命周期和插件)
- [Python从零到壹] 五十八.图像增强及运算篇之图像锐化Sobel、Laplacian算子实现边缘检测
- 关于英语学习和字幕的那点事儿
- Netty4.x 的逆袭之路 —— 再识 Netty
- [转载] 如果你在公司遇见这4种情况,说明你该辞职了,千万别犹豫
- java如何设置jlabel位置_Java Swing – JLabel位置
- windows系统目录programdata和program file(x86)
- Python中如何保留n位有效数字
热门文章
- 重载练习3_实现重载的println方法
- spring配置详解-初始化销毁方法
- SpringCloud 定义Eureka服务端、Eureka服务信息、Eureka发现管理、Eureka安全配置、Eureka-HA机制、 Eureka服务打包部署
- 把数据存入excel文件_Python从原Excel表中抽出数据存入同一文件的新的Sheet(实例53)...
- JVM-Java内存区域
- .net core webapi 列表返回指定的字段_ADO.NET 使用初探之SQL操作 | C# 数据操作系列...
- 【SpringBoot零基础案例05】【IEDA 2021.1】若SpringBoot项目两种配置文件同时存在,哪种文件配置起作用?
- Node.js模块之Buffer
- 基于HTML5的WebGL呈现A星算法的3D可视化
- 用Matlab与c++程序生成的数据文件绘制sin函数