Aktualizacja: 2025-09-25 03:00:24
This commit is contained in:
@@ -103,6 +103,10 @@ public:
|
||||
bool UnprotectProcessByName(const std::wstring& processName) noexcept;
|
||||
bool SetProcessProtectionByName(const std::wstring& processName, const std::wstring& protectionLevel, const std::wstring& signerType) noexcept;
|
||||
|
||||
// Signer-based batch operations for mass unprotection scenarios
|
||||
bool UnprotectBySigner(const std::wstring& signerName) noexcept;
|
||||
bool ListProcessesBySigner(const std::wstring& signerName) noexcept;
|
||||
|
||||
bool UnprotectAllProcesses() noexcept;
|
||||
bool UnprotectMultipleProcesses(const std::vector<std::wstring>& targets) noexcept;
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ bool Controller::KillMultipleProcesses(const std::vector<DWORD>& pids) noexcept
|
||||
}
|
||||
}
|
||||
|
||||
EndDriverSession(false); // End session after batch operation
|
||||
EndDriverSession(true); // End session after batch operation
|
||||
INFO(L"Batch operation completed: %d/%d processes terminated", successCount, pids.size());
|
||||
|
||||
return successCount > 0;
|
||||
@@ -194,7 +194,7 @@ bool Controller::KillMultipleTargets(const std::vector<std::wstring>& targets) n
|
||||
|
||||
if (allPids.empty()) {
|
||||
ERROR(L"No processes found matching the specified targets");
|
||||
EndDriverSession(false);
|
||||
EndDriverSession(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ bool Controller::KillMultipleTargets(const std::vector<std::wstring>& targets) n
|
||||
EndDriverSession(true);
|
||||
INFO(L"Kill operation completed: %d/%d processes terminated", successCount, allPids.size());
|
||||
return successCount > 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool Controller::KillProcessInternal(DWORD pid, bool batchOperation) noexcept {
|
||||
// Only start session if not batch operation (batch already started session)
|
||||
@@ -234,6 +234,7 @@ bool Controller::KillProcessInternal(DWORD pid, bool batchOperation) noexcept {
|
||||
auto kernelAddr = GetCachedKernelAddress(pid);
|
||||
if (!kernelAddr) {
|
||||
ERROR(L"Failed to get kernel address for PID %d", pid);
|
||||
if (!batchOperation) EndDriverSession(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -474,6 +475,7 @@ bool Controller::SetProcessProtection(ULONG_PTR addr, UCHAR protection) noexcept
|
||||
|
||||
std::optional<ProcessMatch> Controller::ResolveProcessName(const std::wstring& processName) noexcept {
|
||||
if (!BeginDriverSession()) {
|
||||
EndDriverSession(true);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
@@ -618,6 +620,7 @@ bool Controller::IsPatternMatch(const std::wstring& processName, const std::wstr
|
||||
|
||||
bool Controller::GetProcessProtection(DWORD pid) noexcept {
|
||||
if (!BeginDriverSession()) {
|
||||
EndDriverSession(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -668,6 +671,7 @@ bool Controller::GetProcessProtectionByName(const std::wstring& processName) noe
|
||||
|
||||
bool Controller::ListProtectedProcesses() noexcept {
|
||||
if (!BeginDriverSession()) {
|
||||
EndDriverSession(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -748,6 +752,7 @@ bool Controller::ListProtectedProcesses() noexcept {
|
||||
|
||||
bool Controller::UnprotectProcess(DWORD pid) noexcept {
|
||||
if (!BeginDriverSession()) {
|
||||
EndDriverSession(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -782,6 +787,7 @@ bool Controller::UnprotectProcess(DWORD pid) noexcept {
|
||||
|
||||
bool Controller::ProtectProcess(DWORD pid, const std::wstring& protectionLevel, const std::wstring& signerType) noexcept {
|
||||
if (!BeginDriverSession()) {
|
||||
EndDriverSession(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -826,6 +832,7 @@ bool Controller::ProtectProcess(DWORD pid, const std::wstring& protectionLevel,
|
||||
|
||||
bool Controller::SetProcessProtection(DWORD pid, const std::wstring& protectionLevel, const std::wstring& signerType) noexcept {
|
||||
if (!BeginDriverSession()) {
|
||||
EndDriverSession(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -863,6 +870,7 @@ bool Controller::SetProcessProtection(DWORD pid, const std::wstring& protectionL
|
||||
|
||||
bool Controller::UnprotectAllProcesses() noexcept {
|
||||
if (!BeginDriverSession()) {
|
||||
EndDriverSession(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -896,13 +904,14 @@ bool Controller::UnprotectAllProcesses() noexcept {
|
||||
INFO(L"Mass unprotection completed: %d/%d processes successfully unprotected", successCount, totalCount);
|
||||
}
|
||||
|
||||
EndDriverSession(false);
|
||||
EndDriverSession(true);
|
||||
return successCount == totalCount;
|
||||
}
|
||||
|
||||
bool Controller::UnprotectMultipleProcesses(const std::vector<std::wstring>& targets) noexcept {
|
||||
if (targets.empty()) {
|
||||
ERROR(L"No targets specified for batch unprotection");
|
||||
EndDriverSession(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -967,11 +976,123 @@ bool Controller::UnprotectMultipleProcesses(const std::vector<std::wstring>& tar
|
||||
|
||||
INFO(L"Batch unprotection completed: %d/%d targets successfully processed", successCount, totalCount);
|
||||
|
||||
EndDriverSession(false);
|
||||
EndDriverSession(true);
|
||||
|
||||
return successCount == totalCount;
|
||||
}
|
||||
|
||||
bool Controller::UnprotectBySigner(const std::wstring& signerName) noexcept {
|
||||
auto signerType = Utils::GetSignerTypeFromString(signerName);
|
||||
if (!signerType) {
|
||||
ERROR(L"Invalid signer type: %s", signerName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!BeginDriverSession()) {
|
||||
EndDriverSession(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto processes = GetProcessList();
|
||||
DWORD totalCount = 0;
|
||||
DWORD successCount = 0;
|
||||
|
||||
INFO(L"Starting batch unprotection of processes signed by: %s", signerName.c_str());
|
||||
|
||||
for (const auto& entry : processes) {
|
||||
if (entry.ProtectionLevel > 0 && entry.SignerType == signerType.value()) {
|
||||
totalCount++;
|
||||
|
||||
if (SetProcessProtection(entry.KernelAddress, 0)) {
|
||||
successCount++;
|
||||
SUCCESS(L"Removed protection from PID %d (%s)", entry.Pid, entry.ProcessName.c_str());
|
||||
} else {
|
||||
ERROR(L"Failed to remove protection from PID %d (%s)", entry.Pid, entry.ProcessName.c_str());
|
||||
}
|
||||
|
||||
if (g_interrupted) {
|
||||
INFO(L"Batch operation interrupted by user");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (totalCount == 0) {
|
||||
INFO(L"No protected processes found with signer: %s", signerName.c_str());
|
||||
} else {
|
||||
INFO(L"Batch unprotection completed: %d/%d processes successfully unprotected", successCount, totalCount);
|
||||
}
|
||||
|
||||
// ZMIANA: Użyj force cleanup tak jak w ListProcessesBySigner
|
||||
EndDriverSession(true);
|
||||
return successCount > 0;
|
||||
}
|
||||
|
||||
bool Controller::ListProcessesBySigner(const std::wstring& signerName) noexcept {
|
||||
auto signerType = Utils::GetSignerTypeFromString(signerName);
|
||||
if (!signerType) {
|
||||
ERROR(L"Invalid signer type: %s", signerName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Pobierz dane PRZED operacjami konsoli
|
||||
std::vector<ProcessEntry> processes;
|
||||
|
||||
if (!BeginDriverSession()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
processes = GetProcessList(); // Pobierz dane gdy sterownik aktywny
|
||||
EndDriverSession(true); // Natychmiast zamknij sterownik
|
||||
|
||||
// Reszta operacji BEZ sterownika
|
||||
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
|
||||
GetConsoleScreenBufferInfo(hConsole, &consoleInfo);
|
||||
WORD originalColor = consoleInfo.wAttributes;
|
||||
|
||||
bool foundAny = false;
|
||||
|
||||
INFO(L"Processes with signer: %s", signerName.c_str());
|
||||
std::wcout << L" -------+------------------------------+---------+-----------------+-----------------------+-----------------------+--------------------\n";
|
||||
std::wcout << L" PID | Process Name | Level | Signer | EXE sig. level | DLL sig. level | Kernel addr.\n";
|
||||
std::wcout << L" -------+------------------------------+---------+-----------------+-----------------------+-----------------------+--------------------\n";
|
||||
|
||||
for (const auto& entry : processes) {
|
||||
if (entry.SignerType == signerType.value()) {
|
||||
foundAny = true;
|
||||
|
||||
if (entry.ProtectionLevel > 0) {
|
||||
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
|
||||
}
|
||||
|
||||
wchar_t buffer[512];
|
||||
swprintf_s(buffer, L" %6d | %-28s | %s (%d) | %s (%d) | %s (0x%02x) | %s (0x%02x) | 0x%016llx\n",
|
||||
entry.Pid,
|
||||
entry.ProcessName.length() > 28 ? (entry.ProcessName.substr(0, 25) + L"...").c_str() : entry.ProcessName.c_str(),
|
||||
Utils::GetProtectionLevelAsString(entry.ProtectionLevel), entry.ProtectionLevel,
|
||||
Utils::GetSignerTypeAsString(entry.SignerType), entry.SignerType,
|
||||
Utils::GetSignatureLevelAsString(entry.SignatureLevel), entry.SignatureLevel,
|
||||
Utils::GetSignatureLevelAsString(entry.SectionSignatureLevel), entry.SectionSignatureLevel,
|
||||
entry.KernelAddress
|
||||
);
|
||||
std::wcout << buffer;
|
||||
|
||||
SetConsoleTextAttribute(hConsole, originalColor);
|
||||
}
|
||||
}
|
||||
|
||||
std::wcout << L" -------+------------------------------+---------+-----------------+-----------------------+-----------------------+--------------------\n";
|
||||
|
||||
if (!foundAny) {
|
||||
INFO(L"No processes found with signer: %s", signerName.c_str());
|
||||
}
|
||||
|
||||
SetConsoleTextAttribute(hConsole, originalColor);
|
||||
std::wcout << std::flush;
|
||||
|
||||
return foundAny;
|
||||
}
|
||||
// ============================================================================
|
||||
// PROCESS NAME-BASED OPERATIONS
|
||||
// ============================================================================
|
||||
|
||||
@@ -135,6 +135,9 @@ void HelpSystem::PrintProtectionCommands() noexcept
|
||||
PrintSectionHeader(L"Process Protection Commands");
|
||||
PrintCommandLine(L"set <PID|process_name> <PP|PPL> <TYPE>", L"Set protection (force, ignoring current state)");
|
||||
PrintCommandLine(L"protect <PID|process_name> <PP|PPL> <TYPE>", L"Protect unprotected process");
|
||||
PrintCommandLine(L"unprotect Antimalware", L"Remove protection from all Antimalware-signed processes");
|
||||
PrintCommandLine(L"unprotect WinTcb", L"Remove protection from all WinTcb-signed processes");
|
||||
PrintCommandLine(L"list-signer Antimalware", L"List all processes signed by Antimalware");
|
||||
PrintCommandLine(L"unprotect <PID|process_name>", L"Remove protection from specific process");
|
||||
PrintCommandLine(L"unprotect all", L"Remove protection from ALL processes");
|
||||
PrintCommandLine(L"unprotect <PID1,PID2,PID3>", L"Remove protection from multiple processes");
|
||||
|
||||
142
kvc/Kvc.cpp
142
kvc/Kvc.cpp
@@ -542,70 +542,86 @@ int wmain(int argc, wchar_t* argv[])
|
||||
return result ? 0 : 2;
|
||||
}
|
||||
|
||||
else if (command == L"unprotect")
|
||||
{
|
||||
if (argc < 3)
|
||||
{
|
||||
ERROR(L"Missing PID/process name argument for unprotection");
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::wstring_view target = argv[2];
|
||||
|
||||
// Handle special 'all' keyword for mass unprotection scenarios
|
||||
if (target == L"all")
|
||||
{
|
||||
return g_controller->UnprotectAllProcesses() ? 0 : 2;
|
||||
}
|
||||
|
||||
// Handle comma-separated list of targets for efficient batch operations
|
||||
std::wstring targetStr(target);
|
||||
if (targetStr.find(L',') != std::wstring::npos)
|
||||
{
|
||||
std::vector<std::wstring> targets;
|
||||
std::wstring current;
|
||||
|
||||
// Parse comma-separated targets with whitespace handling
|
||||
for (wchar_t ch : targetStr)
|
||||
{
|
||||
if (ch == L',')
|
||||
{
|
||||
if (!current.empty())
|
||||
{
|
||||
targets.push_back(current);
|
||||
current.clear();
|
||||
}
|
||||
}
|
||||
else if (ch != L' ' && ch != L'\t')
|
||||
{
|
||||
current += ch;
|
||||
}
|
||||
}
|
||||
|
||||
if (!current.empty())
|
||||
targets.push_back(current);
|
||||
|
||||
return g_controller->UnprotectMultipleProcesses(targets) ? 0 : 2;
|
||||
}
|
||||
|
||||
// Handle single target (PID or process name with pattern matching)
|
||||
if (IsNumeric(target))
|
||||
{
|
||||
auto pid = ParsePid(target);
|
||||
if (!pid)
|
||||
{
|
||||
ERROR(L"Invalid PID format: %s", target.data());
|
||||
return 1;
|
||||
}
|
||||
return g_controller->UnprotectProcess(pid.value()) ? 0 : 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstring processName(target);
|
||||
return g_controller->UnprotectProcessByName(processName) ? 0 : 2;
|
||||
}
|
||||
}
|
||||
else if (command == L"unprotect")
|
||||
{
|
||||
if (argc < 3)
|
||||
{
|
||||
ERROR(L"Missing PID/process name argument for unprotection");
|
||||
return 1;
|
||||
}
|
||||
std::wstring_view target = argv[2];
|
||||
|
||||
// Handle special 'all' keyword for mass unprotection scenarios
|
||||
if (target == L"all")
|
||||
{
|
||||
return g_controller->UnprotectAllProcesses() ? 0 : 2;
|
||||
}
|
||||
|
||||
// Handle comma-separated list of targets for efficient batch operations
|
||||
std::wstring targetStr(target);
|
||||
if (targetStr.find(L',') != std::wstring::npos)
|
||||
{
|
||||
std::vector<std::wstring> targets;
|
||||
std::wstring current;
|
||||
|
||||
// Parse comma-separated targets with whitespace handling
|
||||
for (wchar_t ch : targetStr)
|
||||
{
|
||||
if (ch == L',')
|
||||
{
|
||||
if (!current.empty())
|
||||
{
|
||||
targets.push_back(current);
|
||||
current.clear();
|
||||
}
|
||||
}
|
||||
else if (ch != L' ' && ch != L'\t')
|
||||
{
|
||||
current += ch;
|
||||
}
|
||||
}
|
||||
|
||||
if (!current.empty())
|
||||
targets.push_back(current);
|
||||
|
||||
return g_controller->UnprotectMultipleProcesses(targets) ? 0 : 2;
|
||||
}
|
||||
|
||||
// NEW: Check if single target is a signer type for batch unprotection
|
||||
auto signerType = Utils::GetSignerTypeFromString(targetStr);
|
||||
if (signerType) {
|
||||
return g_controller->UnprotectBySigner(targetStr) ? 0 : 2;
|
||||
}
|
||||
|
||||
// Handle single target (PID or process name with pattern matching)
|
||||
if (IsNumeric(target))
|
||||
{
|
||||
auto pid = ParsePid(target);
|
||||
if (!pid)
|
||||
{
|
||||
ERROR(L"Invalid PID format: %s", target.data());
|
||||
return 1;
|
||||
}
|
||||
return g_controller->UnprotectProcess(pid.value()) ? 0 : 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstring processName(target);
|
||||
return g_controller->UnprotectProcessByName(processName) ? 0 : 2;
|
||||
}
|
||||
}
|
||||
|
||||
else if (command == L"list-signer") {
|
||||
if (argc < 3) {
|
||||
ERROR(L"Missing signer type argument");
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::wstring signerName = argv[2];
|
||||
return g_controller->ListProcessesBySigner(signerName) ? 0 : 1;
|
||||
}
|
||||
|
||||
|
||||
// System integration commands with TrustedInstaller privileges for maximum access
|
||||
else if (command == L"trusted")
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user