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. 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. 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. 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;