更改外部类的VTable
Changing the VTable of an external Class
经过一些谷歌搜索,我找到了一种修改类的VTable的方法,但在我的情况下,我只有一个指向类的指针和一个将其转换到的接口。我需要将其中一个函数(在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()并在调试器中打开该地址,或者如果编译器创建了导出函数,您可以直接转到YourDell.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,而不是
相关文章:
- 在函数内部的声明中初始化数组,并在外部使用它
- 使外部项目可用于find_package CMake
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- 使用外部SDK工具链文件在VisualStudio上生成项目编译错误
- C++:来自外部文件的Trivia
- 从函数角度看ID到文件路径的内部与外部映射
- C++:将外部库链接到dll库
- spdlog标头仅与外部fmt一起使用.spdlog错误:'内部':不是'fmt'
- 节俭并发:未解决的外部问题
- 如何在c++中从git建立外部库
- 未解析的外部符号_MsiLocateComponentW@12.
- 如何使用对C函数和类对象的外部调用来处理C++头文件
- 具有外部"c"和程序集的未定义函数
- 为什么导入Mixed native/CLR lib.dll的本机C++应用程序没有在Mixed lib.dll中的外部变
- 在C++中使用 gRPC 时未解析的外部符号
- 在类函数中初始化外部作用域变量
- 如果全局变量默认是外部变量,为什么要添加"extern"关键字?
- 调用外部函数,无法指定类型 C++/MVS
- 同时具有"外部"和"内联"说明符的变量
- LibPrivoxy: 未解析的外部符号 __declspec(dllimport) int __stdcall Sta