- Timestamp:
- Jun 8, 2020, 9:27:14 PM (5 years ago)
- Location:
- trunk/src/kWorker
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kWorker/Makefile.kmk
r3355 r3361 34 34 kWorker_DEFS.debug = K_STRICT 35 35 kWorker_DEFS.release = NASSERT 36 ifeq ($(USERNAME),bird) 37 kWorker_CFLAGS = -W4 -wd4127 -wd4100 -wd4214 -wd4201 -wd4204 38 endif 36 39 kWorker_SOURCES = \ 37 40 kWorker.c \ … … 50 53 $(PATH_SDK_WINDDK71_LIB_WNET)/psapi.lib 51 54 kWorker_LDFLAGS.win = \ 52 /BASE:0x10000 /DYNAMICBASE:NO /FIXED 55 /DYNAMICBASE:NO /FIXED 56 kWorker_LDFLAGS.win.x86 = /BASE:0x00010000 57 kWorker_LDFLAGS.win.amd64 = /BASE:0x0000000420000000 58 53 59 #kWorker_LDFLAGS.win.x86 = \ 54 60 # /SAFESEH:NO - doesn't help anyone. … … 159 165 # A couple of dummy DLLs we use for grabbing LDR TLS entries. 160 166 # 161 DLLS += kWorkerTls1K kWorkerTls64K kWorkerTls512K 167 DLLS += kWorkerTls1K kWorkerTls1K01 kWorkerTls1K02 kWorkerTls1K03 kWorkerTls1K04 kWorkerTls1K05 kWorkerTls1K06 kWorkerTls1K07 \ 168 kWorkerTls1K08 kWorkerTls1K09 kWorkerTls1K10 kWorkerTls1K11 kWorkerTls1K12 kWorkerTls1K13 kWorkerTls1K14 kWorkerTls1K15 162 169 kWorkerTls1K_TEMPLATE = BIN-STATIC-THREADED 163 kWorkerTls1K_DEFS = KWORKER_BASE=0x10000TLS_SIZE=1024170 kWorkerTls1K_DEFS = TLS_SIZE=1024 164 171 kWorkerTls1K_SOURCES = kWorkerTlsXxxK.c 165 172 kWorkerTls1K_LDFLAGS = /Entry:DummyDllEntry 166 173 174 kWorkerTls1K01_EXTENDS = kWorkerTls1K 175 kWorkerTls1K02_EXTENDS = kWorkerTls1K 176 kWorkerTls1K03_EXTENDS = kWorkerTls1K 177 kWorkerTls1K04_EXTENDS = kWorkerTls1K 178 kWorkerTls1K05_EXTENDS = kWorkerTls1K 179 kWorkerTls1K06_EXTENDS = kWorkerTls1K 180 kWorkerTls1K07_EXTENDS = kWorkerTls1K 181 kWorkerTls1K08_EXTENDS = kWorkerTls1K 182 kWorkerTls1K09_EXTENDS = kWorkerTls1K 183 kWorkerTls1K10_EXTENDS = kWorkerTls1K 184 kWorkerTls1K11_EXTENDS = kWorkerTls1K 185 kWorkerTls1K12_EXTENDS = kWorkerTls1K 186 kWorkerTls1K13_EXTENDS = kWorkerTls1K 187 kWorkerTls1K14_EXTENDS = kWorkerTls1K 188 kWorkerTls1K15_EXTENDS = kWorkerTls1K 189 190 DLLS += kWorkerTls64K kWorkerTls512K 191 167 192 kWorkerTls64K_TEMPLATE = BIN-STATIC-THREADED 168 kWorkerTls64K_DEFS = KWORKER_BASE=0x10000TLS_SIZE=65536193 kWorkerTls64K_DEFS = TLS_SIZE=65536 169 194 kWorkerTls64K_SOURCES = kWorkerTlsXxxK.c 170 195 kWorkerTls64K_LDFLAGS = /Entry:DummyDllEntry 171 196 172 197 kWorkerTls512K_TEMPLATE = BIN-STATIC-THREADED 173 kWorkerTls512K_DEFS = KWORKER_BASE=0x10000TLS_SIZE=524288198 kWorkerTls512K_DEFS = TLS_SIZE=524288 174 199 kWorkerTls512K_SOURCES = kWorkerTlsXxxK.c 175 200 kWorkerTls512K_LDFLAGS = /Entry:DummyDllEntry -
trunk/src/kWorker/kWorker.c
r3355 r3361 320 320 /** The windows module handle. */ 321 321 HMODULE hOurMod; 322 /** Parent (real) module if this is a virtual API module (api-ms-*.dll or 323 * ext-ms-*.dll). Referenced. */ 324 PKWMODULE pVirtualApiMod; 322 325 /** The of the loaded image bits. */ 323 326 KSIZE cbImage; … … 348 351 /** The state. */ 349 352 KWMODSTATE enmState; 353 /** The re-init state. */ 354 KWMODSTATE enmReInitState; 350 355 #if defined(KBUILD_OS_WINDOWS) && defined(KBUILD_ARCH_AMD64) 351 356 /** The number of entries in the table. */ … … 443 448 444 449 450 /** One TLS DLL. */ 451 typedef struct KWTLSDLL 452 { 453 const wchar_t *pwszName; /**< The DLL name. */ 454 KBOOL fUsed; /**< Set if used, clear if not. */ 455 } KWTLSDLL; 456 typedef KWTLSDLL *PKWTLSDLL; 457 458 /** 459 * TLS DLL tracker. 460 */ 461 typedef struct KWTLSDLLENTRY 462 { 463 KU32 cbTls; /**< Max TLS size. */ 464 KU32 cDlls; /**< Number of DLLs we ship (paDlls). */ 465 PKWTLSDLL paDlls; /**< Array of DLLs we ship. */ 466 } KWTLSDLLENTRY; 467 typedef KWTLSDLLENTRY *PKWTLSDLLENTRY; 468 469 445 470 /** 446 471 * A cached file. … … 794 819 typedef struct KWSANDBOX 795 820 { 821 /** Jump buffer (first for alignment reasons). */ 822 jmp_buf JmpBuf; 796 823 /** The tool currently running in the sandbox. */ 797 824 PKWTOOL pTool; 798 /** Jump buffer. */799 jmp_buf JmpBuf;800 825 /** The thread ID of the main thread (owner of JmpBuf). */ 801 826 DWORD idMainThread; … … 866 891 PKWFSTEMPFILE pTempFileHead; 867 892 893 /** Critical section protecting pVirtualAllocHead. */ 894 CRITICAL_SECTION VirtualAllocLock; 868 895 /** Head of the virtual alloc allocations. */ 869 896 PKWVIRTALLOC pVirtualAllocHead; … … 948 975 KU32 iSlot; 949 976 950 /** The CRT module data. 977 /** The CRT module data. */ 951 978 PKWMODULE pModule; 952 /** Pointer to the malloc function. 979 /** Pointer to the malloc function. */ 953 980 void * (__cdecl *pfnMalloc)(size_t); 981 /** Pointer to the beginthreadex function. */ 982 uintptr_t (__cdecl *pfnBeginThreadEx)(void *, unsigned, unsigned (__stdcall *)(void *), void *, unsigned, unsigned *); 954 983 955 984 } KWCRTSLOT; … … 1064 1093 static PKWMODULE g_pModPendingTlsAlloc = NULL; 1065 1094 1095 /** The 1KB TLS DLLs. */ 1096 static KWTLSDLL g_aTls1KDlls[] = 1097 { 1098 { L"kWorkerTls1K.dll", K_FALSE }, 1099 { L"kWorkerTls1K01.dll", K_FALSE }, 1100 { L"kWorkerTls1K02.dll", K_FALSE }, 1101 { L"kWorkerTls1K03.dll", K_FALSE }, 1102 { L"kWorkerTls1K04.dll", K_FALSE }, 1103 { L"kWorkerTls1K05.dll", K_FALSE }, 1104 { L"kWorkerTls1K06.dll", K_FALSE }, 1105 { L"kWorkerTls1K07.dll", K_FALSE }, 1106 { L"kWorkerTls1K08.dll", K_FALSE }, 1107 { L"kWorkerTls1K09.dll", K_FALSE }, 1108 { L"kWorkerTls1K10.dll", K_FALSE }, 1109 { L"kWorkerTls1K11.dll", K_FALSE }, 1110 { L"kWorkerTls1K12.dll", K_FALSE }, 1111 { L"kWorkerTls1K13.dll", K_FALSE }, 1112 { L"kWorkerTls1K14.dll", K_FALSE }, 1113 { L"kWorkerTls1K15.dll", K_FALSE }, 1114 }; 1115 1116 /** The 64KB TLS DLLs. */ 1117 static KWTLSDLL g_aTls64KDlls[] = 1118 { 1119 { L"kWorkerTls64K.dll", K_FALSE }, 1120 }; 1121 1122 /** The 512KB TLS DLLs. */ 1123 static KWTLSDLL g_aTls512KDlls[] = 1124 { 1125 { L"kWorkerTls512K.dll", K_FALSE }, 1126 }; 1127 1128 /** The TLS DLLs grouped by size. */ 1129 static KWTLSDLLENTRY const g_aTlsDlls[] = 1130 { 1131 { 1024, K_ELEMENTS(g_aTls1KDlls), g_aTls1KDlls }, 1132 { 64*1024, K_ELEMENTS(g_aTls64KDlls), g_aTls64KDlls }, 1133 { 512*1024, K_ELEMENTS(g_aTls512KDlls), g_aTls512KDlls }, 1134 }; 1135 1066 1136 /** CRT slots. 1067 1137 * @note The number of entires here must match CRT_SLOT_FUNCTION_WRAPPER. */ 1068 1138 static KWCRTSLOT g_aCrtSlots[32]; 1139 1140 /** windbg .reload statements. vs */ 1141 char g_szReloads[4096]; 1142 /** Current offset into g_szReloads. */ 1143 KU32 volatile g_cchReloads; 1069 1144 1070 1145 /** The file system cache. */ … … 1206 1281 const char *pszSearchPath, PKWMODULE *ppMod); 1207 1282 static PKWMODULE kwLdrModuleForLoadedNative(const char *pszName, KBOOL fEnsureCrtSlot, KBOOL fAlwaysPresent); 1283 static PKWMODULE kwLdrModuleForLoadedNativeByHandle(HMODULE hModule, KBOOL fEnsureCrtSlot, const char *pszLogName); 1284 static int kwLdrModuleCreateCrtSlot(PKWMODULE pModule); 1285 static PKWMODULE kwToolLocateModuleByHandle(PKWTOOL pTool, HMODULE hmod); 1208 1286 static char *kwSandboxDoGetEnvA(PKWSANDBOX pSandbox, const char *pchVar, KSIZE cchVar); 1209 1287 static KBOOL kwSandboxHandleTableEnter(PKWSANDBOX pSandbox, PKWHANDLE pHandle, HANDLE hHandle); … … 1771 1849 { 1772 1850 kHlpAssert(pMod->cRefs > 0); 1773 kHlpAssert(pMod->cRefs < 64 );1851 kHlpAssert(pMod->cRefs < 64 || pMod->fNative /* kernelbase.dll and VC++ 14.2 */); 1774 1852 pMod->cRefs++; 1775 1853 return pMod; … … 1789 1867 if (!pMod->fExe) 1790 1868 { 1791 PKWMODULE pPrev = NULL;1792 1869 unsigned idx = pMod->uHashPath % K_ELEMENTS(g_apModules); 1793 1870 if (g_apModules[idx] == pMod) … … 1864 1941 } 1865 1942 else 1866 kHlpAssert(pMod->cRefs < 64 );1943 kHlpAssert(pMod->cRefs < 64 || pMod->fNative /* kernelbase.dll and VC++ 14.2 */); 1867 1944 } 1868 1945 … … 1968 2045 { 1969 2046 IMAGE_IMPORT_BY_NAME const *pName = (IMAGE_IMPORT_BY_NAME const *)&pbImage[off]; 1970 KSIZE const cchSymbol = kHlpStrLen( pName->Name);2047 KSIZE const cchSymbol = kHlpStrLen((const char *)&pName->Name[0]); 1971 2048 KU32 i = g_cSandboxNativeReplacements; 1972 2049 while (i-- > 0) … … 1977 2054 || kHlpStrICompAscii(g_aSandboxNativeReplacements[i].pszModule, pszImport) == 0) 1978 2055 { 1979 KW _LOG(("%s: replacing %s!%s\n", pMod->pLdrMod->pszName, pszImport, pName->Name));2056 KWLDR_LOG(("%s: replacing %s!%s\n", pMod->pLdrMod->pszName, pszImport, pName->Name)); 1980 2057 1981 2058 /* The .rdata section is normally read-only, so we need to make it writable first. */ … … 2003 2080 case PAGE_EXECUTE_WRITECOPY: 2004 2081 /* Already writable, nothing to do. */ 2082 fRc = TRUE; 2005 2083 break; 2006 2084 … … 2081 2159 */ 2082 2160 static PKWMODULE kwLdrModuleCreateForNativekLdrModule(PKLDRMOD pLdrMod, const char *pszPath, KSIZE cbPath, KU32 uHashPath, 2083 KBOOL fDoReplacements )2161 KBOOL fDoReplacements, PKWMODULE pVirtualApiMod) 2084 2162 { 2085 2163 /* … … 2089 2167 if (pMod) 2090 2168 { 2091 pMod->pwszPath = (wchar_t *)(pMod + 1);2169 pMod->pwszPath = (wchar_t *)(pMod + 1); 2092 2170 kwStrToUtf16(pszPath, (wchar_t *)pMod->pwszPath, cbPath * 2); 2093 pMod->pszPath = (char *)kHlpMemCopy((char *)&pMod->pwszPath[cbPath * 2], pszPath, cbPath);2094 pMod->uHashPath = uHashPath;2095 pMod->cRefs = 1;2096 pMod->offFilename = (KU16)(kHlpGetFilename(pszPath) - pszPath);2097 pMod->offFilenameW = (KU16)(kwPathGetFilenameW(pMod->pwszPath) - pMod->pwszPath);2098 pMod->fExe = K_FALSE;2099 pMod->fNative = K_TRUE;2100 pMod->pLdrMod = pLdrMod;2101 pMod->hOurMod = (HMODULE)(KUPTR)pLdrMod->aSegments[0].MapAddress;2102 pMod->cbImage = (KSIZE)kLdrModSize(pLdrMod);2103 pMod->iCrtSlot = KU8_MAX;2104 pMod->fNeedReInit = K_FALSE;2171 pMod->pszPath = (char *)kHlpMemCopy((char *)&pMod->pwszPath[cbPath * 2], pszPath, cbPath); 2172 pMod->uHashPath = uHashPath; 2173 pMod->cRefs = 1; 2174 pMod->offFilename = (KU16)(kHlpGetFilename(pszPath) - pszPath); 2175 pMod->offFilenameW = (KU16)(kwPathGetFilenameW(pMod->pwszPath) - pMod->pwszPath); 2176 pMod->fExe = K_FALSE; 2177 pMod->fNative = K_TRUE; 2178 pMod->pLdrMod = pLdrMod; 2179 pMod->hOurMod = (HMODULE)(KUPTR)pLdrMod->aSegments[0].MapAddress; 2180 pMod->cbImage = (KSIZE)kLdrModSize(pLdrMod); 2181 pMod->iCrtSlot = KU8_MAX; 2182 pMod->fNeedReInit = K_FALSE; 2105 2183 pMod->pszMsPdbSrvEndpoint = NULL; 2106 2184 pMod->fReInitOnMsPdbSrvEndpointChange = kHlpStrNICompAscii(&pMod->pszPath[pMod->offFilename], TUPLE("mspdb")) == 0; 2185 pMod->pVirtualApiMod = pVirtualApiMod; 2186 if (pVirtualApiMod) 2187 kwLdrModuleRetain(pVirtualApiMod); 2107 2188 2108 2189 if (fDoReplacements) … … 2113 2194 } 2114 2195 2115 KW_LOG(("New module: %p LB %#010x %s (native)\n", 2116 (KUPTR)pMod->pLdrMod->aSegments[0].MapAddress, kLdrModSize(pMod->pLdrMod), pMod->pszPath)); 2196 KWLDR_LOG(("New module: %p LB %#010x %s (native%s%s)\n", 2197 (KUPTR)pMod->pLdrMod->aSegments[0].MapAddress, kLdrModSize(pMod->pLdrMod), pMod->pszPath, 2198 pVirtualApiMod ? ", virtual api => " : "", pVirtualApiMod ? pVirtualApiMod->pszPath : "")); 2117 2199 g_cModules++; 2118 2200 return kwLdrModuleLink(pMod); … … 2134 2216 static PKWMODULE kwLdrModuleCreateNative(const char *pszPath, KU32 uHashPath, KBOOL fDoReplacements) 2135 2217 { 2218 PKLDRMOD pLdrMod; 2219 int rc; 2220 2136 2221 /* 2137 * Open the module and check the type. 2222 * HACK ALERT! Make sure the application path is searched when looking for 2223 * imports in the module we're loading. 2138 2224 */ 2139 PKLDRMOD pLdrMod; 2140 int rc = kLdrModOpenNative(pszPath, KLDRMOD_OPEN_FLAGS_NATIVE_ALLOW_INIT_TERM, &pLdrMod); 2225 /** @todo improve on this hack! */ 2226 PKWMODULE pExe = g_Sandbox.pTool ? g_Sandbox.pTool->u.Sandboxed.pExe : NULL; 2227 if (pExe) 2228 { 2229 /* HACK ALERT! */ 2230 wchar_t *pwzFilename = (wchar_t *)&pExe->pwszPath[pExe->offFilenameW]; 2231 wchar_t wcSaved = pExe->pwszPath[pExe->offFilenameW]; 2232 *pwzFilename = '\0'; 2233 if (!SetDllDirectoryW(pExe->pwszPath)) 2234 kwErrPrintf("SetDllDirectoryW failed: %u\n", GetLastError()); 2235 *pwzFilename = wcSaved; 2236 } 2237 2238 /* 2239 * Load the library and create a module structure for it. 2240 */ 2241 rc = kLdrModOpenNative(pszPath, KLDRMOD_OPEN_FLAGS_NATIVE_ALLOW_INIT_TERM, &pLdrMod); 2141 2242 if (rc == 0) 2142 2243 { 2143 PKWMODULE pMod = kwLdrModuleCreateForNativekLdrModule(pLdrMod, pszPath, kHlpStrLen(pszPath) + 1, 2144 uHashPath, fDoReplacements); 2244 KSIZE cchPath = kHlpStrLen(pszPath); 2245 PKWMODULE pMod = kwLdrModuleCreateForNativekLdrModule(pLdrMod, pszPath, cchPath + 1, uHashPath, 2246 fDoReplacements, NULL /*pVirtualApiMod*/); 2145 2247 if (pMod) 2146 2248 return pMod; … … 2148 2250 } 2149 2251 return NULL; 2252 } 2253 2254 2255 /** 2256 * Checks if the given name could be a virtual API module or not. 2257 */ 2258 static KBOOL kwLdrIsVirtualApiModule(const char *pszName, KSIZE cchName) 2259 { 2260 if (cchName <= 7) 2261 return K_FALSE; 2262 switch (*pszName) 2263 { 2264 default: 2265 return K_FALSE; 2266 case 'a': 2267 case 'A': 2268 if (pszName[1] != 'p' && pszName[1] != 'P') 2269 return K_FALSE; 2270 if (pszName[2] != 'i' && pszName[2] != 'I') 2271 return K_FALSE; 2272 break; 2273 case 'e': 2274 case 'E': 2275 if (pszName[1] != 'x' && pszName[1] != 'X') 2276 return K_FALSE; 2277 if (pszName[2] != 't' && pszName[2] != 'T') 2278 return K_FALSE; 2279 break; 2280 } 2281 if (pszName[3] != '-') 2282 return K_FALSE; 2283 if (pszName[4] != 'm' && pszName[4] != 'M') 2284 return K_FALSE; 2285 if (pszName[5] != 's' && pszName[5] != 'S') 2286 return K_FALSE; 2287 if (pszName[6] != '-') 2288 return K_FALSE; 2289 return K_TRUE; 2290 } 2291 2292 2293 /** 2294 * Try load what seems to be a virtual API DLL. 2295 * 2296 * This is a worker for kwLdrModuleResolveAndLookup and 2297 * kwSandbox_Kernel32_LoadLibraryExA_VirtualApiModule. 2298 * 2299 * @returns Pointer to module on success, NULL on failure. 2300 * @param pszName The name of the module. This must be 2301 * normalized already! 2302 * @param cchName The length of the name. 2303 */ 2304 static PKWMODULE kwLdrModuleTryLoadVirtualDll(const char *pszName, KSIZE cchName) 2305 { 2306 HMODULE hModule; 2307 2308 /* 2309 * Look it up in the hash table. 2310 */ 2311 KU32 const uHashPath = kwStrHash(pszName); 2312 unsigned idxHash = uHashPath % K_ELEMENTS(g_apModules); 2313 PKWMODULE pMod = g_apModules[idxHash]; 2314 if (pMod) 2315 { 2316 do 2317 { 2318 if ( pMod->uHashPath == uHashPath 2319 && kHlpStrComp(pMod->pszPath, pszName) == 0) 2320 return kwLdrModuleRetain(pMod); 2321 pMod = pMod->pNextHash; 2322 } while (pMod); 2323 } 2324 2325 /* 2326 * Not found. Try load it. 2327 */ 2328 hModule = LoadLibraryA(pszName); 2329 if (!hModule) 2330 { 2331 KWLDR_LOG(("kwLdrModuleTryLoadVirtualDll: %s failed (%u)\n", pszName, GetLastError())); 2332 return NULL; 2333 } 2334 2335 /* 2336 * Loaded successfully. Create a module for the real module. 2337 */ 2338 pMod = kwLdrModuleForLoadedNativeByHandle(hModule, K_FALSE /*fEnsureCrtSlot*/, pszName); 2339 if (pMod) 2340 { 2341 /* Create a module for the virtual API name too, unless it is actually a real DLL. */ 2342 if (stricmp(&pMod->pszPath[pMod->offFilename], pszName) != 0) 2343 { 2344 PKLDRMOD pLdrMod; 2345 int rc = kLdrModOpenNativeByHandle((KUPTR)hModule, KLDRMOD_OPEN_FLAGS_NATIVE_ALLOW_INIT_TERM, &pLdrMod); 2346 if (rc == 0) 2347 { 2348 PKWMODULE pVirtMod = kwLdrModuleCreateForNativekLdrModule(pLdrMod, pszName, cchName + 1, kwStrHash(pszName), 2349 K_FALSE /*fDoReplacements*/, pMod /*pVirtualApiMod*/); 2350 if (pVirtMod) 2351 { 2352 kwLdrModuleRelease(pMod); 2353 pMod = pVirtMod; 2354 } 2355 else 2356 { 2357 kLdrModClose(pLdrMod); 2358 kwErrPrintf("out of memory\n"); 2359 } 2360 } 2361 else 2362 kwErrPrintf("kLdrModOpenNativeByHandle failed for %p / '%s': %d\n", hModule, pszName, rc); 2363 } 2364 else 2365 KWLDR_LOG(("kwLdrModuleTryLoadVirtualDll: %s -> %s - A real DLL!\n", pszName, pMod->pszPath)); 2366 } 2367 2368 return pMod; 2150 2369 } 2151 2370 … … 2214 2433 pMod->u.Manual.aQuickCopyChunks[iChunk].pbSrc = &pMod->u.Manual.pbCopy[(KSIZE)paSegs[iSeg].RVA]; 2215 2434 pMod->u.Manual.aQuickCopyChunks[iChunk].cbToCopy = paSegs[iSeg].cbMapped - cbTrailingZeros; 2216 pMod->u.Manual.cQuickCopyChunks = iChunk + 1;2435 pMod->u.Manual.cQuickCopyChunks = (KU8)(iChunk + 1); 2217 2436 KWLDR_LOG(("aQuickCopyChunks[%u]: %#p LB %#" KSIZE_PRI " <- %p (%*.*s)\n", iChunk, 2218 2437 pMod->u.Manual.aQuickCopyChunks[iChunk].pbDst, … … 2231 2450 + pMod->u.Manual.aQuickCopyChunks[iChunk].cbToCopy; 2232 2451 pMod->u.Manual.aQuickZeroChunks[iZero].cbToZero = cbTrailingZeros; 2233 pMod->u.Manual.cQuickZeroChunks = iZero + 1;2452 pMod->u.Manual.cQuickZeroChunks = (KU8)(iZero + 1); 2234 2453 KWLDR_LOG(("aQuickZeroChunks[%u]: %#p LB %#" KSIZE_PRI " <- zero (%*.*s)\n", iZero, 2235 2454 pMod->u.Manual.aQuickZeroChunks[iZero].pbDst, … … 2286 2505 * Try sabotage the DLL name so we can load this module again. 2287 2506 */ 2507 /** @todo this doesn't work W10 18363 */ 2288 2508 pHead = &pPeb->Ldr->InMemoryOrderModuleList; 2289 2509 for (pCur = pHead->Blink; pCur != pHead; pCur = pCur->Blink) … … 2330 2550 KU32 const cEntries = pTlsDir->Size / sizeof(IMAGE_TLS_DIRECTORY); 2331 2551 KU32 iEntry; 2552 KU32 iTlsDll; 2553 KU32 iTlsDllSub; 2332 2554 KUPTR offIndex; 2333 2555 KUPTR offCallbacks; … … 2384 2606 /* 2385 2607 * Make the allocation by loading a new instance of one of the TLS dlls. 2386 * The DLL will make a call to 2608 * The DLL will make a call to kwLdrTlsAllocationHook. 2387 2609 */ 2388 2610 offIndex = (KUPTR)paEntries[0].AddressOfIndex - (KUPTR)pMod->u.Manual.pbLoad; … … 2390 2612 puCallbacks = (KUPTR const *)&pbImg[offCallbacks]; 2391 2613 cbData = paEntries[0].SizeOfZeroFill + (paEntries[0].EndAddressOfRawData - paEntries[0].StartAddressOfRawData); 2392 if (cbData <= 1024) 2393 pwszTlsDll = L"kWorkerTls1K.dll"; 2394 else if (cbData <= 65536) 2395 pwszTlsDll = L"kWorkerTls64K.dll"; 2396 else if (cbData <= 524288) 2397 pwszTlsDll = L"kWorkerTls512K.dll"; 2398 else 2399 { 2400 kwErrPrintf("TLS data size in %s is too big: %u (%#p), max 512KB\n", pMod->pszPath, (unsigned)cbData, cbData); 2401 return -1; 2402 } 2614 2615 /** @todo find better strategy here. Like temporary copy or whatever when 2616 * there is more than a single user. */ 2617 for (iTlsDll = 0; cbData > g_aTlsDlls[iTlsDll].cbTls;) 2618 if (++iTlsDll >= K_ELEMENTS(g_aTlsDlls)) 2619 { 2620 kwErrPrintf("TLS data size in %s is too big: %u (%#p), max 512KB\n", pMod->pszPath, (unsigned)cbData, cbData); 2621 return -1; 2622 } 2623 for (iTlsDllSub = 0; g_aTlsDlls[iTlsDll].paDlls[iTlsDllSub].fUsed;) 2624 if (++iTlsDllSub >= g_aTlsDlls[iTlsDll].cDlls) 2625 { 2626 kwErrPrintf("No unused TLS DLLs for %s of size %u!\n", pMod->pszPath, (unsigned)cbData); 2627 return -1; 2628 } 2629 2630 g_aTlsDlls[iTlsDll].paDlls[iTlsDllSub].fUsed = K_TRUE; 2631 pwszTlsDll = g_aTlsDlls[iTlsDll].paDlls[iTlsDllSub].pwszName; 2403 2632 2404 2633 pMod->u.Manual.idxTls = KU32_MAX; … … 2542 2771 { 2543 2772 KI32 iImp; 2773 KU32 cchReloads; 2544 2774 2545 2775 /* … … 2548 2778 pMod->hOurMod = (HMODULE)pMod->u.Manual.pbLoad; 2549 2779 kwLdrModuleLink(pMod); 2550 KW _LOG(("New module: %p LB %#010x %s (kLdr)\n",2551 pMod->u.Manual.pbLoad, pMod->cbImage, pMod->pszPath));2552 KW _LOG(("TODO: .reload /f %s=%p\n", pMod->pszPath, pMod->u.Manual.pbLoad));2780 KWLDR_LOG(("New module: %p LB %#010x %s (kLdr)\n", 2781 pMod->u.Manual.pbLoad, pMod->cbImage, pMod->pszPath)); 2782 KWLDR_LOG(("TODO: .reload /f %s=%p\n", pMod->pszPath, pMod->u.Manual.pbLoad)); 2553 2783 kwDebuggerPrintf("TODO: .reload /f %s=%p\n", pMod->pszPath, pMod->u.Manual.pbLoad); 2784 cchReloads = g_cchReloads; 2785 if (cchReloads + 80 < sizeof(g_szReloads)) 2786 { 2787 cchReloads += _snprintf(&g_szReloads[cchReloads], sizeof(g_szReloads) - cchReloads, 2788 "%s.reload /f %s=%p\n", cchReloads ? "; " : "", 2789 pMod->pszPath, pMod->u.Manual.pbLoad); 2790 g_cchReloads = cchReloads; 2791 } 2554 2792 2555 2793 for (iImp = 0; iImp < cImports; iImp++) … … 2611 2849 pMod->u.Manual.pvBits = pMod->u.Manual.pbCopy; 2612 2850 pMod->u.Manual.enmState = KWMODSTATE_NEEDS_BITS; 2851 pMod->u.Manual.enmReInitState = KWMODSTATE_NEEDS_BITS; 2852 if ( g_Sandbox.pTool 2853 && ( g_Sandbox.pTool->u.Sandboxed.enmHint == KWTOOLHINT_VISUAL_CPP_CL 2854 || g_Sandbox.pTool->u.Sandboxed.enmHint == KWTOOLHINT_VISUAL_CPP_LINK) 2855 && !pMod->fExe) 2856 pMod->u.Manual.enmReInitState = KWMODSTATE_READY; 2613 2857 g_cModules++; 2614 2858 g_cNonNativeModules++; … … 2675 2919 || !g_aSandboxReplacements[i].fOnlyExe) 2676 2920 { 2677 KW_LOG(("replacing %s!%s\n",&pImpMod->pszPath[pImpMod->offFilename], g_aSandboxReplacements[i].pszFunction)); 2678 *puValue = g_aSandboxReplacements[i].pfnReplacement; 2921 KWLDR_LOG(("replacing %s!%s\n",&pImpMod->pszPath[pImpMod->offFilename], g_aSandboxReplacements[i].pszFunction)); 2922 if (!g_aSandboxReplacements[i].fCrtSlotArray) 2923 *puValue = g_aSandboxReplacements[i].pfnReplacement; 2924 else 2925 { 2926 if (pImpMod->iCrtSlot == KU8_MAX) 2927 { 2928 rc = kwLdrModuleCreateCrtSlot(pImpMod); 2929 if (rc) 2930 KWLDR_LOG(("kwLdrModuleGetImportCallback: kwLdrModuleCreateCrtSlot failed: %d\n", rc)); 2931 } 2932 *puValue = ((KUPTR *)g_aSandboxReplacements[i].pfnReplacement)[pImpMod->iCrtSlot]; 2933 } 2679 2934 } 2680 2935 break; … … 2684 2939 2685 2940 //printf("iImport=%u (%s) %*.*s rc=%d\n", iImport, &pImpMod->pszPath[pImpMod->offFilename], cchSymbol, cchSymbol, pchSymbol, rc); 2686 KW _LOG(("iImport=%u (%s) %*.*s rc=%d\n", iImport, &pImpMod->pszPath[pImpMod->offFilename], cchSymbol, cchSymbol, pchSymbol, rc));2941 KWLDR_LOG(("iImport=%u (%s) %*.*s rc=%d\n", iImport, &pImpMod->pszPath[pImpMod->offFilename], cchSymbol, cchSymbol, pchSymbol, rc)); 2687 2942 return rc; 2688 2943 … … 2721 2976 if (enmLocation != KWLOCATION_SYSTEM32) 2722 2977 return K_TRUE; 2723 return kHlpStrNICompAscii(pszFilename, TUPLE("msvc")) == 0 2724 || kHlpStrNICompAscii(pszFilename, TUPLE("msdis")) == 0 2725 || kHlpStrNICompAscii(pszFilename, TUPLE("mspdb")) == 0; 2978 return kHlpStrNICompAscii(pszFilename, TUPLE("msvc")) == 0 2979 || kHlpStrNICompAscii(pszFilename, TUPLE("msdis")) == 0 2980 || kHlpStrNICompAscii(pszFilename, TUPLE("mspdb")) == 0 2981 || kHlpStrNICompAscii(pszFilename, TUPLE("vcruntime")) == 0 2982 || kHlpStrNICompAscii(pszFilename, TUPLE("ucrtbase")) == 0 2983 || kHlpStrNICompAscii(pszFilename, TUPLE("api-ms-win-crt-")) == 0 2984 ; 2726 2985 } 2727 2986 … … 2775 3034 if (enmLocation == KWLOCATION_UNKNOWN_NATIVE) 2776 3035 return K_TRUE; 3036 if ( enmLocation == KWLOCATION_UNKNOWN 3037 && kwLdrIsVirtualApiModule(pszFilename, kHlpStrLen(pszFilename))) 3038 return K_TRUE; 2777 3039 2778 3040 /* If the location is unknown, we must check if it's some dynamic loading … … 2797 3059 } 2798 3060 2799 return kHlpStrNICompAscii(pszFilename, TUPLE("msvc")) == 0 2800 || kHlpStrNICompAscii(pszFilename, TUPLE("msdis")) == 0 2801 || kHlpStrNICompAscii(pszFilename, TUPLE("mspdb")) == 0; 3061 return kHlpStrNICompAscii(pszFilename, TUPLE("msvc")) == 0 3062 || kHlpStrNICompAscii(pszFilename, TUPLE("msdis")) == 0 3063 || kHlpStrNICompAscii(pszFilename, TUPLE("mspdb")) == 0 3064 || kHlpStrNICompAscii(pszFilename, TUPLE("tbbmalloc")) == 0 3065 || kHlpStrNICompAscii(pszFilename, TUPLE("ucrtbase")) == 0 3066 || kHlpStrNICompAscii(pszFilename, TUPLE("vcruntime")) == 0 3067 || ( enmLocation != KWLOCATION_UNKNOWN 3068 && kwLdrIsVirtualApiModule(pszFilename, kHlpStrLen(pszFilename))); 2802 3069 } 2803 3070 … … 2929 3196 KSIZE cchSuffix = fNeedSuffix ? 4 : 0; 2930 3197 3198 /* Virtual API module. Normalize and try load it. */ 3199 if (pMod == NULL && cchName > 7 && kwLdrIsVirtualApiModule(pszName, cchName)) 3200 { 3201 if (cchName + cchSuffix >= sizeof(szPath)) 3202 return KERR_BUFFER_OVERFLOW; 3203 kHlpMemCopy(szPath, pszName, cchName); 3204 if (fNeedSuffix) 3205 kHlpMemCopy(&szPath[cchName], ".dll", sizeof(".dll")); 3206 szPath[cchName + cchSuffix] = '\0'; 3207 _strlwr(szPath); 3208 pMod = kwLdrModuleTryLoadVirtualDll(szPath, cchName + cchSuffix); 3209 } 2931 3210 2932 3211 /* The import path. */ … … 3043 3322 kwErrPrintf("Failed to resolved 'malloc' in '%s': %d\n", pModule->pszPath, rc); 3044 3323 3324 rc = kLdrModQuerySymbol(pModule->pLdrMod, NULL /*pvBits*/, KLDRMOD_BASEADDRESS_MAP, KU32_MAX, "_beginthreadex", 14, 3325 NULL /*pvszVersion*/, NULL /*pfnGetForwarder*/, NULL /*pvUser*/, &uAddr, NULL); 3326 *(KUPTR *)&g_aCrtSlots[iSlot].pfnBeginThreadEx = rc == 0 ? (KUPTR)uAddr : 0; 3327 //if (rc != 0) 3328 // kwErrPrintf("Failed to resolved '_beginthreadex' in '%s': %d\n", pModule->pszPath, rc); 3329 3045 3330 return 0; 3046 3331 } 3047 3332 kwErrPrintf("Out of CRT slots!\n"); 3048 3333 return KERR_NO_MEMORY; 3334 } 3335 3336 3337 /** 3338 * Locates the module structure for an already loaded native module. 3339 * 3340 * This will create a module structure if needed. 3341 * 3342 * @returns Pointer to the module structure on success, NULL on failure. 3343 * @param hModule The native module handle. 3344 * @param fEnsureCrtSlot Whether to ensure that it has a valid CRT slot. 3345 * @param pszLogName The name to use for logging/errors. 3346 */ 3347 static PKWMODULE kwLdrModuleForLoadedNativeByHandle(HMODULE hModule, KBOOL fEnsureCrtSlot, const char *pszLogName) 3348 { 3349 /* 3350 * Get a normalized path for it. 3351 */ 3352 char szModPath[1024]; 3353 if (GetModuleFileNameA(hModule, szModPath, sizeof(szModPath)) > 0) 3354 { 3355 char szNormPath[1024]; 3356 int rc = kwPathNormalize(szModPath, szNormPath, sizeof(szNormPath)); 3357 if (rc == 0) 3358 { 3359 /* 3360 * Hash the path and look it up. 3361 */ 3362 KU32 uHashPath; 3363 KSIZE const cchPath = kwStrHashEx(szNormPath, &uHashPath); 3364 unsigned idxHash = uHashPath % K_ELEMENTS(g_apModules); 3365 PKWMODULE pMod = g_apModules[idxHash]; 3366 if (pMod) 3367 { 3368 do 3369 { 3370 if ( pMod->uHashPath == uHashPath 3371 && kHlpStrComp(pMod->pszPath, szNormPath) == 0) 3372 { 3373 kwLdrModuleRetain(pMod); 3374 break; 3375 } 3376 pMod = pMod->pNextHash; 3377 } while (pMod); 3378 } 3379 3380 /* 3381 * If not in the hash table, so create a module entry. 3382 */ 3383 if (!pMod) 3384 { 3385 PKLDRMOD pLdrMod; 3386 rc = kLdrModOpenNativeByHandle((KUPTR)hModule, KLDRMOD_OPEN_FLAGS_NATIVE_ALLOW_INIT_TERM, &pLdrMod); 3387 if (rc == 0) 3388 { 3389 /** @todo more accurately determine location */ 3390 const char *pszFilename = kHlpGetFilename(szNormPath); 3391 KBOOL fDoReplacements = kwLdrModuleShouldDoNativeReplacements(pszFilename, KWLOCATION_SYSTEM32); 3392 pMod = kwLdrModuleCreateForNativekLdrModule(pLdrMod, szNormPath, cchPath + 1, uHashPath, 3393 fDoReplacements, NULL /*pVirtualApiMod*/); 3394 if (!pMod) 3395 { 3396 kLdrModClose(pLdrMod); 3397 kwErrPrintf("out of memory\n"); 3398 } 3399 } 3400 else 3401 kwErrPrintf("kLdrModOpenNativeByHandle failed for %p / '%s': %d\n", hModule, pszLogName, rc); 3402 } 3403 if (pMod) 3404 { 3405 /* 3406 * Create a CRT slot for the module if necessary. 3407 */ 3408 if (!fEnsureCrtSlot || pMod->iCrtSlot != KU8_MAX) 3409 return pMod; 3410 rc = kwLdrModuleCreateCrtSlot(pMod); 3411 if (rc == 0) 3412 return pMod; 3413 kwLdrModuleRelease(pMod); 3414 } 3415 } 3416 else 3417 kwErrPrintf("kwPathNormalize failed for '%s' (%s): %u!\n", szModPath, pszLogName, GetLastError()); 3418 } 3419 else 3420 kwErrPrintf("GetModuleFileNameA failed for '%s': %u!\n", pszLogName, GetLastError()); 3421 return NULL; 3049 3422 } 3050 3423 … … 3064 3437 { 3065 3438 /* 3066 * Locate the module and get a normalized path for it.3439 * Locate the module handle and pass it to kwLdrModuleForLoadedNativeByHandle. 3067 3440 */ 3068 3441 HANDLE hModule = GetModuleHandleA(pszName); 3069 3442 if (hModule) 3070 { 3071 char szModPath[1024]; 3072 if (GetModuleFileNameA(hModule, szModPath, sizeof(szModPath)) > 0) 3073 { 3074 char szNormPath[1024]; 3075 int rc = kwPathNormalize(szModPath, szNormPath, sizeof(szNormPath)); 3076 if (rc == 0) 3077 { 3078 /* 3079 * Hash the path and look it up. 3080 */ 3081 KU32 uHashPath; 3082 KSIZE const cchPath = kwStrHashEx(szNormPath, &uHashPath); 3083 unsigned idxHash = uHashPath % K_ELEMENTS(g_apModules); 3084 PKWMODULE pMod = g_apModules[idxHash]; 3085 if (pMod) 3086 { 3087 do 3088 { 3089 if ( pMod->uHashPath == uHashPath 3090 && kHlpStrComp(pMod->pszPath, szNormPath) == 0) 3091 { 3092 kwLdrModuleRetain(pMod); 3093 break; 3094 } 3095 pMod = pMod->pNextHash; 3096 } while (pMod); 3097 } 3098 3099 /* 3100 * If not in the hash table, so create a module entry. 3101 */ 3102 if (!pMod) 3103 { 3104 PKLDRMOD pLdrMod; 3105 rc = kLdrModOpenNativeByHandle((KUPTR)hModule, KLDRMOD_OPEN_FLAGS_NATIVE_ALLOW_INIT_TERM, &pLdrMod); 3106 if (rc == 0) 3107 { 3108 pMod = kwLdrModuleCreateForNativekLdrModule(pLdrMod, szNormPath, cchPath + 1, uHashPath, 3109 K_FALSE /*fDoReplacements*/); 3110 if (!pMod) 3111 { 3112 kLdrModClose(pLdrMod); 3113 kwErrPrintf("out of memory\n"); 3114 } 3115 } 3116 else 3117 kwErrPrintf("kLdrModOpenNativeByHandle failed for %p / '%s': %d\n", hModule, pszName, rc); 3118 } 3119 if (pMod) 3120 { 3121 /* 3122 * Create a CRT slot for the module if necessary. 3123 */ 3124 if (!fEnsureCrtSlot || pMod->iCrtSlot != KU8_MAX) 3125 return pMod; 3126 rc = kwLdrModuleCreateCrtSlot(pMod); 3127 if (rc == 0) 3128 return pMod; 3129 kwLdrModuleRelease(pMod); 3130 } 3131 } 3132 else 3133 kwErrPrintf("kwPathNormalize failed for '%s' (%s): %u!\n", szModPath, pszName, GetLastError()); 3134 } 3135 else 3136 kwErrPrintf("GetModuleFileNameA failed for '%s': %u!\n", pszName, GetLastError()); 3137 } 3138 else if (fAlwaysPresent) 3443 return kwLdrModuleForLoadedNativeByHandle(hModule, fEnsureCrtSlot, pszName); 3444 if (fAlwaysPresent) 3139 3445 kwErrPrintf("Module '%s' was not found by GetModuleHandleA/W!\n", pszName); 3140 3446 return NULL; … … 3346 3652 PKWDYNLOAD pDynLoad; 3347 3653 3654 if (pTool) 3655 { /* likely */ } 3656 else 3657 return NULL; 3658 3348 3659 /* The executable. */ 3349 3660 if ( hmod == NULL 3350 || pTool->u.Sandboxed.pExe->hOurMod == hmod) 3351 return kwLdrModuleRetain(pTool->u.Sandboxed.pExe); 3661 || (pTool->u.Sandboxed.pExe && pTool->u.Sandboxed.pExe->hOurMod == hmod)) 3662 { 3663 if (pTool->u.Sandboxed.pExe) 3664 return kwLdrModuleRetain(pTool->u.Sandboxed.pExe); 3665 return NULL; 3666 } 3352 3667 3353 3668 /* … … 3362 3677 for (;;) 3363 3678 { 3364 KUPTR const uHMod This= (KUPTR)papMods[i]->hOurMod;3365 if (uHMod < uHMod This)3679 KUPTR const uHModCur = (KUPTR)papMods[i]->hOurMod; 3680 if (uHMod < uHModCur) 3366 3681 { 3367 3682 iEnd = i--; … … 3371 3686 break; 3372 3687 } 3373 else if (uHMod != uHMod This)3688 else if (uHMod != uHModCur) 3374 3689 { 3375 3690 iStart = ++i; … … 3379 3694 break; 3380 3695 } 3696 /* We've got a match. Always return the non-virtual module (first) when there is one. */ 3697 else if (!papMods[i]->pVirtualApiMod) 3698 return kwLdrModuleRetain(papMods[i]); 3381 3699 else 3700 { 3701 while (i > 0 && papMods[i - 1]->pVirtualApiMod && papMods[i - 1]->hOurMod == hmod) 3702 i--; 3382 3703 return kwLdrModuleRetain(papMods[i]); 3704 } 3383 3705 3384 3706 i = iStart + (iEnd - iStart) / 2; … … 3430 3752 for (;;) 3431 3753 { 3432 KUPTR const uHModThis = (KUPTR)papMods[i]->hOurMod; 3433 if (uHMod < uHModThis) 3754 PKWMODULE pCurMod = papMods[i]; 3755 KUPTR const uHModCur = (KUPTR)pCurMod->hOurMod; 3756 if (uHMod < uHModCur) 3434 3757 { 3435 3758 iEnd = i; … … 3439 3762 break; 3440 3763 } 3441 else if (uHMod != uHMod This)3764 else if (uHMod != uHModCur) 3442 3765 { 3443 3766 iStart = ++i; … … 3449 3772 else 3450 3773 { 3451 /* Already there in the table. */ 3774 /* Already there in the table. The non-virtual module must be the first 3775 entry if we've got duplicate hmod values because of virtual modules. */ 3776 if (pMod != pCurMod) 3777 { 3778 /* Skip to the last module with the same hmod. */ 3779 while (i + 1 < iEnd && (KUPTR)(pCurMod = papMods[i + 1])->hOurMod == uHMod) 3780 { 3781 if (pMod == pCurMod) 3782 return 0; 3783 i++; 3784 } 3785 3786 /* Then scan backwards till the first one. */ 3787 while (i > 0 && (KUPTR)(pCurMod = papMods[i - 1])->hOurMod == uHMod) 3788 { 3789 if (pMod == pCurMod) 3790 return 0; 3791 i--; 3792 } 3793 pCurMod = papMods[i]; 3794 if (pMod != pCurMod) 3795 { 3796 if (pMod->pVirtualApiMod && !pCurMod->pVirtualApiMod) 3797 i++; 3798 break; 3799 } 3800 } 3452 3801 return 0; 3453 3802 } … … 3460 3809 { 3461 3810 kHlpAssert(papMods[iStart] != pMod); 3462 kHlpAssert((KUPTR)papMods[iStart]->hOurMod != uHMod); 3463 } 3464 kHlpAssert(i == 0 || (KUPTR)papMods[i - 1]->hOurMod < uHMod); 3465 kHlpAssert(i == pTool->u.Sandboxed.cModules || (KUPTR)papMods[i]->hOurMod > uHMod); 3811 kHlpAssert( (KUPTR)papMods[iStart]->hOurMod != uHMod 3812 || pMod->pVirtualApiMod 3813 || papMods[iStart]->pVirtualApiMod); 3814 } 3815 kHlpAssert(i == 0 || (KUPTR)papMods[i - 1]->hOurMod <= uHMod); 3816 kHlpAssert(i == pTool->u.Sandboxed.cModules || (KUPTR)papMods[i]->hOurMod >= uHMod); 3466 3817 #endif 3467 3818 } … … 3485 3836 papMods[i] = kwLdrModuleRetain(pMod); 3486 3837 pTool->u.Sandboxed.cModules++; 3487 KW _LOG(("kwToolAddModule: %u modules after adding %p=%s\n", pTool->u.Sandboxed.cModules, uHMod, pMod->pszPath));3838 KWLDR_LOG(("kwToolAddModule: %u modules after adding %p=%s\n", pTool->u.Sandboxed.cModules, uHMod, pMod->pszPath)); 3488 3839 return 0; 3489 3840 } … … 3500 3851 { 3501 3852 int rc = kwToolAddModule(pTool, pMod); 3853 if (pMod->pVirtualApiMod && rc == 0) 3854 rc = kwToolAddModule(pTool, pMod->pVirtualApiMod); 3502 3855 if (!pMod->fNative && rc == 0) 3503 3856 { … … 3512 3865 } 3513 3866 } 3867 3514 3868 return 0; 3515 3869 } … … 3817 4171 break; 3818 4172 pfFlags = pchPool; 3819 PUTC(( char)_ARG_NONZERO);4173 PUTC((unsigned char)_ARG_NONZERO); 3820 4174 PUTV; 3821 4175 bs = 0; chQuote = 0; … … 3979 4333 return NULL; 3980 4334 } 3981 KW_LOG(("_onexit(%p) - IGNORED\n", pfnFunc));3982 return pfnFunc;4335 //KW_LOG(("_onexit(%p) - IGNORED\n", pfnFunc)); 4336 //return pfnFunc; 3983 4337 } 3984 4338 … … 4004 4358 return -1; 4005 4359 } 4006 KW_LOG(("atexit(%p) - IGNORED!\n", pfnFunc));4007 return 0;4360 //KW_LOG(("atexit(%p) - IGNORED!\n", pfnFunc)); 4361 //return 0; 4008 4362 } 4009 4363 … … 4241 4595 4242 4596 /** _beginthreadex - create a new thread. */ 4243 static uintptr_t __cdecl kwSandbox_msvcrt__beginthreadex(void *pvSecAttr, unsigned cbStack, 4244 unsigned (__stdcall *pfnThreadProc)(void *), void *pvUser, 4245 unsigned fCreate, unsigned *pidThread) 4246 { 4597 static uintptr_t __cdecl kwSandbox_msvcrt__beginthreadex_wrapped(void *pvSecAttr, unsigned cbStack, 4598 unsigned (__stdcall *pfnThreadProc)(void *), void *pvUser, 4599 unsigned fCreate, unsigned *pidThread, PKWCRTSLOT pSlot) 4600 { 4601 /* 4602 * Since the VC++ 12 (VS 2013) compiler, the 2nd pass is now threaded. 4603 * Let it do whatever it needs to. 4604 */ 4605 KW_LOG(("kwSandbox_msvcrt__beginthreadex: pvSecAttr=%p (inh=%d) cbStack=%#x pfnThreadProc=%p pvUser=%p fCreate=%#x pidThread=%p\n", 4606 pvSecAttr, pvSecAttr ? ((LPSECURITY_ATTRIBUTES)pvSecAttr)->bInheritHandle : 0, cbStack, 4607 pfnThreadProc, pvUser, fCreate, pidThread)); 4608 if ( g_Sandbox.pTool->u.Sandboxed.enmHint == KWTOOLHINT_VISUAL_CPP_CL 4609 && pSlot->pfnBeginThreadEx) 4610 { 4611 uintptr_t rcRet = pSlot->pfnBeginThreadEx(pvSecAttr, cbStack, pfnThreadProc, pvUser, fCreate, pidThread); 4612 KW_LOG(("kwSandbox_msvcrt__beginthreadex: returns %p *pidThread=%#x\n", rcRet, pidThread ? *pidThread : -1)); 4613 return rcRet; 4614 } 4615 4247 4616 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread); 4248 4617 KWFS_TODO(); 4249 4618 return 0; 4250 4619 } 4620 4621 CRT_SLOT_FUNCTION_WRAPPER(uintptr_t __cdecl, kwSandbox_msvcrt__beginthreadex, 4622 (void *pvSecAttr, unsigned cbStack, unsigned (__stdcall *pfnThreadProc)(void *), 4623 void *pvUser, unsigned fCreate, unsigned *pidThread), 4624 (pvSecAttr, cbStack, pfnThreadProc, pvUser, fCreate, pidThread, &g_aCrtSlots[iCrtSlot])); 4625 4251 4626 4252 4627 … … 4286 4661 } 4287 4662 *psz++ = '\0'; 4288 kHlpAssert( psz - pszzEnv== cbNeeded);4663 kHlpAssert((KUPTR)(psz - pszzEnv) == cbNeeded); 4289 4664 } 4290 4665 … … 4302 4677 fprintf(stderr, " %u:%p=<eos>\n\n", iVar, pszCur); 4303 4678 pszCur++; 4304 fprintf(stderr, "ended at %p, after %u bytes (ex epcted %u)\n", pszCur, pszCur - pszzEnv, cbNeeded);4679 fprintf(stderr, "ended at %p, after %u bytes (expected %u)\n", pszCur, pszCur - pszzEnv, cbNeeded); 4305 4680 #endif 4306 4681 return pszzEnv; … … 4343 4718 } 4344 4719 *pwsz++ = '\0'; 4345 kHlpAssert( pwsz - pwszzEnv== cwcNeeded);4720 kHlpAssert((KUPTR)(pwsz - pwszzEnv) == cwcNeeded); 4346 4721 } 4347 4722 … … 5054 5429 pDynLoad->pNext = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead; 5055 5430 g_Sandbox.pTool->u.Sandboxed.pDynLoadHead = pDynLoad; 5056 KW _LOG(("LoadLibraryExA(%s,,[resource]) -> %p\n", pDynLoad->szRequest, pDynLoad->hmod));5431 KWLDR_LOG(("LoadLibraryExA(%s,,[resource]) -> %p\n", pDynLoad->szRequest, pDynLoad->hmod)); 5057 5432 } 5058 5433 else … … 5067 5442 static HMODULE WINAPI kwSandbox_Kernel32_LoadLibraryExA_VirtualApiModule(PKWDYNLOAD pDynLoad, DWORD fFlags) 5068 5443 { 5069 HMODULE hmod; 5444 static const char s_szDll[] = ".dll"; 5445 KSIZE cbFilename = kHlpStrLen(pDynLoad->szRequest) + 1; 5070 5446 PKWMODULE pMod; 5071 KU32 uHashPath;5072 KSIZE idxHash;5073 5447 char szNormPath[256]; 5074 KSIZE cbFilename = kHlpStrLen(pDynLoad->szRequest) + 1;5075 5448 5076 5449 /* 5077 * Lower case it and make it ends with .dll.5450 * Lower case it and make sure it ends with .dll. 5078 5451 */ 5079 if (cbFilename <= sizeof(szNormPath)) 5080 { 5081 static const char s_szDll[] = ".dll"; 5082 kHlpMemCopy(szNormPath, pDynLoad->szRequest, cbFilename); 5083 _strlwr(szNormPath); 5084 if ( ( cbFilename <= 4 5085 || strcmp(&szNormPath[cbFilename - 5], s_szDll) != 0) 5086 && cbFilename + sizeof(s_szDll) - 1 <= sizeof(szNormPath)) 5087 { 5088 memcpy(&szNormPath[cbFilename - sizeof(s_szDll)], s_szDll, sizeof(s_szDll)); 5089 cbFilename += sizeof(s_szDll) - 1; 5090 } 5091 } 5092 else 5452 if (cbFilename > sizeof(szNormPath)) 5093 5453 { 5094 5454 SetLastError(ERROR_FILENAME_EXCED_RANGE); 5095 5455 return NULL; 5096 5456 } 5457 kHlpMemCopy(szNormPath, pDynLoad->szRequest, cbFilename); 5458 _strlwr(szNormPath); 5459 kHlpAssert(cbFilename > 7 /* api-ms- */ ); 5460 if (strcmp(&szNormPath[cbFilename - 5], s_szDll) != 0) 5461 { 5462 if (cbFilename + sizeof(s_szDll) - 1 > sizeof(szNormPath)) 5463 { 5464 SetLastError(ERROR_FILENAME_EXCED_RANGE); 5465 return NULL; 5466 } 5467 5468 memcpy(&szNormPath[cbFilename - sizeof(s_szDll)], s_szDll, sizeof(s_szDll)); 5469 cbFilename += sizeof(s_szDll) - 1; 5470 } 5097 5471 5098 5472 /* 5099 * Check if it has already been loaded so we don't create an unnecessary 5100 * loader module for it. 5473 * Try load it. 5101 5474 */ 5102 uHashPath = kwStrHash(szNormPath); 5103 idxHash = uHashPath % K_ELEMENTS(g_apModules); 5104 pMod = g_apModules[idxHash]; 5475 pMod = kwLdrModuleTryLoadVirtualDll(szNormPath, cbFilename - 1); 5105 5476 if (pMod) 5106 5477 { 5107 do 5108 { 5109 if ( pMod->uHashPath == uHashPath 5110 && kHlpStrComp(pMod->pszPath, szNormPath) == 0) 5111 { 5112 pDynLoad->pMod = kwLdrModuleRetain(pMod); 5113 pDynLoad->hmod = pMod->hOurMod; 5114 5115 pDynLoad->pNext = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead; 5116 g_Sandbox.pTool->u.Sandboxed.pDynLoadHead = pDynLoad; 5117 KW_LOG(("LoadLibraryExA(%s,,) -> %p [virtual API module - already loaded]\n", pDynLoad->szRequest, pDynLoad->hmod)); 5118 return pDynLoad->hmod; 5119 } 5120 pMod = pMod->pNextHash; 5121 } while (pMod); 5122 } 5123 5124 5125 /* 5126 * Try load it and make a kLdr module for it. 5127 */ 5128 hmod = LoadLibraryExA(szNormPath, NULL /*hFile*/, fFlags); 5129 if (hmod) 5130 { 5131 PKLDRMOD pLdrMod; 5132 int rc = kLdrModOpenNativeByHandle((KUPTR)hmod, KLDRMOD_OPEN_FLAGS_NATIVE_ALLOW_INIT_TERM, &pLdrMod); 5133 if (rc == 0) 5134 { 5135 PKWMODULE pMod = kwLdrModuleCreateForNativekLdrModule(pLdrMod, szNormPath, cbFilename, uHashPath, 5136 K_FALSE /*fDoReplacements*/); 5137 if (pMod) 5138 { 5139 kwToolAddModuleAndImports(g_Sandbox.pTool, pMod); 5140 5141 pDynLoad->pMod = pMod; 5142 pDynLoad->hmod = hmod; 5143 5144 pDynLoad->pNext = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead; 5145 g_Sandbox.pTool->u.Sandboxed.pDynLoadHead = pDynLoad; 5146 KW_LOG(("LoadLibraryExA(%s,,) -> %p [virtual API module - new]\n", pDynLoad->szRequest, pDynLoad->hmod)); 5147 return hmod; 5148 } 5149 KWFS_TODO(); 5150 } 5151 else 5152 KWFS_TODO(); 5478 kwToolAddModuleAndImports(g_Sandbox.pTool, pMod); 5479 5480 pDynLoad->pMod = pMod; 5481 pDynLoad->hmod = pMod->hOurMod; 5482 5483 pDynLoad->pNext = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead; 5484 g_Sandbox.pTool->u.Sandboxed.pDynLoadHead = pDynLoad; 5485 KWLDR_LOG(("LoadLibraryExA(%s,,) -> %p [virtual API module - new]\n", pDynLoad->szRequest, pDynLoad->hmod)); 5486 return pDynLoad->hmod; 5153 5487 } 5154 5488 kHlpFree(pDynLoad); 5155 return hmod;5489 return NULL; 5156 5490 } 5157 5491 … … 5166 5500 int rc; 5167 5501 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread); 5502 //fprintf(stderr, "LoadLibraryExA: %s, %#x\n", pszFilename, fFlags); 5168 5503 5169 5504 /* … … 5193 5528 if (rc == 0) 5194 5529 { 5195 KW _LOG(("LoadLibraryExA(%s,,) -> %p [cached]\n", pszFilename, pDynLoad->hmod));5530 KWLDR_LOG(("LoadLibraryExA(%s,,) -> %p [cached]\n", pszFilename, pDynLoad->hmod)); 5196 5531 return pDynLoad->hmod; 5197 5532 } … … 5211 5546 else 5212 5547 { 5213 KW _LOG(("LoadLibraryExA: Out of memory!\n"));5548 KWLDR_LOG(("LoadLibraryExA: Out of memory!\n")); 5214 5549 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 5215 5550 return NULL; … … 5228 5563 * Special case: api-ms-win-core-synch-l1-2-0 and friends (32-bit yasm, built with VS2015). 5229 5564 */ 5230 if ( strnicmp(pszFilename, TUPLE("api-ms-")) == 05565 if ( kwLdrIsVirtualApiModule(pszFilename, cchFilename) 5231 5566 && kHlpIsFilenameOnly(pszFilename)) 5232 5567 return kwSandbox_Kernel32_LoadLibraryExA_VirtualApiModule(pDynLoad, fFlags); … … 5263 5598 if (rc == 0) 5264 5599 { 5265 KW _LOG(("LoadLibraryExA(%s,,) -> %p\n", pszFilename, pDynLoad->hmod));5600 KWLDR_LOG(("LoadLibraryExA(%s,,) -> %p\n", pszFilename, pDynLoad->hmod)); 5266 5601 return pDynLoad->hmod; 5267 5602 } … … 5479 5814 || pDynLoad->pMod->u.Manual.enmState == KWMODSTATE_READY) 5480 5815 { 5481 KW _LOG(("kwSandbox_Kernel32_GetModuleHandleA(%s,,) -> %p [dynload]\n", pszModule, pDynLoad->hmod));5816 KWLDR_LOG(("kwSandbox_Kernel32_GetModuleHandleA(%s,,) -> %p [dynload]\n", pszModule, pDynLoad->hmod)); 5482 5817 return pDynLoad->hmod; 5483 5818 } … … 5492 5827 * to and go via the g_aGetModuleHandleCache cache. 5493 5828 */ 5494 if (strnicmp(pszModule, "api-ms-win-", 11) == 0) 5829 /** @todo virtual api DLLs */ 5830 if (kHlpStrNICompAscii(pszModule, "api-ms-win-", 11) == 0) 5495 5831 { 5496 5832 HMODULE hmod = GetModuleHandleA(pszModule); … … 5504 5840 if (hmod == GetModuleHandleW(L"NTDLL.DLL")) 5505 5841 return kwSandbox_Kernel32_GetModuleHandleA("NTDLL.DLL"); 5842 if (hmod == GetModuleHandleW(L"UCRTBASE.DLL")) 5843 return kwSandbox_Kernel32_GetModuleHandleA("UCRTBASE.DLL"); 5506 5844 } 5507 5845 else … … 5615 5953 KWFS_TODO(); 5616 5954 #endif 5617 return -1;5955 return ~(UINT)0; 5618 5956 } 5619 5957 … … 5722 6060 < g_Sandbox.pTool->u.Sandboxed.pExe->cbImage) 5723 6061 { 5724 uValue = g_aSandboxGetProcReplacements[i].pfnReplacement; 6062 if (!g_aSandboxReplacements[i].fCrtSlotArray) 6063 uValue = g_aSandboxGetProcReplacements[i].pfnReplacement; 6064 else 6065 { 6066 if (pMod->iCrtSlot == KU8_MAX) 6067 { 6068 int rc = kwLdrModuleCreateCrtSlot(pMod); 6069 if (rc) 6070 { 6071 KW_LOG(("GetProcAddress: kwLdrModuleCreateCrtSlot failed: %d\n", rc)); 6072 SetLastError(ERROR_INTERNAL_ERROR); 6073 return NULL; 6074 } 6075 } 6076 uValue = ((KUPTR *)g_aSandboxGetProcReplacements[i].pfnReplacement)[pMod->iCrtSlot]; 6077 } 6078 5725 6079 KW_LOG(("GetProcAddress(%s, %s) -> %p replaced\n", pMod->pszPath, pszProc, (KUPTR)uValue)); 5726 6080 } … … 5839 6193 for (;;) 5840 6194 { 5841 KUPTR const uHMod This= (KUPTR)papMods[i]->hOurMod;5842 if (uPC < uHMod This)6195 KUPTR const uHModCur = (KUPTR)papMods[i]->hOurMod; 6196 if (uPC < uHModCur) 5843 6197 { 5844 6198 iEnd = i; … … 5848 6202 break; 5849 6203 } 5850 else if (uPC != uHMod This)6204 else if (uPC != uHModCur) 5851 6205 { 5852 6206 iStart = ++i; … … 5972 6326 return K_TRUE; 5973 6327 } 6328 6329 /* In VC2019 there is also one {UUID} file in temp: */ 6330 if (pwszName[0] == '{') 6331 { 6332 KSIZE cwcName = kwUtf16Len(pwszName); 6333 if ( cwcName == sizeof("{4465DDD9-E494-471B-996B-9B556E25AEF8}") - 1 6334 && pwszName[37] == '}' 6335 && iswalnum(pwszName[1]) // 4 6336 && iswalnum(pwszName[2]) // 4 6337 && iswalnum(pwszName[3]) // 6 6338 && iswalnum(pwszName[4]) // 5 6339 && iswalnum(pwszName[5]) // d 6340 && iswalnum(pwszName[6]) // d 6341 && iswalnum(pwszName[7]) // d 6342 && iswalnum(pwszName[8]) // 9 6343 && pwszName[9] == '-' // - 6344 && iswalnum(pwszName[10]) // e 6345 && iswalnum(pwszName[11]) // 4 6346 && iswalnum(pwszName[12]) // 9 6347 && iswalnum(pwszName[13]) // 4 6348 && pwszName[14] == '-' // - 6349 && iswalnum(pwszName[15]) // 4 6350 && iswalnum(pwszName[16]) // 7 6351 && iswalnum(pwszName[17]) // 1 6352 && iswalnum(pwszName[18]) // b 6353 && pwszName[19] == '-' // - 6354 && iswalnum(pwszName[20]) // 9 6355 && iswalnum(pwszName[21]) // 9 6356 && iswalnum(pwszName[22]) // 6 6357 && iswalnum(pwszName[23]) // b 6358 && pwszName[24] == '-' // - 6359 && iswalnum(pwszName[25]) // 9 6360 && iswalnum(pwszName[26]) // b 6361 && iswalnum(pwszName[27]) // 5 6362 && iswalnum(pwszName[28]) // 5 6363 && iswalnum(pwszName[29]) // 6 6364 && iswalnum(pwszName[30]) // e 6365 && iswalnum(pwszName[31]) // 2 6366 && iswalnum(pwszName[32]) // 5 6367 && iswalnum(pwszName[33]) // a 6368 && iswalnum(pwszName[34]) // 3 6369 && iswalnum(pwszName[35]) // f 6370 && iswalnum(pwszName[36])) // 8 6371 return K_TRUE; 6372 } 5974 6373 } 5975 6374 return K_FALSE; … … 6029 6428 6030 6429 6031 static HANDLE kwFsTempFileCreateW(const wchar_t *pwszFilename, DWORD dwDesiredAccess, DWORD dwCreationDisposition) 6430 static HANDLE kwFsTempFileCreateW(const wchar_t *pwszFilename, DWORD dwDesiredAccess, DWORD dwCreationDisposition, 6431 KBOOL *pfFallback) 6032 6432 { 6033 6433 HANDLE hFile; … … 6053 6453 * Create a new temporary file instance if not found. 6054 6454 */ 6455 *pfFallback = K_FALSE; 6055 6456 if (pTempFile == NULL) 6056 6457 { … … 6061 6462 case CREATE_ALWAYS: 6062 6463 case OPEN_ALWAYS: 6464 case CREATE_NEW: 6063 6465 dwErr = NO_ERROR; 6064 6466 break; 6065 6467 6066 case CREATE_NEW:6067 kHlpAssertFailed();6068 SetLastError(ERROR_ALREADY_EXISTS);6069 return INVALID_HANDLE_VALUE;6070 6071 6468 case OPEN_EXISTING: 6072 6469 case TRUNCATE_EXISTING: 6470 *pfFallback = K_TRUE; 6073 6471 kHlpAssertFailed(); 6074 6472 SetLastError(ERROR_FILE_NOT_FOUND); … … 6113 6511 break; 6114 6512 case OPEN_ALWAYS: 6115 dwErr = ERROR_ALREADY_EXISTS 6513 dwErr = ERROR_ALREADY_EXISTS; 6116 6514 break; 6117 6515 … … 6369 6767 kHlpAssertReturn(pFsObj->pParent->hDir != INVALID_HANDLE_VALUE, NULL); 6370 6768 6371 Ios.Information = -1;6769 Ios.Information = ~(ULONG_PTR)0; 6372 6770 Ios.u.Status = -1; 6373 6771 … … 6627 7025 && kwFsIsClTempFileW(pwszFilename)) 6628 7026 { 6629 hFile = kwFsTempFileCreateW(pwszFilename, dwDesiredAccess, dwCreationDisposition); 6630 KWFS_LOG(("CreateFileW(%ls) -> %p [temp]\n", pwszFilename, hFile)); 6631 return hFile; 7027 KBOOL fFallback = K_FALSE; 7028 hFile = kwFsTempFileCreateW(pwszFilename, dwDesiredAccess, dwCreationDisposition, &fFallback); 7029 if (!fFallback) 7030 { 7031 KWFS_LOG(("CreateFileW(%ls) -> %p [temp]\n", pwszFilename, hFile)); 7032 return hFile; 7033 } 6632 7034 } 6633 7035 #endif … … 7089 7491 { 7090 7492 pOutBuf->u.Fully.cchBufAlloc = sizeof(pOutBuf->abPadding); 7091 pOutBuf->u.Fully.pchBuf = pOutBuf->abPadding;7493 pOutBuf->u.Fully.pchBuf = (char *)&pOutBuf->abPadding[0]; 7092 7494 } 7093 7495 } … … 8042 8444 fRet = INVALID_FILE_ATTRIBUTES; 8043 8445 } 8044 8446 #ifndef NDEBUG 8447 { 8448 DWORD fCheck = GetFileAttributesW(pwszFilename); 8449 kHlpAssertMsg(fCheck == fRet, ("fCheck=%x vs fRet=%#x diff=%#x; %ls\n", fCheck, fRet, fCheck ^ fRet, pwszFilename)); 8450 } 8451 #endif 8045 8452 KWFS_LOG(("GetFileAttributesW(%ls) -> %#x [cached]\n", pwszFilename, fRet)); 8046 8453 return fRet; … … 8078 8485 *(KU64 *)&pData->ftLastWriteTime = birdNtTimeFromTimeSpec(&pFsObj->Stats.st_mtim); 8079 8486 kFsCacheObjRelease(g_pFsCache, pFsObj); 8487 fRet = TRUE; 8080 8488 } 8081 8489 else … … 8091 8499 } 8092 8500 8501 #ifdef K_STRICT 8502 { 8503 WIN32_FILE_ATTRIBUTE_DATA CheckData = { 0 }; 8504 DWORD const dwErrSaved = GetLastError(); 8505 BOOL const fRetCheck = GetFileAttributesExA(pszFilename, enmLevel, &CheckData); 8506 kHlpAssertMsg(fRet == fRetCheck, ("fRet=%d fRetCheck=%d; %s\n", fRet, fRetCheck, pszFilename)); 8507 if (fRetCheck && fRet) 8508 { 8509 # define ASSERT_FS_FIELD_EQUAL_A(pResult, pExpected, pszFilename, Field, szFmt) \ 8510 kHlpAssertMsg((pResult)->Field == (pExpected)->Field, (#Field ": " szFmt " , expected " szFmt "; %s\n", (pResult)->Field, (pExpected)->Field, pszFilename)) 8511 ASSERT_FS_FIELD_EQUAL_A(pData, &CheckData, pszFilename, dwFileAttributes, "%#x"); 8512 ASSERT_FS_FIELD_EQUAL_A(pData, &CheckData, pszFilename, nFileSizeHigh, "%#x"); 8513 ASSERT_FS_FIELD_EQUAL_A(pData, &CheckData, pszFilename, nFileSizeLow, "%#x"); 8514 ASSERT_FS_FIELD_EQUAL_A(pData, &CheckData, pszFilename, ftCreationTime.dwHighDateTime, "%#x"); 8515 ASSERT_FS_FIELD_EQUAL_A(pData, &CheckData, pszFilename, ftCreationTime.dwLowDateTime, "%#x"); 8516 ASSERT_FS_FIELD_EQUAL_A(pData, &CheckData, pszFilename, ftLastWriteTime.dwHighDateTime, "%#x"); 8517 ASSERT_FS_FIELD_EQUAL_A(pData, &CheckData, pszFilename, ftLastWriteTime.dwLowDateTime, "%#x"); 8518 } 8519 else 8520 kHlpAssertMsg(dwErrSaved == GetLastError(), ("%u, expected %u; %s\n", dwErrSaved, GetLastError(), pszFilename)); 8521 SetLastError(dwErrSaved); 8522 } 8523 #endif 8093 8524 KWFS_LOG(("GetFileAttributesA(%s,%d,) -> %d [cached]\n", pszFilename, enmLevel, fRet)); 8094 8525 return fRet; … … 8125 8556 *(KU64 *)&pData->ftLastWriteTime = birdNtTimeFromTimeSpec(&pFsObj->Stats.st_mtim); 8126 8557 kFsCacheObjRelease(g_pFsCache, pFsObj); 8558 fRet = TRUE; 8127 8559 } 8128 8560 else … … 8138 8570 } 8139 8571 8140 KWFS_LOG(("GetFileAttributesW(%ls,%d,) -> %d [cached]\n", pwszFilename, enmLevel, fRet)); 8572 #ifdef K_STRICT 8573 { 8574 WIN32_FILE_ATTRIBUTE_DATA CheckData = { 0 }; 8575 DWORD const dwErrSaved = GetLastError(); 8576 BOOL const fRetCheck = GetFileAttributesExW(pwszFilename, enmLevel, &CheckData); 8577 kHlpAssertMsg(fRet == fRetCheck, ("fRet=%d fRetCheck=%d; %ls\n", fRet, fRetCheck, pwszFilename)); 8578 if (fRetCheck && fRet) 8579 { 8580 # define ASSERT_FS_FIELD_EQUAL_W(pResult, pExpected, pszFilename, Field, szFmt) \ 8581 kHlpAssertMsg((pResult)->Field == (pExpected)->Field, (#Field ": " szFmt " , expected " szFmt "; %ls\n", (pResult)->Field, (pExpected)->Field, pwszFilename)) 8582 ASSERT_FS_FIELD_EQUAL_W(pData, &CheckData, pwszFilename, dwFileAttributes, "%#x"); 8583 ASSERT_FS_FIELD_EQUAL_W(pData, &CheckData, pwszFilename, nFileSizeHigh, "%#x"); 8584 ASSERT_FS_FIELD_EQUAL_W(pData, &CheckData, pwszFilename, nFileSizeLow, "%#x"); 8585 ASSERT_FS_FIELD_EQUAL_W(pData, &CheckData, pwszFilename, ftCreationTime.dwHighDateTime, "%#x"); 8586 ASSERT_FS_FIELD_EQUAL_W(pData, &CheckData, pwszFilename, ftCreationTime.dwLowDateTime, "%#x"); 8587 ASSERT_FS_FIELD_EQUAL_W(pData, &CheckData, pwszFilename, ftLastWriteTime.dwHighDateTime, "%#x"); 8588 ASSERT_FS_FIELD_EQUAL_W(pData, &CheckData, pwszFilename, ftLastWriteTime.dwLowDateTime, "%#x"); 8589 } 8590 else 8591 kHlpAssertMsg(dwErrSaved == GetLastError(), ("%u, expected %u; %ls\n", dwErrSaved, GetLastError(), pwszFilename)); 8592 SetLastError(dwErrSaved); 8593 } 8594 #endif 8595 KWFS_LOG(("GetFileAttributesExW(%ls,%d,) -> %d [cached]\n", pwszFilename, enmLevel, fRet)); 8141 8596 return fRet; 8142 8597 } … … 8861 9316 */ 8862 9317 PKWVIRTALLOC pTracker; 8863 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread); 8864 9318 9319 EnterCriticalSection(&g_Sandbox.VirtualAllocLock); 8865 9320 pTracker = g_Sandbox.pVirtualAllocHead; 8866 9321 while ( pTracker 8867 9322 && (KUPTR)pvMem - (KUPTR)pTracker->pvAlloc >= pTracker->cbAlloc) 8868 9323 pTracker = pTracker->pNext; 9324 LeaveCriticalSection(&g_Sandbox.VirtualAllocLock); 8869 9325 if (!pTracker) 8870 9326 { … … 8876 9332 pTracker->cbAlloc = cb; 8877 9333 pTracker->idxPreAllocated = idxPreAllocated; 9334 EnterCriticalSection(&g_Sandbox.VirtualAllocLock); 8878 9335 pTracker->pNext = g_Sandbox.pVirtualAllocHead; 8879 9336 g_Sandbox.pVirtualAllocHead = pTracker; 9337 LeaveCriticalSection(&g_Sandbox.VirtualAllocLock); 8880 9338 } 8881 9339 SetLastError(dwErr); … … 8900 9358 if (dwFreeType & MEM_RELEASE) 8901 9359 { 8902 PKWVIRTALLOC pTracker = g_Sandbox.pVirtualAllocHead; 9360 PKWVIRTALLOC pTracker; 9361 EnterCriticalSection(&g_Sandbox.VirtualAllocLock); 9362 pTracker = g_Sandbox.pVirtualAllocHead; 8903 9363 if (pTracker) 8904 9364 { … … 8922 9382 { 8923 9383 kwSandboxResetFixedAllocation(pTracker->idxPreAllocated); 9384 LeaveCriticalSection(&g_Sandbox.VirtualAllocLock); 8924 9385 KW_LOG(("VirtualFree: pvAddr=%p cb=%p type=%#x -> TRUE [pre allocated #%u]\n", 8925 9386 pvAddr, cb, dwFreeType, pTracker->idxPreAllocated)); … … 8937 9398 g_Sandbox.pVirtualAllocHead = pTracker; 8938 9399 } 9400 LeaveCriticalSection(&g_Sandbox.VirtualAllocLock); 8939 9401 KW_LOG(("VirtualFree: pvAddr=%p cb=%p type=%#x -> %d\n", pvAddr, cb, dwFreeType, fRc)); 8940 9402 return fRc; … … 8943 9405 KW_LOG(("VirtualFree: pvAddr=%p not found!\n", pvAddr)); 8944 9406 } 9407 LeaveCriticalSection(&g_Sandbox.VirtualAllocLock); 8945 9408 } 8946 9409 } … … 9188 9651 if (g_Sandbox.pTool->u.Sandboxed.enmHint == KWTOOLHINT_VISUAL_CPP_CL) 9189 9652 { 9653 /** @todo do generic caching of hash results. Need SHA-1 and SHA-256 for 9654 * more recent compilers. */ 9190 9655 if (idAlg == CALG_MD5) 9191 9656 { … … 9222 9687 kwErrPrintf("CryptCreateHash: hKey=%p is not supported with CALG_MD5\n", hKey); 9223 9688 } 9224 else9225 kwErrPrintf("CryptCreateHash: idAlg=%#x is not supported\n", idAlg);9689 //else 9690 // kwErrPrintf("CryptCreateHash: idAlg=%#x is not supported\n", idAlg); 9226 9691 } 9227 9692 … … 9337 9802 else 9338 9803 kwErrPrintf("CryptHashData: Hash is already finalized!!\n"); 9339 SetLastError( NTE_BAD_HASH);9804 SetLastError((DWORD)NTE_BAD_HASH); 9340 9805 fRc = FALSE; 9341 9806 } … … 9447 9912 default: 9448 9913 kwErrPrintf("CryptGetHashParam: Unknown dwParam=%#x\n", dwParam); 9449 SetLastError( NTE_BAD_TYPE);9914 SetLastError((DWORD)NTE_BAD_TYPE); 9450 9915 return FALSE; 9451 9916 } … … 9485 9950 { 9486 9951 kwErrPrintf("CryptGetHashParam: dwFlags is not zero: %#x!\n", dwFlags); 9487 SetLastError( NTE_BAD_FLAGS);9952 SetLastError((DWORD)NTE_BAD_FLAGS); 9488 9953 } 9489 9954 } … … 9491 9956 { 9492 9957 kwErrPrintf("CryptGetHashParam: Invalid cached hash handle!!\n"); 9493 SetLastError( NTE_BAD_HASH);9958 SetLastError((DWORD)NTE_BAD_HASH); 9494 9959 } 9495 9960 fRc = FALSE; … … 9919 10384 KSIZE cbLeft = cb; 9920 10385 while (cbLeft-- > 0) 9921 *pbDst++ = bFiller;10386 *pbDst++ = (KU8)bFiller; 9922 10387 return pvDst; 9923 10388 } … … 10046 10511 10047 10512 { TUPLE("_beginthread"), NULL, (KUPTR)kwSandbox_msvcrt__beginthread }, 10048 { TUPLE("_beginthreadex"), NULL, (KUPTR)kwSandbox_msvcrt__beginthreadex },10513 { TUPLE("_beginthreadex"), NULL, (KUPTR)kwSandbox_msvcrt__beginthreadex, K_FALSE /*fOnlyExe*/, K_TRUE /*fCrtSlotArray*/ }, 10049 10514 { TUPLE("_beginthreadex"), "msvcr120.dll", (KUPTR)kwSandbox_msvcr120__beginthreadex }, /* higher priority last */ 10050 10515 … … 10262 10727 10263 10728 10729 #if 0 10264 10730 /** 10265 10731 * Resets the KWMODULE::fVisited flag for _all_ known modules. … … 10326 10792 } 10327 10793 } 10794 #else 10795 /** 10796 * Used by kwSandboxExec to reset the state of the module tree. 10797 */ 10798 static void kwSandboxResetModuleState(void) 10799 { 10800 PKWMODULE pMod = g_pModuleHead; 10801 while (pMod) 10802 { 10803 if (!pMod->fNative) 10804 pMod->u.Manual.enmState = K_MIN(pMod->u.Manual.enmReInitState, pMod->u.Manual.enmState); 10805 /* Hack: Re-init mspdbXXX.dll when we want to use a different mspdbsrv.exe instance. */ 10806 else if ( pMod->fReInitOnMsPdbSrvEndpointChange 10807 && ( g_Sandbox.pTool->u.Sandboxed.enmHint == KWTOOLHINT_VISUAL_CPP_CL 10808 || g_Sandbox.pTool->u.Sandboxed.enmHint == KWTOOLHINT_VISUAL_CPP_LINK)) 10809 { 10810 const char *pszValue = kwSandboxDoGetEnvA(&g_Sandbox, TUPLE("_MSPDBSRV_ENDPOINT_")); 10811 if (pMod->fReInitOnMsPdbSrvEndpointChange == 1) 10812 { 10813 pMod->fReInitOnMsPdbSrvEndpointChange = 2; 10814 pMod->pszMsPdbSrvEndpoint = pszValue ? kHlpStrDup(pszValue) : NULL; 10815 KWLDR_LOG(("Not re-initing '%s': first time used (_MSPDBSRV_ENDPOINT_ is '%s')\n", 10816 pMod->pszPath, pszValue ? pszValue : "<null>")); 10817 } 10818 else if ( (pszValue == NULL && pMod->pszMsPdbSrvEndpoint == NULL) 10819 || (pszValue != NULL && pMod->pszMsPdbSrvEndpoint != NULL && kHlpStrComp(pszValue, pMod->pszMsPdbSrvEndpoint) == 0)) 10820 KWLDR_LOG(("Not re-initing '%s': _MSPDBSRV_ENDPOINT_ unchanged ('%s')\n", 10821 pMod->pszPath, pszValue ? pszValue : "<null>")); 10822 else 10823 { 10824 KWLDR_LOG(("Re-initing '%s': _MSPDBSRV_ENDPOINT_ changed from '%s' to '%s'\n", pMod->pszPath, 10825 pMod->pszMsPdbSrvEndpoint ? pMod->pszMsPdbSrvEndpoint : "<null>", pszValue ? pszValue : "<null>")); 10826 kHlpFree(pMod->pszMsPdbSrvEndpoint); 10827 if (pszValue != NULL) 10828 pMod->pszMsPdbSrvEndpoint = kHlpStrDup(pszValue); 10829 else 10830 pMod->pszMsPdbSrvEndpoint = NULL; 10831 pMod->fNeedReInit = K_TRUE; 10832 } 10833 } 10834 10835 pMod = pMod->pNextList; 10836 } 10837 } 10838 #endif 10328 10839 10329 10840 static PPEB kwSandboxGetProcessEnvironmentBlock(void) … … 10740 11251 10741 11252 /* Free left behind VirtualAlloc leaks. */ 11253 EnterCriticalSection(&g_Sandbox.VirtualAllocLock); 10742 11254 pTracker = g_Sandbox.pVirtualAllocHead; 10743 11255 g_Sandbox.pVirtualAllocHead = NULL; 11256 LeaveCriticalSection(&g_Sandbox.VirtualAllocLock); 10744 11257 while (pTracker) 10745 11258 { … … 10911 11424 * Do module initialization. 10912 11425 */ 10913 kwSandboxResetModuleVisited(); 10914 kwSandboxResetModuleState(pTool->u.Sandboxed.pExe); 11426 #if 0 11427 //kwSandboxResetModuleVisited(); 11428 //kwSandboxResetModuleState(pTool->u.Sandboxed.pExe); 11429 #else 11430 kwSandboxResetModuleState(); 11431 #endif 10915 11432 rc = kwLdrModuleInitTree(pTool->u.Sandboxed.pExe); 10916 11433 if (rc == 0) … … 11877 12394 * Do the job. 11878 12395 */ 12396 rcExit = 0; 11879 12397 for (j = 0; j < cRepeats; j++) 11880 12398 { … … 12017 12535 * @param pszAppend The string to append. 12018 12536 */ 12019 static int kwFullTestVectorAppend(const char ***ppapszVector, int*pcEntries, char const *pszAppend)12020 { 12021 unsignedcEntries = *pcEntries;12537 static int kwFullTestVectorAppend(const char ***ppapszVector, KU32 *pcEntries, char const *pszAppend) 12538 { 12539 KU32 cEntries = *pcEntries; 12022 12540 if (!(cEntries & 15)) 12023 12541 { … … 12395 12913 return kwErrPrintfRc(3, "VirtualProtect(%p, %#x, PAGE_EXECUTE_READWRITE,NULL) failed: %u\n", 12396 12914 g_abDefLdBuf, sizeof(g_abDefLdBuf), GetLastError()); 12915 InitializeCriticalSection(&g_Sandbox.VirtualAllocLock); 12397 12916 12398 12917 #ifdef WITH_CONSOLE_OUTPUT_BUFFERING … … 12519 13038 && uValue <= 5) 12520 13039 { 12521 DWORD dwClass, dwPriority; 13040 DWORD dwClass; 13041 int dwPriority; 12522 13042 switch (uValue) 12523 13043 { 12524 13044 case 1: dwClass = IDLE_PRIORITY_CLASS; dwPriority = THREAD_PRIORITY_IDLE; break; 12525 13045 case 2: dwClass = BELOW_NORMAL_PRIORITY_CLASS; dwPriority = THREAD_PRIORITY_BELOW_NORMAL; break; 13046 default: 12526 13047 case 3: dwClass = NORMAL_PRIORITY_CLASS; dwPriority = THREAD_PRIORITY_NORMAL; break; 12527 case 4: dwClass = HIGH_PRIORITY_CLASS; dwPriority = 0xffffffff; break;12528 case 5: dwClass = REALTIME_PRIORITY_CLASS; dwPriority = 0xffffffff; break;13048 case 4: dwClass = HIGH_PRIORITY_CLASS; dwPriority = INT_MAX; break; 13049 case 5: dwClass = REALTIME_PRIORITY_CLASS; dwPriority = INT_MAX; break; 12529 13050 } 12530 13051 SetPriorityClass(GetCurrentProcess(), dwClass); 12531 if (dwPriority != 0xffffffff)13052 if (dwPriority != INT_MAX) 12532 13053 SetThreadPriority(GetCurrentThread(), dwPriority); 12533 13054 } … … 12692 13213 if (g_fRestart) 12693 13214 { 13215 DWORD cbIgnored = 1; 12694 13216 KU8 b; 12695 13217 FlushFileBuffers(hPipe); 12696 ReadFile(hPipe, &b, 1, &cb Msg, NULL);13218 ReadFile(hPipe, &b, 1, &cbIgnored, NULL); 12697 13219 } 12698 13220 -
trunk/src/kWorker/kWorkerTlsXxxK.c
r3042 r3361 58 58 * Initialization data. 59 59 */ 60 static char const g_abDummy[TLS_SIZE] = {0x42}; 60 //static char const g_abDummy[TLS_SIZE] = {0x42}; 61 static char g_abDummy[TLS_SIZE] = {0}; 61 62 62 63 /** … … 88 89 if (dwReason == DLL_PROCESS_ATTACH) 89 90 { 90 HMODULE hModExe = (HMODULE)(ULONG_PTR)KWORKER_BASE; 91 //HMODULE hModExe = (HMODULE)(ULONG_PTR)KWORKER_BASE; 92 HMODULE hModExe = GetModuleHandleW(NULL); 91 93 KWLDRTLSALLOCATIONHOOK *pfnHook = (KWLDRTLSALLOCATIONHOOK *)GetProcAddress(hModExe, "kwLdrTlsAllocationHook"); 92 94 if (pfnHook)
Note:
See TracChangeset
for help on using the changeset viewer.