
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

Cheers,
Joseph