Use C# to call functions in other exe

need:

At present, I want to transform an exe file with a window and use WPF to realize it.
The most important part of this exe file is a function (int f(int a, int b)), use this f function to realize its core calculation function.

question:

Currently, there is no source code of the exe file, so it is not possible to simply rewrite this f function in C#. But we can consider calling this function directly in the C# code for calculation.

difficulty:

exe does not export this f function, so DllImport cannot be used directly in C# to make PInvoke calls.

method:

1. In C#, load the exe file into memory through LoadLibrary in Windows Api.
2. Use IDA to find the offset of the f function in this exe file.
3. Call directly through the address of the f function in C#.

C language demo code:

#include <iostream>

int f(int a,int b)
{
    
    
    return a + b;
}

int main()
{
    
    
    std::cout << "Hello World! C++\n";
}

There is an f function here, and a main function, where the calculation function we care about is f. main is the startup function, we don't need to care about it.
The f function here is not exported. That is to say, in the function export table of the program, the f function does not exist. Other programs cannot call it in the usual way.

IDA view function location

insert image description here

C# demo code

internal class Program
{
    
    
    //定义委托,对应于C语言中的函数原型
    //int f(int a,int b)
    public delegate int F(int a, int b);

    static void Main(string[] args)
    {
    
    
        IntPtr hLib = LoadLibrary("C:\\Users\\Zmrbak\\source\\repos\\ConsoleApplication1\\Debug\\ConsoleApplication1.exe");
        if (hLib == IntPtr.Zero)
        {
    
    
            Console.WriteLine("加载exe文件失败!");
            return;
        }

        //函数地址
        var offset = hLib + 0x12380;

        int a = 10;
        int b = 20;
        var a1 = (F)Marshal.GetDelegateForFunctionPointer(offset, typeof(F));

        if (a1 != null)
        {
    
    
            //调用函数
            var c = a1(a, b);
            Console.WriteLine(c);
        }
    }

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern IntPtr LoadLibrary(string lpFileName);
}

In the C# startup function main, first load the exe file into the memory, which will get a loading address.
Next, calculate the actual location of this function in memory through the offset 0x12380.
Then, use this address to call.
It should be noted here that when calling, you need to use a delegate (delegate), which can convert a function address into a function, so that it can be called according to the C# standard.

Results of the:

30

C:\Users\Zmrbak\source\repos\ConsoleApplication1\ConsoleApp1\bin\Debug\net6.0\ConsoleApp1.exe (进程 14816)已退出,代码为 0
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

postscript

In addition, you can also see that when the program is running, only the f function written in C language is called, and the main function written in C language is not called. So as to achieve our purpose and complete our needs.

Guess you like

Origin blog.csdn.net/u013667796/article/details/130024463