RTDECL(int) RTPathUserDocuments(char *pszPath, size_t cchPath) { /* * Validate input */ AssertPtrReturn(pszPath, VERR_INVALID_POINTER); AssertReturn(cchPath, VERR_INVALID_PARAMETER); RTLDRMOD hShell32; int rc = RTLdrLoad("Shell32.dll", &hShell32); if (RT_SUCCESS(rc)) { PFNSHGETFOLDERPATHW pfnSHGetFolderPathW; rc = RTLdrGetSymbol(hShell32, "SHGetFolderPathW", (void**)&pfnSHGetFolderPathW); if (RT_SUCCESS(rc)) { RTUTF16 wszPath[RTPATH_MAX]; HRESULT hrc = pfnSHGetFolderPathW(0, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, wszPath); if ( hrc == S_OK /* Found */ || hrc == S_FALSE) /* Found, but doesn't exist */ { /* * Convert and return. */ RTLdrClose(hShell32); return RTUtf16ToUtf8Ex(&wszPath[0], RTSTR_MAX, &pszPath, cchPath, NULL); } } RTLdrClose(hShell32); } return VERR_PATH_NOT_FOUND; }
bool VBoxLibDlpiFound(void) { RTLDRMOD hLibDlpi; if (g_hLibDlpi && g_fCheckedForLibDlpi) return true; if (g_fCheckedForLibDlpi) return false; if (!RT_SUCCESS(RTLdrLoad(LIB_DLPI, &hLibDlpi))) return false; if ( RT_SUCCESS(RTLdrGetSymbol(hLibDlpi, "dlpi_open", (void **)&g_pfnLibDlpiOpen)) && RT_SUCCESS(RTLdrGetSymbol(hLibDlpi, "dlpi_close", (void **)&g_pfnLibDlpiClose)) && RT_SUCCESS(RTLdrGetSymbol(hLibDlpi, "dlpi_info", (void **)&g_pfnLibDlpiInfo)) && RT_SUCCESS(RTLdrGetSymbol(hLibDlpi, "dlpi_bind", (void **)&g_pfnLibDlpiBind)) && RT_SUCCESS(RTLdrGetSymbol(hLibDlpi, "dlpi_promiscon", (void **)&g_pfnLibDlpiPromiscon)) && RT_SUCCESS(RTLdrGetSymbol(hLibDlpi, "dlpi_set_physaddr", (void **)&g_pfnLibDlpiSetPhysAddr)) && RT_SUCCESS(RTLdrGetSymbol(hLibDlpi, "dlpi_recv", (void **)&g_pfnLibDlpiRecv)) && RT_SUCCESS(RTLdrGetSymbol(hLibDlpi, "dlpi_fd", (void **)&g_pfnLibDlpiFd)) ) { g_hLibDlpi = hLibDlpi; g_fCheckedForLibDlpi = true; return true; } else { RTLdrClose(hLibDlpi); g_fCheckedForLibDlpi = true; return false; } }
bool VBoxSolarisLibDlpiFound(void) { RTLDRMOD hLibDlpi; if (g_hLibDlpi && g_fCheckedForLibDlpi) return true; if (g_fCheckedForLibDlpi) return false; if (!RT_SUCCESS(RTLdrLoad(LIB_DLPI, &hLibDlpi))) return false; /* * Unfortunately; we cannot make use of dlpi_get_physaddr because it requires us to * open the VNIC/link which requires root permissions :/ */ if (RT_SUCCESS(RTLdrGetSymbol(hLibDlpi, "dlpi_walk", (void **)&g_pfnLibDlpiWalk))) { g_hLibDlpi = hLibDlpi; g_fCheckedForLibDlpi = true; return true; } else { RTLdrClose(hLibDlpi); g_fCheckedForLibDlpi = true; return false; } }
bool VBoxSolarisLibDlpiFound(void) { RTLDRMOD hLibDlpi; if (g_fCheckedForLibDlpi) return g_hLibDlpi != NIL_RTLDRMOD; g_fCheckedForLibDlpi = true; int rc = RTLdrLoad(LIB_DLPI, &hLibDlpi); if (RT_SUCCESS(rc)) { /* * Unfortunately; we cannot make use of dlpi_get_physaddr because it requires us to * open the VNIC/link which requires root permissions :/ */ rc = RTLdrGetSymbol(hLibDlpi, "dlpi_walk", (void **)&g_pfnLibDlpiWalk); rc |= RTLdrGetSymbol(hLibDlpi, "dlpi_close", (void **)&g_pfnLibDlpiClose); rc |= RTLdrGetSymbol(hLibDlpi, "dlpi_open", (void **)&g_pfnLibDlpiOpen); if (RT_SUCCESS(rc)) { g_hLibDlpi = hLibDlpi; return true; } RTLdrClose(hLibDlpi); } hLibDlpi = NIL_RTLDRMOD; return false; }
static void vboxClipboardInitNewAPI(VBOXCLIPBOARDCONTEXT *pCtx) { RTLDRMOD hUser32 = NIL_RTLDRMOD; int rc = RTLdrLoadSystem("User32.dll", /* fNoUnload = */ true, &hUser32); if (RT_SUCCESS(rc)) { rc = RTLdrGetSymbol(hUser32, "AddClipboardFormatListener", (void**)&pCtx->pfnAddClipboardFormatListener); if (RT_SUCCESS(rc)) { rc = RTLdrGetSymbol(hUser32, "RemoveClipboardFormatListener", (void**)&pCtx->pfnRemoveClipboardFormatListener); } RTLdrClose(hUser32); } if (RT_SUCCESS(rc)) { Log(("New Clipboard API is enabled\n")); } else { pCtx->pfnAddClipboardFormatListener = NULL; pCtx->pfnRemoveClipboardFormatListener = NULL; Log(("New Clipboard API is not available. rc = %Rrc\n", rc)); } }
/** * Builds and allocates the security descriptor required for securing the local pipe. * * @return IPRT status code. * @param ppDesc Where to store the allocated security descriptor on success. * Must be free'd using LocalFree(). */ static int rtLocalIpcServerWinAllocSecurityDescriptior(PSECURITY_DESCRIPTOR *ppDesc, bool fServer) { /** @todo Stuff this into RTInitOnce? Later. */ PFNCONVERTSTRINGSECURITYDESCRIPTORTOSECURITYDESCRIPTOR pfnConvertStringSecurityDescriptorToSecurityDescriptor = NULL; RTLDRMOD hAdvApi32 = NIL_RTLDRMOD; int rc = RTLdrLoadSystem("Advapi32.dll", true /*fNoUnload*/, &hAdvApi32); if (RT_SUCCESS(rc)) rc = RTLdrGetSymbol(hAdvApi32, "ConvertStringSecurityDescriptorToSecurityDescriptorW", (void**)&pfnConvertStringSecurityDescriptorToSecurityDescriptor); PSECURITY_DESCRIPTOR pSecDesc = NULL; if (RT_SUCCESS(rc)) { AssertPtr(pfnConvertStringSecurityDescriptorToSecurityDescriptor); /* * We'll create a security descriptor from a SDDL that denies * access to network clients (this is local IPC after all), it * makes some further restrictions to prevent non-authenticated * users from screwing around. */ PRTUTF16 pwszSDDL; rc = RTStrToUtf16(fServer ? RTLOCALIPC_WIN_SDDL_SERVER : RTLOCALIPC_WIN_SDDL_CLIENT, &pwszSDDL); if (RT_SUCCESS(rc)) { if (!pfnConvertStringSecurityDescriptorToSecurityDescriptor((LPCTSTR)pwszSDDL, SDDL_REVISION_1, &pSecDesc, NULL)) { rc = RTErrConvertFromWin32(GetLastError()); } RTUtf16Free(pwszSDDL); } } else { /* Windows OSes < W2K SP2 not supported for now, bail out. */ /** @todo Implement me! */ rc = VERR_NOT_SUPPORTED; } if (hAdvApi32 != NIL_RTLDRMOD) RTLdrClose(hAdvApi32); if (RT_SUCCESS(rc)) { AssertPtr(pSecDesc); *ppDesc = pSecDesc; } return rc; }
/** * Gets the user home directory. * * @returns iprt status code. * @param pszPath Buffer where to store the path. * @param cchPath Buffer size in bytes. */ RTDECL(int) RTPathUserHome(char *pszPath, size_t cchPath) { /* * Validate input */ AssertPtrReturn(pszPath, VERR_INVALID_POINTER); AssertReturn(cchPath, VERR_INVALID_PARAMETER); RTUTF16 wszPath[RTPATH_MAX]; bool fValidFolderPath = false; /* * Try with Windows XP+ functionality first. */ RTLDRMOD hShell32; int rc = RTLdrLoadSystem("Shell32.dll", true /*fNoUnload*/, &hShell32); if (RT_SUCCESS(rc)) { PFNSHGETFOLDERPATHW pfnSHGetFolderPathW; rc = RTLdrGetSymbol(hShell32, "SHGetFolderPathW", (void**)&pfnSHGetFolderPathW); if (RT_SUCCESS(rc)) { HRESULT hrc = pfnSHGetFolderPathW(0, CSIDL_PROFILE, NULL, SHGFP_TYPE_CURRENT, wszPath); fValidFolderPath = (hrc == S_OK); } RTLdrClose(hShell32); } DWORD dwAttr; if ( !fValidFolderPath || (dwAttr = GetFileAttributesW(&wszPath[0])) == INVALID_FILE_ATTRIBUTES || !(dwAttr & FILE_ATTRIBUTE_DIRECTORY)) { /* * Fall back to Windows specific environment variables. HOME is not used. */ if ( !GetEnvironmentVariableW(L"USERPROFILE", &wszPath[0], RTPATH_MAX) || (dwAttr = GetFileAttributesW(&wszPath[0])) == INVALID_FILE_ATTRIBUTES || !(dwAttr & FILE_ATTRIBUTE_DIRECTORY)) { /* %HOMEDRIVE%%HOMEPATH% */ if (!GetEnvironmentVariableW(L"HOMEDRIVE", &wszPath[0], RTPATH_MAX)) return VERR_PATH_NOT_FOUND; size_t const cwc = RTUtf16Len(&wszPath[0]); if ( !GetEnvironmentVariableW(L"HOMEPATH", &wszPath[cwc], RTPATH_MAX - (DWORD)cwc) || (dwAttr = GetFileAttributesW(&wszPath[0])) == INVALID_FILE_ATTRIBUTES || !(dwAttr & FILE_ATTRIBUTE_DIRECTORY)) return VERR_PATH_NOT_FOUND; } } /* * Convert and return. */ return RTUtf16ToUtf8Ex(&wszPath[0], RTSTR_MAX, &pszPath, cchPath, NULL); }
void VBoxVRDPDestroy(const VBOXSERVICEENV *pEnv, void *pInstance) { Log(("VBoxTray: VBoxVRDPDestroy\n")); VBOXVRDPCONTEXT *pCtx = (VBOXVRDPCONTEXT *)pInstance; vboxExperienceRestore (pCtx->level); if (gCtx.hModUxTheme != NIL_RTLDRMOD) { RTLdrClose(gCtx.hModUxTheme); gCtx.hModUxTheme = NIL_RTLDRMOD; } return; }
RTDECL(bool) RTLdrIsLoadable(const char *pszFilename) { /* * Try to load the library. */ RTLDRMOD hLib; int rc = RTLdrLoad(pszFilename, &hLib); if (RT_SUCCESS(rc)) { RTLdrClose(hLib); return true; } return false; }
RTDECL(void *) RTLdrGetSystemSymbol(const char *pszFilename, const char *pszSymbol) { void *pvRet = NULL; RTLDRMOD hLdrMod; int rc = RTLdrLoadSystem(pszFilename, true /*fNoUnload*/, &hLdrMod); if (RT_SUCCESS(rc)) { rc = RTLdrGetSymbol(hLdrMod, pszSymbol, &pvRet); if (RT_FAILURE(rc)) pvRet = NULL; /* paranoia */ RTLdrClose(hLdrMod); } return pvRet; }
void VBoxMMRCleanup(VBOXMMRCONTEXT *pCtx) { if (pCtx->hHook) { UnhookWindowsHookEx(pCtx->hHook); pCtx->hHook = NULL; } if (pCtx->hModHook != NIL_RTLDRMOD) { RTLdrClose(pCtx->hModHook); pCtx->hModHook = NIL_RTLDRMOD; } }
int main(int argc, char **argv) { int rcRet = 0; RTR3InitExe(argc, &argv, 0); /* * If no args, display usage. */ if (argc <= 1) { RTPrintf("Syntax: %s [so/dll [so/dll [..]]\n", argv[0]); return 1; } /* * Iterate the arguments and treat all of them as so/dll paths. */ for (int i = 1; i < argc; i++) { RTLDRMOD hLdrMod = (RTLDRMOD)0xbaadffaa; int rc = RTLdrLoad(argv[i], &hLdrMod); if (RT_SUCCESS(rc)) { RTPrintf("tstLdrLoad: %d - %s\n", i, argv[i]); rc = RTLdrClose(hLdrMod); if (RT_FAILURE(rc)) { RTPrintf("tstLdrLoad: rc=%Rrc RTLdrClose()\n", rc); rcRet++; } } else { RTPrintf("tstLdrLoad: rc=%Rrc RTLdrOpen('%s')\n", rc, argv[i]); rcRet++; } } /* * Summary. */ if (!rcRet) RTPrintf("tstLdrLoad: SUCCESS\n"); else RTPrintf("tstLdrLoad: FAILURE - %d errors\n", rcRet); return !!rcRet; }
void VBoxSeamlessDestroy(const VBOXSERVICEENV *pEnv, void *pInstance) { Log(("VBoxTray: VBoxSeamlessDestroy\n")); VBoxSeamlessSetSupported(FALSE); /* Inform the host that we no longer support the seamless window mode. */ if (gCtx.pfnVBoxHookRemoveWindowTracker) gCtx.pfnVBoxHookRemoveWindowTracker(); if (gCtx.hModHook != NIL_RTLDRMOD) { RTLdrClose(gCtx.hModHook); gCtx.hModHook = NIL_RTLDRMOD; } return; }
void VBoxSeamlessDestroy(void *pInstance) { LogFlowFuncEnter(); PVBOXSEAMLESSCONTEXT pCtx = (PVBOXSEAMLESSCONTEXT)pInstance; AssertPtr(pCtx); VBoxSeamlessSetSupported(FALSE); /* Inform the host that we no longer support the seamless window mode. */ if (pCtx->pfnVBoxHookRemoveWindowTracker) pCtx->pfnVBoxHookRemoveWindowTracker(); if (pCtx->hModHook != NIL_RTLDRMOD) { RTLdrClose(pCtx->hModHook); pCtx->hModHook = NIL_RTLDRMOD; } return; }
bool gLibHalCheckPresence(void) { RTLDRMOD hLibHal; if (ghLibHal != 0 && gCheckedForLibHal == true) return true; if (gCheckedForLibHal == true) return false; if (!RT_SUCCESS(RTLdrLoad(LIB_HAL, &hLibHal))) { return false; } if ( RT_SUCCESS(RTLdrGetSymbol(hLibHal, "dbus_error_init", (void **) &gDBusErrorInit)) && RT_SUCCESS(RTLdrGetSymbol(hLibHal, "dbus_bus_get", (void **) &gDBusBusGet)) && RT_SUCCESS(RTLdrGetSymbol(hLibHal, "dbus_error_free", (void **) &gDBusErrorFree)) && RT_SUCCESS(RTLdrGetSymbol(hLibHal, "dbus_connection_unref", (void **) &gDBusConnectionUnref)) && RT_SUCCESS(RTLdrGetSymbol(hLibHal, "libhal_ctx_new", (void **) &gLibHalCtxNew)) && RT_SUCCESS(RTLdrGetSymbol(hLibHal, "libhal_ctx_set_dbus_connection", (void **) &gLibHalCtxSetDBusConnection)) && RT_SUCCESS(RTLdrGetSymbol(hLibHal, "libhal_ctx_init", (void **) &gLibHalCtxInit)) && RT_SUCCESS(RTLdrGetSymbol(hLibHal, "libhal_manager_find_device_string_match", (void **) &gLibHalFindDeviceStringMatch)) && RT_SUCCESS(RTLdrGetSymbol(hLibHal, "libhal_device_get_property_string", (void **) &gLibHalDeviceGetPropertyString)) && RT_SUCCESS(RTLdrGetSymbol(hLibHal, "libhal_free_string", (void **) &gLibHalFreeString)) && RT_SUCCESS(RTLdrGetSymbol(hLibHal, "libhal_free_string_array", (void **) &gLibHalFreeStringArray)) && RT_SUCCESS(RTLdrGetSymbol(hLibHal, "libhal_ctx_shutdown", (void **) &gLibHalCtxShutdown)) && RT_SUCCESS(RTLdrGetSymbol(hLibHal, "libhal_ctx_free", (void **) &gLibHalCtxFree)) ) { ghLibHal = hLibHal; gCheckedForLibHal = true; return true; } else { RTLdrClose(hLibHal); gCheckedForLibHal = true; return false; } }
int VBoxMMRInit(const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread) { LogFlowFuncEnter(); int rc = RTLdrLoadAppPriv(g_pszMMRDLL, &gCtx.hModHook); if (RT_SUCCESS(rc)) { HOOKPROC pHook = (HOOKPROC)RTLdrGetFunction(gCtx.hModHook, g_pszMMRPROC); if (pHook) { HMODULE hMod = (HMODULE)RTLdrGetNativeHandle(gCtx.hModHook); Assert(hMod != (HMODULE)~(uintptr_t)0); gCtx.hHook = SetWindowsHookEx(WH_CBT, pHook, hMod, 0); if (gCtx.hHook) { *ppInstance = &gCtx; return VINF_SUCCESS; } rc = RTErrConvertFromWin32(GetLastError()); LogFlowFunc(("Error installing hooking proc: %Rrc\n", rc)); } else { LogFlowFunc(("Hooking proc not found\n")); rc = VERR_NOT_FOUND; } RTLdrClose(gCtx.hModHook); gCtx.hModHook = NIL_RTLDRMOD; } else LogFlowFunc(("Hooking library not found (%Rrc)\n", rc)); return rc; }
/** * Adds what we think is an image file to the cache. * * @returns IPRT status code. * @param pszPath Path to the image file. * @param pszExtraSuff Optional extra suffix. Mach-O dSYM hack. * @param pszUuidMapDir The UUID map subdirectory in the cache, if this is * wanted, otherwise NULL. * @param pCfg Configuration data. */ static int rtDbgSymCacheAddImageFile(const char *pszPath, const char *pszExtraSuff, const char *pszUuidMapDir, PCRTDBGSYMCACHEADDCFG pCfg) { /* * Use the loader to open the alleged image file. We need to open it with * arch set to amd64 and x86_32 in order to handle FAT images from the mac * guys (we should actually enumerate archs, but that's currently not * implemented nor necessary for our current use). */ /* Open it as AMD64. */ RTLDRMOD hLdrMod64; int rc = RTLdrOpen(pszPath, RTLDR_O_FOR_DEBUG, RTLDRARCH_AMD64, &hLdrMod64); if (RT_FAILURE(rc)) { if (rc != VERR_LDR_ARCH_MISMATCH) { if (rc != VERR_INVALID_EXE_SIGNATURE) return RTMsgErrorRc(rc, "RTLdrOpen failed opening '%s' [arch=amd64]: %Rrc", pszPath, rc); RTMsgInfo("Skipping '%s', no a recognizable image file...", pszPath); return VINF_SUCCESS; } hLdrMod64 = NIL_RTLDRMOD; } /* Open it as X86. */ RTLDRMOD hLdrMod32; rc = RTLdrOpen(pszPath, RTLDR_O_FOR_DEBUG, RTLDRARCH_X86_32, &hLdrMod32); if (RT_FAILURE(rc)) { if (rc != VERR_LDR_ARCH_MISMATCH) { RTLdrClose(hLdrMod32); return RTMsgErrorRc(rc, "RTLdrOpen failed opening '%s' [arch=x86]: %Rrc", pszPath, rc); } hLdrMod32 = NIL_RTLDRMOD; } /* * Add the file. */ if (hLdrMod32 == NIL_RTLDRMOD) rc = rtDbgSymCacheAddImageFileWorker(pszPath, pCfg, hLdrMod64, pszExtraSuff, pszUuidMapDir); else if (hLdrMod64 == NIL_RTLDRMOD) rc = rtDbgSymCacheAddImageFileWorker(pszPath, pCfg, hLdrMod32, pszExtraSuff, pszUuidMapDir); else { /* * Do we need to add it once or twice? */ RTLDRFMT enmFmt = RTLdrGetFormat(hLdrMod32); bool fSame = enmFmt == RTLdrGetFormat(hLdrMod64); if (fSame && enmFmt == RTLDRFMT_MACHO) { RTUUID Uuid32, Uuid64; int rc32 = RTLdrQueryProp(hLdrMod32, RTLDRPROP_UUID, &Uuid32, sizeof(Uuid32)); int rc64 = RTLdrQueryProp(hLdrMod64, RTLDRPROP_UUID, &Uuid64, sizeof(Uuid64)); fSame = RT_SUCCESS(rc32) == RT_SUCCESS(rc64); if (fSame && RT_SUCCESS(rc32)) fSame = RTUuidCompare(&Uuid32, &Uuid64) == 0; } else if (fSame && enmFmt == RTLDRFMT_PE) { fSame = RTLdrSize(hLdrMod32) == RTLdrSize(hLdrMod64); if (fSame) { uint32_t uTimestamp32, uTimestamp64; int rc32 = RTLdrQueryProp(hLdrMod32, RTLDRPROP_TIMESTAMP_SECONDS, &uTimestamp32, sizeof(uTimestamp32)); int rc64 = RTLdrQueryProp(hLdrMod64, RTLDRPROP_TIMESTAMP_SECONDS, &uTimestamp64, sizeof(uTimestamp64)); fSame = RT_SUCCESS(rc32) == RT_SUCCESS(rc64); if (fSame && RT_SUCCESS(rc32)) fSame = uTimestamp32 == uTimestamp64; } } rc = rtDbgSymCacheAddImageFileWorker(pszPath, pCfg, hLdrMod64, pszExtraSuff, pszUuidMapDir); if (!fSame) { /** @todo should symlink or hardlink this second copy. */ int rc2 = rtDbgSymCacheAddImageFileWorker(pszPath, pCfg, hLdrMod32, pszExtraSuff, pszUuidMapDir); if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) rc = rc2; } } RTLdrClose(hLdrMod32); RTLdrClose(hLdrMod64); return VINF_SUCCESS; }
RTDECL(int) RTCrStoreCreateSnapshotById(PRTCRSTORE phStore, RTCRSTOREID enmStoreId, PRTERRINFO pErrInfo) { AssertReturn(enmStoreId > RTCRSTOREID_INVALID && enmStoreId < RTCRSTOREID_END, VERR_INVALID_PARAMETER); /* * Create an empty in-memory store. */ RTCRSTORE hStore; int rc = RTCrStoreCreateInMem(&hStore, 128); if (RT_SUCCESS(rc)) { *phStore = hStore; /* * Resolve the APIs we need to do this job. */ RTLDRMOD hLdrMod; int rc2 = RTLdrLoadSystem("crypt32.dll", false /*NoUnload*/, &hLdrMod); if (RT_SUCCESS(rc2)) { PFNCERTOPENSTORE pfnOpenStore = NULL; rc2 = RTLdrGetSymbol(hLdrMod, "CertOpenStore", (void **)&pfnOpenStore); PFNCERTCLOSESTORE pfnCloseStore = NULL; if (RT_SUCCESS(rc2)) rc2 = RTLdrGetSymbol(hLdrMod, "CertCloseStore", (void **)&pfnCloseStore); PFNCERTENUMCERTIFICATESINSTORE pfnEnumCerts = NULL; if (RT_SUCCESS(rc2)) rc2 = RTLdrGetSymbol(hLdrMod, "CertEnumCertificatesInStore", (void **)&pfnEnumCerts); if (RT_SUCCESS(rc2)) { /* * Do the work. */ switch (enmStoreId) { case RTCRSTOREID_USER_TRUSTED_CAS_AND_CERTIFICATES: case RTCRSTOREID_SYSTEM_TRUSTED_CAS_AND_CERTIFICATES: { DWORD fStore = enmStoreId == RTCRSTOREID_USER_TRUSTED_CAS_AND_CERTIFICATES ? CERT_SYSTEM_STORE_CURRENT_USER : CERT_SYSTEM_STORE_LOCAL_MACHINE; static PCRTUTF16 const s_apwszStores[] = { L"AuthRoot", L"CA", L"MY", L"Root" }; for (uint32_t i = 0; i < RT_ELEMENTS(s_apwszStores); i++) rc = rtCrStoreAddCertsFromNative(hStore, fStore, s_apwszStores[i], pfnOpenStore, pfnCloseStore, pfnEnumCerts, rc, pErrInfo); break; } default: AssertFailed(); /* implement me */ } } else rc = RTErrInfoSetF(pErrInfo, -rc2, "Error resolving crypt32.dll APIs"); RTLdrClose(hLdrMod); } else rc = RTErrInfoSetF(pErrInfo, -rc2, "Error loading crypt32.dll"); } else RTErrInfoSet(pErrInfo, rc, "RTCrStoreCreateInMem failed"); return rc; }
/** * Resolve APIs not present on older windows versions. */ void VGSvcWinResolveApis(void) { RTLDRMOD hLdrMod; #define RESOLVE_SYMBOL(a_fn) do { RT_CONCAT(g_pfn, a_fn) = (decltype(a_fn) *)RTLdrGetFunction(hLdrMod, #a_fn); } while (0) /* From ADVAPI32.DLL: */ int rc = RTLdrLoadSystem("advapi32.dll", true /*fNoUnload*/, &hLdrMod); AssertRC(rc); if (RT_SUCCESS(rc)) { RESOLVE_SYMBOL(RegisterServiceCtrlHandlerExA); RESOLVE_SYMBOL(ChangeServiceConfig2A); RESOLVE_SYMBOL(GetNamedSecurityInfoA); RESOLVE_SYMBOL(SetEntriesInAclA); RESOLVE_SYMBOL(SetNamedSecurityInfoA); RESOLVE_SYMBOL(LsaNtStatusToWinError); RTLdrClose(hLdrMod); } /* From KERNEL32.DLL: */ rc = RTLdrLoadSystem("kernel32.dll", true /*fNoUnload*/, &hLdrMod); AssertRC(rc); if (RT_SUCCESS(rc)) { RESOLVE_SYMBOL(CreateToolhelp32Snapshot); RESOLVE_SYMBOL(Process32First); RESOLVE_SYMBOL(Process32Next); RESOLVE_SYMBOL(Module32First); RESOLVE_SYMBOL(Module32Next); RESOLVE_SYMBOL(GetSystemTimeAdjustment); RESOLVE_SYMBOL(SetSystemTimeAdjustment); RTLdrClose(hLdrMod); } /* From NTDLL.DLL: */ rc = RTLdrLoadSystem("ntdll.dll", true /*fNoUnload*/, &hLdrMod); AssertRC(rc); if (RT_SUCCESS(rc)) { RESOLVE_SYMBOL(ZwQuerySystemInformation); RTLdrClose(hLdrMod); } /* From IPHLPAPI.DLL: */ rc = RTLdrLoadSystem("iphlpapi.dll", true /*fNoUnload*/, &hLdrMod); if (RT_SUCCESS(rc)) { RESOLVE_SYMBOL(GetAdaptersInfo); RTLdrClose(hLdrMod); } /* From WS2_32.DLL: */ rc = RTLdrLoadSystem("ws2_32.dll", true /*fNoUnload*/, &hLdrMod); if (RT_SUCCESS(rc)) { RESOLVE_SYMBOL(WSAStartup); RESOLVE_SYMBOL(WSACleanup); RESOLVE_SYMBOL(WSASocketA); RESOLVE_SYMBOL(WSAIoctl); RESOLVE_SYMBOL(WSAGetLastError); RESOLVE_SYMBOL(closesocket); RESOLVE_SYMBOL(inet_ntoa); RTLdrClose(hLdrMod); } }
static RTEXITCODE HandleExtractExeSignerCert(int cArgs, char **papszArgs) { /* * Parse arguments. */ static const RTGETOPTDEF s_aOptions[] = { { "--ber", 'b', RTGETOPT_REQ_NOTHING }, { "--cer", 'c', RTGETOPT_REQ_NOTHING }, { "--der", 'd', RTGETOPT_REQ_NOTHING }, { "--exe", 'e', RTGETOPT_REQ_STRING }, { "--output", 'o', RTGETOPT_REQ_STRING }, }; const char *pszExe = NULL; const char *pszOut = NULL; RTLDRARCH enmLdrArch = RTLDRARCH_WHATEVER; uint32_t fCursorFlags = RTASN1CURSOR_FLAGS_DER; RTGETOPTSTATE GetState; int rc = RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST); AssertRCReturn(rc, RTEXITCODE_FAILURE); RTGETOPTUNION ValueUnion; int ch; while ((ch = RTGetOpt(&GetState, &ValueUnion))) { switch (ch) { case 'e': pszExe = ValueUnion.psz; break; case 'o': pszOut = ValueUnion.psz; break; case 'b': fCursorFlags = 0; break; case 'c': fCursorFlags = RTASN1CURSOR_FLAGS_CER; break; case 'd': fCursorFlags = RTASN1CURSOR_FLAGS_DER; break; case 'V': return HandleVersion(cArgs, papszArgs); case 'h': return HelpExtractExeSignerCert(g_pStdOut, RTSIGNTOOLHELP_FULL); case VINF_GETOPT_NOT_OPTION: if (!pszExe) pszExe = ValueUnion.psz; else if (!pszOut) pszOut = ValueUnion.psz; else return RTMsgErrorExit(RTEXITCODE_FAILURE, "Too many file arguments: %s", ValueUnion.psz); break; default: return RTGetOptPrintError(ch, &ValueUnion); } } if (!pszExe) return RTMsgErrorExit(RTEXITCODE_FAILURE, "No executable given."); if (!pszOut) return RTMsgErrorExit(RTEXITCODE_FAILURE, "No output file given."); if (RTPathExists(pszOut)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "The output file '%s' exists.", pszOut); /* * Do it. */ /* Open the executable image and query the PKCS7 info. */ RTLDRMOD hLdrMod; rc = RTLdrOpen(pszExe, RTLDR_O_FOR_VALIDATION, enmLdrArch, &hLdrMod); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error opening executable image '%s': %Rrc", pszExe, rc); RTEXITCODE rcExit = RTEXITCODE_FAILURE; #ifdef DEBUG size_t cbBuf = 64; #else size_t cbBuf = _512K; #endif void *pvBuf = RTMemAlloc(cbBuf); size_t cbRet = 0; rc = RTLdrQueryPropEx(hLdrMod, RTLDRPROP_PKCS7_SIGNED_DATA, NULL /*pvBits*/, pvBuf, cbBuf, &cbRet); if (rc == VERR_BUFFER_OVERFLOW && cbRet < _4M && cbRet > 0) { RTMemFree(pvBuf); cbBuf = cbRet; pvBuf = RTMemAlloc(cbBuf); rc = RTLdrQueryPropEx(hLdrMod, RTLDRPROP_PKCS7_SIGNED_DATA, NULL /*pvBits*/, pvBuf, cbBuf, &cbRet); } if (RT_SUCCESS(rc)) { static RTERRINFOSTATIC s_StaticErrInfo; RTErrInfoInitStatic(&s_StaticErrInfo); /* * Decode the output. */ RTASN1CURSORPRIMARY PrimaryCursor; RTAsn1CursorInitPrimary(&PrimaryCursor, pvBuf, (uint32_t)cbRet, &s_StaticErrInfo.Core, &g_RTAsn1DefaultAllocator, fCursorFlags, "exe"); RTCRPKCS7CONTENTINFO Pkcs7Ci; rc = RTCrPkcs7ContentInfo_DecodeAsn1(&PrimaryCursor.Cursor, 0, &Pkcs7Ci, "pkcs7"); if (RT_SUCCESS(rc)) { if (RTCrPkcs7ContentInfo_IsSignedData(&Pkcs7Ci)) { PCRTCRPKCS7SIGNEDDATA pSd = Pkcs7Ci.u.pSignedData; if (pSd->SignerInfos.cItems == 1) { PCRTCRPKCS7ISSUERANDSERIALNUMBER pISN = &pSd->SignerInfos.paItems[0].IssuerAndSerialNumber; PCRTCRX509CERTIFICATE pCert; pCert = RTCrPkcs7SetOfCerts_FindX509ByIssuerAndSerialNumber(&pSd->Certificates, &pISN->Name, &pISN->SerialNumber); if (pCert) { /* * Write it out. */ RTFILE hFile; rc = RTFileOpen(&hFile, pszOut, RTFILE_O_WRITE | RTFILE_O_DENY_WRITE | RTFILE_O_CREATE); if (RT_SUCCESS(rc)) { uint32_t cbCert = pCert->SeqCore.Asn1Core.cbHdr + pCert->SeqCore.Asn1Core.cb; rc = RTFileWrite(hFile, pCert->SeqCore.Asn1Core.uData.pu8 - pCert->SeqCore.Asn1Core.cbHdr, cbCert, NULL); if (RT_SUCCESS(rc)) { rc = RTFileClose(hFile); if (RT_SUCCESS(rc)) { hFile = NIL_RTFILE; rcExit = RTEXITCODE_SUCCESS; RTMsgInfo("Successfully wrote %u bytes to '%s'", cbCert, pszOut); } else RTMsgError("RTFileClose failed: %Rrc", rc); } else RTMsgError("RTFileWrite failed: %Rrc", rc); RTFileClose(hFile); } else RTMsgError("Error opening '%s': %Rrc", pszOut, rc); } else RTMsgError("Certificate not found."); } else RTMsgError("SignerInfo count: %u", pSd->SignerInfos.cItems); } else RTMsgError("No PKCS7 content: ContentType=%s", Pkcs7Ci.ContentType.szObjId); RTAsn1VtDelete(&Pkcs7Ci.SeqCore.Asn1Core); } else RTMsgError("RTPkcs7ContentInfoDecodeAsn1 failed: %Rrc - %s", rc, s_StaticErrInfo.szMsg); } else RTMsgError("RTLDRPROP_PKCS7_SIGNED_DATA failed on '%s': %Rrc", pszExe, rc); RTMemFree(pvBuf); rc = RTLdrClose(hLdrMod); if (RT_FAILURE(rc)) rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "RTLdrClose failed: %Rrc\n", rc); return rcExit; }
/** * One test iteration with one file. * * The test is very simple, we load the file three times * into two different regions. The first two into each of the * regions the for compare usage. The third is loaded into one * and then relocated between the two and other locations a few times. * * @returns number of errors. * @param pszFilename The file to load the mess with. */ static int testLdrOne(const char *pszFilename) { RTLDRMOD hLdrMod; int rc = RTLdrOpen(pszFilename, 0, RTLDRARCH_WHATEVER, &hLdrMod); if (RT_FAILURE(rc)) { RTPrintf("tstLdr: Failed to open '%s', rc=%Rrc. aborting test.\n", pszFilename, rc); Assert(hLdrMod == NIL_RTLDRMOD); return 1; } int rcRet = 1; size_t cb = RTLdrSize(hLdrMod); if (cb > 100) { void *pvBits = RTMemAlloc(cb); if (pvBits) { RTUINTPTR Addr = 0xc0000000; rc = RTLdrGetBits(hLdrMod, pvBits, Addr, testGetImport, NULL); if (RT_SUCCESS(rc)) { RTUINTPTR Value; rc = RTLdrGetSymbolEx(hLdrMod, pvBits, Addr, "Entrypoint", &Value); if (RT_SUCCESS(rc)) { unsigned off = Value - Addr; if (off < cb) { DISCPUSTATE Cpu; memset(&Cpu, 0, sizeof(Cpu)); Cpu.mode = CPUMODE_32BIT; if (MyDisBlock(&Cpu, (uintptr_t)pvBits + off, 200, Addr - (uintptr_t)pvBits)) { RTUINTPTR Addr2 = 0xd0000000; rc = RTLdrRelocate(hLdrMod, pvBits, Addr2, Addr, testGetImport, NULL); if (RT_SUCCESS(rc)) { if (MyDisBlock(&Cpu, (uintptr_t)pvBits + off, 200, Addr2 - (uintptr_t)pvBits)) rcRet = 0; else RTPrintf("tstLdr: Disassembly failed!\n"); } else RTPrintf("tstLdr: Relocate of '%s' from %#x to %#x failed, rc=%Rrc. Aborting test.\n", pszFilename, Addr2, Addr, rc); } else RTPrintf("tstLdr: Disassembly failed!\n"); } else RTPrintf("tstLdr: Invalid value for symbol '%s' in '%s'. off=%#x Value=%#x\n", "Entrypoint", pszFilename, off, Value); } else RTPrintf("tstLdr: Failed to resolve symbol '%s' in '%s', rc=%Rrc.\n", "Entrypoint", pszFilename, rc); } else RTPrintf("tstLdr: Failed to get bits for '%s', rc=%Rrc. aborting test\n", pszFilename, rc); RTMemFree(pvBits); } else RTPrintf("tstLdr: Out of memory '%s' cb=%d. aborting test.\n", pszFilename, cb); } else RTPrintf("tstLdr: Size is odd, '%s'. aborting test.\n", pszFilename); /* cleanup */ rc = RTLdrClose(hLdrMod); if (RT_FAILURE(rc)) { RTPrintf("tstLdr: Failed to close '%s', rc=%Rrc.\n", pszFilename, rc); rcRet++; } return rcRet; }
/** * One test iteration with one file. * * The test is very simple, we load the file three times * into two different regions. The first two into each of the * regions the for compare usage. The third is loaded into one * and then relocated between the two and other locations a few times. * * @returns number of errors. * @param pszFilename The file to load the mess with. */ static int testLdrOne(const char *pszFilename) { int cErrors = 0; size_t cbImage = 0; struct Load { RTLDRMOD hLdrMod; void *pvBits; size_t cbBits; const char *pszName; } aLoads[6] = { { NULL, NULL, 0, "foo" }, { NULL, NULL, 0, "bar" }, { NULL, NULL, 0, "foobar" }, { NULL, NULL, 0, "kLdr-foo" }, { NULL, NULL, 0, "kLdr-bar" }, { NULL, NULL, 0, "kLdr-foobar" } }; unsigned i; int rc; /* * Load them. */ for (i = 0; i < RT_ELEMENTS(aLoads); i++) { if (!strncmp(aLoads[i].pszName, RT_STR_TUPLE("kLdr-"))) rc = RTLdrOpenkLdr(pszFilename, 0, RTLDRARCH_WHATEVER, &aLoads[i].hLdrMod); else rc = RTLdrOpen(pszFilename, 0, RTLDRARCH_WHATEVER, &aLoads[i].hLdrMod); if (RT_FAILURE(rc)) { RTPrintf("tstLdr-4: Failed to open '%s'/%d, rc=%Rrc. aborting test.\n", pszFilename, i, rc); Assert(aLoads[i].hLdrMod == NIL_RTLDRMOD); cErrors++; break; } /* size it */ size_t cb = RTLdrSize(aLoads[i].hLdrMod); if (cbImage && cb != cbImage) { RTPrintf("tstLdr-4: Size mismatch '%s'/%d. aborting test.\n", pszFilename, i); cErrors++; break; } aLoads[i].cbBits = cbImage = cb; /* Allocate bits. */ aLoads[i].pvBits = RTMemExecAlloc(cb); if (!aLoads[i].pvBits) { RTPrintf("tstLdr-4: Out of memory '%s'/%d cbImage=%d. aborting test.\n", pszFilename, i, cbImage); cErrors++; break; } /* Get the bits. */ rc = RTLdrGetBits(aLoads[i].hLdrMod, aLoads[i].pvBits, (uintptr_t)aLoads[i].pvBits, testGetImport, NULL); if (RT_FAILURE(rc)) { RTPrintf("tstLdr-4: Failed to get bits for '%s'/%d, rc=%Rrc. aborting test\n", pszFilename, i, rc); cErrors++; break; } } /* * Execute the code. */ if (!cErrors) { for (i = 0; i < RT_ELEMENTS(aLoads); i += 1) { /* get the pointer. */ RTUINTPTR Value; rc = RTLdrGetSymbolEx(aLoads[i].hLdrMod, aLoads[i].pvBits, (uintptr_t)aLoads[i].pvBits, UINT32_MAX, "DisasmTest1", &Value); if (rc == VERR_SYMBOL_NOT_FOUND) rc = RTLdrGetSymbolEx(aLoads[i].hLdrMod, aLoads[i].pvBits, (uintptr_t)aLoads[i].pvBits, UINT32_MAX, "_DisasmTest1", &Value); if (RT_FAILURE(rc)) { RTPrintf("tstLdr-4: Failed to get symbol \"DisasmTest1\" from load #%d: %Rrc\n", i, rc); cErrors++; break; } DECLCALLBACKPTR(int, pfnDisasmTest1)(void) = (DECLCALLBACKPTR(int, RT_NOTHING)(void))(uintptr_t)Value; /* eeeh. */ RTPrintf("tstLdr-4: pfnDisasmTest1=%p / add-symbol-file %s %#x\n", pfnDisasmTest1, pszFilename, aLoads[i].pvBits); /* call the test function. */ rc = pfnDisasmTest1(); if (rc) { RTPrintf("tstLdr-4: load #%d Test1 -> %#x\n", i, rc); cErrors++; } } } /* * Clean up. */ for (i = 0; i < RT_ELEMENTS(aLoads); i++) { if (aLoads[i].pvBits) RTMemExecFree(aLoads[i].pvBits, aLoads[i].cbBits); if (aLoads[i].hLdrMod) { rc = RTLdrClose(aLoads[i].hLdrMod); if (RT_FAILURE(rc)) { RTPrintf("tstLdr-4: Failed to close '%s' i=%d, rc=%Rrc.\n", pszFilename, i, rc); cErrors++; } } } return cErrors; }
/** * Retrieves the module name of a given process. * * @return IPRT status code. * @param pProc * @param pszBuf * @param cbBuf */ static int VBoxServiceVMInfoWinProcessesGetModuleName(PVBOXSERVICEVMINFOPROC const pProc, TCHAR *pszName, size_t cbName) { AssertPtrReturn(pProc, VERR_INVALID_POINTER); AssertPtrReturn(pszName, VERR_INVALID_POINTER); AssertReturn(cbName, VERR_INVALID_PARAMETER); OSVERSIONINFOEX OSInfoEx; RT_ZERO(OSInfoEx); OSInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); if ( !GetVersionEx((LPOSVERSIONINFO) &OSInfoEx) || OSInfoEx.dwPlatformId != VER_PLATFORM_WIN32_NT) { /* Platform other than NT (e.g. Win9x) not supported. */ return VERR_NOT_SUPPORTED; } int rc = VINF_SUCCESS; DWORD dwFlags = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ; if (OSInfoEx.dwMajorVersion >= 6 /* Vista or later */) dwFlags = 0x1000; /* = PROCESS_QUERY_LIMITED_INFORMATION; less privileges needed. */ HANDLE h = OpenProcess(dwFlags, FALSE, pProc->id); if (h == NULL) { DWORD dwErr = GetLastError(); if (g_cVerbosity) VBoxServiceError("Unable to open process with PID=%ld, error=%ld\n", pProc->id, dwErr); rc = RTErrConvertFromWin32(dwErr); } else { /* Since GetModuleFileNameEx has trouble with cross-bitness stuff (32-bit apps cannot query 64-bit apps and vice verse) we have to use a different code path for Vista and up. */ /* Note: For 2000 + NT4 we might just use GetModuleFileName() instead. */ if (OSInfoEx.dwMajorVersion >= 6 /* Vista or later */) { /* Loading the module and getting the symbol for each and every process is expensive * -- since this function (at the moment) only is used for debugging purposes it's okay. */ RTLDRMOD hMod; rc = RTLdrLoad("kernel32.dll", &hMod); if (RT_SUCCESS(rc)) { PFNQUERYFULLPROCESSIMAGENAME pfnQueryFullProcessImageName; rc = RTLdrGetSymbol(hMod, "QueryFullProcessImageNameA", (void **)&pfnQueryFullProcessImageName); if (RT_SUCCESS(rc)) { DWORD dwLen = cbName / sizeof(TCHAR); if (!pfnQueryFullProcessImageName(h, 0 /*PROCESS_NAME_NATIVE*/, pszName, &dwLen)) rc = VERR_ACCESS_DENIED; } RTLdrClose(hMod); } } else { if (!GetModuleFileNameEx(h, NULL /* Get main executable */, pszName, cbName / sizeof(TCHAR))) rc = VERR_ACCESS_DENIED; } CloseHandle(h); } return rc; }