При каких обстоятельствах я могу использовать rundll32 для вызова функции в DLL?

1365
Ben N

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

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

5

1 ответ на вопрос

5
Ben N

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

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

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

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

rundll32предназначен только для вызова очень определенного типа функций, в частности, функций, которые создают окно и обрабатывают сообщения окна. В этом документе Microsoft об rundll32интерфейсе объясняется, что вызываемая вами функция должна принимать HWND, a HINSTANCE, a LPSTRи an int(в таком порядке), должна использовать соглашение _stdcall/ CALLBACKcall и ничего не возвращать ( 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, дайте им ссылку на эту страницу!

Спасибо за функцию `ExitWindowsEx` (или даже метод), я не знал об этом. Чтобы добавить, `tsdiscon` предназначен для [tag: RDP] и есть` stop-computer` [tag: cmdlet] для выключения. w17t 6 лет назад 0