如何使用 Rundll32 执行 DLL 函数?
Posted
技术标签:
【中文标题】如何使用 Rundll32 执行 DLL 函数?【英文标题】:How to use Rundll32 to execute DLL Function? 【发布时间】:2011-03-13 13:12:49 【问题描述】:使用ShellExecute documentation 作为参考:
我从命令行运行以下命令:
C:\>RUNDLL32.EXE SHELL32.DLL,ShellExecute handle,"open","C:\Documents and Settings\admin\Desktop\tmp",NULL,NULL,SW_SHOWNORMAL
这会导致异常错误。
我不知道这是什么意思:
HINSTANCE ShellExecute(
__in_opt HWND hwnd,
__in_opt LPCTSTR lpOperation,
__in LPCTSTR lpFile,
__in_opt LPCTSTR lpParameters,
__in_opt LPCTSTR lpDirectory,
__in INT nShowCmd
);
但在描述中,提到了句柄(HWND)和指向以空字符结尾的字符串(LPCTSTR)的指针,但这很混乱。
任何帮助将不胜感激。我还想了解更多信息,因此任何参考资料(书籍、网络链接等)也会很棒!
【问题讨论】:
如果您解释了您要完成的工作,这将很有帮助,因为可能有比使用 RUNDLL32 更好的方法。不管怎样,你没有正确调用 RUNDLL32。例如,参数必须用空格分隔(逗号仅将入口点与 DLL 分隔),hwnd 和 nShowCmd 需要整数值等。有关详细信息,请参阅support.microsoft.com/kb/164787。 我是个流浪的脑袋。我读到:vlaurie.com/computers2/Articles/rundll32.htm。然后我开始查看不同的 dll 文件,发现了这个:msdn.microsoft.com/en-us/library/bb776426%28v=VS.85%29.aspx。我开始研究各个函数,想知道它们是否可以与 rundll32.exe 一起使用。我选择了 ShellExecute 函数,因为我了解它的作用(打开一个文件夹)。我主要是想了解这些东西是如何工作的(在 MSDN 中)。我什至不知道是C、C++、C#等。 【参考方案1】:Rundll32 仅支持运行具有以下签名的 DLL 导出:
void CALLBACK
EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);
它不支持运行任意入口点。由于 ShellExecute 没有该签名,显然会发生不好的事情。
INFO: Windows Rundll and Rundll32 Interface 有更多关于 rundll32 接口的信息。
如果您想从命令行执行 ShellExecute 的等效操作,只需使用 start:
C:\>start "C:\Documents and Settings\admin\Desktop\tmp"
【讨论】:
我如何知道哪些 DLL 导出具有正确的签名? 你不应该用随机函数调用 Rundll32。要么记录您可以使用 Rundll32(用于安装,InstallHinfSection),要么您自己提供导出。 如果你够勇敢,你可以调用其他函数——它们会接受这 4 个参数(通过 cdecl 调用约定)。这对于一些无参数函数或其他只接受一个或两个无意义句柄作为参数的函数是可能的。您还可以轻松编写自己的 DLL,入口点(=dll 导出)遵循此签名,并使用 rundll32 调用它们。 WinAPI 中的函数在 MSDN 中有说明。你会发现很少有可以直接用rundll32... 好像不一定非得是void CALLBACK EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
。我用extern "C" void Example()
编译了我自己的DLL,它运行正常(extern "C"
在那里,所以我可以得到一个干净的函数名,void Example()
工作得很好,只要你使用 Dependency Walker 来查找函数的名称)。所以看起来它必须是无效的才能工作。但是,我不一定鼓励您使用它。
如果你只有 extern "C" void Example(),它很可能是 __cdecl(调用者清理堆栈的默认调用约定)。 CALLBACK 是 __stdcall 调用约定,被调用者清理堆栈。您的函数将忽略 4 个参数,这很好,但它不会清理堆栈,这意味着堆栈在返回时会损坏,可能会导致 rundll32 进程崩溃。以上是关于如何使用 Rundll32 执行 DLL 函数?的主要内容,如果未能解决你的问题,请参考以下文章