Sentinel Pointers
Consider this crash point:
0:000> r
eax=02d0f15c ebx=02a62918 ecx=77e41c30 edx=00000000 esi=ffffffff edi=02a8ed28
eip=76154193 esp=02d0f124 ebp=02d0f130 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246
Application!GetData+0xb:
76154193 8b9eac000000 mov ebx,dword ptr [esi+0ACh] ds:0023:000000ab=????????
Seeing 000000ab address we can think that ESI was 0 but it was 0xFFFFFFFF. Adding 0xAC to it produced an effective NULL data pointer 0xAB through integer addition overflow if we consider addition as unsigned. It is easy to see the result if we consider 0xFFFFFFFF as signed -1. Looking at stack trace and function disassembly we see that 0xFFFFFFFF was passed as a parameter:
0:000> kv
ChildEBP RetAddr Args to Child
02d0f130 7616328d ffffffff 02d0f15c 02d0f150 Application!GetData+0xb
[…]
02d0ffec 00000000 740420d8 02a74070 00000000 kernel32!BaseThreadStart+0×34
0:000> u Application!GetData
Application!GetData:
76154188 mov edi,edi
7615418a push ebp
7615418b mov ebp,esp
7615418d push ecx
7615418e push ebx
7615418f push esi
76154190 mov esi,dword ptr [ebp+8]
76154193 mov ebx,dword ptr [esi+0ACh]
This is an example of a sentinel pointer marking the end of a linked list, for example, although NULL pointers having 0 value are usually used. Also -1 value can be used to assign an invalid pointer value.
- Dmitry Vostokov @ DumpAnalysis.org -