关于使用类成员函数作为回调的方法
为什么类成员函数不能直接做为回调函数?
因为windows中,回调函数都是显式使用CALLBACk修饰符修饰,也就是_stdcall参数传递方式。_stdcall修饰的函数,参数从右至左依次压入堆栈,被调用者负责平衡堆栈。
而所有类的成员函数在定义的时候都被隐式(implicit)定义为__thiscall参数传递方式。__thiscall 修饰的函数参数从右至左依次压入堆栈,被调用者负责平衡堆栈。与所有参数传递方式均不相同的一点:成员函数所在类的this指针被存入ecx寄存器(这个特性只针对Intel x86架构)。
根据第一节对回调函数与类成员函数各自特点的分析。不难发现,只要能想办法在类成员函数被调用之前设置好ecx寄存器,就能在__stdcall调用的基础上模拟出一个完好的__thiscall调用。
具体实现如下
const
PageSize = 4096;
SizeOfJmpCode = 5;
type
TCode = packed record
Int3: Byte;
PopEAX: Byte;
Push: Byte;
AddrOfSelf: TObject;
PushEAX: Byte;
Jmp: Byte;
AddrOfJmp: Cardinal;
end;
var
LCode: ^TCode;
begin
Result := VirtualAlloc(nil, PageSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
LCode := Result;
LCode^.Int3 := $90; // nop
// LCode^.Int3 := $CC; //Int 3
LCode^.PopEAX := $58;
LCode^.Push := $68;
LCode^.AddrOfSelf := Obj;
LCode^.PushEAX := $50;
LCode^.Jmp := $E9;
LCode^.AddrOfJmp := DWORD(CallBackProc) - (DWORD(@LCode^.Jmp) + SizeOfJmpCode); // 计算相对地址
end;
procedure Runk(Thunk: Pointer);
begin
VirtualFree(Thunk, 0, MEM_RELEASE);
end;
转载于:https://www.cnblogs.com/toosuo/archive/2012/01/07/2315574.html
关于使用类成员函数作为回调的方法相关推荐
- C++类成员函数作回调函数
前面写了一篇文章 C语言消息注册派发模式 介绍了下我理解的C语言消息派发.因为C语言是函数式语言,写回调函数的时候很简单 参数就是一个简单的函数指针就好了, 那在C++里的时候 就有些不一样了,虽然C ...
- C++中 线程函数为静态函数 及 类成员函数作为回调函数(转载)
C++中 线程函数为静态函数 及 类成员函数作为回调函数 线程函数为静态函数: 线程控制函数和是不是静态函数没关系,静态函数是在构造中分配的地址空间,只有在析构时才释放也就是全局的东西,不管线程是否运 ...
- C++ 类成员函数指针的使用方法
C++ 类成员函数指针的使用方法 #include <iostream>void func(){ std::cout << "void func()" &l ...
- 将类的成员函数作为回调函数(外一篇:友元函数)
转自:http://blog.csdn.net/xylary/article/details/1548596 将类成员函数用做C回调函数 提出问题: 回调函数是基于C编程的Windows SDK的技 ...
- 如何定义和实现一个类的成员函数为回调函数
如果试图直接使用C++的成员函数作为回调函数将发生错误,甚至编译就不能通过.通过查询资料发现,其错误是普通的C++成员函数都隐含了一个传递函数作为参数,亦即"this"指针,C++ ...
- c++ 线程函数(类成员函数作为线程函数使用)
C++类成员函数使用时,都会隐式传递一个this指针给该函数,this指针指向该类的对象.函数体可以通过显示调用该指针或直接访问类内成员. 回调函数是通过指针调用的函数,最常使用的回调函数就是在创建线 ...
- 如何让API回调你的VC类成员函数而不是静态函数
首先需要包含一个由yzwykkldczsh同志编写的模板类-----万能多用自适应无限制回调模板(为纪念友人fishskin,此模板又称为H>W模板) /******************** ...
- c++类的成员函数作回调函数为啥要声明为static的
简单说明 C++的类成员函数不能像普通函数那样用于回调,因为每个成员函数都需要有一个对象实例去调用它. 把成员函数作为回调函数,可以把该成员函数声明为静态成员函数,但这样做有一个缺点,就是会破坏类的结 ...
- 类成员函数作为CreateThread的回调函数
类成员函数作为CreateThread的回调函数 0 通过内嵌汇编方式 改变指针的指向 1 头文件 #pragma once#include <Windows.h> class MyThr ...
最新文章
- CentOS 7使用systemctl如何补全服务名称
- Spring boot使用Rabbitmq注解及消息序列化
- JavaScript记录一下
- Java解析Json
- python无人机路径规划算法_快速拓展随机树(RRT)路径规划,python
- HikariCP不断打印WARN日志Failed to validate connection com.mysql.jdbc.JDBC4Connection@xxxxx (...) Possibly
- 随机数生成--可复现--可重复:random_state
- LINQ的基本语法包含如下的8个上下文关键字,这些关键字和具体的说明如下
- 收藏!深度学习必读10篇经典算法论文总结!
- C语言k近邻算法及例题,K近邻算法的理解及KD树的构建
- 单片机74LS138应用
- matlab图像取样和量化,数字图像基础之图像取样和量化
- node-gyp rebuild 报错处理
- linux 儒略日时间计算,儒略日(儒略日 在线计算器)
- Saturday morning
- 程序人生 - 西瓜霜能吃下去吗?
- 关于使用Restlet的升级
- [分享]高仿网易新闻WebApp模板+Dcloud打包源码下载
- 简单使用html+css+js随机获取一注双色球号码
- access内置函数:(适用access2000)