Размер
RunDll32 - вызов функций библиотек DLL
Play

RunDll32 - вызов функций библиотек DLL

Все мы прекрасно знаем, что в операционной системе Windows существуют функции/процедуры, размещаемые внутри динамических библиотек (DLL). Эта особенность является одним из основных отличительных черт современных операционных систем, и Windows тут не исключение.

Но у библиотек имеется одна характерная особенность: они не запускаются через привычные пользователям механизмы, применимые к исполняемым образам .exe (например, запуск двойным щелчком из проводника), вместо этого процедуры/функции/ресурсы библиотеки доступны для использования исключительно из кода приложений. Одним словом просто так вот щелкнуть в проводнике по .DLL-файлу и запустить его не получится. И все же, у специалиста/пользователя время от времени возникает необходимость воспользоваться функциями той или иной библиотеки, в этом случае имеется два основных пути:

  • Написать собственное приложение, которое будет использовать требуемые функции [той или иной библиотеки];
  • Воспользоваться специализированным средством (утилитой) командной строки rundll32.exe;

Очевидно, что в рамках данной заметки нам интересен именно второй подход. Для его реализации разработчики из MS создали своеобразный "стартер", который вызывает код [заданной] функции (процедуры), размещаемой в одной из доступных в системе библиотек, прямо из командной строки. Идея была реализована Microsoft в виде утилиты под названием rundll32.exe. RunDll32 - [системная] утилита командной строки, разработанная для загрузки и запуска функций из 32/64-битных библиотек DLL. Тем не менее, ошибочно было бы считать, что утилита rundll32 является средством для "запуска DLL" по аналогии с исполняемым приложением, в действительности же невозможно "запустить DLL", поскольку это не исполняемый образ в классическом понимании (вроде .EXE-образов).

Теоретически rundll32 может использоваться для запуска функций из любых типов файлов, по структуре идентичных с библиотеками DLL: элементов ActiveX (* .ocx ), апплетов панели управления (* .cpl ), драйверов (* .drv ). Бытует мнение, что когда-то функциональные особенности rundll32 были неявными, то есть "скрытыми" от пользователя системы, но при этом самой системой активно эксплуатирующимися. Не совсем понятное утверждение, поскольку у разработчиков никогда и не существовало проблем в том, чтобы набросать алгоритм запуска произвольных функций библиотек и выделить его в отдельный функционал, к тому же в Windows это основа основ. Со временем утилита rundll32 превратилась в достаточно продвинутое средство, и в определенный момент, по причине того, что программа предоставляла возможности общего характера, разработчики решили включить её в базовый комплект ОС в виде отдельной утилиты. В состав Microsoft Windows 95, Windows 98 и Windows Millennium входили программы rundll.exe и rundll32.exe , а в операционных системах Microsoft Windows NT 4.0, Windows 2000 и Windows XP, в сборку была включена единственная утилита с именем rundll32.exe .

Причина подобного отношения кроется в многочисленных проблемах, связанных с использованием rundll32 в своих программных окружениях. Как же без rundll32, спросите Вы? Оказывается, Microsoft активно внедряет специализированные системные утилиты, которые постепенно заменяют функционал полюбившегося многим программного средства. Поэтому, время от времени в процессах Windows 7 можно таки встретить процесс rundll32 , однако встречается подобное явление всё реже и реже.

Алгоритм работы rundll32

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

  1. Вызывается функция LoadLibrary , которая загружает выбранную DLL;
  2. Вызывается функция GetProcAddress , для получения адреса точки входа вызываемой из библиотеки функции;
  3. Вызывается проверка соответствия функции специфическим требованиям;
  4. Вызывается сама функция и ей передаются входные параметры;
  5. Происходит выход из функции по завершению её работы;
  6. Библиотека DLL выгружается из памяти процесса.

Как увидеть полный путь запуска rundll32

Если в системе ни с того ни с сего вдруг удалось обнаружить запущенный процесс rundll32 , и вам стало интересно, а какой же, собственно, функционал утилита выполняет, то можно определить это по полному пути запуска утилиты rundll32 . Посмотреть полный путь запуска, то есть параметры командной строки можно при помощи системной утилиты Диспетчер задач Windows (Task Manager). Вызовите "Диспетчер задач" ( Ctrl + Shift + Esc ), перейдите в меню "Вид", выберите пункт "Выбрать столбцы.." и пролистав список вниз, найдите пункт "Командная строка" и отметьте его чекбокс, затем нажмите ОК . Результатом будет появление в главном окне диспетчера задач в параметре "командная строка" полной строки запуска rundll32.

32-битные и 64-битные версии программы

В 64-битных версиях ОС семейства Windows присутствуют 2 варианта программы rundll32.exe :

  • 64-битная версия, расположенная в %SystemRoot%\System32\ ;
  • 32-битная версия, расположенная в %SystemRoot%\SysWOW64\ .

В 64-битной ОС, для загрузки 64-битной библиотеки DLL может быть использована 64-битная версия rundll32.exe , находящаяся в директории %SystemRoot%\System32\ . Напротив, 32-битные программы в 64-битной ОС, обращающиеся к %SystemRoot%\System32\ , в целях обеспечения совместимости будут перенаправлены в %SystemRoot%\SysWOW64\ и, соответственно, будут использовать уже 32-битную версию rundll32.exe .

Пример использования rundll32

Для запуска программы rundll32 используется синтаксис командной строки следующего вида:

В качестве примера предлагаю разобрать команду запуска апплета "Язык и региональные стандарты" панели управления, вкладка "Форматы":

rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,0

При выполнении данной команды утилита rundll32 вызовет функцию Control_RunDLL , находящуюся в библиотеке shell32.dll , и передаст ей следующие параметры:

Параметр Описание hWnd Идентификатор (дескриптор) родительского окна, который обычно используется при создании окон в функциях загружаемой библиотеки DLL. hInstance Дескриптор (заголовок экземпляра) выбранной библиотеки DLL. Иначе, стартовый адрес процесса DLL в адресном пространстве. В нашем случае - библиотеки shell32.dll . lpCmdLine Командная строка, передаваемая библиотеке. То есть параметры, передаваемые самой библиотеке. В нашем случае intl.cpl,,0 ; nCmdShow Режим отображения окон выбранной библиотеки. (данные, передаваемые функции CreateProcess ).

Теперь давайте отметим и некоторые требования к синтаксису rundll32 :

  • Параметр, описывающий точку входа вызываемой функции (метка EntryPoint ) чувствителен к регистру. Это означает, что значение Control_RunDLL не тоже самое что control_rundll . Довольно часто неправильное указание регистра символов вызываемой функции приводит к ошибкам отказа в обнаружении последних.
  • Функция (в приведенном выше примере — функция Control_RunDLL ) должна самостоятельно выполнять анализ командной строки и идентифицировать отдельные ее аргументы.
  • Утилиты rundll / rundll32 ищут указанную библиотеку DLL в стандартных местоположениях.

Правила создания функций

Очевидно, что в создаваемую нами собственную библиотеку DLL необходимо поместить функцию со следующими входными параметрами (пример описания на Ассемблере):

📎📎📎📎📎📎📎📎📎📎