Quase certamente haverá problemas.
Que funções posso usar rundll32
on?
Bem, optimamente, você não o usaria de todo - é obsoleto :
Rundll32 is a leftover from Windows 95, and it has been deprecated since at least Windows Vista because it violates a lot of modern engineering guidelines. If you run something via Rundll32, then you lose the ability to tailor the execution environment to the thing you’re running.
rundll32
é projetado apenas para chamar um tipo muito específico de função, especificamente, funções que criam uma janela e processam mensagens de janela. Este documento da Microsoft sobre a interface rundll32
explica que a função que você está chamando deve < use um HWND
, um HINSTANCE
, um LPSTR
e um int
(nessa ordem), deve usar a convenção de chamada _stdcall
/ CALLBACK
e não deve retornar nada ( void
).
Consulte a documentação da MSDN sobre a função que você deseja chamar para ver se ela possui essa assinatura. Por exemplo, ExitWindowsEx
não em forma. Na verdade, não consigo encontrar uma única função com essa assinatura documentada.
Se você não tem certeza do que significa tudo isso, você pode pular a próxima seção e ir para a final.
O que pode dar errado se eu usá-lo em outras funções?
Lembre-se de toda essa coisa de assinatura de função? rundll32
assume que a função que você está tentando chamar tem a assinatura certa , não importa se esse é realmente o caso. Quando sua suposição está errada, coisas relacionadas a pilha seriamente bizarras podem continuar. A pilha é um local de memória que armazena parâmetros passados entre funções.
As assinaturas de função não combinadas resultarão na interpretação dos dados fornecidos por rundll32
como algo diferente devido ao local onde a função espera que seus parâmetros estejam na pilha. O primeiro datum rundll32
supplies é um identificador de janela, que é atribuído de maneira não determinística. Portanto, se você usar de forma incorreta rundll32
, estará efetivamente transmitindo dados aleatórios como o primeiro parâmetro . Naturalmente, isso pode não apenas afetar o primeiro parâmetro da função vítima, porque diferentes tipos de dados ocupam diferentes quantidades de espaço. Outras leituras: O que pode dar errado quando você discorda da convenção de chamada?
Os demais parâmetros não funcionam melhor. Mesmo se você fornecer uma linha de comando para a função via rundll32
, ela não será analisada nos tipos de dados apropriados para a função. Em vez disso, rundll32
apenas pega todo o texto "extra", congestiona-o em uma variável de string e passa um ponteiro para esses dados para a função como um parâmetro posterior. Cabe à função analisar o texto. Portanto, não há esperança de invocar funções arbitrárias com argumentos fornecidos pelo usuário com rundll32
.
Não é um desastre completo se a função alvo não espera parâmetros, mas você ainda está bagunçando a pilha. Existe código em rundll32
para lidar com isso , mas isso não dar-lhe uma desculpa para continuar abusando dele.
Se você estiver usando rundll32
para invocar uma função compatível em uma DLL de terceiros projetada para ser usada dessa forma, ainda assim poderá ter problemas. rundll32
sempre opta por todos os novos recursos do Windows (por exemplo, Prevenção de Execução de Dados ), que pode introduzir alterações que o código de terceiros não foi projetado para; é por isso que o comportamento é opt-in.
Felizmente, existe uma maneira melhor de fazer o que você quer.
O que posso fazer em vez disso?
Tentando bloquear a estação de trabalho ( user32.dll,LockWorkStation
)? Apenas execute tsdiscon
.
Tentando desligar o sistema ( user32.dll,ExitWindowsEx
)? Use o utilitário shutdown
com os sinalizadores apropriados - consulte shutdown /?
para obter ajuda.
Você é um desenvolvedor de aplicativos e está tentando invocar uma função DLL sem gravar um novo EXE? Escreva esse EXE (provavelmente em C ++).
Tentando executar outra coisa? Meu utilitário de código aberto SprintDLL suporta listas de parâmetros especificadas pelo usuário, várias convenções de chamada e scripts para trabalhar com várias funções e suas saídas. Se você preferir usar apenas ferramentas incluídas no Windows, você pode fazer P / Invoke with PowerShell .
This question and answer were written as a reference usable for correcting those who suggest using
rundll32
in a dubious fashion. If you see people abusingrundll32
, give them a link to this page!