
Recent research has demonstrated novel techniques for injecting malicious code into Windows processes without relying on traditional memory allocation and writing stages—the very steps upon which most attack detection systems are built. In their experiments, researchers focused solely on the execution phase and proved that it alone can suffice for successful code injection.
The classic method of injecting code into a foreign process typically follows a sequence: the attacker first allocates memory in the target process (e.g., using VirtualAllocEx), writes the payload into that memory (often via WriteProcessMemory), and finally initiates execution through mechanisms like CreateRemoteThread or APC. This “allocate-write-execute” chain is what most modern EDR (Endpoint Detection and Response) solutions are designed to detect and block. However, the new study revealed that this entire chain is not strictly necessary.
The researchers posed a provocative question: what if both memory allocation and writing were omitted entirely? This led them to explore techniques based solely on execution mechanisms. One of the first methods they tested was a “pointer-only” DLL injection. In this approach, LoadLibraryA is invoked with a pointer to an existing string in the target process’s memory—for instance, the string “0,” which is always present in ntdll.dll. A malicious file named “0.dll” is then placed in the file system, and the system loads it without any memory write operations to the target process. This attack evaded detection by two leading EDR products.
Another method involved using CreateRemoteThread in combination with SetThreadContext. A new thread is created in a suspended state, after which its context is manually configured, including registers RCX, RDX, R8, and R9—corresponding to the Windows x64 calling convention. This allows the attacker to invoke any API function, such as VirtualAlloc or RtlFillMemory, with arbitrary arguments. Since the writing and execution occur within the victim process itself, external monitoring tools detect nothing unusual.
The third method leverages NtCreateThread, an obscure system call that permits passing a preconfigured CONTEXT structure—including desired registers and a stack pointer—directly into the kernel. Unlike CreateRemoteThread, which modifies the thread context after creation, this technique allows full control from the outset, enhancing stealth. In one implementation, a thread was launched using a ROP (Return-Oriented Programming) gadget chain to sequentially invoke VirtualAlloc, then RtlFillMemory, and finally the shellcode.
The research also examined fundamental weaknesses in attack detection architecture. Many EDR solutions correlate two or three suspicious actions: remote memory allocation, memory modification, and code execution. If only execution mechanisms are used—and all activity occurs “locally” within the target process—this logic breaks down. Context manipulation of threads becomes especially difficult to track when it doesn’t involve direct memory writes or calls to commonly monitored APIs.
Moreover, it was noted that cross-process thread creation is not inherently suspicious—debuggers, profilers, compatibility layers, monitoring agents, and even legitimate Windows components routinely perform such actions. As a result, alerts triggered by CreateRemoteThread often get lost in the noise.
The researchers successfully implemented the described techniques, achieving DLL injection and shellcode execution without memory write operations, using a variety of execution methods—from the classic CreateRemoteThread to the more advanced NtQueueApcThreadEx2. They also demonstrated context replacement using ROP gadgets and multi-stage strategies.
While the process did present challenges—such as stack management complexities and limitations on argument passing—these hurdles were ultimately overcome. Some methods required identifying ROP gadgets in memory, though this could be substituted with static analysis of PE files.
The key takeaway is that modern security solutions overly rely on templated attack models, failing to catch sophisticated scenarios in which attackers coerce the target process into executing the desired code on their behalf. In such cases, the attacker effectively seizes control, while conventional telemetry records none of the usual signs of intrusion. This asymmetry is what renders execution-only attacks especially dangerous.
In essence, EDR solutions solve a three-variable equation: who allocated the memory, who modified it, and who executed the code. But if the attacker already knows the answer—such as invoking LoadLibraryA with a pre-existing string—they can outmaneuver detection and remain invisible.