混淆DLL入口点(入口点未找到异常) [英] Confused over DLL entry points (entry point not found exception)

查看:430
本文介绍了混淆DLL入口点(入口点未找到异常)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想学习如何在C#中使用DLL。我有一个非常简单的DLL只是为了测试的基础。

  // MainForm.cs 

b $ b使用系统;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

使用System.Runtime.InteropServices;

命名空间DLL_Test
{
public partial class Form1:Form
{
[DllImport(TestDLL.dll,
EntryPoint = ?添加@@ YGHHH @ Z,
ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
public static extern int Add(int a,int b);

public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender,EventArgs e)
{
int num;
try
{
num = Add(2,3);
richTextBox1.AppendText(num.ToString()+\\\
);
}
catch(DllNotFoundException ex)
{
MessageBox.Show(ex.ToString());
}
catch(EntryPointNotFoundException ex)
{
MessageBox.Show(ex.ToString());
}
}
}
}

DLL代码:

  // TestDLL.cpp 

__declspec(dllexport)int __stdcall Add a,int b){
return(a + b);
}

dumpbin返回以下内容:


$ b b

 顺序提示RVA名称
1 0 00011005?Add @@ YGHHH @ Z = @ ILT + 0(?Add @@ YGHHH @ Z)

此(以及下面列出的其他尝试)都返回相同的异常:

  System.EntryPointException:找不到名为...的入口点

所以我是如何解决这个问题的损失。也许我不明白DllMain如何作为DLL的C#入口点。



搜索帮助后,我尝试了以下更改:

  // TestDLL.cpp 

externC__declspec(dllexport)int __stdcall Add(int a,int b){
return(a + b);
}

这将导致dumpbin

 顺序提示RVA名称
1 0 00011005 _Add @ 8 = @ ILT + 135(_Add @ 8)

因此,我改变了我的C#代码:

  / MainForm.cs 

...

[DllImport(TestDLL.dll,
EntryPoint =_ Add,
ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
public static extern int Add(int a,int b);

...

> __ cdecl :

  // TestDLL.cpp 

externC __declspec(dllexport)int __cdecl Add(int a,int b){
return(a + b);
}

  // MainForm.cs 

...

[DllImport(TestDLL.dll,
EntryPoint =_ Add ,
ExactSpelling = true,
CallingConvention = CallingConvention.Cdecl)]
public static extern int Add(int a,int b);

...

也许我误解了调用约定。任何帮助将非常感激。谢谢。

解决方案

使用

  externC__declspec(dllexport)int __stdcall Add(int a,int b){...} 

  [DllImport(TestDLL.dll,CallingConvention = CallingConvention.Stdcall)] 
public static extern int Add(int a,int b);

externC与参数和返回类型如?添加@@ YGHHH @ Z
__stdcall将在前面添加 _ 并添加 @ 8 _Add @ / code>(其中8是参数的总大小)。注意,它也影响参数在堆栈上的推送方式。



DLLImport 语句中, CallingConvention.StdCall ,您不需要指定名称mangling。只需给出常规名称( Add ),.NET将负责名称调整( _Add @ 8 )。 / p>

请注意,您必须指定CallingConvention或.NET不会发出正确的代码来在堆栈中推送参数


I'm trying to learn how to use DLL's in C#. I have a very simple DLL just to test the basics.

// MainForm.cs


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Runtime.InteropServices;

namespace DLL_Test
{
        public partial class Form1 : Form
        {
            [DllImport("TestDLL.dll",
                        EntryPoint="?Add@@YGHHH@Z",
                        ExactSpelling = true,
                        CallingConvention = CallingConvention.StdCall)]
            public static extern int Add(int a, int b);

            public Form1()
            {
                InitializeComponent();
            }

            private void button1_Click(object sender, EventArgs e)
            {
                int num;
                try
                {
                    num = Add(2, 3);
                    richTextBox1.AppendText(num.ToString() + "\n");
                }
                catch (DllNotFoundException ex)
                {
                    MessageBox.Show(ex.ToString());
                }
                catch (EntryPointNotFoundException ex)
                {
                    MessageBox.Show(ex.ToString());
                }
             }
         }
}

And the DLL code:

// TestDLL.cpp

__declspec(dllexport) int __stdcall Add(int a, int b) {
return(a + b);
}

dumpbin returns the following:

ordinal   hint   RVA        name
      1      0   00011005   ?Add@@YGHHH@Z = @ILT+0(?Add@@YGHHH@Z)

This (and other attempts listed below) have all returned the same exception:

System.EntryPointException: Unable to find entry point named "..."

So I am at a loss for how to solve this. Perhaps I do not understand how DllMain functions as the C# entry point for a DLL. TestDLL.dll works when I test it in a C++ application.

After searching for help, I've attempted the following changes:

// TestDLL.cpp

extern "C" __declspec(dllexport) int __stdcall Add(int a, int b) {
return(a + b);
}

Which results in this from dumpbin

ordinal   hint   RVA        name
      1      0   00011005   _Add@8 = @ILT+135(_Add@8)

Thus, I changed my C# code:

 // MainForm.cs

...

[DllImport("TestDLL.dll",
                        EntryPoint="_Add",
                        ExactSpelling = true,
                        CallingConvention = CallingConvention.StdCall)]
            public static extern int Add(int a, int b);

...

I've also tried __cdecl:

// TestDLL.cpp

extern "C" __declspec(dllexport) int __cdecl Add(int a, int b) {
return(a + b);
}

.

// MainForm.cs

...

[DllImport("TestDLL.dll",
                        EntryPoint="_Add",
                        ExactSpelling = true,
                        CallingConvention = CallingConvention.Cdecl)]
            public static extern int Add(int a, int b);

...

Perhaps I'm misunderstanding the calling conventions. Any help would be very appreciated. Thank you.

解决方案

use

extern "C" __declspec(dllexport) int __stdcall Add(int a, int b) { ... }

and

[DllImport("TestDLL.dll", CallingConvention = CallingConvention.Stdcall)] 
public static extern int Add(int a, int b); 

extern "C" will prevent name mangling with params and return type such as ?Add@@YGHHH@Z. __stdcall will prepend an _ and add @8 : _Add@8 (where 8 is the total size of arguments). Note that it also affects the way parameters are pushed on the stack.

In your DLLImport statement, since you specify CallingConvention.StdCall, you don't need to specify the name mangling. Just give the regular name (Add) and .NET will take care of name mangling (_Add@8).

Note that you must specify the CallingConvention or .NET wouldn't emit the correct code to push arguments on the stack

这篇关于混淆DLL入口点(入口点未找到异常)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆