使用v表thunk链接过程调用 [英] Using v-table thunks to chain procedure calls

查看:246
本文介绍了使用v表thunk链接过程调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在网上阅读了一些关于Vtable thunks的文章,我在某处读到thunk可以用于hook / chain过程调用。



是否可以实现? p>

有没有人知道如何工作,我也找不到好的资源解释thunk。
有什么建议吗?

解决方案

以v表thunk的方式实现原始thunk是最后的手段。



一般来说,thunk可以做到以下几点:


  1. 修正输入参数(例如,转换为其他格式)

  2. li>
  3. 清除步骤1 /修正输出参数

要查看其工作原理的示例,让我们来看看我们的好友Raymond Chen和他对调整器thunks的讨论:



http://blogs.msdn.com/oldnewthing/archive/2004/02/06/68695.aspx



他使用的thunk如下:

  [thunk]:CSample :: QueryInterface`adjustor { 4}':
sub DWORD PTR [esp + 4],4; this - = sizeof(lpVtbl)
jmp CSample :: QueryInterface

有一个类通过多个接口实现相同的方法,因此它有多个v表。 (如果你不知道COM,所有你需要知道的是它直接与v表一起使用,所以指向一个特定接口的指针必须包含该接口的所有方法的函数指针,以便。)



如果在特定插槽中使用不同的方法实现两个接口,则需要多个v表。但是,你只写一次重叠方法,所以该方法需要能够使用这个指针。为了做到这一点,编译器生成一个方法来执行必要的fixup并调用原来的实现。



因此,这个thunk执行以下步骤:


  1. 修正第一行中的输入参数,即隐藏的this指针。

  2. 调用真正的实现


  3. $ b

    这是通常,如果你使用 call 调用函数,它会返回给你,您必须 ret 回拨给您的来电者。由于没有清理做,编译器做一个优化,它将执行直接移动到实际的实现,让我们的实现的返回语句返回到你的调用者。这只是一个优化,而不是thunking的基本部分。例如,16/32位thunk将根据需要在16位和32位之间转换输入/输出参数,因此它不能跳过清除步骤;它必须调用,而不是 jmp



    道德的故事是:如果你需要做一些事情,如 jmp 优化,你不能直接写在C ++或你的其他高级语言的选择,继续编写汇编语言thunk。



    老实说,它听起来像是要求性能优化,大多数时候(1)编译器比我们想象的更好地优化;(2)它不会给你像你想象的改进。


    I was reading some articles on net regarding Vtable thunks and I read somewhere that thunks can be used to hook /chain procedures calls.

    Is it achievable?

    Does anyone know how that works , also I am not able to find good resource explaining thunks. Any suggestions for that?

    解决方案

    Implementing a raw thunk in the style of v-table thunks is a last resort. Whatever you need to accomplish can most likely be achieved with a wrapper function, and it will be much less painful.

    In general, a thunk does the following:

    1. Fix up the input parameters (e.g., convert to a different format)
    2. Call the real implementation
    3. Clean up step 1 / fix the output parameters

    To see an example of how it works, let's turn to our good friend Raymond Chen and his discussion of adjuster thunks:

    http://blogs.msdn.com/oldnewthing/archive/2004/02/06/68695.aspx

    The thunk he used was as follows:

    [thunk]:CSample::QueryInterface`adjustor{4}':
      sub     DWORD PTR [esp+4], 4 ; this -= sizeof(lpVtbl)
      jmp     CSample::QueryInterface
    

    As he describes, you have a class that implements the same methods through multiple interfaces, so it has multiple v-tables. (If you don't know COM, all you need to know is that it works with v-tables directly, so a pointer to a specific interface must contain function pointers to all the methods of that interface in order.)

    If you implement two interfaces with different methods in a particular slot, you need multiple v-tables. But, you only write the overlapping methods once, so that method needs to be able to work with both "this" pointers. To do that, the compiler generates a method that does the fixup necessary and calls the original implementation.

    So, this thunk does the following steps:

    1. Fix up the input parameters, namely the hidden "this" pointer, in the first line.
    2. Call the real implementation in the second line.
    3. Cleanup: none required (see below)

    This is where the jmp instruction comes in. Normally, if you were to call the function using call, it would return to you, and you'd have to ret back to your caller. Since there is no cleanup to do, the compiler does an optimization where it moves execution straight to the real implementation and let's the real implementation's return statement return to your caller. This is only an optimization, not a fundamental part of thunking. For example, 16/32-bit thunks will convert the input / output parameters between 16 and 32 bits as necessary, so it can't skip the cleanup step; it has to call, not jmp.

    The moral of the story is: if you need to do something, such as the jmp optimization, that you can't write directly in C++ or your other high level language of choice, go ahead and write an assembly language thunk. Otherwise, just write a wrapper and be done with it.

    Honestly, it sounds like you're asking for the performance optimization, and most of the time (1) the compiler is better at optimizing than we think and (2) it's not going to give you as big of an improvement as you think.

    这篇关于使用v表thunk链接过程调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆