[issue24201] _winreg PyHKEY Type Confusion
eryksun
report at bugs.python.org
Sat May 16 12:30:51 CEST 2015
eryksun added the comment:
> ntdll!RtlAllocateHeap+0x17:
> 776f1037 8b4344 mov eax,dword ptr [ebx+44h] ds:002b:00000044=????????
Some functions in RPCRT4 assume RPCRT4!PerformRpcInitialization has already been called. How else could you get an RPC handle? In this case RPCRT4!hRpcHeap hasn't been initialized yet.
That said, if you first perform some operation that properly initializes RPCRT4 -- such as query a privilege value from LSA -- then using a corrupt RPC handle will possibly trigger an unhandled exception farther down the line. I don't think this is a problem that needs to be addressed in winreg. It's an application bug.
Also, note that changing this in the winreg module isn't as simple as just commenting out the code in PyHKEY_AsHKEY. You'd also have to special case the HKEY constants, one way or another.
Here's an example that first calls an LSA API to initialize RPCRT4 (test system: 64-bit Windows 10, 32-bit Python 2.7).
Microsoft (R) Windows Debugger Version 10.0.10075.9 X86
Copyright (c) Microsoft Corporation. All rights reserved.
CommandLine: python
************* Symbol Path validation summary **************
Response Time (ms) Location
Deferred symsrv*symsrv.dll*
C:\Symbols*http://msdl.microsoft.com/download/symbols
Symbol search path is: symsrv*symsrv.dll*
C:\Symbols*http://msdl.microsoft.com/download/symbols
Executable search path is:
(818.b4c): Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=00000000 ecx=0cbe0000 edx=00000000 esi=1d0000e8 edi=7ffde000
eip=7756fb65 esp=0028fa64 ebp=0028fa90 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
ntdll!LdrpDoDebuggerBreak+0x2b:
7756fb65 cc int 3
0:000> bp RPCRT4!PerformRpcInitialization
0:000> g
Python 2.7.9 (default, Dec 10 2014, 12:24:55) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes, _winreg
>>> advapi32 = ctypes.WinDLL('advapi32')
>>> x = (ctypes.c_void_p * 4)()
>>> advapi32.LookupPrivilegeValueA(None, 'SeDebugPrivilege', x)
Breakpoint 0 hit
eax=0028f558 ebx=00000000 ecx=00000000 edx=00000000 esi=00000000 edi=0028f580
eip=7477183a esp=0028f51c ebp=0028f530 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
RPCRT4!PerformRpcInitialization:
7477183a 8bff mov edi,edi
0:000> dd RPCRT4!hRpcHeap l1
747dc870 00000000
0:000> pt; dd RPCRT4!hRpcHeap l1
747dc870 003a0000
0:000> g
1
>>> x[0] = 123 # bad internal RPC handle
>>> x[1] = 0xFEDCBA98 # RPC context handle signature
>>> _winreg.DeleteKey(ctypes.addressof(x) | 1, '')
RPCRT4 is initialized, so the unhandled exception shown below is no longer due to RPCRT4!hRpcHeap. Checking the context handle also succeeds in this case since I added the 0xFEDCBA98 signature, but it fails while checking the internal handle (0x7b, in register esi) for the signature 0x89ABCDEF.
(818.b4c): Access violation - code c0000005 (!!! second chance !!!)
eax=9b4e8357 ebx=0028f860 ecx=00000024 edx=00000001 esi=0000007b edi=748c66d0
eip=74766121 esp=0028f814 ebp=0028f828 iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010206
RPCRT4!I_RpcGetBufferWithObject+0x21:
74766121 817e04efcdab89 cmp dword ptr [esi+4],89ABCDEFh ds:002b:0000007f=????????
In a 64-bit process this example doesn't crash the process. Instead the x64 version of RPCRT4.DLL handles the access violation by returning the exception code 0xC0000005.
----------
_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue24201>
_______________________________________
More information about the Python-bugs-list
mailing list