C#获取EIP内存地址

约翰尼 5

我试图找到(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>通用方法的地址,但通常不会将其存储在方法表中,它们是在运行时构建的。
所以我想如果我能打印出当前正在执行的行之一的地址,我会更接近弄清楚它。

如何获取特定行指令的内存地址?

西麦克夏普菲斯

GetNativeOffsetstackframe方法就是这样做的。有点令人惊讶的结果是字符串和整数特化的值相同,而 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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章