簡體   English   中英

使用CreateProcess執行rundll32.exe

[英]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()文檔:

如果lpApplicationNamelpCommandLine均為非NULL,則lpApplicationName指向的以Null終止的字符串指定要執行的模塊,而lpCommandLine指向的以Null終止的字符串lpCommandLine指定命令行。 新進程可以使用GetCommandLine檢索整個命令行。 用C編寫的控制台進程可以使用argcargv參數來解析命令行。 由於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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM