January 10, 2014

Triaging crash on instruction "call [rax]"

The following Python script causing handled access violation when it's executed with Python 2.7.6.
import tkMessageBox
import time

time.sleep(6)
The exception can be caught by the following command.
C:\Work>"c:\Program Files\Debugging Tools for Windows (x64)\windbg.exe" -g c:\Python27\python.exe messagebox.py
Then Windbg displays:
(c2a4.c374): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for c:\Python27\DLLs\tk85.dll -
tk85!Tk_MainLoop+0x122:
00000000`102de8b2 ff9068030000    call    qword ptr [rax+368h] ds:00000000`00000368=????????????????
call [rax] suggests to pay attention because the issue could be exploitable if rax is attacker controlled.

We can see the crash happens when we read address near null so you may think it's a non-exploitable null pointer dereference. However to confirm this we need to investigate how rax is set to null. If null is read from previously freed memory we may have the chance to corrupt the memory in a way to inject arbitrary pointer therefore to make the issue exploitable.

So the preceding instruction sets rax that is:
0:000> ub rip L1
tk85!Tk_MainLoop+0x11b:
00000000`102de8ab 488b0576bd0d00  mov     rax,qword ptr [tk85!XDrawLine+0x59b98 (00000000`103ba628)]
We can see the address is fixed, relative to tk85, which was allocated when the module was being loaded in the virtual address space. Now we can say with more confidence the issue is a non-exploitable null pointer dereference.

Python 3.x doesn't support tkMessageBox so it's not affected.
  This blog is written and maintained by Attila Suszter. Read in Feed Reader.