Page 1 of 2
RunPE No Longer Works on Windows 24H2 (0xc0000141 Error) – Need Help :)
Posted: Wed Jan 22, 2025 11:56 pm
by boyoss
Hi everyone!
I’ve been using a custom RunPE (memory injection) routine in my PureBasic project for years without any issues. It’s basically a method that “wraps” my main executable, asks for a password, and then launches it—just an extra layer of protection. I originally found the code here:
viewtopic.php?p=311116&sid=71318ad4a9f4 ... 91#p311116
Everything was fine on older Windows versions, but ever since upgrading to Windows 24H2, I’m now getting the 0xc0000141 error at launch, and the process never starts. I tried a few tweaks (changing context flags, checking 32/64-bit settings, etc.), but I still get the same error. Has anyone else encountered this problem or found a workaround?
Here’s the code I’m using, which worked great on previous versions:
Code: Select all
Procedure RunPE(lBuff, parameters.s)
; http://forums.purebasic.com/english/viewtopic.php?p=311116&sid=71318ad4a9f408ffe97d5eb450eef191#p311116
Protected *idh.IMAGE_DOS_HEADER = lBuff
Protected *ish.IMAGE_SECTION_HEADERS
Protected pi.PROCESS_INFORMATION
Protected *inh.IMAGE_NT_HEADERS
Protected si.STARTUPINFO
Protected lpBaseAddres.l
Protected Ctx.CONTEXT
Protected Addr.l, RET.l, i.l
CreateProcess_(#NUL, ProgramFilename() + " " + parameters, #NUL, #NUL, #False, #CREATE_SUSPENDED, #NUL, #NUL, @si, @pi)
Ctx\ContextFlags = #CONTEXT_INTEGER
If GetThreadContext_(pi\hThread, Ctx) = 0 : Goto EndThread : EndIf
ReadProcessMemory_(pi\hProcess, Ctx\Ebx + 8, @Addr, 4, #NUL)
If ZwUnmapViewOfSection_(Pi\hProcess, Addr) : Goto EndThread : EndIf
If lBuff = 0 : Goto EndThread : EndIf
*inh = lBuff + *idh\e_lfanew
lpBaseAddres = VirtualAllocEx_(pi\hProcess, *inh\OptionalHeader\ImageBase, *inh\OptionalHeader\SizeOfImage, #MEM_COMMIT | #MEM_RESERVE, #PAGE_EXECUTE_READWRITE)
WriteProcessMemory_(pi\hProcess, lpBaseAddres, lBuff, *inh\OptionalHeader\SizeOfHeaders, @ret)
*ish = *inh\OptionalHeader + *inh\FileHeader\SizeOfOptionalHeader
For i = 0 To *inh\FileHeader\NumberOfSections - 1
WriteProcessMemory_(pi\hProcess, lpBaseAddres + *ish\ish[i]\VirtualAddress, lBuff + *ish\ish[i]\PointerToRawData, *ish\ish[i]\SizeOfRawData, @ret)
Next
WriteProcessMemory_(pi\hProcess, Ctx\Ebx + 8, @lpBaseAddres, 4, #NUL)
Ctx\Eax = lpBaseAddres + *inh\OptionalHeader\AddressOfEntryPoint
SetThreadContext_(pi\hThread, Ctx)
ResumeThread_(pi\hThread)
ProcedureReturn
EndThread:
TerminateProcess_(pi\hProcess, #NUL)
CloseHandle_(pi\hThread)
CloseHandle_(pi\hProcess)
EndProcedure
RunPE(?filea, "")
DataSection
filea:
IncludeBinary "C:\Windows\SysWOW64\calc.exe" : end_filea:
EndDataSection
Any suggestions or updated methods to get this running on Windows 24H2? I’d really appreciate any insight. Thank you so much in advance!
Cheers,
Joseph
Re: RunPE No Longer Works on Windows 24H2 (0xc0000141 Error) – Need Help :)
Posted: Thu Jan 23, 2025 12:02 am
by miso
Hello,
try replacing the long variables to integer. Not sure if that's the problem though, but the chances are good.
(the ones that refers to addresses like lpBaseAddres.l )
Re: RunPE No Longer Works on Windows 24H2 (0xc0000141 Error) – Need Help :)
Posted: Thu Jan 23, 2025 12:12 am
by boyoss
you mean like this? same problem...
Code: Select all
Procedure RunPE(lBuff.i, parameters.s)
; http://forums.purebasic.com/english/viewtopic.php?p=311116&sid=71318ad4a9f408ffe97d5eb450eef191#p311116
Protected *idh.IMAGE_DOS_HEADER = lBuff
Protected *ish.IMAGE_SECTION_HEADERS
Protected pi.PROCESS_INFORMATION
Protected *inh.IMAGE_NT_HEADERS
Protected si.STARTUPINFO
Protected lpBaseAddres.i
Protected Ctx.CONTEXT
Protected Addr.i, RET.i, i.i
CreateProcess_(#NUL, ProgramFilename() + " " + parameters, #NUL, #NUL, #False, #CREATE_SUSPENDED, #NUL, #NUL, @si, @pi)
Ctx\ContextFlags = #CONTEXT_INTEGER
If GetThreadContext_(pi\hThread, Ctx) = 0 : Goto EndThread : EndIf
ReadProcessMemory_(pi\hProcess, Ctx\Ebx + 8, @Addr, 4, #NUL)
If ZwUnmapViewOfSection_(Pi\hProcess, Addr) : Goto EndThread : EndIf
If lBuff = 0 : Goto EndThread : EndIf
*inh = lBuff + *idh\e_lfanew
lpBaseAddres = VirtualAllocEx_(pi\hProcess, *inh\OptionalHeader\ImageBase, *inh\OptionalHeader\SizeOfImage, #MEM_COMMIT | #MEM_RESERVE, #PAGE_EXECUTE_READWRITE)
WriteProcessMemory_(pi\hProcess, lpBaseAddres, lBuff, *inh\OptionalHeader\SizeOfHeaders, @ret)
*ish = *inh\OptionalHeader + *inh\FileHeader\SizeOfOptionalHeader
For i = 0 To *inh\FileHeader\NumberOfSections - 1
WriteProcessMemory_(pi\hProcess, lpBaseAddres + *ish\ish[i]\VirtualAddress, lBuff + *ish\ish[i]\PointerToRawData, *ish\ish[i]\SizeOfRawData, @ret)
Next
WriteProcessMemory_(pi\hProcess, Ctx\Ebx + 8, @lpBaseAddres, 4, #NUL)
Ctx\Eax = lpBaseAddres + *inh\OptionalHeader\AddressOfEntryPoint
SetThreadContext_(pi\hThread, Ctx)
ResumeThread_(pi\hThread)
ProcedureReturn
EndThread:
TerminateProcess_(pi\hProcess, #NUL)
CloseHandle_(pi\hThread)
CloseHandle_(pi\hProcess)
EndProcedure
Re: RunPE No Longer Works on Windows 24H2 (0xc0000141 Error) – Need Help :)
Posted: Thu Jan 23, 2025 12:24 am
by miso
Yes, I meant that. Unfortunately, that was my only guess.
Re: RunPE No Longer Works on Windows 24H2 (0xc0000141 Error) – Need Help :)
Posted: Thu Jan 23, 2025 3:43 pm
by ricardo_sdl
Where exactly you get the eror? When calling CreateProcess_? Your program starts okay without CreateProcess_? Did you try to zero the memory for sti and pi structs (like in this
example?
Re: RunPE No Longer Works on Windows 24H2 (0xc0000141 Error) – Need Help :)
Posted: Thu Jan 23, 2025 9:19 pm
by Piero
It may also seem a black hat thing, but the most irritating thing is that the term "injection" probably reminds to most of us of far worse stuff…

Re: RunPE No Longer Works on Windows 24H2 (0xc0000141 Error) – Need Help :)
Posted: Thu Jan 23, 2025 10:09 pm
by boyoss
I just want to clarify that my software is a serious, fully legitimate application—it's even certified by Microsoft.
The “injection” reference in my post simply describes how I’m protecting the program in memory, rather than distributing the original, unprotected file.
This is purely a security layer and not related to any malicious behavior or virus development.
Hope that clears things up!
Re: RunPE No Longer Works on Windows 24H2 (0xc0000141 Error) – Need Help :)
Posted: Thu Jan 23, 2025 10:16 pm
by tj1010
Piero wrote: Thu Jan 23, 2025 9:19 pm
It may also seem a black hat thing, but the most irritating thing is that the term "injection" probably reminds to most of us of far worse stuff…
99% of malware doesn't manually map pe/elf/mach. Most just do crypter or packer to get past static-sigature AV and the fake HIDS/HIPS; which is most AV regardless of marketing..
If I wanted license protection on something I'd just put TheMida or VMProtect on it and hide the check in VM code. Oreans products explicitly support PB binaries and it's not expensive. Someone talented at cracking would still have to spend hours devirtualizing and fixing hashes and pointers on new code, and since it's not an AAA game they likely won't bother..
I didn't test this, but it's likely breaking relocation, or there is some process-hollowing protection. ASLR and DEP are transparently handled by VirtualAllocEx and the kernel->EPROCESS. Windows 10 and 11 have the same process security and UAC hasn't changed..
Re: RunPE No Longer Works on Windows 24H2 (0xc0000141 Error) – Need Help :)
Posted: Thu Jan 23, 2025 10:31 pm
by Piero
tj1010 wrote: Thu Jan 23, 2025 10:16 pmASLR and DEP are transparently handled by VirtualAllocEx and the kernel->EPROCESS.
My ignorance about your Egyptian simply makes me hope you will employ your skills for the benefit of us all

Re: RunPE No Longer Works on Windows 24H2 (0xc0000141 Error) – Need Help :)
Posted: Fri Jan 24, 2025 12:15 am
by boyoss
Hi everyone,
I got help from DeepSeek AI to prepare an updated version of the RunPE code, but now I'm getting a 0xc00004ac error.
Does anyone know if there's a way to fix this, or should we assume this method simply won't work anymore with recent Windows versions?
Here's the new code I'm trying:
Code: Select all
Procedure RunPE(lBuff, parameters.s)
; Define structures
Protected *idh.IMAGE_DOS_HEADER = lBuff
Protected *inh.IMAGE_NT_HEADERS
Protected *ish.IMAGE_SECTION_HEADER
Protected pi.PROCESS_INFORMATION
Protected si.STARTUPINFO
Protected lpBaseAddress.l
Protected Ctx.CONTEXT
Protected Addr.l, RET.l, i.l
; Initialize STARTUPINFO structure
ZeroMemory_(@si, SizeOf(STARTUPINFO))
si\cb = SizeOf(STARTUPINFO)
; Create a suspended process
If CreateProcess_(#NUL, ProgramFilename(), #NUL, #NUL, #False, #CREATE_SUSPENDED, #NUL, #NUL, @si, @pi) = 0
Debug "CreateProcess failed: " + Str(GetLastError_())
ProcedureReturn #False
EndIf
; Set context flags and get thread context
Ctx\ContextFlags = #CONTEXT_FULL
If GetThreadContext_(pi\hThread, @Ctx) = 0
Debug "GetThreadContext failed: " + Str(GetLastError_())
TerminateProcess_(pi\hProcess, 0)
CloseHandle_(pi\hThread)
CloseHandle_(pi\hProcess)
ProcedureReturn #False
EndIf
; Read the base address of the target process
If ReadProcessMemory_(pi\hProcess, Ctx\Ebx + 8, @Addr, 4, #NUL) = 0
Debug "ReadProcessMemory failed: " + Str(GetLastError_())
TerminateProcess_(pi\hProcess, 0)
CloseHandle_(pi\hThread)
CloseHandle_(pi\hProcess)
ProcedureReturn #False
EndIf
; Get the NT headers
*inh = lBuff + *idh\e_lfanew
; Allocate memory in the target process (let Windows choose the base address)
lpBaseAddress = VirtualAllocEx_(pi\hProcess, #Null, *inh\OptionalHeader\SizeOfImage, #MEM_COMMIT | #MEM_RESERVE, #PAGE_EXECUTE_READWRITE)
If lpBaseAddress = 0
Debug "VirtualAllocEx failed: " + Str(GetLastError_())
TerminateProcess_(pi\hProcess, 0)
CloseHandle_(pi\hThread)
CloseHandle_(pi\hProcess)
ProcedureReturn #False
EndIf
; Write the headers to the target process
If WriteProcessMemory_(pi\hProcess, lpBaseAddress, lBuff, *inh\OptionalHeader\SizeOfHeaders, @RET) = 0
Debug "WriteProcessMemory (headers) failed: " + Str(GetLastError_())
TerminateProcess_(pi\hProcess, 0)
CloseHandle_(pi\hThread)
CloseHandle_(pi\hProcess)
ProcedureReturn #False
EndIf
; Write each section to the target process
*ish = lBuff + *idh\e_lfanew + SizeOf(IMAGE_NT_HEADERS)
For i = 0 To *inh\FileHeader\NumberOfSections - 1
If WriteProcessMemory_(pi\hProcess, lpBaseAddress + *ish\VirtualAddress, lBuff + *ish\PointerToRawData, *ish\SizeOfRawData, @RET) = 0
Debug "WriteProcessMemory (section " + Str(i) + ") failed: " + Str(GetLastError_())
TerminateProcess_(pi\hProcess, 0)
CloseHandle_(pi\hThread)
CloseHandle_(pi\hProcess)
ProcedureReturn #False
EndIf
*ish + SizeOf(IMAGE_SECTION_HEADER)
Next
; Update the base address in the target process
If WriteProcessMemory_(pi\hProcess, Ctx\Ebx + 8, @lpBaseAddress, 4, #NUL) = 0
Debug "WriteProcessMemory (base address) failed: " + Str(GetLastError_())
TerminateProcess_(pi\hProcess, 0)
CloseHandle_(pi\hThread)
CloseHandle_(pi\hProcess)
ProcedureReturn #False
EndIf
; Set the entry point
Ctx\Eax = lpBaseAddress + *inh\OptionalHeader\AddressOfEntryPoint
; Set the thread context
If SetThreadContext_(pi\hThread, @Ctx) = 0
Debug "SetThreadContext failed: " + Str(GetLastError_())
TerminateProcess_(pi\hProcess, 0)
CloseHandle_(pi\hThread)
CloseHandle_(pi\hProcess)
ProcedureReturn #False
EndIf
; Load required dependencies manually (example: kernel32.dll)
Protected hKernel32 = LoadLibrary_("kernel32.dll")
If hKernel32 = 0
Debug "Failed to load kernel32.dll"
TerminateProcess_(pi\hProcess, 0)
CloseHandle_(pi\hThread)
CloseHandle_(pi\hProcess)
ProcedureReturn #False
EndIf
; Resume the thread
If ResumeThread_(pi\hThread) = -1
Debug "ResumeThread failed: " + Str(GetLastError_())
TerminateProcess_(pi\hProcess, 0)
CloseHandle_(pi\hThread)
CloseHandle_(pi\hProcess)
ProcedureReturn #False
EndIf
; Close handles
CloseHandle_(pi\hThread)
CloseHandle_(pi\hProcess)
Debug "Process executed successfully"
ProcedureReturn #True
EndProcedure
; Example usage
RunPE(?filea, "")
DataSection
filea:
IncludeBinary "C:\Windows\SysWOW64\calc.exe"
end_filea:
EndDataSection
Re: RunPE No Longer Works on Windows 24H2 (0xc0000141 Error) – Need Help :)
Posted: Tue Jan 28, 2025 12:22 am
by tj1010
This worked on 11 24H2 64bit with all security disabled. I'm not sure what feature breaks it I didn't want to reboot and test a lot..
Code: Select all
Procedure RunPE(lBuff, parameters.s)
Protected *idh.IMAGE_DOS_HEADER = lBuff
Protected *ish.IMAGE_SECTION_HEADERS
Protected pi.PROCESS_INFORMATION
Protected *inh.IMAGE_NT_HEADERS
Protected si.STARTUPINFO
Protected lpBaseAddres.l
Protected Ctx.CONTEXT
Protected Addr.l, RET.l, i.l
If CreateProcess_(#NUL,ProgramFilename()+" "+parameters,#NUL,#NUL,#False,#CREATE_SUSPENDED,#NUL,#NUL, @si, @pi)
Ctx\ContextFlags = #CONTEXT_INTEGER
If GetThreadContext_(pi\hThread, Ctx)
If ReadProcessMemory_(pi\hProcess, Ctx\Rcx+8, @Addr, 4, #NUL)
If ZwUnmapViewOfSection_(Pi\hProcess, Addr)
If lBuff > 0
*inh = lBuff+*idh\e_lfanew
lpBaseAddres = VirtualAllocEx_(pi\hProcess, *inh\OptionalHeader\ImageBase, *inh\OptionalHeader\SizeOfImage, #MEM_COMMIT | #MEM_RESERVE, #PAGE_EXECUTE_READWRITE)
WriteProcessMemory_(pi\hProcess, lpBaseAddres, lBuff, *inh\OptionalHeader\SizeOfHeaders, @ret)
*ish = *inh\OptionalHeader + *inh\FileHeader\SizeOfOptionalHeader
For i = 0 To *inh\FileHeader\NumberOfSections - 1
WriteProcessMemory_(pi\hProcess, lpBaseAddres + *ish\ish[i]\VirtualAddress, lBuff + *ish\ish[i]\PointerToRawData, *ish\ish[i]\SizeOfRawData, @ret)
Next
WriteProcessMemory_(pi\hProcess, Ctx\Rcx+8, @lpBaseAddres, 4, #NUL)
Ctx\Rdx = lpBaseAddres + *inh\OptionalHeader\AddressOfEntryPoint
SetThreadContext_(pi\hThread, Ctx)
ResumeThread_(pi\hThread)
ProcedureReturn
Else
TerminateProcess_(pi\hProcess, #NUL)
CloseHandle_(pi\hThread)
CloseHandle_(pi\hProcess)
MessageRequester("Error","lBuff Empty")
EndIf
Else
TerminateProcess_(pi\hProcess, #NUL)
CloseHandle_(pi\hThread)
CloseHandle_(pi\hProcess)
MessageRequester("Error","ZwUnmapViewOfSection Failed")
EndIf
Else
TerminateProcess_(pi\hProcess, #NUL)
CloseHandle_(pi\hThread)
CloseHandle_(pi\hProcess)
MessageRequester("Error","ReadProcessMemory Failed")
EndIf
Else
TerminateProcess_(pi\hProcess, #NUL)
CloseHandle_(pi\hThread)
CloseHandle_(pi\hProcess)
MessageRequester("Error","GetThreadContext Failed")
EndIf
Else
MessageRequester("Error","Process Failed To Launch")
EndIf
EndProcedure
Re: RunPE No Longer Works on Windows 24H2 (0xc0000141 Error) – Need Help :)
Posted: Tue Jan 28, 2025 8:33 am
by boyoss
ok i'm checking thank you
Re: RunPE No Longer Works on Windows 24H2 (0xc0000141 Error) – Need Help :)
Posted: Tue Jan 28, 2025 4:14 pm
by tj1010
I found out the MEM_PRIVATE to MEM_IMAGE change in the windows loader broke RunPE in 24H2. There are around four other methods to run memory resident code via CreateProcess->VirtualAllocEX, though. You can also hook a call in ntdll to disable to check for MEM_IMAGE.
I use to have code to map a exe without CreateProcess using host process PID but I lost it on a SSD that went bad. These other methods are just based around process hollowing.
There is also a way with PowerShell that I never looked in to that doesn't need a new PID, and of course with a driver by manipulating EPROCESS or memory injection.
Re: RunPE No Longer Works on Windows 24H2 (0xc0000141 Error) – Need Help :)
Posted: Wed Jan 29, 2025 12:42 am
by boyoss
Thank you.
If you provide me a working code i'll pay you 100 dollars..
Re: RunPE No Longer Works on Windows 24H2 (0xc0000141 Error) – Need Help :)
Posted: Wed Jan 29, 2025 1:34 pm
by breeze4me