mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-05 01:23:24 -08:00
Some checks failed
CodeQL / Analyze (cpp) (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
Build Desktop / Configure (push) Has been cancelled
Build Desktop / Prune caches (push) Has been cancelled
Build Docker / Servatrice (arm) (push) Has been cancelled
Build Docker / Servatrice (x86) (push) Has been cancelled
Build Desktop / Debian 13 (push) Has been cancelled
Build Desktop / Debian 12 (push) Has been cancelled
Build Desktop / Fedora 44 (push) Has been cancelled
Build Desktop / Fedora 43 (push) Has been cancelled
Build Desktop / Servatrice_Debian 12 (push) Has been cancelled
Build Desktop / Ubuntu 24.04 (push) Has been cancelled
Build Desktop / Ubuntu 26.04 (push) Has been cancelled
Build Desktop / Arch (push) Has been cancelled
Build Desktop / Ubuntu 26.04 cover (push) Has been cancelled
Build Desktop / macOS 13 Intel (push) Has been cancelled
Build Desktop / macOS 14 (push) Has been cancelled
Build Desktop / macOS 15 (push) Has been cancelled
Build Desktop / macOS 26 Debug (push) Has been cancelled
Build Desktop / Windows 10 (push) Has been cancelled
Build Docker / Publish multi-platform Servatrice image (push) Has been cancelled
The running-instance lookup named every process whose image path began with the install directory, subfolders included. Installing into a folder that holds another application in a subfolder therefore reported that application as holding the previous version, and nothing the guard offers could clear it: the close asks cockatrice.exe only, and the end answer refuses anything that is not a payload program. Both answers were no-ops, so the update could only abort and tell the user to close a program that was never touching the files. Name only the programs the payload installs, and only when the image lies in the install directory itself. A program below the directory that really does hold a payload file is still named by the Restart Manager lookup, which is the lookup for that question. The Windows probe check now covers a payload-named program in a subfolder and a program the payload does not install; both have to come back as nothing. Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
52 lines
1.9 KiB
C++
52 lines
1.9 KiB
C++
#include "payload_paths.h"
|
|
|
|
#include <algorithm>
|
|
#include <cstddef>
|
|
#include <iterator>
|
|
|
|
namespace
|
|
{
|
|
/// The payload programs, by image name. A process running one of these is what the guard
|
|
/// exists to name, so askingProcessIds() stops its walk up the parent chain at one.
|
|
constexpr const wchar_t *PAYLOAD_PROGRAMS[] = {L"cockatrice.exe", L"oracle.exe", L"servatrice.exe"};
|
|
|
|
/// Compares two file names the way the file system does, without a locale.
|
|
///
|
|
/// Only the names above are ever compared against, and all of them are ASCII, so folding
|
|
/// the ASCII letters is the whole answer. The Windows ordinal comparison is not used here
|
|
/// on purpose: this file is compiled into a test that runs everywhere, and the question
|
|
/// "is this image a program the payload installs?" must be answerable without Windows.
|
|
bool equalsIgnoringAsciiCase(const std::wstring &left, const std::wstring &right)
|
|
{
|
|
if (left.size() != right.size()) {
|
|
return false;
|
|
}
|
|
return std::equal(left.begin(), left.end(), right.begin(), [](wchar_t a, wchar_t b) {
|
|
const wchar_t foldedA = a >= L'A' && a <= L'Z' ? static_cast<wchar_t>(a - L'A' + L'a') : a;
|
|
const wchar_t foldedB = b >= L'A' && b <= L'Z' ? static_cast<wchar_t>(b - L'A' + L'a') : b;
|
|
return foldedA == foldedB;
|
|
});
|
|
}
|
|
} // namespace
|
|
|
|
std::wstring fileNameOf(const std::wstring &path)
|
|
{
|
|
const std::size_t separator = path.find_last_of(L"\\/");
|
|
return separator == std::wstring::npos ? path : path.substr(separator + 1);
|
|
}
|
|
|
|
std::wstring parentDirectoryOf(const std::wstring &path)
|
|
{
|
|
const std::size_t separator = path.find_last_of(L"\\/");
|
|
return separator == std::wstring::npos ? std::wstring() : path.substr(0, separator);
|
|
}
|
|
|
|
bool isPayloadProgram(const std::wstring &imageName)
|
|
{
|
|
for (const wchar_t *program : PAYLOAD_PROGRAMS) {
|
|
if (equalsIgnoringAsciiCase(imageName, program)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|