_stdcallthunk
// c:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\atlmfc\include\atlstdthunk.h
// This is a part of the Active Template Library.
// Copyright (C) Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Active Template Library Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Active Template Library product.
#ifndef __ATLSTDTHUNK_H__
#define __ATLSTDTHUNK_H__
#pragma once
#pragma push_macro("new")
#undef new
#include <atldef.h>
#if !defined(_ATL_USE_WINAPI_FAMILY_DESKTOP_APP)
#error This file is not compatible with the current WINAPI_FAMILY
#endif
#if !defined(USE_ATL_THUNK2) && (defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM) || defined(_M_ARM64))
#define USE_ATL_THUNK2
#endif
#include <atlthunk.h>
namespace ATL
{
/////////////////////////////////////////////////////////////////////////////
// Thunks for __stdcall member functions
#if defined(_M_IX86)
PVOID __stdcall __AllocStdCallThunk(VOID);
VOID __stdcall __FreeStdCallThunk(_In_opt_ PVOID);
#pragma pack(push,1)
struct _stdcallthunk
{
DWORD m_mov; // mov dword ptr [esp+0x4], pThis (esp+0x4 is hWnd)
DWORD m_this; //
BYTE m_jmp; // jmp WndProc
DWORD m_relproc; // relative jmp
BOOL Init(
_In_ DWORD_PTR proc,
_In_opt_ void* pThis)
{
m_mov = 0x042444C7; //C7 44 24 0C
m_this = PtrToUlong(pThis);
m_jmp = 0xe9;
m_relproc = DWORD((INT_PTR)proc - ((INT_PTR)this+sizeof(_stdcallthunk)));
// write block from data cache and
// flush from instruction cache
FlushInstructionCache(GetCurrentProcess(), this, sizeof(_stdcallthunk));
return TRUE;
}
//some thunks will dynamically allocate the memory for the code
void* GetCodeAddress()
{
return this;
}
_Ret_maybenull_ _Post_writable_byte_size_(sizeof(_stdcallthunk)) void* operator new(_In_ size_t)
{
return __AllocStdCallThunk();
}
void operator delete(_In_opt_ void* pThunk)
{
__FreeStdCallThunk(pThunk);
}
};
#pragma pack(pop)
#elif defined(_M_X64)
PVOID __stdcall __AllocStdCallThunk(VOID);
VOID __stdcall __FreeStdCallThunk(PVOID);
#pragma pack(push,2)
struct _stdcallthunk
{
USHORT RcxMov; // mov rcx, pThis
ULONG64 RcxImm; //
USHORT RaxMov; // mov rax, target
ULONG64 RaxImm; //
USHORT RaxJmp; // jmp target
BOOL Init(
_In_ DWORD_PTR proc,
_In_opt_ void *pThis)
{
RcxMov = 0xb948; // mov rcx, pThis
RcxImm = (ULONG64)pThis; //
RaxMov = 0xb848; // mov rax, target
RaxImm = (ULONG64)proc; //
RaxJmp = 0xe0ff; // jmp rax
FlushInstructionCache(GetCurrentProcess(), this, sizeof(_stdcallthunk));
return TRUE;
}
//some thunks will dynamically allocate the memory for the code
void* GetCodeAddress()
{
return this;
}
_Ret_maybenull_ _Post_writable_byte_size_(sizeof(_stdcallthunk)) void* operator new(_In_ size_t)
{
return __AllocStdCallThunk();
}
void operator delete(_In_opt_ void* pThunk)
{
__FreeStdCallThunk(pThunk);
}
};
#pragma pack(pop)
#elif defined (_M_THUMB)
// note this case must be before _M_ARM because _M_ARM is also defined
PVOID __stdcall __AllocStdCallThunk(VOID);
VOID __stdcall __FreeStdCallThunk(PVOID);
#pragma pack(push,2)
struct _stdcallthunk
{
USHORT m_mov_r0[2]; // mov r0, pThis
USHORT m_mov_pc[2]; // mov pc, pFunc
DWORD m_pThis;
DWORD m_pFunc;
BOOL Init(DWORD_PTR proc, void* pThis)
{
m_mov_r0[0] = 0xF8DF;
m_mov_r0[1] = 0x0004;
m_mov_pc[0] = 0xF8DF;
m_mov_pc[1] = 0xF004;
m_pThis = (DWORD)pThis;
m_pFunc = (DWORD)proc;
// write block from data cache and
// flush from instruction cache
FlushInstructionCache(GetCurrentProcess(), this, sizeof(_stdcallthunk));
return TRUE;
}
void* GetCodeAddress()
{
return (void *)((ULONG_PTR)this | 1);
}
void* operator new(size_t)
{
return __AllocStdCallThunk();
}
void operator delete(void* pThunk)
{
__FreeStdCallThunk(pThunk);
}
};
#pragma pack(pop)
#elif defined(_M_ARM64)
PVOID __stdcall __AllocStdCallThunk(VOID);
VOID __stdcall __FreeStdCallThunk(PVOID);
#pragma pack(push,4)
struct _stdcallthunk {
ULONG m_ldr_r16; // ldr x16, [pc, #24]
ULONG m_ldr_r0; // ldr x0, [pc, #12]
ULONG m_br; // br x16
ULONG m_pad;
ULONG64 m_pThis;
ULONG64 m_pFunc;
BOOL Init(DWORD_PTR proc, void* pThis) {
m_ldr_r16 = 0x580000D0;
m_ldr_r0 = 0x58000060;
m_br = 0xd61f0200;
m_pThis = (ULONG64)pThis;
m_pFunc = (ULONG64)proc;
// write block from data cache and
// flush from instruction cache
FlushInstructionCache(GetCurrentProcess(), this, sizeof(_stdcallthunk));
return TRUE;
}
void* GetCodeAddress() {
return (void *)((ULONG_PTR)this | 1);
}
void* operator new(size_t)
{
return __AllocStdCallThunk();
}
void operator delete(void* pThunk) {
__FreeStdCallThunk(pThunk);
}
};
#pragma pack(pop)
#elif defined(_ARM_)
#pragma pack(push,4)
struct _stdcallthunk // this should come out to 16 bytes
{
DWORD m_mov_r0; // mov r0, pThis
DWORD m_mov_pc; // mov pc, pFunc
DWORD m_pThis;
DWORD m_pFunc;
BOOL Init(
_In_ DWORD_PTR proc,
_In_opt_ void* pThis)
{
m_mov_r0 = 0xE59F0000;
m_mov_pc = 0xE59FF000;
m_pThis = (DWORD)pThis;
m_pFunc = (DWORD)proc;
// write block from data cache and
// flush from instruction cache
FlushInstructionCache(GetCurrentProcess(), this, sizeof(_stdcallthunk));
return TRUE;
}
void* GetCodeAddress()
{
return this;
}
};
#pragma pack(pop)
#else
#error Only X86, X64, ARM, and ARM64 supported
#endif
#if defined(_M_IX86) || defined (_M_X64) || defined(_M_ARM)
#pragma pack(push,8)
// avoid ODR violations
#ifdef USE_ATL_THUNK2
typedef class CDynamicStdCallThunk2 CDynamicStdCallThunk; class CDynamicStdCallThunk2
#else
class CDynamicStdCallThunk
#endif
{
public:
#ifdef USE_ATL_THUNK2
AtlThunkData_t* pThunk;
#else
_stdcallthunk *pThunk;
#endif
#ifdef USE_ATL_THUNK2
CDynamicStdCallThunk2()
#else
CDynamicStdCallThunk()
#endif
{
pThunk = NULL;
}
#ifdef USE_ATL_THUNK2
~CDynamicStdCallThunk2()
#else
~CDynamicStdCallThunk()
#endif
{
if (pThunk)
{
#ifdef USE_ATL_THUNK2
AtlThunk_FreeData(pThunk);
#else
delete pThunk;
#endif
}
}
BOOL Init(
_In_ DWORD_PTR proc,
_In_opt_ void *pThis)
{
if (pThunk == NULL)
{
#ifdef USE_ATL_THUNK2
pThunk = AtlThunk_AllocateData();
#else
pThunk = new _stdcallthunk;
#endif
if (pThunk == NULL)
{
return FALSE;
}
}
#ifdef USE_ATL_THUNK2
AtlThunk_InitData(pThunk, (void*)proc, (size_t)pThis);
return TRUE;
#else
return pThunk->Init(proc, pThis);
#endif
}
void* GetCodeAddress()
{
#ifdef USE_ATL_THUNK2
return AtlThunk_DataToCode(pThunk);
#else
return pThunk->GetCodeAddress();
#endif
}
};
#pragma pack(pop)
typedef CDynamicStdCallThunk CStdCallThunk;
#else
typedef _stdcallthunk CStdCallThunk;
#endif // _M_IX86 || _M_X64 || _M_ARM
} // namespace ATL
#pragma pop_macro("new")
#endif // __ATLSTDTHUNK_H__
_stdcallthunk的更多相关文章
- ATL中窗口句柄与窗口过程的关联方法
ATL中采用了一种动态生成机器指令的方式进行窗口句柄与窗口对象进行关联,以是详细分析: CWindowImpl会在第一次调用Create时注册窗口类,该窗口类是的信息是在CWindowImpl的子类中 ...
- [IE编程] 多页面基于IE内核浏览器的代码示例
有不少人发信问这个问题,我把答案贴在这里: 建议参考 WTL (Windows Template Library) 的代码示例工程TabBrowser (在WTL目录/Samples/TabBrow ...
- ATL Thunk机制深入分析
如果你有SDK的编程经验,就一定应该知道在创建窗口时需要指定窗口类,窗口类中的一种重要的参数就是窗口过程.任何窗口接收到的消息,都是由该窗口过程来处理. 在面向对象编程中,如果还需要开发人员来使用原始 ...
- wtl学习总结
在windows平台,相比MFC,我更喜欢WTL,因其简洁漂亮.所以陆续花了一年的时间学习之,这里总结一下(在学习Wtl/Atl之前,最好是对WinApi编程有一定的了解). 安装 Wtl主页 htt ...
- ATL7窗口类详细剖析
前言: ATL是微软继MFC之后提供的一套C++模板类库,小巧.精妙.效率极高.它的主要作用是为我们编写COM/DOM/COM+程序提供了丰富的支持.但是ATL只能写COM么?我以前只是MFC程序员的 ...
- 深入解析Windows窗体创建和消息分发
Windows GUI採用基于事件驱动的编程模型,其实差点儿全部的界面库都是这样做的.在纯粹的Window32 SDK编程时代.人们还能够搞懂整个Windows窗口创建和消息的流通过程.可是在如今各种 ...
- 深入解析Windows窗口创建和消息分发(三个核心问题:怎么将不同的窗口过程勾到一起,将不同的hwnd消息分发给对应的CWnd类去处理,CWnd如何简单有效的去处理消息,由浅入深,非常清楚) good
笔记:争取不用看下面的内容,只看自己的笔记,就能记住这个流程,就算明白了: _tWinMain-->AfxWinMain,它调用四个函数: -->AfxWinInit用于做一些框架的初始化 ...
随机推荐
- MySQL主从复制什么原因会造成不一致,如何预防及解决?
一.导致主从不一致的原因主要有: 人为原因导致从库与主库数据不一致(从库写入) 主从复制过程中,主库异常宕机 设置了ignore/do/rewrite等replication等规则 binlog非ro ...
- OpenStack核心组件-keystone
1. Keystone介绍 keystone是OpenStack的组件之一,用于为OpenStack家族中的其它组件成员提供统一的认证服务,包括身份验证.令牌的发放和校验.服务列表.用户权限的定义等等 ...
- keepalived日志显示脚本能执行成功,但是amoeba程序没启动起来,单独执行脚本amoeba能启动成功,放到keepalived里面启动不起来
keepalived日志如图: 解决:keepalived还有crontab等计划任务自动执行脚本,并不会有本地用户的环境变量,需要在脚本里面加 . /etc/profile 引入本地用户的环境变量
- jmeter+nmon+crontab简单的执行接口定时压测
一.概述 临时接到任务要对系统的接口进行压测,上面的要求就是:压测,并发2000 在不熟悉系统的情况下,按目前的需求,需要做的步骤: 需要有接口脚本 需要能监控系统性能 需要能定时执行脚本 二.观察 ...
- The Sum of the k-th Powers(Educational Codeforces Round 7F+拉格朗日插值法)
题目链接 传送门 题面 题意 给你\(n,k\),要你求\(\sum\limits_{i=1}^{n}i^k\)的值. 思路 根据数学知识或者说题目提示可知\(\sum\limits_{i=1}^{n ...
- Educational Codeforces Round 64 (Rated for Div. 2)题解
Educational Codeforces Round 64 (Rated for Div. 2)题解 题目链接 A. Inscribed Figures 水题,但是坑了很多人.需要注意以下就是正方 ...
- 学习app开发思路
1.首先在学习之前进行一次或者是整体或者是部分的检测,当第一次检测就通过,则可以认为是熟练掌握的东西(可以在后期对其进行验证是否是熟练)2.后面的学习过程,对回答的正确与否以及从第一次开始学习到目前为 ...
- UVA11424 GCD - Extreme (I)[数论]
其实这题我也没太明白... 我们要求 \[ \sum_{i=1}^{N-1}\sum_{j=i+1}^Ngcd(i,j) \] 引理: 我们要求\(gcd(i,j)=k\)的个数,可转化为求\(gcd ...
- Alpha冲刺(7/10)——2019.4.30
所属课程 软件工程1916|W(福州大学) 作业要求 Alpha冲刺(7/10)--2019.4.30 团队名称 待就业六人组 1.团队信息 团队名称:待就业六人组 团队描述:同舟共济扬帆起,乘风破浪 ...
- HDU-2196-Computer(树上DP)
链接: http://acm.hdu.edu.cn/showproblem.php?pid=2196 题意: A school bought the first computer some time ...