使用C#调用其它exe中的函数

29 篇文章 1 订阅
2 篇文章 0 订阅

需求:

目前想改造一个带有窗口的exe文件,将其使用WPF来实现。
这个exe文件中最重要的一段内容就是一个函数(int f(int a,int b)),使用这个f函数来实现其核心的计算功能。

问题:

当前,没有exe文件的源码,因此无法使用C#简单地重写这个f函数。但我们可以考虑在C#代码中直接调用这个函数来进行计算。

困难:

exe没有导出这个f函数,因此在C#中无法直接使用DllImport来进行PInvoke调用。

方法:

1、在C#中通过Windows Api中的LoadLibrary把这个exe文件加载到内存。
2、使用IDA找到f函数在这个exe文件中的偏移量。
3、在C#中通过f函数的地址直接调用。

C语言演示代码:

#include <iostream>

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

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

这里有一个f函数,还有一个main函数,其中我们要关心的计算函数为f。main是启动函数,我们不用关心。
这里f函数,并未导出。也就是说,在程序的函数导出表中,不存在f函数。其它程序无法使用常用的方式来调用它。

IDA查看函数位置

在这里插入图片描述

C#演示代码

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

在C#的启动函数main中,首先将这个exe文件加载到内存,这会得到一个加载的地址。
接下来通过偏移量 0x12380,计算出这个函数在内存中的实际位置。
然后,通过这个地址来调用。
这里需要注意,调用的时候,需要用到委托(delegate ),它可以将一个函数地址转换成一个函数,从而按照C#的标准来调用。

执行结果:

30

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

后记

另外,你还可以看到,程序运行的时候,只调用了C语言编写的f函数,C语言编写的main函数并未调用。从而达到了我们的目的,完成了我们的需求。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵庆明老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值