【问题标题】:Calling convention is wrong and I can't figure out. C++调用约定是错误的,我无法弄清楚。 C++
【发布时间】:2014-04-18 10:26:49
【问题描述】:

我试图绕过应用程序中的一个函数。我有它的来源。

class Foot : public Something, public SomethingElse {    
public:
    Foot( double SomethingAgain, double Somethings,
                      Blahblah *AnotherThing = NULL );

    virtual ~Foot();
    virtual void detourmepls( const char *ARGUMENT );
};

这是在头文件中定义的。

这是我用来定义它的,所以我会使用正确的地址从我的 dll 中调用它。

void (__cdecl* detourmepls)(const char *stuff);

这个虚拟 void 函数的真正调用约定是什么?

感谢任何帮助。

新的编辑和信息:

我正在使用 MS Detours 1.5

detourmepls = (void(__thiscall*)(void *Pthis,void *Unknown,const char *))DetourFunction((PBYTE)ADDRESS, (PBYTE)hookedFunction);

这就是我尝试绕道的方式(它非常混乱。)

【问题讨论】:

  • 我假设您将函数作为 C 回调传递,这是不可能的。如果注册回调函数允许传递用户数据,请编写一个静态函数并将其与“this”指针一起传递给注册函数。
  • 你遇到了什么错误?
  • 当我尝试调用原始函数时应用程序崩溃。
  • 你使用微软的弯路吗?如果是这样,这可能是相关的,因为您正在尝试取消非静态成员函数:stackoverflow.com/questions/11048176/… BTW 如果您发布更多代码(如何挂钩函数以及如何尝试调用它等),您可以获得更多帮助...)

标签: c++ windows calling-convention abi


【解决方案1】:

背景

带有虚函数的回调需要一个“this”对象来解析虚函数。虚函数指针实际上更像是一个 vtable“偏移量”(在存在多个虚拟双秘密继承的情况下相当麻烦;)。

__cdecl 不支持这些。

您注册回调的 API 是什么样的?这听起来像一个C-api。这些有时会无效*。如果没有,那么您需要将对象存储在其他位置。

回调只是函数,没有数据

如果它只是一个回调函数,没有用户数据,你需要将对象指针单独存储在你身边,并在你注册的静态函数中解析虚函数调用。

void registerCallback(void (__cdecl* callbackfn)(const char* stuff));

class Foo {
     static Foo* s_callback_object;

     ~Foo() { 
          // never hurts
          if (this == s_callback_object) 
              s_callback_object = 0; 
     } 

     static void Foo::callbackResolver(const char* stuff) {
          assert(s_callback_object);
          s_callback_object->detourmepls(stuff);     
     }
}

Fop* foo::s_callback_object = 0;

Foo myFoo;
Foo::s_callback_object = &myFoo;
registerCallback(&Foo::callBackResolver);

带有用户数据参数的回调函数:

(这是应该的,伙计们)

对于案例 2,用户数据,您可以将其转换为您的对象:

void registerCallback(void (__cdecl* callbackfn)(const char* stuff),
                     void *userdata);

class Foo {
     static void Foo::callbackResolver(const char* stuff, void *userdata) {
          Foo* foo = reinterpret_cast<Foo*>(userdata);
          foo->detourmepls(stuff);     
     }
}

Foo myFoo;
registerCallBack(&Foo::callbackResolver, &myFoo);

即使在普通的 C 编程中,后一种方案也非常有用,因此如果您编写自己的 API,请这样做。 :)

【讨论】:

  • 我正在使用 MS Detours 1.5
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多