我在测试的时候发现一个crash,原因是写入socket的时候发生了意外的错误。不幸的是,抛出的异常实际上并不包含失败的直接原因(即 send() 失败,但在抛出异常时它没有保存 WSAGetLastError() 的值)。发送发生在“内部管道”上,该管道是通过将套接字连接到侦听本地主机的同一进程的侦听套接字而创建的,因此发生任何错误都很奇怪(它用于线程间通信,它只是在尝试发送一个字节来唤醒另一个执行 select()) 的线程
由于崩溃是在发送失败后立即发生的,并且其间线程上不应该有任何其他套接字操作,我相信错误代码应该在转储文件中的某个地方。我对 x8664 汇编的了解不是很好,但我希望能够破译 WSAGetLastError 的实现以找出在哪里可以找到该错误代码(有没有更简单的方法来做到这一点?)
使用https://github.com/lucasg/Dependencies,我在我的系统(0x00012730)上的ws2_32.dll中找到了WSAGetLastError的地址,并且从核心转储中我找到了那个DLL的基址(0x7ffc95e50000),所以我将它们加在一起并在 visual studio 中查看了 0x7FFC95E62730 的反汇编(同时调试核心转储)并看到
00007FFC95E62730 48 FF 25 01 35 03 00 jmp qword ptr [__imp_GetLastError (07FFC95E95C38h)]
00007FFC95E62737 CC int 3
00007FFC95E62738 CC int 3
00007FFC95E62739 CC int 3
00007FFC95E6273A CC int 3
00007FFC95E6273B CC int 3
00007FFC95E6273C CC int 3
00007FFC95E6273D CC int 3
然后我看着
*(void*)0x07FFC95E95C38
= 0x7FFC93DACD60
00007FFC93DACD60 65 48 8B 04 25 30 00 00 00 mov rax,qword ptr gs:[30h]
00007FFC93DACD69 8B 40 68 mov eax,dword ptr [rax+68h]
00007FFC93DACD6C C3 ret
虽然我不确定如何解释
qword ptr gs:[30h]
。 WinDBG 告诉我该线程上的 GS 寄存器的值为0x002b
,但0x005b
不是映射地址。