我试图找到(EIP)指令指针正在执行的内存地址。我有一个非常简单的程序:
internal class Program
{
private static void Main(string[] args)
{
var sample = new Sample();
var val = sample.GenericMethod("Nippies");
Console.ReadLine();
}
}
public class Sample
{
public int GenericMethod<T>(T input)
{
//How can I get the current memory address
var currentMemoryAddress = "";
Console.WriteLine(currentMemoryAddress );
return 5;
}
}
TBH 我正在尝试获取GenericMethod<T>
通用方法的地址,但通常不会将其存储在方法表中,它们是在运行时构建的。
所以我想如果我能打印出当前正在执行的行之一的地址,我会更接近弄清楚它。
如何获取特定行指令的内存地址?
GetNativeOffset
stackframe的方法就是这样做的。有点令人惊讶的结果是字符串和整数特化的值相同,而 Guid 的值不同。
这是一个更好的方法,它检索实际的 EIP 寄存器值。我在这里找到了组装位,并针对手头的问题对其进行了调整。
using ByteToFunc;
using System;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace eip
{
internal class Program
{
private static void Main(string[] args)
{
var vals = Sample.GenericMethod("Nibbles");
var valg = Sample.GenericMethod(Guid.NewGuid());
var vali = Sample.GenericMethod(42);
Console.ReadLine();
}
}
public class Sample
{
/* trap values: bad beef is bad food */
public static int[] EipEspEbpEsiEdiEbxHolder = new[] { 0xBADF00D, 0xBADBEEF, 0xBADF00D, 0xBADBEEF, 0xBADF00D, 0xBADBEEF };
public static int GenericMethod<T>(T input)
{
//How can I get the current memory address
var subjectAddress = GetAddress(nameof(Sample.SubjectMethod));
var holderAddress = GetEipEspEbpEsiEdiEbxHolder();
var captureRegisters = FuncGenerator.Generate<Action<int>, ActionInt>(
new byte[0].Concat(new byte[]
{
0xE8, 0x1C, 0x00, 0x00, 0x00 // call 28
})
.Concat(new byte[]
{
// save EIP, ESP, EBP, ESI, EDI to temp array
0x83, 0xC0, 0x1B, // add eax,0x1B (27 bytes)
0x89, 0x02, // mov DWORD PTR [edx],eax
0x89, 0x62, 0x04, // mov DWORD PTR [edx+0x4],esp
0x89, 0x6A, 0x08, // mov DWORD PTR [edx+0x8],ebp
0x89, 0x72, 0x0C, // mov DWORD PTR [edx+0xc],esi
0x89, 0x7A, 0x10, // mov DWORD PTR [edx+0x10],edi
0x89, 0x5A, 0x14, // mov DWORD PTR [edx+0x14],ebx
})
.Concat(new byte[]
{
0xB8, // mov eax
})
.Concat(subjectAddress)
.Concat(new byte[]
{
0xFF, 0xD0 // call eax
})
.Concat(new byte[]
{
0xC3 //retn
})
.Concat(new byte[]
{
// Helper function for getting EIP as it is inaccessible directly on x86_32
0x8B, 0x04, 0x24, // mov eax,DWORD PTR [esp]
0xC3 //retn
})
.ToArray()
);
captureRegisters(holderAddress);
Console.WriteLine($"EIP = { EipEspEbpEsiEdiEbxHolder[0].ToString("X") }");
return 5;
}
public static int SubjectMethod()
{
return 5;
}
private static int GetEipEspEbpEsiEdiEbxHolder()
{
unsafe
{
var typedReference = __makeref(EipEspEbpEsiEdiEbxHolder);
int* fieldAddress = (int*)*(int*)*(int*)&typedReference;
return (int)fieldAddress + 8;
}
}
private static byte[] GetAddress(string name)
{
return BitConverter.GetBytes((int)GetRawAddress(name)).ToArray();
}
private static IntPtr GetRawAddress(string name)
{
var methodHandle = typeof(Sample).GetMethod(name, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance).MethodHandle;
RuntimeHelpers.PrepareMethod(methodHandle);
return methodHandle.GetFunctionPointer();
}
}
}
要编译和运行,您可以使用一个简单的 Console 项目,并FuncGenerator
从这里通过 afish添加类:https ://gist.github.com/afish/8fd6cf8f8c196901b5e1a5ee1000ee68
结果:EIP 的三个不同值,这应该是预期的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句