Estoy teniendo un problema con C#, me gustaría obtener un puntero de un método en mi código, pero parece imposible. Necesito el puntero del método porque quiero no-op es el uso de WriteProcessMemory. ¿Cómo hago para conseguir el puntero?

Código de ejemplo

main()
{
    function1();
    function2();
}

function1()
{
    //get function2 pointer
    //use WPM to nop it (I know how, this is not the problem)
}
function2()
{
    Writeline("bla"); //this will never happen because I added a no-op.
}
  • Que no es válido código de C#. ¿qué estás tratando de hacer?
  • parece similar (muy) a esta pregunta here. también podría ayudar.
  • Se está acercando el problema en la (totalmente) de manera incorrecta. ¿Por qué quieres inefectiva el método? Usted puede hacer eso, pero de manera diferente, dependiendo de su código de llamada.
  • Ya que C# es un JITted idioma, el código de la función puede no existir en el momento de preguntar. Su aplicación de parches también pueden interferir con el CLR, ya que también juega divertidos juegos para hacer GC. En lugar de parches, el uso de la API de depuración.
  • Parece que están tratando de hackear algo. Suponiendo que usted no está haciendo algo ilegal, C++ es el mejor idioma para los de bajo nivel de hacks.
  • Jacot-Descombes no estoy nada de hacking. Estoy trabajando con un modding de la api en un juego. Necesito editar un método de juego que no se puede acceder a través de la api. Así que en lugar de la edición que yo podría nop es.
  • En realidad, usted puede con el Mariscal.GetFunctionPointerForDelegate, (la cual es utilizada internamente durante el PInvoke mecanismo para que pueda obtener las devoluciones de llamada en C# de código no administrado) – esto obliga a un JIT de el método, si no está ya compilado. Pero es que además el punto. Lo user1276333 está haciendo es una mala idea – la JITted código es unpredicable y nunca deben ser echadas a perder.
  • Posibles duplicados de Cómo almacenar un puntero a función en C#

InformationsquelleAutor user1276333 | 2012-03-17

5 Comentarios

  1. 34

    Sé que esto es muy antiguo, pero un ejemplo de algo parecido a un puntero a función en C# sería como este:

    class Temp 
    {
       public void DoSomething() {}
       public void DoSomethingElse() {}
       public void DoSomethingWithAString(string myString) {}
       public bool GetANewCat(string name) { return true; }
    }

    …y luego, en su principal o donde sea:

    var temp = new Temp();
    Action myPointer = null, myPointer2 = null;
    myPointer = temp.DoSomething;
    myPointer2 = temp.DoSomethingElse;

    Luego llamar a la función original,

    myPointer();
    myPointer2();

    Si usted tiene argumentos a sus métodos, entonces es tan simple como añadir argumentos genéricos para su Acción:

    Action<string> doItWithAString = null;
    doItWithAString = temp.DoSomethingWithAString;
    
    doItWithAString("help me");

    O si usted necesita devolver un valor:

    Func<string, bool> getACat = null;
    getACat = temp.GetANewCat;
    
    var gotIt = getACat("help me");
    • Wow, gran respuesta. Tal vez no se concreta a esta pregunta, pero he aprendido algo y resolvió mi problema.
    • +1 Mejor respuesta! Gracias por compartir ejemplos para cada uno de los escenarios (void -> void, args -> void, args -> return)
  2. 22

    EDIT: no entendí tu pregunta y no veo el poco acerca de querer NOP una declaración con la raw de la memoria de la manipulación. Me temo que esto no es recomendable porque, como Raymond Chen dice, el GC se mueve cosas en la memoria (de ahí el ‘anclados’ palabra clave ‘ en C#). Usted probablemente puede hacer con la reflexión, pero su pregunta sugiere usted no tiene un fuerte arraigo en el CLR. De todos modos, volver a la original de mi irrelevante respuesta (donde pensaba que sólo quería información sobre cómo utilizar delegados):

    C# no es un lenguaje de secuencias de comandos 😉

    De todos modos, C# (CLR) tiene la función de «punteros» – excepto que son llamados «delegados» y con establecimiento inflexible de tipos, lo que significa que usted necesita para definir la firma de la función en adición a la función que desea llamar.

    En su caso, tendría que tener algo como esto:

    public static void Main(String[] args) {
    
        Function1();
    
    }
    
    //This is the "type" of the function pointer, known as a "delegate" in .NET.
    //An instance of this delegate can point to any function that has the same signature (in this case, any function/method that returns void and accepts a single String argument).
    public delegate void FooBarDelegate(String x); 
    
    
    public static void Function1() {
    
        //Create a delegate to Function2
        FooBarDelegate functionPointer = new FooBarDelegate( Function2 );
    
        //call it
        functionPointer("bla");
    }
    
    public static void Function2(String x) {
    
        Console.WriteLine(x);
    }
    • Que puede nop es (sortove). Crear un Function3 que no tiene cuerpo y cambiar el delegado Function3 y han Main llamar al delegado.
    • delegar no es un puntero a función. No es función de puntero y se llama IntPtr. Verificación: El Mariscal.GetFunctionPointerForDelegate método, por ejemplo.
    • Que es incorrecto, lo siento. IntPtr representa cualquier valor de puntero, no sólo los punteros a función – y no se puede «llamar» a un IntPtr bien. El GetFunctionPointerForDelegate método es dejar que pase un raw de la función de puntero (representado por el IntPtr) a código nativo. También tenga en cuenta que usted no puede manipular fácilmente IntPtr valores en C#. Mi punto es que semánticamente un delegado es a (encapsulado) puntero a función, pero es que mejores que los crudos punteros a función.
  3. 14
    public string myFunction(string name)
    {
        return "Hello " + name;
    }
    
    public string functionPointerExample(Func<string,string> myFunction)
    {
        myFunction("Theron");
    }

    Func functionName.. la uso para pasar los métodos de alrededor. No tiene sentido en este contexto, pero eso es básicamente cómo se usaría

  4. 2

    Me gustaría es útil

    class Program
    {
    
        static void Main(string[] args)
        {
            TestPointer test = new TestPointer();
            test.function1();
        }
    }
    class TestPointer
    {
        private delegate void fPointer(); //point to every functions that it has void as return value and with no input parameter
        public void function1()
        {
            fPointer point = new fPointer(function2);
            point();
        }
        private void function2()
        {
            Console.WriteLine("Bla");
        }
    }
  5. 1

    La reescritura de un método no se puede hacer directamente desde código administrado, sin embargo el no administrado .red de perfiles de la api se puede utilizar para hacer esto. Ver este artículo de msdn, por ejemplo, sobre cómo usarlo.

Dejar respuesta

Please enter your comment!
Please enter your name here