本章の内容はインポート表とエクスポート表の準備知識です。
静的リンク ライブラリ
静的リンク ライブラリの作成
VC6 を例として、静的リンク ライブラリを作成します。
VC6 でプロジェクトを作成し、Win32 Static Library を選択します。
現在はまだ何も必要ありませんので、オプションを選択せずに「フィニッシュ」をクリックします。
プロジェクト内で「ClassView」をクリックし、右クリックから新規プロジェクトを作成します。
新規クラスを作成し、名前を付けます。すると、対応するソースファイルとヘッダーファイル(xxx.h と xxx.cpp)が生成されます。
以下に示すように、加減乗除の関数を定義します。
「F7」を押してコンパイルします。生成されたプロジェクト フォルダー内に xxx.h というヘッダーファイルが存在します。
「Debug」フォルダー内には xxx.lib というライブラリファイルが存在します。
静的リンク ライブラリの使用
静的リンク ライブラリを使用することで、他のプログラムが簡単にコードを再利用できます。
使用方法 1
- xxx.h と xxx.lib を、静的リンク ライブラリを使用する .cpp ファイルのルート ディレクトリにコピーします。
- .cpp ファイル内に #include "xxx.h" を追加します。
- .cpp ファイル内に #pragma comment(lib, "xxx.lib") を追加します。
使用方法 2
- xxx.h と xxx.lib を、プロジェクトのルート ディレクトリにコピーします。
- .cpp ファイル内に #include "xxx.h" を追加します。
- プロジェクトの設定から「Link」タブを選択し、ライブラリ モジュールに TestLib.lib を追加します。
通常、printf 関数などはすでにこれらのライブラリがリンクされているため、直接使用できます。
静的リンク ライブラリの特徴
- 利点:コードの再利用を実現します。
- 欠点:生成される可執行ファイルのサイズが大きくなります。
静的リンク ライブラリは、コードを直接可執行ファイルに埋め込むため、モジュール化ではありません。
OD を使用して PE ファイルを確認すると、静的リンク ライブラリの関数は exe ファイル内部に存在します。
動的リンク ライブラリ
動的リンク ライブラリの作成
動的リンク ライブラリを使用して関数をエクスポートする方法は 2 種類あります。
名前指定でのエクスポート
- Win32 Dynamic-Link Library プロジェクトを作成します。
- クラス ビューから新規クラスを作成します。
- .cpp ファイル内に関数を定義します。
- .h ファイル内に extern "C" を使用して関数を宣言します。
- コンパイル後、DEPEND.exe を使用してDLLの関数を確認します。
定義ファイル (.def) を使用したエクスポート
- .def ファイルを作成します。
- 関数の番号を定義します。
この方法は関数名を隠すことができ、セキュリティが向上します。
動的リンク ライブラリの使用
明示的リンク
// DLL ファイルをプロジェクト ディレクトリにコピー
typedef int (*lpPlus)(int, int);
lpPlus myPlus = NULL;
HINSTANCE hDll = LoadLibrary("dllTest.dll");
myPlus = (lpPlus)GetProcAddress(hDll, "Plus");
int result = myPlus(10, 2);
FreeLibrary(hDll);
暗黙的リンク
- DLL ファイルと .lib ファイルをプロジェクト ディレクトリにコピーします。
- #pragma comment(lib, "xxx.lib") を追加します。
- 関数を宣言します。
この方法はコンパイル時にインポート表にDLLの情報を記録します。
DLL のリモート スレッド注入
#include <windows.h>
#include <iostream>
void DllInjector(DWORD pid, const wchar_t* dllPath) {
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
LPVOID allocAddr = VirtualAllocEx(hProcess, NULL, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
SIZE_T written = 0;
WriteProcessMemory(hProcess, allocAddr, dllPath, (wcslen(dllPath) + 1) * 2, &written);
HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibraryW, allocAddr, NULL, NULL);
WaitForSingleObject(hThread, INFINITE);
VirtualFreeEx(hProcess, allocAddr, 0, MEM_RELEASE);
CloseHandle(hProcess);
CloseHandle(hThread);
}
int main() {
DllInjector(1234, L"C:\\example\\test.dll");
return 0;
}
モジュールの列挙
#include <windows.h>
#include <tlhelp32.h>
#include <iostream>
void ListModules(DWORD processId) {
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, processId);
MODULEENTRY32 moduleEntry = { sizeof(MODULEENTRY32) };
while (Module32Next(snapshot, &moduleEntry)) {
std::wcout << "モジュール名: " << moduleEntry.szModule << std::endl;
std::wcout << "パス: " << moduleEntry.szExePath << std::endl;
std::wcout << "基底アドレス: 0x" << std::hex << moduleEntry.modBaseAddr << std::endl;
}
CloseHandle(snapshot);
}
int main() {
ListModules(5678);
return 0;
}
6月4日 22:29 投稿