
Chrome 49 在 ReactOS 上 c0000005 崩溃的修复过程概述Chrome 49 (Chrome_V49) 在 ReactOS 上启动时立即崩溃异常代码c0000005访问违例EIP0。本文档详细记录了从问题分析到修复的完整过程。1. 启用 Chrome 专用崩溃调试日志修改文件dll/win32/kernel32/client/except.c修改内容在UnhandledExceptionFilter调用的PrintStackTrace函数中添加进程名判断仅当当前进程为Chrome.exe时才打印详细的崩溃调试信息。关键代码 - 进程名判断staticBOOLIsChromeProcess(VOID){CHAR szPath[MAX_PATH];CHAR*pName,*pSlash;if(!GetModuleFileNameA(NULL,szPath,sizeof(szPath)))returnFALSE;/* Extract filename from full path */pNameszPath;pSlashstrrchr(szPath,\\);if(pSlash)pNamepSlash1;pSlashstrrchr(szPath,/);if(pSlashpSlashpName-1)pNamepSlash1;/* Convert to lowercase for comparison */for(pSlashpName;*pSlash;pSlash){if(*pSlashA*pSlashZ)*pSlasha-A;}return(strcmp(pName,chrome.exe)0);}调试日志输出10 步步骤内容说明Step 1Exception Basic Information异常代码、标志、地址Step 2Access Violation Details读/写/执行类型、目标地址Step 3Stack Data DumpESP 附近栈数据定位调用参数Step 4Wine Stub Check缺失函数检查Step 5CPU Registers Dump所有寄存器值Step 6Crash Location Analysis崩溃所在的模块名、基址、偏移Step 7Call Stack Trace帧回溯最多 128 帧Step 8All Loaded Modules所有已加载 DLL 列表Step 9Instruction at EIP崩溃位置的 16 字节机器码Step 10Debug Summary异常类型、崩溃位置摘要2. 第一次崩溃分析EIP0 的 NULL 指针调用崩溃日志摘要ExceptionCode: c0000005 (ACCESS_VIOLATION) ExceptionAddress: 00000000 Operation: READ Faulting Address: 00000000 Registers: EAX: 00000000 EBX: 00000000 ECX: 0012fce4 EDX: c0000001 EBP: 0012fe14 ESI: 0015b0d0 ESP: 0012fca0 EDI: 00400000 EIP: 00000000 Call Stack (3 frames): Frame[0]: Chrome.exe:0x1078f (base00400000) Frame[1]: Chrome.exe:0x63e1a (base00400000) Frame[2]: kernel32.dll:0x12535 (base7C5E0000)分析过程调用栈过短仅 3 帧→ 崩溃发生在 Chrome.exe 的非常早期初始化阶段EIP0→ CPU 试图执行地址 0 处的代码 → 通过 NULL 函数指针调用Frame[0]0x1078f→ 单例构造函数返回后的地址反汇编 Chrome.exe 构造函数使用 hex dump objdump 反汇编 Chrome.exe关键代码段RVA 0x104C0 ~ 0x1078f; Chrome 单例对象构造函数 (size 0x4C 76 bytes) ; 第一次 API 动态解析 0x104EE: call [GetCurrentProcess] ; 获取当前进程句柄 0x10504: call [GetModuleHandleW] ; GetModuleHandleW(kernel32.dll) 0x1050B: call [GetProcAddress] ; GetProcAddress(hMod, IsWow64Process) 0x10513: test eax, eax 0x10515: je SKIP ; 如果 NULL 则跳过 ... 0x1052C: call *%eax ; 调用 IsWow64Process ; 第二次 API 动态解析 0x106B9: push GetProductInfo ; 函数名 0x106BE: push kernel32.dll ; 模块名 0x106C3: call [GetModuleHandleW] ; GetModuleHandleW(kernel32.dll) 0x106C9: push eax ; hModule 0x106CA: call [GetProcAddress] ; GetProcAddress(hMod, GetProductInfo) ... 0x106E7: call *%eax ; 调用 GetProductInfo ← CRASH HERE!根因定位寄存器 栈数据综合分析ESP at 0x0012FCA0: 0x0012FCA0: 004106E9 00000006 00000000 00000000ESP 顶部值0x004106E9对应call *%eax指令后的返回地址RVA 0x106E9指令本身在RVA 0x106E7。call *%eax的分析GetProcAddress(hKernel32, GetProductInfo)→ EAX如果 EAX0函数未找到则call *%eax→ EIP0 → 崩溃根因确认ReactOS 的kernel32.spec文件将GetProductInfo定义为转发器 stdcall GetProductInfo(long long long long ptr) ntdll.RtlGetProductInfo但ntdll.dll 并没有导出 RtlGetProductInfoDLL导出 RtlGetProductInfontdll.dll❌ntdll_vista.dll✅ (Ordinal 2)Chrome 通过GetProcAddress(GetModuleHandleW(kernel32.dll), GetProductInfo)查找函数 → 转发器指向ntdll.RtlGetProductInfo→ ntdll 中没有此函数 → 返回 NULL → Chrome 调用 NULL 指针 → 崩溃。3. 修复修改 kernel32.spec 转发器修改文件dll/win32/kernel32/kernel32.spec修改内容- stdcall GetProductInfo(long long long long ptr) ntdll.RtlGetProductInfo stdcall GetProductInfo(long long long long ptr) ntdll_vista.RtlGetProductInfo修复原理Chrome 在 Vista 兼容模式下运行LdrpInitializeProcessCompat: Found guid for winver 0x600Vista 兼容 shim DLLntdll_vista.dll会被自动加载ntdll_vista.dll确实导出了RtlGetProductInfo修改转发器指向ntdll_vista.RtlGetProductInfo后GetProcAddress能正确解析4. 修复验证修复前ExceptionCode: c0000005 ExceptionAddress: 00000000 Call Stack: 3 frames (Chrome.exe → Chrome.exe → kernel32)修复后ExceptionCode: 80000003 (BREAKPOINT) ExceptionAddress: 021D7BCB (chrome.dll 内有效地址) Call Stack: 20 frames (全部在 chrome.dll 内) EIP Bytes: cc c3 6a 01 e8 05 2d ec 00 cc ...结论✅c0000005NULL 指针崩溃已完全修复✅ Chrome 通过了单例构造函数阶段✅ Chrome 进入了chrome.dll 的主初始化代码⏳ 新的80000003断点异常是 Chrome 内部断言失败需要进一步分析5. 文件变更汇总文件变更类型说明dll/win32/kernel32/client/except.c新增调试代码添加IsChromeProcess()和 10 步调试日志dll/win32/kernel32/kernel32.spec修复GetProductInfo转发器从ntdll改为ntdll_vista6. 编译与部署流程# 编译ninja-C output-MinGW-i386 kernel32# 停止 VME:\VirtualBox\VBoxManage.exe controlvmReactOS-Test-Newpoweroff# 部署到 VDIvdi_tool.exe add output-MinGW-i386\ReactOS-Test.vdi ^ output-MinGW-i386\dll\win32\kernel32\kernel32.dll ^/ReactOS/system32/kernel32.dll# 清除串口日志 启动 VMRemove-Itemoutput-MinGW-i386\serial_output.log E:\VirtualBox\VBoxManage.exe startvmReactOS-Test-New# 查看日志Select-String-Pathoutput-MinGW-i386\serial_output.log-PatternCHROME-DBG