我正在尝试从System
程序集中重定向方法。到目前为止,我已经尝试从两个程序集中重定向方法:System.Text.Encoding
和System.Configuration.ConfigurationManager
。
在两种情况下,我最终都遇到以下异常:
System.AccessViolationException:
'Attempted to read or write protected memory.
This is often an indication that other memory is corrupt.'
如果我将重定向代码应用于自己的程序集,它将按预期工作。
以下是我使用的完整测试程序,该程序针对GetEncodings
程序集的System.Text.Encoding
方法:
using System;
using System.Runtime.CompilerServices;
using System.Text;
namespace RuntimeMethodReplace
{
internal class Program
{
internal static void Main(string[] args)
{
Console.WriteLine(System.Text.Encoding.GetEncodings());
Injection.Install();
Console.WriteLine(System.Text.Encoding.GetEncodings());
Console.Read();
}
}
internal static class Injection
{
public static EncodingInfo[] GetEncodings()
{
return null;
}
public static void Install()
{
var methodToReplace = typeof(System.Text.Encoding).GetMethod("GetEncodings");
var methodToInject = typeof(Injection).GetMethod("GetEncodings");
RuntimeHelpers.PrepareMethod(methodToReplace.MethodHandle);
RuntimeHelpers.PrepareMethod(methodToInject.MethodHandle);
unsafe
{
if (IntPtr.Size == 4)
{
var inj = (int*)methodToInject.MethodHandle.Value.ToPointer() + 2;
var tar = (int*)methodToReplace.MethodHandle.Value.ToPointer() + 2;
#if DEBUG
var injInst = (byte*)*inj;
var tarInst = (byte*)*tar;
var injSrc = (int*)(injInst + 1);
var tarSrc = (int*)(tarInst + 1);
*tarSrc = (int)injInst + 5 + *injSrc - ((int)tarInst + 5);
#else
*tar = *inj;
#endif
}
else
{
var inj = (long*)methodToInject.MethodHandle.Value.ToPointer() + 1;
var tar = (long*)methodToReplace.MethodHandle.Value.ToPointer() + 1;
#if DEBUG
var injInst = (byte*)*inj;
var tarInst = (byte*)*tar;
var injSrc = (int*)(injInst + 1);
var tarSrc = (int*)(tarInst + 1);
*tarSrc = (int)injInst + 5 + *injSrc - ((int)tarInst + 5);
#else
*tar = *inj;
#endif
}
}
}
}
}
第65行引发了异常,这是上述else语句中的以下代码位:
*tarSrc = (int)injInst + 5 + *injSrc - ((int)tarInst + 5);
我目前正在猜测是否会发生此异常,因为System.Text.Encoding
程序集在单独的应用程序域(?)中运行。我将不胜感激能为我提供解决方案的任何提示或答案。