Skip to content Skip to sidebar Skip to footer

Using Ctypes To Load A Specific Runtime Library (msvcrt80)

We're using ctypes.windll to load a third-party library. This library uses 'MSVCRT80' and states that it's callers responsibility to free resources. Therefor we've tried using wind

Solution 1:

According to Hans' comment in your other question, you can use GetModuleHandle to get the handle to the already loaded CRT. Like this:

handle = windll.kernel32.GetModuleHandleA('msvcr80')
msvcr80 = WinDLL('', handle=handle)
msvcr80.free(...)

For what it's worth, windll.msvcrt actually refers to the Windows system supplied C runtime, which is named msvcrt.dll and resides in your system32 directory.

Solution 2:

I finally figured out a workaround for this problem. After loading the external library, I enumerate over the loaded modules using EnumProcessModules, determine the filenames using GetModuleFileName and reference the correct module and load the free()-function from this runtime.

The code I'm using to do this is as follows:

from ctypes import *

defenumProcessModules():   
    # Get handle of current process
    kernel32 = windll.kernel32
    kernel32.GetCurrentProcess.restype = c_void_p
    hProcess = kernel32.GetCurrentProcess()

    # Load EnumProcessModules either from kernel32.dll or psapi.dll    try:          
        EnumProcessModulesProc = windll.psapi.EnumProcessModules
    except AttributeError:
        EnumProcessModulesProc = windll.kernel32.EnumProcessModules    
    EnumProcessModulesProc.restype = c_bool
    EnumProcessModulesProc.argtypes = [c_void_p, POINTER(c_void_p), c_ulong, POINTER(c_ulong)]

    hProcess = kernel32.GetCurrentProcess()
    hMods = (c_void_p * 1024)()
    cbNeeded = c_ulong()
    if EnumProcessModulesProc(hProcess, hMods, sizeof(hMods), byref(cbNeeded)):
        return hMods
    returnNonedefgetLoadedModule(moduleName):     
    kernel32 = windll.kernel32
    kernel32.GetModuleFileNameA.restype = c_ulong
    kernel32.GetModuleFileNameA.argtypes = [c_void_p, c_char_p, c_ulong]

    modules = enumProcessModules()
    if modules isNone:
        returnNonefor module in modules:
        cPath = c_char_p(' ' * 1024)
        kernel32.GetModuleFileNameA(module, cPath, c_ulong(1024))
        path = cPath.value
        if path.lower().endswith(moduleName):
            return module
    returnNone

To load the correct runtime and find the free() function I use the code above:

runtimeModuleHandle = getLoadedModule("msvcr80.dll")
    runtimeModule = ctypes.CDLL('', handle = runtimeModuleHandle) # cdecl calling conventionruntimeModule.free.restype = None
    runtimeModule.free.argtypes = [ctypes.c_void_p]        
    myFreeProc = runtimeModule.free

Post a Comment for "Using Ctypes To Load A Specific Runtime Library (msvcrt80)"