分析DLL函数并编写程序调用它的问题

逆向工程 艾达 dll C#
2021-06-21 00:05:19

我在大型软件中有一个自定义的 DLL。DLL 压缩/解压缩图像文件。我需要单独使用 DLL 来将我的重要图像恢复为解压缩版本。我可以在 IDA pro 中看到它的功能,但我不确定我的发现是否正确。而且我不知道如何在 C# 中正确调用该函数。所附图片是我的 IDA pro 结果和我的测试 C# 程序(当然该程序不起作用)。请帮我。

IDA Pro 中的 DLL 函数

测试 C# 程序

1个回答

首先,按照两位评论者的建议,研究一下 ArcCompress 方法的语义。如果它真的返回一个 C 文件指针,你会在 C# 中用它做什么??不多,我想。您可能无法在那里关闭文件。

但无论如何,这里有两种从 C# 调用 ArcCompress 方法的可能性。作为一个小测试,首先是一个虚构的简单 ArcCompress C dll 函数,作为测试工具来查看指针是否正确编组。该函数必须声明为 extern "C" 以避免名称修改。

//Next line is from the header file
//#define PINVOKE_DLL_API __declspec(dllexport)
PINVOKE_DLL_API FILE* __cdecl ArcCompress(char* a1, char* a2, int a3)
{
    a1[2] = 0xfe;
    FILE* f = fopen("D:\\testfile.bin", "wb+");
    fwrite(a1, a3, 1, f);
    return f;
}

这个简单的函数接受您的字节数组,修改一个字节并将其写入文件,返回打开文件的文件指针。这里有两种从 C# 调用这个函数的可能性(在我的例子中,dll 被命名为“pinvoke_dll.dll”而不是“Arc.dll”):

  1. 缓冲区参数是普通引用,这里没有什么特别之处。但是,应该检查 .NET 垃圾收集器是否可能出现问题。假定数组已被初始化。

    [DllImport("pinvoke_dll.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern IntPtr ArcCompress(ref byte a,  ref byte b, Int32 c);
    
    private void button1_Click(object sender, EventArgs e)
    {
        IntPtr f = ArcCompress(ref a[0], ref b[0], a.Length );
    }
    
  2. 缓冲区参数是 C# 指针,就像普通的 C 指针一样。在这种情况下,您必须将您的方法标记为“不安全”(并选中项目属性中的相应复选框),并将指针标记为固定的,从而通知垃圾收集器不要触摸它们。

public unsafe partial class Form1 : Form { public Form1() { InitializeComponent(); } [DllImport("pinvoke_dll.dll", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr ArcCompress(byte* p1, byte* p2, Int32 c); byte[] a = new byte[10]{1,2,3,4,5,6,7,8,9,0}; byte[] b = new byte[10]{0,9,8,7,6,5,4,3,2,1}; private void button1_Click(object sender, EventArgs e) { fixed (byte* p1 = &a[0], p2 = &b[0]) { IntPtr f = ArcCompress(p1, p2, a.Length); } } } 顺便说一句,通过这种方式,您可以像在 C 中一样在 C# 中应用指针算术。您必须记住,您处于不安全的上下文中,就像在 C 或 C++ 中一样。

玩得开心!