[英]Executing rundll32.exe with CreateProcess
我創建了一個DLL,並希望在Windows上使用rundll32.exe命令執行其中一個功能。
使用rundll32.exe,它可以從命令行正確運行; 但是,我想從一個單獨的程序中調用它(rundll32.exe)。 由於我正在使用的基礎庫(Easyhook)中存在32/64位兼容性問題,因此我無法直接從代碼中調用該函數。
下面是我在嘗試運行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 << "ERROR\n";
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();
有什么原因不能將RunProcess32與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:\Windows\system32\rundll32.exe C:\Projects\Test\mydll.dll,MyFunc
產生預期的結果。
更新
如注釋中所述,將application
設置為NULL
並在cmd中包含rundll32.exe
似乎可行。
相關文件:
CreateProcess的
RUNDLL32.EXE
根據CreateProcess()
文檔:
如果
lpApplicationName
和lpCommandLine
均為非NULL,則lpApplicationName
指向的以Null終止的字符串指定要執行的模塊,而lpCommandLine
指向的以Null終止的字符串lpCommandLine
指定命令行。 新進程可以使用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 [輸入,輸出,可選]
...
此函數的Unicode版本CreateProcessW
可以修改此字符串的內容。 因此,該參數不能是指向只讀存儲器的指針 (例如const變量或文字字符串)。 如果此參數是常量字符串,則該函數可能會導致訪問沖突。
您可能仍然考慮將cmd
更改為TCHAR[]
數組,即使在ANSI / MBCS中也是如此,因此您可以執行以下操作:
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, ...);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.