c++ - 如何从dll注入进程的受害者进程调用静态库静态类成员函数
问题描述
我已经成功地用 dll 注入钩住了一个受害者应用程序。我现在需要调用受害者进程的未导出单例函数。这可能吗,我该怎么办?
虽然我有受害者进程的目标文件等,但我无法重建/部署新版本,所以我不能只创建一个带有导出链接的函数。
我在我的钩子过程中尝试了代码:
#include "VictimSingleton.h"
//...
void SomeFuncInHook()
{
VictimSingleton *vs = VictimSingleton::Get();
vs->DoThing();
}
内部 Get() 的实现如下:
VictimSingleton* VictimSingleton::Get()
{
static VictimSingleton singleton;
return &singleton;
}
预期结果:当从我的钩子或我的受害者进程调用时,VictimSingleton::Get() 返回相同的地址。
实际结果: Get 返回的指针虽然有效,但指向与受害进程使用的不同的 VictimSingleton。
我想这是因为它是两个独立的翻译单元,所以当从我的钩子进程调用时,它会创建一个不同版本的单例。
解决方案
如果函数没有导出,你没有 PDB 并且没有嵌入调试符号,那么首先你必须使用反汇编程序(如 IDA Pro)找到函数。如果它是一个虚函数,那么找到它会容易得多,因为您可以使用 IDA 插件(例如 Class Informer)公开运行时类型信息,这将为您提供所有 vtable 函数的列表。
一旦你有了函数的地址,你需要反转它的调用约定和它的参数。这很可能是一个 __thiscall 函数,因为它是一个成员函数。
接下来,为了调用成员函数,您需要一个类实例作为 this 指针传递。为此,您还可以找到类的构造函数并调用它,使用它的返回作为您的实例。
接下来,您需要调用该函数。要调用 __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);
推荐阅读
- angular - 以角度动态加载 twitter-feed
- c - pthread_cond_wait 是否锁定互斥锁和虚假唤醒
- javascript - Gatsby.js:如何将所有 *.js 文件迁移到 *ts?
- docker - 如何使用 ASP.Net Core 从 docker 容器连接到 DB2?
- regression - 将平面拟合到 3D 中的许多点
- reactjs - FlatList 没有在组件中呈现
- angular - Angular 异步管道与路由器相结合在开发构建和生产构建中表现出不同的行为
- java - 无法获得连接,DataSource 无效:“java.sql.SQLException:找不到适合 dataSource 的驱动程序”
- java - 为什么 Hibernate 4 可能比 JdbcTemplate 更快?
- c - 我认为我超出了此过程的可用内存。有人可以看看并验证吗?