> For the complete documentation index, see [llms.txt](https://ymmfty0.gitbook.io/ymmfty0/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ymmfty0.gitbook.io/ymmfty0/pe-file-format/imports-exports/linking-a-dll-with-an-executable-file.md).

# Linking a DLL with an executable file

## **Введение**

Перед тем как перейти к `Exports Table` и `Imports Table`, нужно разобраться, как мы вообще можем использовать функции из других DLL.

Сначала мы пишем код, в котором хотим, например, выводить `HelloWorld`, и для этого используем функцию `MessageBox`.

Что происходит дальше? Как мы используем функцию `MessageBox`, если мы её не писали.

## **Экспорт функций с DLL**

Чтобы мы могли использовать эти функции из DLL, компоновщик для DLL создаёт специальную таблицу `Export Table`. Она содержит информацию о том, какие функции должны быть экспортированы. Про эту таблицу я расскажу подробнее в следующей статье.

В эту таблицу записываются все функции, которые могут использоваться при импорте этих функций в PE-файл, таких как `MessageBox`.

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

```cpp
__declspec(dllexport) 
```

Можете попробовать создать DLL при помощи Visual Studio и вставить код ниже,

```cpp
__declspec(dllexport) void TestFunc();

void TestFunc()
{
	return;
}
```

Если посмотрим в PE Bear, то увидим, то что она теперь доступна для экспорта

<figure><img src="/files/XxTWEU7KuglmEHZCWabw" alt=""><figcaption></figcaption></figure>

Чтобы эта функция работала в нашем исполняемом файле , нужно связать DLL и исполняемый файл.

Есть несколько способов , как происходит это связывание: *Неявное связывание* и *Явное связывание*

## **Неявной связывание**

Неявное связывание: операционная система загружает DLL в исполняемый файл только в тот момент, когда она используется исполняемым файлом.

При компиляции или сборке исходного кода на месте, где вызывается импортированная функция, создаётся ссылка на внешнюю функцию этой DLL.

Для разрешения этой внешней ссылки приложение должно связаться с библиотекой импорта (LIB-файл).\
Библиотека импорта содержит только код для загрузки библиотеки DLL и реализации вызовов её функций.

Чтобы понять, какая DLL и какие функции нужно импортировать, компоновщиком создаётся таблица импорта.

В таблицу импорта сохраняются имя DLL, имя импортированной функции и адреса функций. Сначала адреса функций равны 0.

Адреса функций в таблице импорта записываются уже в момент загрузки приложения в память.

## **Явное связывание**

*Явное связывание* — операционная система загружает библиотеку DLL по запросу во время выполнения. Исполняемый файл, который использует библиотеку DLL, должен явно загружать и выгружать её.

Чтобы использовать библиотеку DLL посредством явного связывания, необходимо вызвать функцию для явной загрузки библиотеки DLL во время выполнения.\
Для этого используются `LoadLibrary` и `GetProcAddress`.

Вот пример кода для использования `MessageBox`:

```cpp
#include <iostream>
#include <Windows.h>


typedef int (WINAPI* messageBoxW)(
	HWND    hWnd,
	LPCWSTR lpText,
	LPCWSTR lpCaption,
	UINT    uType
);

int main()
{
	HMODULE userdll_module = LoadLibraryA("user32.dll");
	PVOID addr_to_mssg_box = GetProcAddress(userdll_module, "MessageBoxW");
	
	if (!addr_to_mssg_box)
	{
		std::cout << "Cannot load MessageBoxW" << std::endl;
		return -1;
	}

	messageBoxW tesMesageBox = reinterpret_cast<messageBoxW>(addr_to_mssg_box);
	tesMesageBox(nullptr, L"PE FORMAT FILE TUTOR", L"MessageBox", MB_OK);
	
	FreeLibrary(userdll_module);
	return 0;
}
```

## Итог

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

* [Creating and Using DLLs (C++)](https://learn.microsoft.com/en-us/cpp/build/dlls-in-visual-cpp?view=msvc-170)
* [Linking an Executable to a DLL](https://learn.microsoft.com/en-us/cpp/build/linking-an-executable-to-a-dll?view=msvc-170)
* [Dynamic-Link Library Creation](https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-creation)
