Win10 64位1909系统中NtCreateThreadEx调用失败问题求助
Let's break down why your NtCreateThreadEx call is failing and how to fix it:
First, the error code 31 maps to ERROR_GEN_FAILURE, and the NTSTATUS value -1073741819 translates to 0xC0000005 (STATUS_ACCESS_VIOLATION). The root issues here are incorrect struct initialization for NtCreateThreadExBuffer and potentially misconfigured parameters/process permissions.
1. Ditch the Complex Buffer (For Vista+ Systems)
On Windows Vista and later, the lpBytesBuffer parameter of NtCreateThreadEx can be set to NULL—you don't need to manually populate that finicky buffer struct. This is the most reliable fix for modern systems, as struct layouts can vary across Windows versions.
Here's a simplified, corrected version of your code:
// Get function pointers HMODULE ntdll = GetModuleHandle(L"ntdll.dll"); HMODULE kernel32 = GetModuleHandle(L"kernel32.dll"); typedef NTSTATUS(WINAPI* LPFUN_NtCreateThreadEx)( OUT PHANDLE hThread, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ProcessHandle, IN PVOID lpStartAddress, IN PVOID lpParameter, IN BOOLEAN CreateSuspended, IN ULONG StackZeroBits, IN ULONG SizeOfStackCommit, IN ULONG SizeOfStackReserve, OUT PVOID lpBytesBuffer ); LPFUN_NtCreateThreadEx funNtCreateThreadEx = (LPFUN_NtCreateThreadEx)GetProcAddress(ntdll, "NtCreateThreadEx"); FARPROC lpfnLoadLibrary = GetProcAddress(kernel32, "LoadLibraryA"); if (funNtCreateThreadEx && lpfnLoadLibrary) { HANDLE hThread = NULL; NTSTATUS status = funNtCreateThreadEx( &hThread, THREAD_ALL_ACCESS, // Use minimal required permissions if possible (e.g., THREAD_CREATE_THREAD | THREAD_QUERY_INFORMATION) NULL, hCurrp, // Ensure this handle has sufficient process permissions (see step 2) (PVOID)lpfnLoadLibrary, (PVOID)param, // Must be a pointer to DLL path in the target process's memory (see step 3) FALSE, 0, 0, 0, NULL // No buffer needed for Vista+ ); if (NT_SUCCESS(status)) { WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); } else { printf("NtCreateThreadEx failed with NTSTATUS: 0x%X\n", status); } }
2. Verify Process Handle Permissions
Make sure you opened the target process with all necessary rights. Without these, even a correct NtCreateThreadEx call will fail:
HANDLE hCurrp = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, targetProcessId // Replace with your target process ID );
3. Ensure DLL Path is Written to Target Memory
The param argument you pass to LoadLibraryA must be a pointer to the DLL path inside the target process's address space, not your local process's memory. Use these calls to write it:
const char* dllPath = "C:\\path\\to\\your.dll"; LPVOID param = VirtualAllocEx(hCurrp, NULL, strlen(dllPath) + 1, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (param) { WriteProcessMemory(hCurrp, param, dllPath, strlen(dllPath) + 1, NULL); // Now use this param in NtCreateThreadEx }
4. XP Compatibility (If Absolutely Necessary)
If you need to support Windows XP (which is extremely rare now), your buffer struct initialization had errors. Here's the corrected XP-compatible setup:
struct NtCreateThreadExBuffer { ULONG Size; ULONG Unknown1; ULONG Unknown2; PULONG Unknown3; ULONG Unknown4; ULONG Unknown5; ULONG Unknown6; PULONG Unknown7; ULONG Unknown8; }; NtCreateThreadExBuffer ntbuffer = {0}; ntbuffer.Size = sizeof(NtCreateThreadExBuffer); ntbuffer.Unknown1 = 0x10003; ntbuffer.Unknown2 = 0x8; ntbuffer.Unknown3 = NULL; // Don't use local pointers—target process can't access them ntbuffer.Unknown4 = 0; ntbuffer.Unknown5 = 0x10004; ntbuffer.Unknown6 = 0; // Your original code set this to 4, which was incorrect ntbuffer.Unknown7 = NULL; ntbuffer.Unknown8 = 0;
Final Notes
The biggest mistake in your original code was overcomplicating the buffer struct—modern Windows doesn't require it. By simplifying the call, fixing process permissions, and ensuring the DLL path is in the target process memory, your injection should work as expected.
内容的提问来源于stack exchange,提问作者Rapunzel

