Changeset 3335 for trunk/src


Ignore:
Timestamp:
Apr 21, 2020, 10:20:56 PM (5 years ago)
Author:
bird
Message:

kWorker: Some GetModuleHandleW/A improvments to handle moc.exe/vcc141/5.6.3.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kWorker/kWorker.c

    r3313 r3335  
    308308    /** The offset of the filename in pszPath. */
    309309    KU16                offFilename;
     310    /** The offset of the filename in pwszPath. */
     311    KU16                offFilenameW;
    310312    /** Set if executable. */
    311313    KBOOL               fExe;
     
    430432{
    431433    const char     *pszName;
     434    const wchar_t  *pwszName;
    432435    KU8             cchName;
    433436    KU8             cwcName;
    434     const wchar_t  *pwszName;
     437    KBOOL           fAlwaysPresent;
    435438    HANDLE          hmod;
    436439} KWGETMODULEHANDLECACHE;
     
    10471050static KWGETMODULEHANDLECACHE g_aGetModuleHandleCache[] =
    10481051{
    1049 #define MOD_CACHE_STRINGS(str) str, sizeof(str) - 1, (sizeof(L##str) / sizeof(wchar_t)) - 1, L##str
    1050     { MOD_CACHE_STRINGS("KERNEL32.DLL"),    NULL },
    1051     { MOD_CACHE_STRINGS("mscoree.dll"),     NULL },
     1052#define MOD_CACHE_STRINGS(str) str, L##str, sizeof(str) - 1, (sizeof(L##str) / sizeof(wchar_t)) - 1
     1053    { MOD_CACHE_STRINGS("KERNEL32.DLL"),    K_TRUE,  NULL },
     1054#if 1
     1055    { MOD_CACHE_STRINGS("KERNELBASE.DLL"),  K_TRUE,  NULL },
     1056    { MOD_CACHE_STRINGS("NTDLL.DLL"),       K_TRUE,  NULL },
     1057#endif
     1058    { MOD_CACHE_STRINGS("mscoree.dll"),     K_FALSE, NULL },
    10521059};
    10531060
     
    20852092        pMod->cRefs         = 1;
    20862093        pMod->offFilename   = (KU16)(kHlpGetFilename(pszPath) - pszPath);
     2094        pMod->offFilenameW  = (KU16)(kwPathGetFilenameW(pMod->pwszPath) - pMod->pwszPath);
    20872095        pMod->fExe          = K_FALSE;
    20882096        pMod->fNative       = K_TRUE;
     
    25092517                    pMod->pwszPath      = (wchar_t *)(pMod->pszPath + cbPath + (cbPath & 1));
    25102518                    kwStrToUtf16(pMod->pszPath, (wchar_t *)pMod->pwszPath, cbPath * 2);
     2519                    pMod->offFilenameW  = (KU16)(kwPathGetFilenameW(pMod->pwszPath) - pMod->pwszPath);
    25112520
    25122521                    /*
     
    33763385            kHlpAssert((KUPTR)papMods[iStart]->hOurMod != uHMod);
    33773386        kHlpAssert(i == 0 || (KUPTR)papMods[i - 1]->hOurMod < uHMod);
    3378         kHlpAssert(i == pTool->u.Sandboxed.cModules || (KUPTR)papMods[i]->hOurMod > uHMod);
    33793387#endif
    33803388    }
     
    50625070
    50635071    /*
    5064      * Lower case it.
     5072     * Lower case it and make it ends with .dll.
    50655073     */
    50665074    if (cbFilename <= sizeof(szNormPath))
    50675075    {
     5076        static const char s_szDll[] = ".dll";
    50685077        kHlpMemCopy(szNormPath, pDynLoad->szRequest, cbFilename);
    50695078        _strlwr(szNormPath);
     5079        if (   (   cbFilename <= 4
     5080                || strcmp(&szNormPath[cbFilename - 5], s_szDll) != 0)
     5081            && cbFilename + sizeof(s_szDll) - 1 <= sizeof(szNormPath))
     5082        {
     5083            memcpy(&szNormPath[cbFilename - sizeof(s_szDll)], s_szDll, sizeof(s_szDll));
     5084            cbFilename += sizeof(s_szDll) - 1;
     5085        }
    50705086    }
    50715087    else
     
    50945110                pDynLoad->pNext = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead;
    50955111                g_Sandbox.pTool->u.Sandboxed.pDynLoadHead = pDynLoad;
    5096                 KW_LOG(("LoadLibraryExA(%s,,) -> %p [already loaded]\n", pDynLoad->szRequest, pDynLoad->hmod));
     5112                KW_LOG(("LoadLibraryExA(%s,,) -> %p [virtual API module - already loaded]\n", pDynLoad->szRequest, pDynLoad->hmod));
    50975113                return pDynLoad->hmod;
    50985114            }
     
    51185134                kwToolAddModuleAndImports(g_Sandbox.pTool, pMod);
    51195135
    5120                 pDynLoad = (PKWDYNLOAD)kHlpAlloc(sizeof(*pDynLoad) + cbFilename + cbFilename * sizeof(wchar_t));
    5121                 if (pDynLoad)
    5122                 {
    5123                     pDynLoad->pMod = pMod;
    5124                     pDynLoad->hmod = hmod;
    5125 
    5126                     pDynLoad->pNext = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead;
    5127                     g_Sandbox.pTool->u.Sandboxed.pDynLoadHead = pDynLoad;
    5128                     KW_LOG(("LoadLibraryExA(%s,,) -> %p\n", pDynLoad->szRequest, pDynLoad->hmod));
    5129                     return hmod;
    5130                 }
    5131 
    5132                 KWFS_TODO();
    5133             }
    5134             else
    5135                 KWFS_TODO();
     5136                pDynLoad->pMod = pMod;
     5137                pDynLoad->hmod = hmod;
     5138
     5139                pDynLoad->pNext = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead;
     5140                g_Sandbox.pTool->u.Sandboxed.pDynLoadHead = pDynLoad;
     5141                KW_LOG(("LoadLibraryExA(%s,,) -> %p [virtual API module - new]\n", pDynLoad->szRequest, pDynLoad->hmod));
     5142                return hmod;
     5143            }
     5144            KWFS_TODO();
    51365145        }
    51375146        else
     
    53765385
    53775386
     5387/** Worker for GetModuleHandleA/W for handling cached modules. */
     5388static HMODULE kwSandbox_Kernel32_GetModuleHandle_ReturnedCachedEntry(KSIZE i)
     5389{
     5390    HMODULE hmod = g_aGetModuleHandleCache[i].hmod;
     5391    if (hmod)
     5392        KWLDR_LOG(("kwSandbox_Kernel32_GetModuleHandle_ReturnedCachedEntry(%u/%s -> %p [cached]\n",
     5393                   hmod, g_aGetModuleHandleCache[i].pszName));
     5394    else
     5395    {
     5396        /*
     5397         * The first time around we have to make sure we have a module table
     5398         * entry for it, if not we add one.  We need to add it to the tools
     5399         * module list to for it to work.
     5400         */
     5401        PKWMODULE pMod = kwLdrModuleForLoadedNative(g_aGetModuleHandleCache[i].pszName, K_FALSE);
     5402        if (pMod)
     5403        {
     5404            hmod = pMod->hOurMod;
     5405            if (!kwToolLocateModuleByHandle(g_Sandbox.pTool, hmod))
     5406            {
     5407                kwToolAddModule(g_Sandbox.pTool, pMod);
     5408                KWLDR_LOG(("kwSandbox_Kernel32_GetModuleHandle_ReturnedCachedEntry(%u/%s -> %p [added to tool]\n",
     5409                           hmod, g_aGetModuleHandleCache[i].pszName));
     5410            }
     5411            else
     5412                KWLDR_LOG(("kwSandbox_Kernel32_GetModuleHandle_ReturnedCachedEntry(%u/%s -> %p [known to tool]\n",
     5413                           hmod, g_aGetModuleHandleCache[i].pszName));
     5414
     5415        }
     5416    }
     5417    return hmod;
     5418}
     5419
     5420
    53785421/** Kernel32 - GetModuleHandleA()   */
    53795422static HMODULE WINAPI kwSandbox_Kernel32_GetModuleHandleA(LPCSTR pszModule)
     
    53825425    KSIZE cchModule;
    53835426    PKWDYNLOAD pDynLoad;
     5427    KSIZE cchSuffix;
     5428    DWORD dwErr = ERROR_MOD_NOT_FOUND;
    53845429    kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread);
    53855430
     
    53885433     */
    53895434    if (pszModule == NULL)
     5435    {
     5436        KWLDR_LOG(("kwSandbox_Kernel32_GetModuleHandleA(NULL) -> %p (exe)\n", g_Sandbox.pTool->u.Sandboxed.pExe->hOurMod));
    53905437        return (HMODULE)g_Sandbox.pTool->u.Sandboxed.pExe->hOurMod;
     5438    }
     5439
     5440    /*
     5441     * If no path of suffix, pretend it ends with .DLL.
     5442     */
     5443    cchSuffix = strpbrk(pszModule, ":/\\.") ? 0 : 4;
    53915444
    53925445    /*
     
    53955448    cchModule = kHlpStrLen(pszModule);
    53965449    for (i = 0; i < K_ELEMENTS(g_aGetModuleHandleCache); i++)
    5397         if (   g_aGetModuleHandleCache[i].cchName == cchModule
    5398             && stricmp(pszModule, g_aGetModuleHandleCache[i].pszName) == 0)
    5399         {
    5400             if (g_aGetModuleHandleCache[i].hmod != NULL)
    5401                 return g_aGetModuleHandleCache[i].hmod;
    5402             return g_aGetModuleHandleCache[i].hmod = GetModuleHandleA(pszModule);
    5403         }
     5450        if (    (   g_aGetModuleHandleCache[i].cchName == cchModule
     5451                 && stricmp(pszModule, g_aGetModuleHandleCache[i].pszName) == 0)
     5452            ||  (   cchSuffix > 0
     5453                 && g_aGetModuleHandleCache[i].cchName == cchModule + cchSuffix
     5454                 && strnicmp(pszModule, g_aGetModuleHandleCache[i].pszName, cchModule)
     5455                 && stricmp(&g_aGetModuleHandleCache[i].pszName[cchModule], ".dll") == 0))
     5456            return kwSandbox_Kernel32_GetModuleHandle_ReturnedCachedEntry(i);
    54045457
    54055458    /*
     
    54075460     */
    54085461    for (pDynLoad = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead; pDynLoad; pDynLoad = pDynLoad->pNext)
    5409         if (   pDynLoad->pMod
    5410             && (   stricmp(pDynLoad->pMod->pszPath, pszModule) == 0
    5411                 || stricmp(&pDynLoad->pMod->pszPath[pDynLoad->pMod->offFilename], pszModule) == 0) )
    5412         {
    5413             if (   pDynLoad->pMod->fNative
    5414                 || pDynLoad->pMod->u.Manual.enmState == KWMODSTATE_READY)
    5415             {
    5416                 KW_LOG(("kwSandbox_Kernel32_GetModuleHandleA(%s,,) -> %p [dynload]\n", pszModule, pDynLoad->hmod));
    5417                 return pDynLoad->hmod;
    5418             }
    5419             SetLastError(ERROR_MOD_NOT_FOUND);
    5420             return NULL;
    5421         }
     5462        if (pDynLoad->pMod)
     5463        {
     5464            const char *pszPath = pDynLoad->pMod->pszPath;
     5465            const char *pszName = &pszPath[pDynLoad->pMod->offFilename];
     5466            if (   stricmp(pszPath, pszModule) == 0
     5467                || stricmp(pszName, pszModule) == 0
     5468                || (   cchSuffix > 0
     5469                    && strnicmp(pszName, pszModule, cchModule) == 0
     5470                    && stricmp(&pszName[cchModule], ".dll") == 0))
     5471            {
     5472                if (   pDynLoad->pMod->fNative
     5473                    || pDynLoad->pMod->u.Manual.enmState == KWMODSTATE_READY)
     5474                {
     5475                    KW_LOG(("kwSandbox_Kernel32_GetModuleHandleA(%s,,) -> %p [dynload]\n", pszModule, pDynLoad->hmod));
     5476                    return pDynLoad->hmod;
     5477                }
     5478                KWLDR_LOG(("kwSandbox_Kernel32_GetModuleHandleA(%s) -> NULL (not read)\n", pszModule));
     5479                SetLastError(ERROR_MOD_NOT_FOUND);
     5480                return NULL;
     5481            }
     5482        }
     5483
     5484    /*
     5485     * Hack for the api-ms-win-xxxxx.dll modules.  Find which module they map
     5486     * to and go via the g_aGetModuleHandleCache cache.
     5487     */
     5488    if (strnicmp(pszModule, "api-ms-win-", 11) == 0)
     5489    {
     5490        HMODULE hmod = GetModuleHandleA(pszModule);
     5491        KWLDR_LOG(("kwSandbox_Kernel32_GetModuleHandleA(%s); hmod=%p\n", pszModule, hmod));
     5492        if (hmod)
     5493        {
     5494            if (hmod == GetModuleHandleW(L"KERNELBASE.DLL"))
     5495                return kwSandbox_Kernel32_GetModuleHandleA("KERNELBASE.DLL");
     5496            if (hmod == GetModuleHandleW(L"KERNEL32.DLL"))
     5497                return kwSandbox_Kernel32_GetModuleHandleA("KERNEL32.DLL");
     5498            if (hmod == GetModuleHandleW(L"NTDLL.DLL"))
     5499                return kwSandbox_Kernel32_GetModuleHandleA("NTDLL.DLL");
     5500        }
     5501        else
     5502            dwErr = GetLastError();
     5503    }
    54225504
    54235505    kwErrPrintf("pszModule=%s\n", pszModule);
     
    54345516    KSIZE cwcModule;
    54355517    PKWDYNLOAD pDynLoad;
     5518    KSIZE cwcSuffix;
     5519    DWORD dwErr = ERROR_MOD_NOT_FOUND;
    54365520    kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread);
    54375521
     
    54405524     */
    54415525    if (pwszModule == NULL)
     5526    {
     5527        KWLDR_LOG(("kwSandbox_Kernel32_GetModuleHandleW(NULL) -> %p (exe)\n", g_Sandbox.pTool->u.Sandboxed.pExe->hOurMod));
    54425528        return (HMODULE)g_Sandbox.pTool->u.Sandboxed.pExe->hOurMod;
     5529    }
     5530
     5531    /*
     5532     * If no path of suffix, pretend it ends with .DLL.
     5533     */
     5534    cwcSuffix = wcspbrk(pwszModule, L":/\\.") ? 0 : 4;
    54435535
    54445536    /*
     
    54475539    cwcModule = kwUtf16Len(pwszModule);
    54485540    for (i = 0; i < K_ELEMENTS(g_aGetModuleHandleCache); i++)
    5449         if (   g_aGetModuleHandleCache[i].cwcName == cwcModule
    5450             && _wcsicmp(pwszModule, g_aGetModuleHandleCache[i].pwszName) == 0)
    5451         {
    5452             if (g_aGetModuleHandleCache[i].hmod != NULL)
    5453                 return g_aGetModuleHandleCache[i].hmod;
    5454             return g_aGetModuleHandleCache[i].hmod = GetModuleHandleW(pwszModule);
    5455         }
     5541        if (   (   g_aGetModuleHandleCache[i].cwcName == cwcModule
     5542                && _wcsicmp(pwszModule, g_aGetModuleHandleCache[i].pwszName) == 0)
     5543            || (   cwcSuffix > 0
     5544                && g_aGetModuleHandleCache[i].cwcName == cwcModule + cwcSuffix
     5545                && _wcsnicmp(pwszModule, g_aGetModuleHandleCache[i].pwszName, cwcModule) == 0
     5546                && _wcsicmp(&g_aGetModuleHandleCache[i].pwszName[cwcModule], L".dll") == 0))
     5547            return kwSandbox_Kernel32_GetModuleHandle_ReturnedCachedEntry(i);
    54565548
    54575549    /*
     
    54595551     */
    54605552    for (pDynLoad = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead; pDynLoad; pDynLoad = pDynLoad->pNext)
    5461         if (   pDynLoad->pMod
    5462             && (   _wcsicmp(pDynLoad->pMod->pwszPath, pwszModule) == 0
    5463                 || _wcsicmp(&pDynLoad->pMod->pwszPath[pDynLoad->pMod->offFilename], pwszModule) == 0) ) /** @todo wrong offset */
    5464         {
    5465             if (   pDynLoad->pMod->fNative
    5466                 || pDynLoad->pMod->u.Manual.enmState == KWMODSTATE_READY)
    5467             {
    5468                 KW_LOG(("kwSandbox_Kernel32_GetModuleHandleW(%ls,,) -> %p [dynload]\n", pwszModule, pDynLoad->hmod));
    5469                 return pDynLoad->hmod;
    5470             }
    5471             SetLastError(ERROR_MOD_NOT_FOUND);
    5472             return NULL;
    5473         }
     5553        if (pDynLoad->pMod)
     5554        {
     5555            const wchar_t *pwszPath = pDynLoad->pMod->pwszPath;
     5556            const wchar_t *pwszName = &pwszPath[pDynLoad->pMod->offFilenameW];
     5557            if (   _wcsicmp(pwszPath, pwszModule) == 0
     5558                || _wcsicmp(pwszName, pwszModule) == 0
     5559                || (   cwcSuffix
     5560                    && _wcsnicmp(pwszName, pwszModule, cwcModule) == 0
     5561                    && _wcsicmp(&pwszName[cwcModule], L".dll") == 0))
     5562            {
     5563                if (   pDynLoad->pMod->fNative
     5564                    || pDynLoad->pMod->u.Manual.enmState == KWMODSTATE_READY)
     5565                {
     5566                    KWLDR_LOG(("kwSandbox_Kernel32_GetModuleHandleW(%ls,,) -> %p [dynload]\n", pwszModule, pDynLoad->hmod));
     5567                    return pDynLoad->hmod;
     5568                }
     5569                KWLDR_LOG(("kwSandbox_Kernel32_GetModuleHandleW(%ls) -> NULL (not read)\n", pwszModule));
     5570                SetLastError(ERROR_MOD_NOT_FOUND);
     5571                return NULL;
     5572            }
     5573        }
     5574
     5575    /*
     5576     * Hack for the api-ms-win-xxxxx.dll modules.  Find which module they map
     5577     * to and go via the g_aGetModuleHandleCache cache.
     5578     */
     5579    if (_wcsnicmp(pwszModule, L"api-ms-win-", 11) == 0)
     5580    {
     5581        HMODULE hmod = GetModuleHandleW(pwszModule);
     5582        KWLDR_LOG(("kwSandbox_Kernel32_GetModuleHandleW(%ls); hmod=%p\n", pwszModule, hmod));
     5583        if (hmod)
     5584        {
     5585            if (hmod == GetModuleHandleW(L"KERNELBASE.DLL"))
     5586                return kwSandbox_Kernel32_GetModuleHandleW(L"KERNELBASE.DLL");
     5587            if (hmod == GetModuleHandleW(L"KERNEL32.DLL"))
     5588                return kwSandbox_Kernel32_GetModuleHandleW(L"KERNEL32.DLL");
     5589            if (hmod == GetModuleHandleW(L"NTDLL.DLL"))
     5590                return kwSandbox_Kernel32_GetModuleHandleW(L"NTDLL.DLL");
     5591        }
     5592        else
     5593            dwErr = GetLastError();
     5594    }
    54745595
    54755596    kwErrPrintf("pwszModule=%ls\n", pwszModule);
    54765597    KWFS_TODO();
    5477     SetLastError(ERROR_MOD_NOT_FOUND);
     5598    SetLastError(dwErr);
    54785599    return NULL;
    54795600}
Note: See TracChangeset for help on using the changeset viewer.