DLL injection

Trong lập trình máy tính, DLL injection (dịch: Tiêm chích DLL) là một kỹ thuật được sử dụng để chạy mã code trong của một 'tiến trình khác' thông qua cách ép nó tải một thư viện liên kết động. DLL injection hay được các 'chương trình bên ngoài' sử dụng để gây ảnh hưởng đến hành vi của một 'chương trình khác' theo cách mà tác giả của nó không hề tiên liệu hoặc dự định. Ví dụ, 'mã được tiêm' có thể (hook) vào các lời gọi hàm hệ thống, hoặc đọc nội dung của các hộp văn bản mật khẩu, những điều vậy không thể được thực hiện theo cách thông thường. Một chương trình mà được sử dụng để tiêm 'mã tùy ý' vào các 'tiến trình tùy ý' thì được gọi là một DLL injector.
Gian lận trong các trò chơi trực tuyến.
DLL injection là một phương pháp gian lận phổ biến trong các trò chơi bởi việc chạy một DLL bên trong một chương trình cũng như việc có thể thực thi code vào trong game đều là những việc rất dễ dàng. Tuy nhiên, hầu hết các trò chơi đều tự bảo vệ chính mình khỏi DLL injection.
Lối tiếp cận trên Microsoft Windows.
Trên Microsoft Windows, có nhiều cách để ép một tiến trình phải nạp và thực thi code của một DLL, nằm ngoài ý định của tác giả phần mềm đó:
Lối tiếp cận trên các hệ thống kiểu Unix.
Trên các hệ điều hành kiểu Unix với 'trình liên kết động' dựa trên ld.so (trên BSD) và ld-linux.so (trên Linux), các 'thư viện tùy ý' có thể được liên kết với một 'tiến trình mới' bằng cách đặt tên đường dẫn của thư viện đấy vào biến môi trường , biến đó có thể được đặt trên toàn cục hoặc riêng lẻ cho một tiến trình.
Ví dụ, trong bash, lệnh này khởi chạy lệnh "prog" với 'thư viện dùng chung' từ tệp "test.so", tệp này được liên kết với nó tại thời điểm khởi chạy: 
 LD_PRELOAD="./test.so" prog 
Một thư viện như vậy có thể được tạo ra bởi GCC bằng cách biên dịch 'tập tin nguồn' (chứa các toàn cục mới để được liên kết) bằng các tùy chọn -fpic hoặc -fPIC, và liên kết bằng tùy chọn -shared. Thư viện đấy có quyền truy cập vào các 'symbol ngoại tại' được khai báo trong chương trình như mọi thư viện khác.
Trên OS X, 'lệnh sau' khởi chạy lệnh "prog" với 'thư viện dùng chung' từ tệp "test.dylib" được liên kết với nó tại thời điểm khởi chạy: 
 DYLD_INSERT_LIBRARIES="./test.dylib" DYLD_FORCE_FLAT_NAMESPACE=1 prog
Cũng có thể sử dụng các kỹ thuật dựa trên debugger trên các hệ thống kiểu Unix.
Mã làm mẫu.
Sử dụng hàm API LoadLibrary.
Trong hệ điều hành Windows, có một cách đơn giản để tiêm DLL vào tiến trình khác là sử dụng hàm API CreateRemoteThread. Phương pháp là tạo một thread vào tiến trình đấy từ xa, thread đó sẽ nạp 'DLL mong muốn' vào. Hàm CreateRemoteThread yêu cầu một " trỏ tới một hàm nằm ở trong 'không gian địa chỉ' của tiến trình mục tiêu – tức là "phải có sẵn" một hàm có chức năng nạp 'DLL mong muốn' ở ngay tiến trình mục tiêu. Có một sự thật có thể được khai thác, đó là "kernel32.dll được ánh xạ tới cùng một địa chỉ trong hầu hết tất cả các tiến trình". Do đó hàm LoadLibrary của kernel32.dll (có chức năng nạp DLL bất kỳ) cũng sẽ có cùng địa chỉ trong hầu hết tiến trình. Cùng với việc hầu hết các ứng dụng đều liên kết với kernel32.dll nên hàm LoadLibrary luôn có sẵn ở hầu hết các tiến trình. Vì vậy có thể dùng CreateRemoteThread tạo một thread bắt đầu tại hàm LoadLibrary với đối số là đường dẫn tới DLL cần nạp. Xem ví dụ bên dưới cho cụ thể: 
HANDLE inject_DLL(const char* file_name, int PID) {
 // lấy một handle tới tiến trình mục tiêu
 HANDLE h_process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
 // lấy đường dẫn đầy đủ tới file dll
 char fullDLLPath[_MAX_PATH];
 GetFullPathName(file_name, _MAX_PATH, fullDLLPath, NULL);
 // cấp phát bộ nhớ tại tiến trình mục tiêu
 LPVOID DLLPath_addr = VirtualAllocEx(h_process, NULL, _MAX_PATH, 
 MEM_COMMIT | MEM_RESERVE, 
 PAGE_READWRITE);
 // viết đường dẫn dll vào bộ nhớ đó
 WriteProcessMemory(h_process, DLLPath_addr, fullDLLPath, 
 strlen(fullDLLPath), NULL);
 // lấy địa chỉ của LoadLibraryA (đều giống nhau ở mọi tiến trình)
 // để bật thread thực thi tại nó
 LPVOID LoadLib_addr = GetProcAddress(GetModuleHandle("Kernel32"), 
 "LoadLibraryA");
 // bắt đầu một thread thực thi từ xa tại LoadLibraryA
 // rồi truyền đường dẫn dll làm đối số
 HANDLE h_rThread = CreateRemoteThread(h_process, NULL, 0, 
 (LPTHREAD_START_ROUTINE)LoadLib_addr,
 DLLPath_addr, 0, NULL);
 // đợi cho đến khi thread đó hoàn thành
 WaitForSingleObject(h_rThread, INFINITE);
 // lấy 'giá trị trả về' của hàm LoadLibraryA nếu cần
 DWORD exit_code;
 GetExitCodeThread(h_rThread, &amp;exit_code);
 // giải phóng handle của thread vừa mới được inject...
 CloseHandle(h_rThread);
 // ...và bộ nhớ được cấp phát cho đường dẫn DLL đấy
 VirtualFreeEx(h_process, DLLPath_addr, 0, MEM_RELEASE);
 // ...và handle cho tiến trình mục tiêu đấy
 CloseHandle(h_process);
 return (HANDLE)exit_code;