如何从dll注入进程的受害者进程调用静态库静态class成员函数

How to call static library static class member function from victim process of dll-injection process

我已经成功地使用 dll 注入挂钩了一个受害应用程序。 我现在需要调用受害者进程的一个未导出的单例函数。 这可能吗,我该怎么做?

虽然我有受害者进程的目标文件等,但我无法rebuild/deploy新版本,所以我不能只创建一个带有导出链接的函数。

我在钩子过程中尝试过代码:

#include "VictimSingleton.h"
//...
void SomeFuncInHook()
{
  VictimSingleton *vs = VictimSingleton::Get();
  vs->DoThing();
}

内部 Get() 的实现方式如下:

VictimSingleton* VictimSingleton::Get()
{
  static VictimSingleton singleton;
  return &singleton;
}

预期结果: VictimSingleton::Get() returns 从我的挂钩或我的受害者进程调用时的相同地址。

实际结果: Get 返回的指针虽然有效,但指向与受害进程使用的不同的 VictimSingleton。

我想那是因为它是两个独立的翻译单元,所以当从我的挂钩进程调用时它会创建一个不同版本的单例。

如果该函数未导出,您没有 PDB 且未嵌入调试符号,那么首先您必须使用 IDA Pro 等反汇编程序找到该函数。如果它是一个虚函数,那么找到它会容易得多,因为您可以使用 IDA 插件(例如 Class Informer)公开 运行 时间类型信息,这将为您提供所有 vtable 函数的列表.

获得函数地址后,您需要反转它的调用约定和参数。这很可能是一个 __thiscall 函数,因为它是一个成员函数。

接下来,为了调用成员函数,您需要一个 class 实例作为 t​​his 指针传递。为此,您还可以找到 class 的构造函数并调用它,使用它的 return 作为您的实例。

接下来,您需要调用函数。要调用 __thiscall 函数,您实际上将其称为 __fastcall 并将您创建的对象的地址作为 this 指针作为第一个参数传递,第二个变量为 0,然后是实际函数参数。

第二个参数是零,因为 __fastcall 需要在 EDX 中传递一个变量。

typedef一个函数指针原型,创建这个函数指针的一个实例,给它赋值函数的地址,然后调用它。

typedef void(__fastcall* fFunc)(void* thisptr, void* not_edx, float arg1, int arg2);

fFunc Func = (fFunc)0xDEADC0DE; //address of function

Func(objectPtr, 0, 1.0f, 2);