При каких обстоятельствах я могу использовать rundll32 для вызова функции в DLL?
Я хотел бы вызвать функциональность, найденную в различных библиотеках Windows, из командной строки. Похоже, rundll32
Утилита будет делать то, что мне нужно - она берет имя DLL и имя функции, и запускает эту функцию с параметрами.
Я, конечно, надеюсь, что не будет никаких проблем с этим. Какие функции я могу использовать rundll32
на?
1 ответ
Почти наверняка будут проблемы.
Какие функции я могу использовать rundll32
на?
Ну, оптимально, вы бы не использовали его вообще - это устарело:
Rundll32 является остатком Windows 95, и он устарел, по крайней мере, с Windows Vista, потому что он нарушает многие современные технические рекомендации. Если вы запускаете что-то через Rundll32, вы теряете возможность адаптировать среду выполнения к тому, что вы запускаете.
rundll32
предназначен только для вызова очень специфического типа функций, в частности, функций, которые создают окно и обрабатывают сообщения окна. Этот документ Microsoft на rundll32
Интерфейс объясняет, что вызываемая вами функция должна принимать HWND
, HINSTANCE
, LPSTR
и int
(в таком порядке), должны использовать _stdcall
/ CALLBACK
Соглашение о вызовах, и ничего не должно возвращаться (void
).
Обратитесь к документации MSDN по функции, которую вы хотите вызвать, чтобы узнать, имеет ли она эту подпись. Например, ExitWindowsEx
не подходит На самом деле, я не могу найти ни одной функции с этой подписью, которая задокументирована.
Если вы не уверены, что все это значит, вы можете пропустить следующий раздел и перейти к последнему.
Что может пойти не так, если я использую его для других функций?
Помните эту функцию подписи? rundll32
предполагается, что функция, которую вы пытаетесь вызвать, имеет правильную подпись, независимо от того, так ли это на самом деле. Когда его предположение неверно, могут продолжаться серьезно странные вещи, связанные со стеком. Стек - это область памяти, в которой хранятся параметры, передаваемые между функциями.
Несоответствующие сигнатуры функций приведут к данным, предоставленным rundll32
интерпретируется как нечто иное из-за того, что функция ожидает, что ее параметры находятся в стеке. Первый датум rundll32
Supplies - это дескриптор окна, который назначается недетерминированным образом. Поэтому, если вы злоупотребляете rundll32
вы фактически передаете случайные данные в качестве первого параметра. Конечно, это может повлиять не только на первый параметр функции жертвы, потому что разные типы данных занимают разные объемы пространства. Дальнейшее чтение: Что может пойти не так, если вы не соответствуете правилам вызова?
Остальные параметры не работают лучше. Даже если вы введете командную строку для функции через rundll32
он не собирается анализироваться на типы данных, соответствующие функции. Вместо, rundll32
просто берет весь "лишний" текст, сжимает его в строковую переменную и передает указатель на эти данные функции в качестве более позднего параметра. Это до функции разбора текста. Следовательно, нет никакой надежды когда-либо вызвать произвольные функции с предоставленными пользователем аргументами с rundll32
,
Это не полная катастрофа, если целевая функция не ожидает никаких параметров, но вы все еще портите стек. Есть код в rundll32
иметь дело с этим, но это не дает вам повода продолжать злоупотреблять этим.
Если вы используете rundll32
Чтобы вызвать совместимую функцию в сторонней DLL, которая предназначена для такого использования, у вас все еще могут быть проблемы. rundll32
всегда включает все новые функции Windows (например, Data Execution Prevention), которые могут вносить изменения, для которых не был разработан сторонний код; вот почему поведение является добровольным.
К счастью, есть лучший способ сделать то, что вы хотите.
Что я могу сделать вместо этого?
Пытаюсь заблокировать рабочую станцию (user32.dll,LockWorkStation
)? Просто беги tsdiscon
,
Попытка выключить систему (user32.dll,ExitWindowsEx
)? Использовать shutdown
утилита с соответствующими флагами - см. shutdown /?
за помощью.
Вы разработчик приложений и пытаетесь вызвать функцию DLL без написания нового EXE-файла? Напишите этот EXE (возможно, на C++).
Пытаетесь запустить что-то еще? Моя утилита с открытым исходным кодом SprintDLL поддерживает заданные пользователем списки параметров, несколько соглашений о вызовах и сценарии для работы с несколькими функциями и их выходами. Если вы предпочитаете использовать только инструменты, включенные в Windows, вы можете сделать P/Invoke с PowerShell.
Этот вопрос и ответ были написаны как справка, используемая для исправления тех, кто предлагает использовать
rundll32
сомнительным образом. Если вы видите людей, злоупотребляющихrundll32
, дайте им ссылку на эту страницу!