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

Другие вопросы по тегам