C#函数指针

本文关键字:指针 函数 | 更新日期: 2023-09-27 18:28:12

我的C#有问题,我想在代码中获得一个方法的指针,但这似乎不可能。我需要该方法的指针,因为我不想使用WriteProcessMemory对其进行操作。我该如何获得指针?

示例代码

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

C#函数指针

我知道这已经很老了,但C#中类似函数指针的例子是这样的:

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

然后在你的主屏幕或任何地方:

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

然后调用原始函数

myPointer();
myPointer2();

如果您的方法有参数,那么只需在Action:中添加通用参数即可

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

或者,如果您需要返回一个值:

Func<string, bool> getACat = null;
getACat = temp.GetANewCat;
var gotIt = getACat("help me");

EDIT:我误解了你的问题,没有看到想要通过原始内存操作来NOP语句的意思。恐怕这是不推荐的,因为正如Raymond Chen所说,GC在内存中移动内容(因此C#中有"pinned"关键字)。你可能可以通过反思来做到这一点,但你的问题表明你对CLR没有很强的把握。无论如何,回到我最初的无关答案(我以为你只是想了解如何使用代理):

C#不是一种脚本语言;)

无论如何,C#(和CLR)都有"函数指针",只是它们被称为"委托"并且是强类型的,这意味着除了要调用的函数之外,还需要定义函数的签名。

在你的情况下,你会有这样的东西:

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);
}
public string myFunction(string name)
{
    return "Hello " + name;
}
public string functionPointerExample(Func<string,string> myFunction)
{
    return myFunction("Theron");
}

函数名称。。使用它来传递方法。在这种情况下没有任何意义,但这基本上就是你使用它的方式

实际上,在C#9 中引入了真正的函数指针

官方文件

来自链接:

可以使用delegate*语法定义函数指针。编译器将使用calli指令调用函数,而不是实例化委托对象并调用Invoke

文章中的示例示例:

static unsafe void function1()
{
    //get function2 pointer
    delegate*<void> ptr = &function2;
    // do something with ptr
}

我希望它是有用的

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

重写方法不能直接从托管代码中完成,但可以使用非托管的.net评测api来完成。有关如何使用的示例,请参阅这篇msdn文章