Executing rundll32.exe with CreateProcess
Executing rundll32.exe with CreateProcess
我已经创建了一个DLL,并且想使用Windows上的rundll32.exe命令执行其中一个函数。
使用rundll32.exe,它可以从命令行正确运行;但是,我想从一个单独的程序中称其为(rundll32.exe)。由于我使用的基础库中的32/64位兼容性问题,我无法直接从我的代码中调用该函数(Easyhook)。
以下是我在尝试运行DLL函数的尝试:
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi));
LPCTSTR application = "C:\Windows\system32\rundll32.exe";
LPTSTR cmd = "C:\Projects\Test\mydll.dll,MyFunc";
BOOL cpRes = CreateProcess(application,
cmd,
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&si,
&pi);
if(cpRes == 0) {
cout << "ERRORn";
cout << GetLastError() << endl;
} else {
cout << "DLL Launched!" << endl;
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
我控制台的输出始终是DLL Launched
;但是,我看不到我的DLL的效果实际上是被调用的(目前以命令将其写入文件的方式。
如果我将应用程序与C:\Windows\system32\notepad.exe
之类的内容交换,则该程序成功运行。
完成,这是MyFunc
的主体:
ofstream file;
file.open("C:\Projects\Test\test.txt");
file << "I wrote to a file!";
file.close();
是否有任何理由与rundll32一起使用CreateProcess?在阅读本文时,我发现了有关LoadLibrary()
和DLLMain
的几个警告,但它似乎与此相关。
更多澄清:
目前,这是一个32位应用程序(据称)启动32位rundll32.exe
(逻辑将稍后添加以调用32或64位版本)。
我的dll如下:
extern "C" __declspec(dllexport) void CALLBACK MyFunc(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);
void CALLBACK MyFunc(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) { ... }
也有一个.def
文件,其中包括:
EXPORTS
MyFunc
运行
C:Windowssystem32rundll32.exe C:ProjectsTestmydll.dll,MyFunc
产生预期的结果。
更新
将application
设置为NULL
,并在评论中提到的CMD中包括rundll32.exe
。
相关文档:
CreateProcess
rundll32.exe
根据CreateProcess()
文档:
如果
lpApplicationName
和lpCommandLine
都是非空的,则lpApplicationName
指向的null终止字符串指定要执行的模块,并且lpCommandLine
指向的null终止字符串指定命令行。新过程可以使用GetCommandLine
检索整个命令行。C中编写的控制台进程可以使用argc
和argv
参数来解析命令行。因为argv[0]
是模块名称,C程序员通常将模块名称重复为命令行中的第一个令牌。
您没有重复rundll32.exe
作为第一个命令行令牌。
因此,如果您继续使用lpApplicationName
参数,请更改以下内容:
LPCTSTR application = "C:\Windows\system32\rundll32.exe";
LPTSTR cmd = "C:\Projects\Test\mydll.dll,MyFunc";
而是:
LPCTSTR application = TEXT("C:\Windows\system32\rundll32.exe");
LPTSTR cmd = TEXT("C:\Windows\system32\rundll32.exe C:\Projects\Test\mydll.dll,MyFunc");
请注意,您当前正在为ANSI/MBCS编译(由于您将窄字符串传递给CreateProcess()
的事实)。如果您更新项目以编译为Unicode,请改用:
TCHAR cmd[] = TEXT("C:\Windows\system32\rundll32.exe C:\Projects\Test\mydll.dll,MyFunc");
这是因为文档指出:
lpcommandline [IN,OUT,可选]
...
此功能的Unicode版本CreateProcessW
可以修改此字符串的内容。因此,此参数不能是读取仅内存的指针(例如const变量或文字字符串)。如果此参数是恒定字符串,则该功能可能会导致访问违规。
即使在ANSI/MBC中,您也可以考虑将cmd
更改为TCHAR[]
数组,因此您可以做类似的事情:
LPCTSTR application = TEXT("C:\Windows\system32\rundll32.exe");
TCHAR cmd[(MAX_PATH*2)+10];
wsprintf(cmd, TEXT("%s %s,%s"), application, TEXT("C:\Projects\Test\mydll.dll"), TEXT("MyFunc"));
无论哪种方式,通过将模块文件名作为lpCommandLine
参数中的第一个令牌,然后可以将lpApplicationName
参数设置为null:
lpApplicationName
参数可以为null。在这种情况下,模块名称必须是lpCommandLine
字符串中的第一个空白空间 - 删除令牌。
让CreateProcess()
设置正确的命令行,以将rundll32.exe
传递给您:
TCHAR cmd[] = TEXT("C:\Windows\system32\rundll32.exe C:\Projects\Test\mydll.dll,MyFunc");
BOOL cpRes = CreateProcess(NULL, cmd, ...);
- Problems with std::cin.fail()
- 调用CreateProcess()并获取字符串的返回值
- 应用程序崩溃并显示"symbol _ZdlPvm, version Qt_5 not defined in file libQt5Core.so.5 with link time reference"
- 这对"With a stackless coroutine, only the top-level routine may be suspended."意味着什么
- Boost.TEST with CLion: "Test framework quit unexpectedly"
- 避免碎片化的ClientHellos with OpenSSL (DTLS)
- Issues with Win32 ReadProcessMemory API
- Qt with WinAPI MouseProc
- [[maybe_unused]] with structured_binding?
- Issue with WriteProcessMemory
- OpenCV RTP-Stream with FFMPEG
- "Unable to start debugging. No process is associated with this object." - 在Visual Studio Code中使用GDB
- std::adjacent_difference with std::chrono time_point
- DLL Made with CMake 使程序崩溃
- QtCreator with C 库中的链接器问题
- SHBrowseForFolder with BIF_BROWSEFORCOMPUTER and SHGetPathFr
- specialized std::default_delete with QQmlComponent
- CreateProcess stdout with CreateNamedPipe Overlapped
- CreateProcess with std::string
- Executing rundll32.exe with CreateProcess