web-dev-qa-db-fra.com

Pointeur de fonction C #?

J'ai un problème avec C #, j'aimerais avoir un pointeur sur une méthode dans mon code, mais cela semble impossible. J'ai besoin du pointeur de la méthode parce que je veux l'interrompre en utilisant WriteProcessMemory. Comment puis-je obtenir le pointeur?

Exemple de code

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.
}
24
user1276333

Je sais que c'est très ancien, mais un exemple de quelque chose comme un pointeur de fonction en C # serait comme ceci:

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

... puis dans votre main ou n'importe où:

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

Ensuite, pour appeler la fonction d'origine,

myPointer();
myPointer2();

Si vous avez des arguments dans vos méthodes, c'est aussi simple que d'ajouter des arguments génériques à votre action:

Action<string> doItWithAString = null;
doItWithAString = temp.DoSomethingWithAString;

doItWithAString("help me");

Ou si vous devez renvoyer une valeur:

Func<string, bool> getACat = null;
getACat = temp.GetANewCat;

var gotIt = getACat("help me");
32
outbred

EDIT: J'ai mal lu votre question et je n'ai pas vu le peu de vouloir NOP une déclaration avec la manipulation de mémoire brute. Je crains que ce ne soit pas recommandé car, comme le dit Raymond Chen, le GC déplace les choses en mémoire (d'où le mot-clé 'épinglé' en C #). Vous pouvez probablement le faire avec réflexion, mais votre question suggère que vous n'avez pas une bonne compréhension du CLR. Quoi qu'il en soit, revenons à ma réponse originale non pertinente (où je pensais que vous vouliez juste des informations sur la façon d'utiliser les délégués):

C # n'est pas un langage de script;)

Quoi qu'il en soit, C # (et le CLR) a des "pointeurs de fonction" - sauf qu'ils sont appelés "délégués" et sont fortement typés, ce qui signifie que vous devez définir la signature de la fonction en plus de la fonction que vous souhaitez appeler.

Dans votre cas, vous auriez quelque chose comme ceci:

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);
}
22
Dai
public string myFunction(string name)
{
    return "Hello " + name;
}

public string functionPointerExample(Func<string,string> myFunction)
{
    myFunction("Theron");
}

Func functionName .. utilisez-le pour passer des méthodes. Cela n'a aucun sens dans ce contexte, mais c'est essentiellement la façon dont vous l'utiliseriez

14
Thiren Govender

J'aimerais que ce soit utile

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");
    }
}
2
Mahdi

La réécriture d'une méthode ne peut pas être effectuée directement à partir du code managé, cependant l'api de profilage .net non managé peut être utilisé pour ce faire. Voir l'article this msdn pour savoir comment l'utiliser.

1
Mike Zboray