This commit is contained in:
DavidXanatos 2022-02-02 19:31:03 +01:00
parent a20eaeff48
commit 28c88634ce
12 changed files with 165 additions and 105 deletions

View File

@ -381,16 +381,16 @@ _FX HANDLE Gui_GetPropW(HWND hWnd, const WCHAR *lpString)
ULONG LastError = GetLastError();
if (! Gui_IsWindowAccessible(hWnd)) {
if (hWnd != __sys_GetDesktopWindow()) {
SetLastError(ERROR_INVALID_WINDOW_HANDLE);
return NULL;
}
BOOLEAN IsDesktop = (hWnd == __sys_GetDesktopWindow());
if (! Gui_IsWindowAccessible(hWnd) && !IsDesktop) {
SetLastError(ERROR_INVALID_WINDOW_HANDLE);
return NULL;
}
lpString = Gui_ReplaceAtom(lpString);
if (!Gui_UseProxyService || Gui_IsSameBox(hWnd, NULL, NULL))
if (!Gui_UseProxyService || Gui_IsSameBox(hWnd, NULL, NULL) || IsDesktop)
return __sys_GetPropW(hWnd, lpString);
else
return Gui_GetPropCommon(hWnd, lpString, TRUE, LastError);
@ -422,16 +422,16 @@ _FX HANDLE Gui_GetPropA(HWND hWnd, const UCHAR *lpString)
ULONG LastError = GetLastError();
if (! Gui_IsWindowAccessible(hWnd)) {
if (hWnd != __sys_GetDesktopWindow()) {
SetLastError(ERROR_INVALID_WINDOW_HANDLE);
return NULL;
}
BOOLEAN IsDesktop = (hWnd == __sys_GetDesktopWindow());
if (! Gui_IsWindowAccessible(hWnd) && !IsDesktop) {
SetLastError(ERROR_INVALID_WINDOW_HANDLE);
return NULL;
}
lpString = Gui_ReplaceAtom(lpString);
if (!Gui_UseProxyService || Gui_IsSameBox(hWnd, NULL, NULL))
if (!Gui_UseProxyService || Gui_IsSameBox(hWnd, NULL, NULL) || IsDesktop)
return __sys_GetPropA(hWnd, lpString);
else
return Gui_GetPropCommon(hWnd, lpString, TRUE, LastError);

View File

@ -973,7 +973,7 @@ _FX BOOL Proc_CreateProcessInternalW(
if(lpArguments)
wcscat(mybuf, lpArguments);
if (! lpCurrentDirectory) {
if (! lpCurrentDirectory) { // lpCurrentDirectory must not be NULL
lpCurrentDirectory = Dll_Alloc(sizeof(WCHAR) * 8192);
if (lpCurrentDirectory) {
((WCHAR*)lpCurrentDirectory)[0] = L'\0';
@ -992,7 +992,12 @@ _FX BOOL Proc_CreateProcessInternalW(
Dll_Free(mybuf);
goto finish;
//
// when the service returns ERROR_NOT_SUPPORTED this means we should take the normal process creation route
//
if(err != ERROR_NOT_SUPPORTED)
goto finish;
}
}
}

View File

@ -1429,7 +1429,7 @@ static _FX void Process_CheckAlertProcess(
box = List_Head(boxes);
while (box) {
if (Process_CheckForceProcessList(box->box, &box->ForceProcess, name)) {
if (Process_CheckForceProcessList(box->box, &box->AlertProcess, name)) {
*IsAlert = 1;
return;
}

View File

@ -513,6 +513,11 @@ MSG_HEADER *ProcessServer::RunSandboxedHandler(MSG_HEADER *msg)
CallerInSandbox = true;
SbieApi_QueryProcess((HANDLE)(ULONG_PTR)CallerPid, boxname, NULL, NULL, NULL);
BoxNameOrModelPid = -(LONG_PTR)(LONG)CallerPid;
if ((req->si_flags & 0x80000000) != 0) { // bsession0 - this is only allowed for unsandboxed processes
lvl = 0xFF;
err = ERROR_NOT_SUPPORTED;
goto end;
}
} else {
CallerInSandbox = false;
if (*req->boxname == L'-') {
@ -527,11 +532,16 @@ MSG_HEADER *ProcessServer::RunSandboxedHandler(MSG_HEADER *msg)
#ifndef DRV_BREAKOUT
if (CallerInSandbox && wcscmp(req->boxname, L"*UNBOXED*") == 0 && *cmd == L'\"') {
ULONG flags = 0;
if (!NT_SUCCESS(SbieApi_Call(API_QUERY_DRIVER_INFO, 2, 0, (ULONG_PTR)&flags)) || (flags & SBIE_FEATURE_FLAG_CERTIFIED) == 0) {
ULONG SessionId = PipeServer::GetCallerSessionId();
SbieApi_LogEx(SessionId, 6004, L"%S", boxname);
} else {
ULONG flags = 0;
if (!NT_SUCCESS(SbieApi_Call(API_QUERY_DRIVER_INFO, 2, 0, (ULONG_PTR)&flags)) || (flags & SBIE_FEATURE_FLAG_CERTIFIED) == 0) {
ULONG SessionId = PipeServer::GetCallerSessionId();
SbieApi_LogEx(SessionId, 6004, L"%S", boxname);
lvl = 0x66;
err = ERROR_NOT_SUPPORTED;
goto end;
}
WCHAR* lpApplicationName = cmd + 1;
WCHAR* ptr = wcschr(lpApplicationName, L'\"');
if (ptr) {
@ -569,6 +579,23 @@ MSG_HEADER *ProcessServer::RunSandboxedHandler(MSG_HEADER *msg)
if (SbieDll_CheckStringInList(lpProgram + 1, BoxName, L"ForceProcess")
|| SbieDll_CheckPatternInList(lpApplicationName, (ULONG)(lpProgram - lpApplicationName), BoxName, L"ForceFolder")) {
//
// check if the breakout process is suposed to end in the box its trying to break out of
// and deny the breakout in that case, to take the normal process creation route
//
// this happens when a break out is configured globally
//
if (_wcsicmp(boxname, BoxName) == 0) {
lvl = 0;
err = ERROR_NOT_SUPPORTED;
goto end;
}
//
// set otehr box
//
BoxNameOrModelPid = (LONG_PTR)boxname;
wcscpy(boxname, BoxName);
break;
@ -579,7 +606,6 @@ MSG_HEADER *ProcessServer::RunSandboxedHandler(MSG_HEADER *msg)
// restore cmd
*ptr = L'\"';
}
}
}
#endif
@ -637,6 +663,7 @@ MSG_HEADER *ProcessServer::RunSandboxedHandler(MSG_HEADER *msg)
lvl = 0x33;
}
end:
CloseHandle(CallerProcessHandle);
} else {

View File

@ -149,7 +149,7 @@ public:
{
Attach(&other);
}
CSbieResult(const CSbieResult& other) : CSbieResult(other)
CSbieResult(const CSbieResult& other) : CSbieStatus(other)
{
v = other.v;
}

View File

@ -61,7 +61,7 @@ SB_STATUS CSbieUtils::DoAssist()
return SB_ERR(ERROR_OK);
}
SB_STATUS CSbieUtils::Start(EComponent Component)
SB_RESULT(void*) CSbieUtils::Start(EComponent Component)
{
QStringList Ops;
if(!IsInstalled(Component))
@ -79,7 +79,7 @@ void CSbieUtils::Start(EComponent Component, QStringList& Ops)
Ops.append(QString::fromWCharArray(L"kmdutil.exe|start|" SBIEDRV));
}
SB_STATUS CSbieUtils::Stop(EComponent Component)
SB_RESULT(void*) CSbieUtils::Stop(EComponent Component)
{
QStringList Ops;
Stop(Component, Ops);
@ -104,7 +104,7 @@ bool CSbieUtils::IsRunning(EComponent Component)
return true;
}
SB_STATUS CSbieUtils::Install(EComponent Component)
SB_RESULT(void*) CSbieUtils::Install(EComponent Component)
{
QStringList Ops;
Install(Component, Ops);
@ -122,7 +122,7 @@ void CSbieUtils::Install(EComponent Component, QStringList& Ops)
}
}
SB_STATUS CSbieUtils::Uninstall(EComponent Component)
SB_RESULT(void*) CSbieUtils::Uninstall(EComponent Component)
{
QStringList Ops;
Stop(Component, Ops);
@ -147,7 +147,7 @@ bool CSbieUtils::IsInstalled(EComponent Component)
return true;
}
SB_STATUS CSbieUtils::ElevateOps(const QStringList& Ops)
SB_RESULT(void*) CSbieUtils::ElevateOps(const QStringList& Ops)
{
if (Ops.isEmpty())
return SB_OK;
@ -161,7 +161,7 @@ SB_STATUS CSbieUtils::ElevateOps(const QStringList& Ops)
SHELLEXECUTEINFO shex;
memset(&shex, 0, sizeof(SHELLEXECUTEINFO));
shex.cbSize = sizeof(SHELLEXECUTEINFO);
shex.fMask = SEE_MASK_FLAG_NO_UI;
shex.fMask = SEE_MASK_FLAG_NO_UI | SEE_MASK_NOCLOSEPROCESS;
shex.hwnd = NULL;
shex.lpFile = path.c_str();
shex.lpParameters = params.c_str();
@ -170,7 +170,7 @@ SB_STATUS CSbieUtils::ElevateOps(const QStringList& Ops)
if (!ShellExecuteEx(&shex))
return SB_ERR(SB_NeedAdmin);
return SB_ERR(OP_ASYNC);
return CSbieResult<void*>(OP_ASYNC, shex.hProcess);
}
SB_STATUS CSbieUtils::ExecOps(const QStringList& Ops)

View File

@ -18,12 +18,12 @@ public:
static SB_STATUS DoAssist();
static SB_STATUS Start(EComponent Component);
static SB_STATUS Stop(EComponent Component);
static SB_RESULT(void*) Start(EComponent Component);
static SB_RESULT(void*) Stop(EComponent Component);
static bool IsRunning(EComponent Component);
static SB_STATUS Install(EComponent Component);
static SB_STATUS Uninstall(EComponent Component);
static SB_RESULT(void*) Install(EComponent Component);
static SB_RESULT(void*) Uninstall(EComponent Component);
static bool IsInstalled(EComponent Component);
static QString GetContextMenuStartCmd();
@ -34,7 +34,7 @@ public:
static bool GetStartMenuShortcut(class CSbieAPI* pApi, QString &BoxName, QString &LinkPath, QString &IconPath, quint32& IconIndex, QString &WorkDir);
private:
static SB_STATUS ElevateOps(const QStringList& Ops);
static SB_RESULT(void*) ElevateOps(const QStringList& Ops);
static SB_STATUS ExecOps(const QStringList& Ops);
static void Start(EComponent Component, QStringList& Ops);

View File

@ -314,16 +314,11 @@ CSandMan::CSandMan(QWidget *parent)
OnStatusChanged();
if (CSbieUtils::IsRunning(CSbieUtils::eAll) || theConf->GetBool("Options/StartIfStopped", true))
{
SB_STATUS Status = ConnectSbie();
CheckResults(QList<SB_STATUS>() << Status);
SB_RESULT(void*) Status = ConnectSbie();
HandleMaintenance(Status);
}
//qApp->setWindowIcon(GetIcon("IconEmptyDC", false));
if (!g_PendingMessage.isEmpty()) {
OnMessage(g_PendingMessage);
PostQuitMessage(0);
}
}
CSandMan::~CSandMan()
@ -347,7 +342,9 @@ CSandMan::~CSandMan()
void CSandMan::LoadState()
{
setWindowState(Qt::WindowNoState);
restoreGeometry(theConf->GetBlob("MainWindow/Window_Geometry"));
restoreState(theConf->GetBlob("MainWindow/Window_State"));
//m_pBoxTree->restoreState(theConf->GetBlob("MainWindow/BoxTree_Columns"));
m_pMessageLog->GetView()->header()->restoreState(theConf->GetBlob("MainWindow/LogList_Columns"));
m_pLogSplitter->restoreState(theConf->GetBlob("MainWindow/Log_Splitter"));
@ -358,6 +355,7 @@ void CSandMan::LoadState()
void CSandMan::StoreState()
{
theConf->SetBlob("MainWindow/Window_Geometry", saveGeometry());
theConf->SetBlob("MainWindow/Window_State", saveState());
//theConf->SetBlob("MainWindow/BoxTree_Columns", m_pBoxTree->saveState());
theConf->SetBlob("MainWindow/LogList_Columns", m_pMessageLog->GetView()->header()->saveState());
theConf->SetBlob("MainWindow/Log_Splitter", m_pLogSplitter->saveState());
@ -570,8 +568,10 @@ void CSandMan::closeEvent(QCloseEvent *e)
theConf->SetValue("Options/PortableStop", PortableStop);
}
if(PortableStop == 1)
StopSbie(true);
if (PortableStop == 1) {
SB_RESULT(void*) Status = StopSbie(true);
// don't care for Status we quit here anyways
}
}
QApplication::quit();
@ -669,7 +669,7 @@ void CSandMan::OnMessage(const QString& MsgData)
{
QString Op = Message.mid(3);
SB_STATUS Status;
SB_RESULT(void*) Status;
if (Op == "Connect")
Status = ConnectSbie();
else if (Op == "Disconnect")
@ -680,36 +680,8 @@ void CSandMan::OnMessage(const QString& MsgData)
Status = theAPI->TerminateAll();
else
Status = SB_ERR(SB_Message, QVariantList () << (tr("Unknown operation '%1' requested via command line").arg(Op)));
CheckResults(QList<SB_STATUS>() << Status);
}
else if (Message.left(6) == "Status")
{
QString Status = Message.mid(7);
if (Status != "OK")
{
if(m_bStopPending)
QMessageBox::warning(NULL, tr("Sandboxie-Plus - Error"), tr("Failed to stop all Sandboxie components"));
else if(m_bConnectPending)
QMessageBox::warning(NULL, tr("Sandboxie-Plus - Error"), tr("Failed to start required Sandboxie components"));
OnLogMessage(tr("Maintenance operation %1").arg(Status));
CheckResults(QList<SB_STATUS>() << SB_ERR(SB_Message, QVariantList() << Status));
}
else
{
OnLogMessage(tr("Maintenance operation Successful"));
if (m_bConnectPending) {
QTimer::singleShot(1000, [this]() {
SB_STATUS Status = this->ConnectSbieImpl();
CheckResults(QList<SB_STATUS>() << Status);
});
}
}
m_pProgressDialog->hide();
//statusBar()->showMessage(tr("Maintenance operation completed"), 3000);
m_bConnectPending = false;
m_bStopPending = false;
HandleMaintenance(Status);
}
}
@ -720,11 +692,11 @@ void CSandMan::dragEnterEvent(QDragEnterEvent* e)
}
}
void CSandMan::RunSandboxed(const QStringList& Commands, const QString& BoxName, const QString& WrkDir)
bool CSandMan::RunSandboxed(const QStringList& Commands, const QString& BoxName, const QString& WrkDir)
{
CSelectBoxWindow* pSelectBoxWindow = new CSelectBoxWindow(Commands, BoxName, WrkDir);
//pSelectBoxWindow->show();
SafeExec(pSelectBoxWindow);
return SafeExec(pSelectBoxWindow) == 1;
}
void CSandMan::dropEvent(QDropEvent* e)
@ -1452,10 +1424,9 @@ void CSandMan::OnDisableForce2()
theAPI->DisableForceProcess(Status);
}
SB_STATUS CSandMan::ConnectSbie()
SB_RESULT(void*) CSandMan::ConnectSbie()
{
SB_STATUS Status;
bool bJustStarted = false;
SB_RESULT(void*) Status;
if (!CSbieUtils::IsRunning(CSbieUtils::eAll))
{
if (!CSbieUtils::IsInstalled(CSbieUtils::eAll))
@ -1475,24 +1446,16 @@ SB_STATUS CSandMan::ConnectSbie()
return SB_OK;
}
bJustStarted = true;
Status = CSbieUtils::Start(CSbieUtils::eAll);
}
if (Status.GetStatus() == OP_ASYNC) {
m_bConnectPending = true;
return SB_OK;
return Status;
}
if (Status.IsError())
return Status;
if (bJustStarted) {
QTimer::singleShot(1000, [this]() {
SB_STATUS Status = this->ConnectSbieImpl();
CheckResults(QList<SB_STATUS>() << Status);
});
return SB_OK;
}
return ConnectSbieImpl();
}
@ -1505,6 +1468,11 @@ SB_STATUS CSandMan::ConnectSbieImpl()
return SB_OK;
}
if (!g_PendingMessage.isEmpty()) {
OnMessage(g_PendingMessage);
PostQuitMessage(0);
}
return Status;
}
@ -1513,9 +1481,9 @@ SB_STATUS CSandMan::DisconnectSbie()
return theAPI->Disconnect();
}
SB_STATUS CSandMan::StopSbie(bool andRemove)
SB_RESULT(void*) CSandMan::StopSbie(bool andRemove)
{
SB_STATUS Status;
SB_RESULT(void*) Status;
if (theAPI->IsConnected()) {
Status = theAPI->TerminateAll();
@ -1535,7 +1503,7 @@ SB_STATUS CSandMan::StopSbie(bool andRemove)
void CSandMan::OnMaintenance()
{
SB_STATUS Status;
SB_RESULT(void*) Status;
if (sender() == m_pConnect)
Status = ConnectSbie();
else if (sender() == m_pDisconnect)
@ -1566,11 +1534,56 @@ void CSandMan::OnMaintenance()
else if (sender() == m_pUninstallAll)
Status = StopSbie(true);
HandleMaintenance(Status);
}
void CSandMan::HandleMaintenance(SB_RESULT(void*) Status)
{
if (Status.GetStatus() == OP_ASYNC) {
HANDLE hProcess = Status.GetValue();
QWinEventNotifier* processFinishedNotifier = new QWinEventNotifier(hProcess);
processFinishedNotifier->setEnabled(true);
connect(processFinishedNotifier, &QWinEventNotifier::activated, this, [processFinishedNotifier, this, hProcess]() {
processFinishedNotifier->setEnabled(false);
processFinishedNotifier->deleteLater();
DWORD dwStatus = 0;
GetExitCodeProcess(hProcess, & dwStatus);
if (dwStatus != 0)
{
if(m_bStopPending)
QMessageBox::warning(NULL, tr("Sandboxie-Plus - Error"), tr("Failed to stop all Sandboxie components"));
else if(m_bConnectPending)
QMessageBox::warning(NULL, tr("Sandboxie-Plus - Error"), tr("Failed to start required Sandboxie components"));
OnLogMessage(tr("Maintenance operation failed (%1)").arg((quint32)dwStatus));
CheckResults(QList<SB_STATUS>() << SB_ERR(dwStatus));
}
else
{
OnLogMessage(tr("Maintenance operation Successful"));
if (m_bConnectPending) {
QTimer::singleShot(1000, [this]() {
SB_STATUS Status = this->ConnectSbieImpl();
CheckResults(QList<SB_STATUS>() << Status);
});
}
}
m_pProgressDialog->hide();
//statusBar()->showMessage(tr("Maintenance operation completed"), 3000);
m_bConnectPending = false;
m_bStopPending = false;
CloseHandle(hProcess);
});
//statusBar()->showMessage(tr("Executing maintenance operation, please wait..."));
m_pProgressDialog->OnStatusMessage(tr("Executing maintenance operation, please wait..."));
SafeShow(m_pProgressDialog);
return;
}
@ -1586,12 +1599,14 @@ void CSandMan::OnViewMode(QAction* pAction)
void CSandMan::OnAlwaysTop()
{
StoreState();
bool bAlwaysOnTop = m_pWndTopMost->isChecked();
theConf->SetValue("Options/AlwaysOnTop", bAlwaysOnTop);
this->setWindowFlag(Qt::WindowStaysOnTopHint, bAlwaysOnTop);
this->show(); // why is this needed?
m_pPopUpWindow->setWindowFlag(Qt::WindowStaysOnTopHint, bAlwaysOnTop);
m_pProgressDialog->setWindowFlag(Qt::WindowStaysOnTopHint, bAlwaysOnTop);
LoadState();
}
void CSandMan::SetViewMode(bool bAdvanced)

View File

@ -50,7 +50,7 @@ public:
CSbieView* GetBoxView() { return m_pBoxView; }
void RunSandboxed(const QStringList& Commands, const QString& BoxName, const QString& WrkDir = QString());
bool RunSandboxed(const QStringList& Commands, const QString& BoxName, const QString& WrkDir = QString());
QIcon GetBoxIcon(int boxType, bool inUse = false);
QString GetBoxDescription(int boxType);
@ -66,10 +66,10 @@ signals:
void CertUpdated();
protected:
SB_STATUS ConnectSbie();
SB_RESULT(void*) ConnectSbie();
SB_STATUS ConnectSbieImpl();
SB_STATUS DisconnectSbie();
SB_STATUS StopSbie(bool andRemove = false);
SB_RESULT(void*) StopSbie(bool andRemove = false);
static void RecoverFilesAsync(const CSbieProgressPtr& pProgress, const QList<QPair<QString, QString>>& FileList, int Action = 0);
@ -192,6 +192,8 @@ private:
void CreateMenus();
void CreateToolBar();
void HandleMaintenance(SB_RESULT(void*) Status);
void SetViewMode(bool bAdvanced);
void LoadState();

View File

@ -809,15 +809,19 @@ void CSbieView::OnSandBoxAction(QAction* Action)
CSandBoxPtr pBox = SandBoxes.first();
static QMap<void*, CFileBrowserWindow*> FileBrowserWindows;
if (!FileBrowserWindows.contains(pBox.data()))
{
CFileBrowserWindow* pFileBrowserWindow = new CFileBrowserWindow(SandBoxes.first());
CFileBrowserWindow* pFileBrowserWindow = FileBrowserWindows.value(pBox.data());
if (pFileBrowserWindow == NULL) {
pFileBrowserWindow = new CFileBrowserWindow(SandBoxes.first());
FileBrowserWindows.insert(pBox.data(), pFileBrowserWindow);
connect(pFileBrowserWindow, &CFileBrowserWindow::Closed, [this, pBox]() {
FileBrowserWindows.remove(pBox.data());
});
SafeShow(pFileBrowserWindow);
}
else {
pFileBrowserWindow->setWindowState((pFileBrowserWindow->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
SetForegroundWindow((HWND)pFileBrowserWindow->winId());
}
}
else if (Action == m_pMenuExplore)
{
@ -877,15 +881,19 @@ void CSbieView::OnSandBoxAction(QAction* Action)
CSandBoxPtr pBox = SandBoxes.first();
static QMap<void*, CSnapshotsWindow*> SnapshotWindows;
if (!SnapshotWindows.contains(pBox.data()))
{
CSnapshotsWindow* pSnapshotsWindow = new CSnapshotsWindow(SandBoxes.first(), this);
CSnapshotsWindow* pSnapshotsWindow = SnapshotWindows.value(pBox.data());
if (pSnapshotsWindow == NULL) {
pSnapshotsWindow = new CSnapshotsWindow(SandBoxes.first(), this);
SnapshotWindows.insert(pBox.data(), pSnapshotsWindow);
connect(pSnapshotsWindow, &CSnapshotsWindow::Closed, [this, pBox]() {
SnapshotWindows.remove(pBox.data());
});
SafeShow(pSnapshotsWindow);
}
else {
pSnapshotsWindow->setWindowState((pSnapshotsWindow->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
SetForegroundWindow((HWND)pSnapshotsWindow->winId());
}
}
else if (Action == m_pMenuDuplicate)
{

View File

@ -184,5 +184,6 @@ void CSelectBoxWindow::OnRun()
}
//CSandMan::CheckResults(Results);
setResult(1);
close();
}

View File

@ -28,11 +28,13 @@ int main(int argc, char *argv[])
bool IsBoxed = GetModuleHandle(L"SbieDll.dll") != NULL;
SB_STATUS Status = CSbieUtils::DoAssist();
if (Status.GetStatus()) {
if(Status.GetStatus() == ERROR_OK) app.sendMessage("Status:OK");
else app.sendMessage("Status:" + CSandMan::FormatError(Status)); // todo: localization
return 0;
if (!IsBoxed) {
SB_STATUS Status = CSbieUtils::DoAssist();
if (Status.GetStatus()) {
if (Status.GetStatus() != ERROR_OK)
return Status.GetStatus();
return 0;
}
}
QStringList Args = QCoreApplication::arguments();