6

Я хотел бы вызвать функциональность, найденную в различных библиотеках Windows, из командной строки. Похоже, что утилита rundll32 будет делать то, что мне нужно - она берет имя DLL и имя функции и запускает эту функцию с параметрами.

Я, конечно, надеюсь, что не будет никаких проблем с этим. На каких функциях я могу использовать rundll32 ?

1 ответ1

5

Почти наверняка будут проблемы.

На каких функциях я могу использовать rundll32 ?

Ну, оптимально, вы бы не использовали его вообще - это устарело:

Rundll32 является остатком Windows 95, и он устарел, по крайней мере, с Windows Vista, потому что он нарушает многие современные технические рекомендации. Если вы запускаете что-то через Rundll32, вы теряете возможность адаптировать среду выполнения к тому, что вы запускаете.

rundll32 предназначен только для вызова очень специфического типа функций, в частности, функций, которые создают окно и обрабатывают сообщения окна. Этот документ Microsoft на интерфейсе rundll32 объясняет , что функция вы звоните должен принять HWND а HINSTANCE а LPSTR и int (в таком порядке), необходимо использовать _stdcall/CALLBACK соглашения о вызове, и ничего не возвращает void).

Обратитесь к документации MSDN по функции, которую вы хотите вызвать, чтобы узнать, имеет ли она эту подпись. Например, ExitWindowsEx не подходит. На самом деле, я не могу найти ни одной функции с этой подписью, которая документирована.

Если вы не уверены, что все это значит, вы можете пропустить следующий раздел и перейти к последнему.

Что может пойти не так, если я использую его для других функций?

Помните всю эту функцию подписи? rundll32 предполагает, что функция, которую вы пытаетесь вызвать, имеет правильную подпись, независимо от того, так ли это на самом деле. Когда его предположение неверно, могут продолжаться серьезно странные вещи, связанные со стеком. Стек - это область памяти, в которой хранятся параметры, передаваемые между функциями.

Несовпадающие сигнатуры функций приведут к тому, что данные, предоставленные rundll32 будут интерпретированы как нечто иное из-за того, что функция ожидает, что ее параметры находятся в стеке. Первый источник данных rundll32 - это дескриптор окна, который назначается недетерминированным образом. Поэтому, если вы неправильно используете 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 , дайте им ссылку на эту страницу!

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .