gpt4 book ai didi

c++ - 更改外部类的 VTable

转载 作者:太空狗 更新时间:2023-10-29 23:05:50 26 4
gpt4 key购买 nike

经过一些谷歌搜索后,我找到了一种修改类的 VTable 的方法,但在我的例子中,我只有一个指向我的类的指针以及一个将其转换为的接口(interface)。我需要将其中一个函数(在 DLL 中;没有源代码)重定向到我的一个函数。问题是我不知道函数在哪个索引上,所以为了找到它,我尝试扫描 VTable 以查找指向该函数的指针。

有什么办法吗?

到目前为止,这是我的代码:

typedef DWORD (__thiscall *CW_FUNC)();

class ClassWriter
{
public:
PVOID m_hObj;
PVOID *__vfptr;
PVOID m_old[256];
void SetObj(PVOID hObj)
{
m_hObj = hObj;
__vfptr = *(PVOID **)hObj;
}
void AddOverride(int offset, PVOID newfunc)
{
DWORD dwNull;
m_old[offset] = __vfptr[offset];
VirtualProtect(__vfptr + offset * 4, 4, PAGE_EXECUTE_READWRITE, &dwNull);
__vfptr[offset] = newfunc;
}
int GetOffset(PVOID func)
{
for (int i = 0; __vfptr[i] != NULL; i++)
{
if (func == __vfptr[i]) return i;
}
}
CW_FUNC GetFunc(int offset)
{
return (CW_FUNC)m_old[offset];
}
};

void WINAPI ChangeFunc()
{
ClassWriter cw;
HMODULE hMod = GetModuleHandle("dll_to_change.dll");
IMyInterface *myObj = (IMyInterface*)GetProcAddress(hMod, "GetMyClass")();
cw.SetObj(myObj);
int d = cw.GetOffset(myObj->MyFunction);
cw.AddOverride(d, OverrideFunction);
}

最佳答案

所以对于所有看到这个问题但现在真的不知道该怎么做的人:

我正在使用 ollydbg,但您可以使用任何其他调试器/转储器。

执行此操作的最佳方法是将您的代码放入 dll 中。确保执行你的函数,否则编译器不会编译它(至少对我而言)

void OverrideFunction()
{
HMODULE hMod = GetModuleHandle("mydll.dll"); // If not loaded yet use LoadLibrary()
IMyInterface *myObj = (IMyInterface*)GetProcAddress(hMod, "GetMyObject")(); // Get the pointer to your object
char buffer[64];
sprintf_s(buffer, "0x%X", OverrideFunction); // Print position of current function into buffer
MessageBox(0, buffer, "", 0);
myObj->MyFunction(); // Put in your function
}

现在要么执行你的代码直到 MessageBox() 并在调试器中打开该地址,要么如果你的编译器创建了一个导出函数,你可以直接转到 YourDll.OverrideFunction

在下面寻找一行,它是这样的(如果你的编译器检测到名字)

CALL DWORD PTR DS:[<&USER32.MessageBoxA>]

CALL DWORD PTR [YourDll._imp__MessageBoxA]

之后的下一个 CALL 应该是你的类函数,在我的例子中:

CALL DWORD PTR DS:[EAX+34]

您的偏移量是 0x34,也就是 52(记住要始终计算十六进制数)。要获得 VTable 中的索引,您必须除以 4(指针的大小),在我的例子中为 13。

void __fastcall NewFunc(IMyInterface *myObj, int null, (additional params)) // fastcall stores the first 2 params int ECX and EDX, thiscall stores the this-object in ECX
{
// Your code
}

void OverrideFunction()
{
DWORD dwNull;
HMODULE hMod = GetModuleHandle("mydll.dll"); // If not loaded yet use LoadLibrary()
IMyInterface *myObj = (IMyInterface*)GetProcAddress(hMod, "GetMyObject")(); // Get the pointer to your object
PVOID *vtable = *(PVOID**)myObj; // The first int in your object is a pointer to the vtable
// OldFunc = vtable[13]; // You might want to call your old function again, so save the pointer
VirtualProtect(&vtable[13], 4, PAGE_EXECUTE_READWRITE, &dwNull); // Always unprotect the memory
vtable[13] = NewFunc;
}

现在每次 MyObject 调用 MyFunction 时,都会执行 NewFunc

关于c++ - 更改外部类的 VTable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17761484/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com