0

I found a crash while testing, and the cause was an unexpected error while writing to a socket. Unfortunately, the exception which was thrown didn't actually contain the direct reason for the failure (i.e. send() failed, but it didn't save the value of WSAGetLastError() when throwing the exception). The send was happening on an 'internal pipe' which was created by connecting a socket to a listening socket from the same process listening on localhost, so it's strange that any error occurred (it's used for inter-thread communication, and it was just trying to send a single byte to wake up another thread doing a select())

Since the crash occurred right after the send failed, and there shouldn't have been any other socket operations on the thread in between, I believe that the error code should be somewhere in the dump file. My knowledge of x8664 assembly isn't great, but I was hoping to be able to decipher the implementation of WSAGetLastError to figure out where to find that error code (is there any easier way of doing this?)

Using https://github.com/lucasg/Dependencies, I found the address of WSAGetLastError in ws2_32.dll on my system (0x00012730), and from the core dump I found the base address of that DLL (0x7ffc95e50000), so I added them together & looked at the disassembly of 0x7FFC95E62730 in visual studio (while debugging the core dump) & saw

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  

so then I looked at *(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 

I'm not sure how to interpret qword ptr gs:[30h] though. WinDBG tells me that the value of the GS register on that thread is 0x002b, but 0x005b isn't a mapped address.

Bwmat
  • 4,314
  • 3
  • 27
  • 42
  • 0x07FFC95E95C38 is a pointer; look at its value instead. Regardless, if an exception is being thrown it's likely the LastError value will have been overwritten by the time the dump is created. – Luke Mar 01 '23 at 08:08
  • Also, simpler option is to use the debugger command: https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/-gle – Luke Mar 01 '23 at 08:09
  • Yeah I just realized that I missed it was a pointer, but I don't think that gle will help me, since wsa(get/set)lasterror is separate from that? – Bwmat Mar 01 '23 at 17:44
  • https://stackoverflow.com/questions/15586224/is-wsagetlasterror-just-an-alias-for-getlasterror I guess they aren't separate, so my quest was doomed from the start :( – Bwmat Mar 01 '23 at 18:26
  • For x64 code, the gs register addresses the thread environment block (TEB). Windbg can show you its address and content: https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/-teb – Hans Passant Mar 01 '23 at 19:22
  • 0:000> dt ntdll!_TEB -y Las* @$teb +0x068 LastErrorValue : 0 +0x1250 LastStatusValue : 0xc0000034 gs points to teb both Last Error and Hresult are available in teb but it might be stale – blabb Mar 04 '23 at 05:42

0 Answers0