gpt4 book ai didi

C# Hook vmtable

转载 作者:行者123 更新时间:2023-12-01 14:30:06 24 4
gpt4 key购买 nike

作为学习更多关于 c# 原生方面的副项目,我想在虚拟方法表中 Hook 一个虚拟方法。

我成功调用了函数,但是将指向虚方法的指针更改为我自己的方法时调用函数时崩溃。

我为了这个学习目的制作了一个小的 c++ 应用程序,就在这里

#include <iostream>
#include <conio.h>
using namespace std;

class Class
{
public:
virtual void Function ( ) = 0;
virtual void Function2 ( ) = 0;
virtual void Function3 ( ) = 0;
};


class ClassI : Class
{
public:
void Function ( )
{
cout << "Function1" << endl;
}

void Function2 ( )
{
cout << "Function2" << endl;
}

void Function3 ( )
{
cout << "Function3" << endl;
}


};



int main ( )
{
ClassI* a = new ClassI ( );
int aaaa = 10;

int* aaa = &aaaa;

cout << "AddressOfClass: " << &a << endl;
getch ( );

a->Function ( );

getch ( );
delete a;
return 0;
}

我得到一个Class指针的实例并输出它并等待输入。

输入后我运行我想要 Hook 的函数。

现在在我的 C# 端,我创建了一个 dll,该 dll 通过 clr 注入(inject)位于进程的内存空间中。

我通过多种方式验证了注入(inject)的有效性。

 public class EntryPoint
{
#region Delegates
private delegate void orgFunction();
private static orgFunction oFunction;
#endregion




public static void Hooked()
{
Console.WriteLine("HookedFunction");
oFunction();
}



[DllExport("DllMain",CallingConvention.Cdecl)]
public static void DllMain()
{

unsafe
{
Delegate Hook = new Action(Hooked);
IntPtr* vtable = (IntPtr*)*(IntPtr*)0x00F3FE10;
oFunction = Marshal.GetDelegateForFunctionPointer<orgFunction>(*(IntPtr*)vtable[0]);
uint OldProtection;
MUtil.MEMORY_BASIC_INFORMATION mbi;
MUtil.VirtualQuery((IntPtr)vtable, out mbi, (IntPtr)sizeof(MUtil.MEMORY_BASIC_INFORMATION));
MUtil.VirtualProtect(mbi.BaseAddress, (uint)mbi.RegionSize, 0x04, out OldProtection);
vtable[0] = Marshal.GetFunctionPointerForDelegate(Hook);
MUtil.VirtualProtect(mbi.BaseAddress, (uint)mbi.RegionSize, OldProtection, out OldProtection);
}
}
}

这就是我在 C# 端所做的。

在获得 oFunction 之后,为了测试我确实调用了它并删除了其他代码并且它起作用了。

但是 Hook 它一切都很好但是当我在 C++ 程序中发送一个输入并且它运行我们 Hook 的函数时,应用程序崩溃了。

每次运行c++程序时,我也会更新地址。

        [StructLayout(LayoutKind.Sequential)]
public struct MEMORY_BASIC_INFORMATION
{
public IntPtr BaseAddress;
public IntPtr AllocationBase;
public uint AllocationProtect;
public IntPtr RegionSize;
public uint State;
public uint Protect;
public uint Type;
}

[DllImport("kernel32.dll")]
public static extern UIntPtr VirtualQuery(IntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, IntPtr dwLength);


[DllImport("kernel32.dll", SetLastError = true)]
internal static extern bool VirtualProtect(IntPtr address, uint size, uint newProtect, out uint oldProtect);


编辑:

我决定做一个简单的小测试,我把 oFunction 改成了 vmtable[2]

oFunction = Marshal.GetDelegateForFunctionPointer<orgFunction>(*(IntPtr*) vtable[1]  );

上面的代码让我崩溃了,我很惊讶,这让我想到获取 ClassI 实例的地址可能会给出第一个函数的地址而不是 vmtable,我认为情况并非如此。


-

感谢您阅读本文,祝您早日/晚安。

最好的问候。

最佳答案

要执行 vmtable Hook ,您要做的就是用一个新函数指针覆盖 vtable 中的函数指针,为此您只需使用 VirtualProtect() 在必要时获取写入权限,然后使用 WriteProcessMemory() 覆盖它。

您需要手动反转 vtable 并使用 WriteProcessMemory() 手动覆盖它。

  1. 获取vtable的地址
  2. 添加 vTableIndex*4 或 vTableIndex*8(取决于 x86 与 x64)
  3. 用 WriteProcessMemory 覆盖这个地址

关于C# Hook vmtable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37914571/

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