TL;DR
This guide explains how to bypass Data Execution Prevention (DEP) on fully patched Windows XP SP3 Professional using the NtSetInformationProcess function. This technique requires a vulnerable process and allows execution of shellcode in memory regions normally protected by DEP.
Prerequisites
- Windows XP SP3 Professional (fully updated).
- A target process with sufficient permissions to modify its own protection attributes.
- Basic understanding of assembly language and shellcoding.
- Debugging tools like OllyDbg or x64dbg.
Steps
- Identify a Vulnerable Process: Find a process that allows you to inject code. Common targets include applications with known buffer overflows or other vulnerabilities. For demonstration, we’ll assume you have a way to inject shellcode into the target process’s memory space.
- Locate NtSetInformationProcess: This function resides in
ntdll.dll. In your debugger, openntdll.dlland find the address ofNtSetInformationProcess. - Understand the Function Parameters: The
NtSetInformationProcessfunction takes several parameters. We’re interested in these:- ProcessHandle: Handle to the target process.
- InfoClass: Specifies the information class to set. For DEP bypass, we use
0x29(ProcessDynamicEHStructPointer). - Info: A pointer to a structure containing the new information. This is where the magic happens.
- InfoLength: The length of the
Infostructure in bytes.
- Craft the Payload Structure: We need to create a structure that will disable DEP for our shellcode region. This involves manipulating the process’s exception handling information.
typedef struct _PROCESS_DYNAMIC_EH_STRUCT { ULONG Reserved[3]; PVOID ExceptionList; // Important! } PROCESS_DYNAMIC_EH_STRUCT, *PPROCESS_DYNAMIC_EH_STRUCT;The key is setting
ExceptionListto NULL. This effectively disables DEP for the process. - Inject Shellcode: Inject your shellcode into a writable memory region of the target process. Ensure this region has sufficient space and permissions (RWX – Read, Write, Execute).
- Call NtSetInformationProcess: From within the injected code, call
NtSetInformationProcesswith the following parameters:- ProcessHandle: The handle to the target process. You can obtain this using
GetCurrentProcess()if injecting into the same process or by opening it explicitly usingOpenProcess(). - InfoClass: Set to
0x29(ProcessDynamicEHStructPointer). - Info: A pointer to your crafted
PROCESS_DYNAMIC_EH_STRUCTstructure, withExceptionListset to NULL. - InfoLength: The size of the
PROCESS_DYNAMIC_EH_STRUCTstructure (e.g.,sizeof(PROCESS_DYNAMIC_EH_STRUCT)).
- ProcessHandle: The handle to the target process. You can obtain this using
- Execute Shellcode: After calling
NtSetInformationProcess, execute your shellcode from the injected memory region. DEP should now be bypassed.// Example (simplified assembly snippet - requires proper stack setup) PUSHAD MOV EAX, [shellcode_address] CALL EAX POPAD RET - Clean Up: Restore the original exception handling information if necessary to avoid instability. This is crucial for maintaining system stability.
Important Considerations
- ASLR (Address Space Layout Randomization): ASLR can complicate this process, as addresses of functions like
NtSetInformationProcesswill change on each execution. You may need to find a way to resolve the address dynamically at runtime. - UAC (User Account Control): UAC might prevent you from injecting code into protected processes.
- Antivirus/Firewall: Antivirus software and firewalls are likely to detect this technique. You may need to bypass or disable them.
- Stability: Disabling DEP can make the system unstable. Be careful when modifying process memory.

