From 9360fd5ee728229cd43eec657f8d695c114ca91f Mon Sep 17 00:00:00 2001 From: DavidXanatos <3890945+DavidXanatos@users.noreply.github.com> Date: Sun, 21 Jul 2024 20:41:14 +0200 Subject: [PATCH] 1.14.5 --- CHANGELOG.md | 1 + Sandboxie/core/drv/process_force.c | 100 ++++--- SandboxiePlus/SandMan/Forms/OptionsWindow.ui | 266 ++++++++++-------- .../SandMan/Windows/OptionsForce.cpp | 71 ++++- .../SandMan/Windows/OptionsWindow.cpp | 15 +- SandboxiePlus/SandMan/Windows/OptionsWindow.h | 7 +- 6 files changed, 289 insertions(+), 171 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a368e46d..023980d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - added Language Spoof "CustomLCID=1033" [#4024](https://github.com/sandboxie-plus/Sandboxie/pull/4024) (thanks Yeyixiao) - added option to always run the sandman UI as admin [#4090](https://github.com/sandboxie-plus/Sandboxie/issues/4090) - added Proxy exclusion [#4036](https://github.com/sandboxie-plus/Sandboxie/issues/4036) +- added "ForceChildren=Program.exe" [#4070](https://github.com/sandboxie-plus/Sandboxie/issues/4070) ### Fixed - fixed two supporter certificate popping up every time a Sandboxes' settings are opened [#4074](https://github.com/sandboxie-plus/Sandboxie/issues/4074) diff --git a/Sandboxie/core/drv/process_force.c b/Sandboxie/core/drv/process_force.c index 927d4b00..5220fa0a 100644 --- a/Sandboxie/core/drv/process_force.c +++ b/Sandboxie/core/drv/process_force.c @@ -43,6 +43,7 @@ typedef struct _FORCE_BOX { BOX *box; LIST ForceFolder; LIST ForceProcess; + LIST ForceChildren; LIST AlertFolder; LIST AlertProcess; LIST HostInjectProcess; @@ -108,12 +109,12 @@ static void Process_GetDocArg( static BOOLEAN Process_IsDcomLaunchParent(HANDLE ParentId); -static BOOLEAN Process_IsWindowsExplorerParent(HANDLE ParentId); +//static BOOLEAN Process_IsWindowsExplorerParent(HANDLE ParentId); static BOOLEAN Process_IsImmersiveProcess( PEPROCESS ProcessObject, HANDLE ParentId, ULONG SessionId); -static BOOLEAN Process_IsProcessParent(HANDLE ParentId, WCHAR* Name); +//static BOOLEAN Process_IsProcessParent(HANDLE ParentId, WCHAR* Name); void Process_CreateForceData( LIST *boxes, const WCHAR *SidString, ULONG SessionId); @@ -126,7 +127,7 @@ static BOX *Process_CheckForceFolder( LIST *boxes, const WCHAR *path, BOOLEAN alert, ULONG *IsAlert); static BOX *Process_CheckForceProcess( - LIST *boxes, const WCHAR *name, BOOLEAN alert, ULONG *IsAlert, HANDLE parent); + LIST *boxes, const WCHAR *name, BOOLEAN alert, ULONG *IsAlert, const WCHAR *ParentName); static void Process_CheckAlertFolder( LIST *boxes, const WCHAR *path, ULONG *IsAlert); @@ -166,6 +167,11 @@ _FX BOX *Process_GetForcedStartBox( BOOLEAN dfp_already_added; BOOLEAN same_image_name; + + void* nbuf; + ULONG nlen; + WCHAR* ParentName; + check_force = TRUE; // @@ -215,6 +221,9 @@ _FX BOX *Process_GetForcedStartBox( return NULL; } + Process_GetProcessName( + Driver_Pool, (ULONG_PTR)ParentId, &nbuf, &nlen, &ParentName); + // // initialize some more state before checking process // @@ -261,7 +270,7 @@ _FX BOX *Process_GetForcedStartBox( if ((! box) && (! alert)) { box = Process_CheckForceProcess( - &boxes, ImageName, force_alert, &alert, ParentId); + &boxes, ImageName, force_alert, &alert, ParentName); } if ((! box) && CurDir && !is_start_exe && (! alert)) { @@ -368,6 +377,9 @@ _FX BOX *Process_GetForcedStartBox( Process_DeleteForceData(&boxes); + if (nbuf) + Mem_Free(nbuf, nlen); + if (DocArg) Mem_Free(DocArg, DocArg_len); @@ -795,32 +807,31 @@ _FX BOOLEAN Process_IsDcomLaunchParent(HANDLE ParentId) //--------------------------------------------------------------------------- // Process_IsProcessParent -// //--------------------------------------------------------------------------- -_FX BOOLEAN Process_IsProcessParent(HANDLE ParentId, WCHAR* Name) -{ - BOOLEAN retval = FALSE; - - void* nbuf; - ULONG nlen; - WCHAR* nptr; - - Process_GetProcessName( - Driver_Pool, (ULONG_PTR)ParentId, &nbuf, &nlen, &nptr); - if (nbuf) { - - if (_wcsicmp(nptr, Name) == 0) { - - retval = TRUE; - } - - Mem_Free(nbuf, nlen); - } - - return retval; -} +//_FX BOOLEAN Process_IsProcessParent(HANDLE ParentId, WCHAR* Name) +//{ +// BOOLEAN retval = FALSE; +// +// void* nbuf; +// ULONG nlen; +// WCHAR* nptr; +// +// Process_GetProcessName( +// Driver_Pool, (ULONG_PTR)ParentId, &nbuf, &nlen, &nptr); +// if (nbuf) { +// +// if (_wcsicmp(nptr, Name) == 0) { +// +// retval = TRUE; +// } +// +// Mem_Free(nbuf, nlen); +// } +// +// return retval; +//} //--------------------------------------------------------------------------- @@ -828,10 +839,10 @@ _FX BOOLEAN Process_IsProcessParent(HANDLE ParentId, WCHAR* Name) //--------------------------------------------------------------------------- -_FX BOOLEAN Process_IsWindowsExplorerParent(HANDLE ParentId) -{ - return Process_IsProcessParent(ParentId,L"explorer.exe"); -} +//_FX BOOLEAN Process_IsWindowsExplorerParent(HANDLE ParentId) +//{ +// return Process_IsProcessParent(ParentId,L"explorer.exe"); +//} //--------------------------------------------------------------------------- @@ -1112,6 +1123,7 @@ _FX void Process_CreateForceData( List_Init(&box->ForceFolder); List_Init(&box->ForceProcess); + List_Init(&box->ForceChildren); List_Init(&box->AlertFolder); List_Init(&box->AlertProcess); List_Init(&box->HostInjectProcess); @@ -1130,6 +1142,12 @@ _FX void Process_CreateForceData( Process_AddForceProcesses(&box->ForceProcess, L"ForceProcess", section); + // + // scan list of ForceChildren settings for the box + // + + Process_AddForceProcesses(&box->ForceChildren, L"ForceChildren", section); + // // scan list of AlertFolder settings for the box // @@ -1220,6 +1238,7 @@ _FX void Process_DeleteForceData(LIST *boxes) Process_DeleteForceDataFolders(&box->ForceFolder); Process_DeleteForceDataProcesses(&box->ForceProcess); + Process_DeleteForceDataProcesses(&box->ForceChildren); Process_DeleteForceDataFolders(&box->AlertFolder); Process_DeleteForceDataProcesses(&box->AlertProcess); Process_DeleteForceDataProcesses(&box->HostInjectProcess); @@ -1415,7 +1434,7 @@ _FX BOOLEAN Process_CheckForceProcessList( _FX BOX *Process_CheckForceProcess( - LIST *boxes, const WCHAR *name, BOOLEAN alert, ULONG *IsAlert, HANDLE ParentId) + LIST *boxes, const WCHAR *name, BOOLEAN alert, ULONG *IsAlert, const WCHAR *ParentName) { FORCE_BOX *box; @@ -1435,10 +1454,19 @@ _FX BOX *Process_CheckForceProcess( return box->box; } - //if (Process_IsWindowsExplorerParent(ParentId) && Conf_Get_Boolean(box->box->name, L"ForceExplorerChild", 0, FALSE)) { - // if(_wcsicmp(name,L"Sandman.exe")!=0) - // return box->box; - //} + if (ParentName && Process_CheckForceProcessList(box->box, &box->ForceChildren, ParentName) && _wcsicmp(name, L"Sandman.exe") != 0) { // except for sandman exe + if (alert) { + *IsAlert = 1; + return NULL; + } + + return box->box; + } + + //if (Process_IsWindowsExplorerParent(ParentId) && Conf_Get_Boolean(box->box->name, L"ForceExplorerChild", 0, FALSE)) { + // if (_wcsicmp(name, L"Sandman.exe") != 0) + // return box->box; + //} box = List_Next(box); } diff --git a/SandboxiePlus/SandMan/Forms/OptionsWindow.ui b/SandboxiePlus/SandMan/Forms/OptionsWindow.ui index fabe859e..9f4ac0f3 100644 --- a/SandboxiePlus/SandMan/Forms/OptionsWindow.ui +++ b/SandboxiePlus/SandMan/Forms/OptionsWindow.ui @@ -45,7 +45,7 @@ QTabWidget::North - 1 + 3 @@ -1981,7 +1981,7 @@ - 1 + 0 @@ -2012,60 +2012,18 @@ - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - 0 - 0 - - - - - 0 - 23 - - - - Force Folder - - - - + Show Templates - - - - true + + + + Remove - - - Type - - - - - Name - - @@ -2087,20 +2045,81 @@ - - - - Remove + + + + true + + + Type + + + + + Name + + - + Disable forced Process and Folder for this sandbox + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 0 + 0 + + + + + 0 + 23 + + + + Force Folder + + + + + + + + 0 + 0 + + + + + 0 + 23 + + + + Force Children + + + @@ -2124,55 +2143,6 @@ - - - - - 0 - 0 - - - - - 0 - 23 - - - - Breakout Program - - - - - - - Programs entered here will be allowed to break out of this sandbox when they start. It is also possible to capture them into another sandbox, for example to have your web browser always open in a dedicated box. - - - true - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Show Templates - - - @@ -2186,25 +2156,6 @@ - - - - - 0 - 0 - - - - - 0 - 23 - - - - Breakout Folder - - - @@ -2222,6 +2173,16 @@ + + + + Programs entered here will be allowed to break out of this sandbox when they start. It is also possible to capture them into another sandbox, for example to have your web browser always open in a dedicated box. + + + true + + + @@ -2229,6 +2190,64 @@ + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 0 + 0 + + + + + 0 + 23 + + + + Breakout Program + + + + + + + Show Templates + + + + + + + + 0 + 0 + + + + + 0 + 23 + + + + Breakout Folder + + + @@ -4684,6 +4703,7 @@ This is done to prevent rogue processes inside the sandbox from creating a renam + 50 false true @@ -4763,6 +4783,7 @@ This is done to prevent rogue processes inside the sandbox from creating a renam + 75 true true @@ -4797,6 +4818,7 @@ This is done to prevent rogue processes inside the sandbox from creating a renam + 75 true true diff --git a/SandboxiePlus/SandMan/Windows/OptionsForce.cpp b/SandboxiePlus/SandMan/Windows/OptionsForce.cpp index f52be6d9..38706f10 100644 --- a/SandboxiePlus/SandMan/Windows/OptionsForce.cpp +++ b/SandboxiePlus/SandMan/Windows/OptionsForce.cpp @@ -19,6 +19,12 @@ void COptionsWindow::LoadForced() foreach(const QString& Value, m_pBox->GetTextList("ForceProcessDisabled", m_Template)) AddForcedEntry(Value, (int)eProcess, true); + foreach(const QString& Value, m_pBox->GetTextList("ForceChildren", m_Template)) + AddForcedEntry(Value, (int)eParent); + + foreach(const QString& Value, m_pBox->GetTextList("ForceChildrenDisabled", m_Template)) + AddForcedEntry(Value, (int)eParent, true); + foreach(const QString& Value, m_pBox->GetTextList("ForceFolder", m_Template)) AddForcedEntry(Value, (int)ePath); @@ -41,6 +47,11 @@ void COptionsWindow::LoadForced() foreach(const QString& Value, m_pBox->GetTextList("BreakoutFolderDisabled", m_Template)) AddBreakoutEntry(Value, (int)ePath, true); + foreach(const QString& Value, m_pBox->GetTextList("BreakoutDocument", m_Template)) + AddBreakoutEntry(Value, (int)eText); + + foreach(const QString& Value, m_pBox->GetTextList("BreakoutDocumentDisabled", m_Template)) + AddBreakoutEntry(Value, (int)eText, true); LoadForcedTmpl(); LoadBreakoutTmpl(); @@ -57,6 +68,9 @@ void COptionsWindow::LoadForcedTmpl(bool bUpdate) foreach(const QString& Value, m_pBox->GetTextListTmpl("ForceProcess", Template)) AddForcedEntry(Value, (int)eProcess, false, Template); + foreach(const QString& Value, m_pBox->GetTextListTmpl("ForceChildren", Template)) + AddForcedEntry(Value, (int)eParent, false, Template); + foreach(const QString& Value, m_pBox->GetTextListTmpl("ForceFolder", Template)) AddForcedEntry(Value, (int)ePath, false, Template); } @@ -108,9 +122,16 @@ void COptionsWindow::AddForcedEntry(const QString& Name, int type, bool disabled { QTreeWidgetItem* pItem = new QTreeWidgetItem(); pItem->setCheckState(0, disabled ? Qt::Unchecked : Qt::Checked); - pItem->setText(0, (type == (int)eProcess ? tr("Process") : tr("Folder")) + (Template.isEmpty() ? "" : (" (" + Template + ")"))); + QString Type; + switch (type) + { + case eProcess: Type = tr("Process"); break; + case ePath: Type = tr("Folder"); break; + case eParent: Type = tr("Children"); break; + } + pItem->setText(0, Type + (Template.isEmpty() ? "" : (" (" + Template + ")"))); pItem->setData(0, Qt::UserRole, Template.isEmpty() ? type : (int)eTemplate); - SetProgramItem(Name, pItem, (int)eProcess); + SetProgramItem(Name, pItem, 1); pItem->setFlags(pItem->flags() | Qt::ItemIsEditable); ui.treeForced->addTopLevelItem(pItem); } @@ -119,9 +140,16 @@ void COptionsWindow::AddBreakoutEntry(const QString& Name, int type, bool disabl { QTreeWidgetItem* pItem = new QTreeWidgetItem(); pItem->setCheckState(0, disabled ? Qt::Unchecked : Qt::Checked); - pItem->setText(0, (type == (int)eProcess ? tr("Process") : tr("Folder")) + (Template.isEmpty() ? "" : (" (" + Template + ")"))); + QString Type; + switch (type) + { + case eProcess: Type = tr("Process"); break; + case ePath: Type = tr("Folder"); break; + } + pItem->setText(0, Type + (Template.isEmpty() ? "" : (" (" + Template + ")"))); + pItem->setData(0, Qt::UserRole, Template.isEmpty() ? type : (int)eTemplate); - SetProgramItem(Name, pItem, (int)eProcess); + SetProgramItem(Name, pItem, 1, QString(), type == eProcess); pItem->setFlags(pItem->flags() | Qt::ItemIsEditable); ui.treeBreakout->addTopLevelItem(pItem); } @@ -130,6 +158,8 @@ void COptionsWindow::SaveForced() { QStringList ForceProcess; QStringList ForceProcessDisabled; + QStringList ForceChildren; + QStringList ForceChildrenDisabled; QStringList ForceFolder; QStringList ForceFolderDisabled; @@ -143,19 +173,22 @@ void COptionsWindow::SaveForced() if (pItem->checkState(0) == Qt::Checked) { switch (Type) { case eProcess: ForceProcess.append(pItem->data(1, Qt::UserRole).toString()); break; - case ePath: ForceFolder.append(pItem->data(1, Qt::UserRole).toString()); break; + case eParent: ForceChildren.append(pItem->data(1, Qt::UserRole).toString()); break; + case ePath: ForceFolder.append(pItem->data(1, Qt::UserRole).toString()); break; } } else { switch (Type) { case eProcess: ForceProcessDisabled.append(pItem->data(1, Qt::UserRole).toString()); break; - case ePath: ForceFolderDisabled.append(pItem->data(1, Qt::UserRole).toString()); break; + case ePath: ForceFolderDisabled.append(pItem->data(1, Qt::UserRole).toString()); break; } } } WriteTextList("ForceProcess", ForceProcess); WriteTextList("ForceProcessDisabled", ForceProcessDisabled); + WriteTextList("ForceChildren", ForceChildren); + WriteTextList("ForceChildrenDisabled", ForceChildrenDisabled); WriteTextList("ForceFolder", ForceFolder); WriteTextList("ForceFolderDisabled", ForceFolderDisabled); @@ -237,6 +270,28 @@ void COptionsWindow::OnBreakoutBrowse() OnForcedChanged(); } +void COptionsWindow::OnForceChild() +{ + QString Value = SelectProgram(); + if (Value.isEmpty()) + return; + if (!CheckForcedItem(Value, (int)eParent)) + return; + AddForcedEntry(Value, (int)eParent); + OnForcedChanged(); +} + +void COptionsWindow::OnForceBrowseChild() +{ + QString Value = QFileDialog::getOpenFileName(this, tr("Select Executable File"), "", tr("Executable Files (*.exe)")); + if (Value.isEmpty()) + return; + if (!CheckForcedItem(Value, (int)eParent)) + return; + AddForcedEntry(Split2(Value, "/", true).second, (int)eParent); + OnForcedChanged(); +} + void COptionsWindow::OnForceDir() { QString Value = QFileDialog::getExistingDirectory(this, tr("Select Directory")).replace("/", "\\"); @@ -281,7 +336,7 @@ bool COptionsWindow::CheckForcedItem(const QString& Value, int type) QString winPath = QString::fromUtf8(qgetenv("SystemRoot")); - if (type == eProcess) + if (type == eProcess || type == eParent) { if (Value.compare("explorer.exe", Qt::CaseInsensitive) == 0 || Value.compare(winPath + "\\explorer.exe", Qt::CaseInsensitive) == 0) bDangerous = true; @@ -292,7 +347,7 @@ bool COptionsWindow::CheckForcedItem(const QString& Value, int type) else if (Value.contains("sandman.exe", Qt::CaseInsensitive)) bDangerous = true; } - else + else if (type == ePath) { if (Value.compare(winPath.left(3), Qt::CaseInsensitive) == 0) bDangerous = true; // SystemDrive (C:\) diff --git a/SandboxiePlus/SandMan/Windows/OptionsWindow.cpp b/SandboxiePlus/SandMan/Windows/OptionsWindow.cpp index bea8481b..a419c82b 100644 --- a/SandboxiePlus/SandMan/Windows/OptionsWindow.cpp +++ b/SandboxiePlus/SandMan/Windows/OptionsWindow.cpp @@ -463,9 +463,15 @@ COptionsWindow::COptionsWindow(const QSharedPointer& pBox, const QStri // Force connect(ui.btnForceProg, SIGNAL(clicked(bool)), this, SLOT(OnForceProg())); QMenu* pFileBtnMenu = new QMenu(ui.btnForceProg); - pFileBtnMenu->addAction(tr("Browse for File"), this, SLOT(OnForceBrowse())); + pFileBtnMenu->addAction(tr("Browse for File"), this, SLOT(OnForceBrowseProg())); ui.btnForceProg->setPopupMode(QToolButton::MenuButtonPopup); ui.btnForceProg->setMenu(pFileBtnMenu); + + connect(ui.btnForceChild, SIGNAL(clicked(bool)), this, SLOT(OnForceChild())); + pFileBtnMenu = new QMenu(ui.btnForceChild); + pFileBtnMenu->addAction(tr("Browse for File"), this, SLOT(OnForceBrowseChild())); + ui.btnForceChild->setPopupMode(QToolButton::MenuButtonPopup); + ui.btnForceChild->setMenu(pFileBtnMenu); connect(ui.btnForceDir, SIGNAL(clicked(bool)), this, SLOT(OnForceDir())); connect(ui.btnDelForce, SIGNAL(clicked(bool)), this, SLOT(OnDelForce())); connect(ui.chkShowForceTmpl, SIGNAL(clicked(bool)), this, SLOT(OnShowForceTmpl())); @@ -631,8 +637,11 @@ COptionsWindow::COptionsWindow(const QSharedPointer& pBox, const QStri if (iOptionTree == 2) iOptionTree = iViewMode == 2 ? 1 : 0; - if (iOptionTree) + if (iOptionTree) { + m_HoldChange = true; OnSetTree(); + m_HoldChange = false; + } else { //this->setMinimumHeight(490); this->setMinimumHeight(390); @@ -1193,7 +1202,7 @@ void COptionsWindow::UpdateCurrentTab() } else if (m_pCurrentTab == ui.tabDNS || m_pCurrentTab == ui.tabNetProxy) { - if (!m_pCurrentTab->isEnabled()) + if (!m_HoldChange && !m_pCurrentTab->isEnabled()) theGUI->CheckCertificate(this, 2); } else if (m_pCurrentTab == ui.tabCOM) { diff --git a/SandboxiePlus/SandMan/Windows/OptionsWindow.h b/SandboxiePlus/SandMan/Windows/OptionsWindow.h index a8fbddd6..a5209695 100644 --- a/SandboxiePlus/SandMan/Windows/OptionsWindow.h +++ b/SandboxiePlus/SandMan/Windows/OptionsWindow.h @@ -29,7 +29,8 @@ public: eProcess, ePath, eText, - eTemplate + eTemplate, + eParent }; signals: @@ -84,7 +85,9 @@ private slots: void OnGroupsChanged(QTreeWidgetItem* pItem, int Index) { m_GroupsChanged = true; OnOptChanged(); } void OnForceProg(); - void OnForceBrowse(); + void OnForceBrowseProg(); + void OnForceChild(); + void OnForceBrowseChild(); void OnForceDir(); void OnDelForce(); void OnShowForceTmpl() { LoadForcedTmpl(true); }