Я много читал о возможностях перезаписи методов C # / .NET во время выполнения.Посмотрев пример кода, есть один вопрос, на который я не могу ответить. очень простой PoC для замены метода во время выполнения может выглядеть следующим образом:
class Program
{
public static void A(int x)
{
Console.WriteLine("A: " + x);
}
public static void B(int x)
{
Console.WriteLine("B: " + x);
}
internal static void Main(string[] args)
{
MethodInfo a = null;
MethodInfo b = null;
foreach(MethodInfo mi in typeof(Program).GetMethods())
{
if (mi.Name == "A" || mi.Name == "B")
{
// make sure methods are jitted
RuntimeHelpers.PrepareMethod(mi.MethodHandle);
}
if (mi.Name == "A") a = mi;
if (mi.Name == "B") b = mi;
}
unsafe
{
if (IntPtr.Size == 4) // x86
{
int* inj = (int*)a.MethodHandle.Value.ToPointer() + 2;
int* tar = (int*)b.MethodHandle.Value.ToPointer() + 2;
*tar = *inj;
}
else // x64
{
ulong* inj = (ulong*)a.MethodHandle.Value.ToPointer() + 1;
ulong* tar = (ulong*)b.MethodHandle.Value.ToPointer() + 1;
*tar = *inj;
}
}
Program.A(0);
Program.B(1);
Console.ReadLine();
}
}
Как и следовало ожидать, вызов A(0) and B(1)
теперь печатает:
A: 0
A: 1
Все идет нормально.Тем не менее, я также видел пример, где кажется, что не делается никакого различия между кодом x86 / x64:
...
int* inj = (int*)(a.MethodHandle.Value.ToPointer() + 8);
int* tar = (int*)(b.MethodHandle.Value.ToPointer() + 8);
...
В этом случае 8 добавляется к указателю.Может ли кто-нибудь объяснить причину этого?Кроме того, что именно означает это смещение указателя?Если кто-то может порекомендовать хорошие материалы для чтения о C # /. NET / CLR, пожалуйста, дайте мне знать.
Спасибо