Thunk 应用

51 篇文章 0 订阅
46 篇文章 0 订阅

Thunk 应用

作者:RobertBaker

在网上看到很多 Thunk 的介绍,但是很少有几个实际的 Demo,这里用一个实例说明Thunk的用法。

以下是所使用的 Thunk。(CAuxStdThunk, 从网上找的,不知道作者,如有冒犯还请原谅。)

// AUX Thunk, 全局函数 -> 类成员函数
#pragma pack(push, 1)

template <class T>
class CAuxStdThunk
{
 BYTE m_mov;   // mov eax, %pThis
 DWORD m_this;   //
 DWORD m_xchg_push;  // xchg eax, [esp] : push eax
 BYTE m_jmp;   // jmp func
 DWORD m_relproc;  // relative jmp

public:
 typedef void (_stdcall T::*TMFP)();

 void Init(TMFP method, const T *pThis)
 {
  union {
   DWORD func;
   TMFP method;
  } addr;

  addr.method = method;
  m_jmp  = 0xE9;
  m_mov  = 0xB8;
  m_this  = (DWORD)(PVOID) pThis;
  m_xchg_push = 0x50240487;
  m_relproc = addr.func - (DWORD)(PVOID)(this + 1);

  FlushInstructionCache(GetCurrentProcess(), this, sizeof(*this));
 }

 FARPROC GetThunk() const { return (FARPROC) this; }
};

#pragma pack(pop)

//

这里是 Timer,它通过 Thunk 定期向自己的所有者调用 OnTimer。
#ifndef Timer_H
#define Timer_H

#include <Windows.h>

#include "Thunk.h"

const DWORD INVALID_EVENT_ID = (DWORD)-1;

// CTimer need the Windows Message Loop
template <class Owner>
class CTimer
{
 CAuxStdThunk<CTimer<Owner> > m_thunk; // Thunk 要放在类的最前面。
public:
 CTimer(Owner *pOwner = 0)
  : m_pOwner(pOwner),
   m_nIDEvent(INVALID_EVENT_ID)
 {
  m_thunk.Init((CAuxStdThunk<CTimer<Owner> >::TMFP) (CTimer<Owner>::TimerHandler), this);
 }
 ~CTimer()
 {
  Stop();
 }

 void SetOwner(Owner *pOwner) { m_pOwner = pOwner; }

 void Stop()
 {
  if (m_nIDEvent != INVALID_EVENT_ID) {
   KillTimer(NULL, m_nIDEvent);
  }
 }
 BOOL Start(UINT_PTR nIDEvent, UINT nElapse)
 {
  Stop();

  m_nIDEvent = SetTimer(NULL, nIDEvent, nElapse, (TIMERPROC) m_thunk.GetThunk());
  return (m_nIDEvent != INVALID_EVENT_ID);
 }

 void _stdcall TimerHandler(HWND, UINT nMessage, UINT nIDEvent, DWORD dwTime)
 {
  if (m_pOwner) {
   m_pOwner->OnTimer(nIDEvent, dwTime);
  }
 }

private:
 Owner *m_pOwner;
 UINT_PTR m_nIDEvent;
};

#endif

这里是使用 Timer 的方法。

#include <conio.h>
#include <iostream.h>

#include "Timer.h"

class CClock
{
public:
 CClock()
 {
  m_timer1.SetOwner(this);
  m_timer1.Start(0, 500);

  m_timer2.SetOwner(this);
  m_timer2.Start(0, 500);
 }

 void OnTimer(UINT nIDEvent, DWORD dwTime)
 {
  cout << "OnTimer " << nIDEvent << " " << dwTime << endl;
 }

private:
 CTimer<CClock> m_timer1;
 CTimer<CClock> m_timer2;
};

int main()
{
 CClock clock;
 MSG msg;
 while (GetMessage(&msg, NULL, 0, 0)) {
  if (kbhit()) {
   break;
  }
         DispatchMessage(&msg);
 }
 return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值