gpt4 book ai didi

c# - 交换属性 GetMethod 实现运行时

转载 作者:行者123 更新时间:2023-12-03 15:18:08 25 4
gpt4 key购买 nike

我目前正在尝试通过用一些 IL 替换它来交换属性获取实现。
我使用这个问题作为引用:How to replace a pointer to a pointer to a method in a class of my method inherited from the system class?

我唯一的区别是我的方法是通过 MethodBuilder 声明的:

MethodBuilder propertyGetBuilder = builder.DefineMethod
(
dynamicFunctionName,
MethodAttributes.Public,
propertyInfo.PropertyType,
Type.EmptyTypes
);

ILGenerator propertyGetIlGenerator = propertyGetBuilder.GetILGenerator();

propertyGetIlGenerator.Emit(OpCodes.Ldarg_0);
propertyGetIlGenerator.Emit(OpCodes.Ldstr, propertyInfo.Name);
propertyGetIlGenerator.Emit(OpCodes.Ldstr, relationKeyField.Name);
propertyGetIlGenerator.Emit(OpCodes.Ldstr, relationAttribute.RelationColumn);
propertyGetIlGenerator.Emit(OpCodes.Call, loadRelationMethod);

propertyGetIlGenerator.Emit(OpCodes.Ret);

这向名为 BeforeGet{PropertyName} 的生成类型添加了一个新函数。

生成新类型后,我将其实例化以确保内存地址存在: dynamic fakeType = Activator.CreateInstance(type);
我从现有的类中检索 propertyInfo GetMethod,以及新创建的 BeforeGet{PropertyName} fakeType 类类型。

之后,在此函数中使用了两个 MethodInfo:
RuntimeHelpers.PrepareMethod(methodA.MethodHandle);
RuntimeHelpers.PrepareMethod(methodB.MethodHandle);

unsafe
{
if (IntPtr.Size == 4)
{
int* inj = (int*)methodA.MethodHandle.Value.ToPointer() + 2;
int* tar = (int*)methodB.MethodHandle.Value.ToPointer() + 2;
#if DEBUG
Console.WriteLine("\nVersion x86 Debug?\n");

byte* injInst = (byte*)*inj;
byte* tarInst = (byte*)*tar;

int* injSrc = (int*)(injInst + 1);
int* tarSrc = (int*)(tarInst + 1);

*tarSrc = (((int)injInst + 5) + *injSrc) - ((int)tarInst + 5);
#else
*tar = *inj;
#endif
}
else
{
long* inj = (long*)methodA.MethodHandle.Value.ToPointer() + 1;
long* tar = (long*)methodB.MethodHandle.Value.ToPointer() + 1;
#if DEBUG
Console.WriteLine("\nVersion x64 Debug\n");
byte* injInst = (byte*)*inj;
byte* tarInst = (byte*)*tar;

int* injSrc = (int*)(injInst + 1);
int* tarSrc = (int*)(tarInst + 1);

*tarSrc = (((int)injInst + 5) + *injSrc) - ((int)tarInst + 5);
#else
*tar = *inj;
#endif
}
}

运行此代码后,我将在我的程序中执行以下代码: LoadedTag.Item.ItemID;其中 LoadedTag 是应该获得 Item 的新实现的类。 Getter 但是我得到了一个空引用异常,因为该函数没有被替换。

但是,如果我在即时窗口中执行此代码,则确实设置了 ItemID 并调用了拦截函数。

我认为这个问题是由于垃圾收集器删除了 fakeType,它保存了指向方法交换期间使用的函数的实际指针。
如果是这样,我应该如何解决这个问题?

先感谢您!

如果需要,请查询完整代码,我会将其上传到 Github。

最佳答案

从您的代码中不清楚,但是:“fakeType”是否与您交换指针的范围在同一范围内?

如果您更改了范围,并且 fakeType 确实不可用,则垃圾收集器可能会使内存空间无效。

因此,我会尝试在生成 faketype 后立即移动“交换代码”以测试这是否是问题所在。

干杯,希望它有帮助

关于c# - 交换属性 GetMethod 实现运行时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48159656/

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