Files
ma/src/ma_uninstaller/ma_uninstaller.cpp
2024-02-19 17:24:41 +01:00

229 lines
7.3 KiB
C++

// ma_uninstaller.cpp : Diese Datei enthält die Funktion "main". Hier beginnt und endet die Ausführung des Programms.
//
//todo:
/* remove folders
* remove background task
*/
#include <iostream>
#include <Windows.h>
#include <iostream>
#include <Windows.h>
#include <taskschd.h>
#include <comdef.h>
#pragma comment(lib, "taskschd.lib")
//check if programm is run as admin
bool is_admin() {
BOOL fIsRunAsAdmin = FALSE;
PSID pAdminSID = NULL;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
if (AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
&pAdminSID)) {
if (!CheckTokenMembership(NULL, pAdminSID, &fIsRunAsAdmin)) {
fIsRunAsAdmin = FALSE;
}
FreeSid(pAdminSID);
}
return (fIsRunAsAdmin != 0);
}
bool run_as_admin() {
wchar_t szPath[MAX_PATH];
if (GetModuleFileName(NULL, szPath, ARRAYSIZE(szPath))) {
// Launch itself as admin
SHELLEXECUTEINFO sei = { sizeof(sei) };
sei.lpVerb = L"runas";
sei.lpFile = szPath;
sei.hwnd = NULL;
sei.nShow = SW_NORMAL;
if (!ShellExecuteEx(&sei)) {
DWORD dwError = GetLastError();
if (dwError == ERROR_CANCELLED)
{
// The user refused to allow privileges elevation.
return false;
}
}
else {
// End the calling process. User allowd admin rights
return true;
}
}
return false;
}
bool remove_dir(const std::wstring& path) {
// Remove the directory and its contents recursively
if (!RemoveDirectory(path.c_str())) {
DWORD error = GetLastError();
if (error != ERROR_DIR_NOT_EMPTY) {
// Failed to remove the directory
std::wcerr << L"Error removing directory '" << path << L"'. Error code: " << error << std::endl;
return false;
}
// The directory is not empty, so we need to remove its contents first
WIN32_FIND_DATA findFileData;
HANDLE hFind = FindFirstFile((path + L"\\*").c_str(), &findFileData);
if (hFind == INVALID_HANDLE_VALUE) {
std::wcerr << L"Error finding files in directory '" << path << L"'. Error code: " << GetLastError() << std::endl;
return false;
}
do {
if (wcscmp(findFileData.cFileName, L".") != 0 && wcscmp(findFileData.cFileName, L"..") != 0) {
std::wstring filePath = path + L"\\" + findFileData.cFileName;
if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
// Recursively remove subdirectories
if (!remove_dir(filePath)) {
FindClose(hFind);
return false;
}
}
else {
// Delete files in the directory
if (DeleteFile(filePath.c_str()) == FALSE) {
std::wcerr << L"Error deleting file '" << filePath << L"'. Error code: " << GetLastError() << std::endl;
FindClose(hFind);
return false;
}
}
}
} while (FindNextFile(hFind, &findFileData) != 0);
FindClose(hFind);
// Try to remove the directory again after its contents have been deleted
if (!RemoveDirectory(path.c_str())) {
std::wcerr << L"Error removing directory '" << path << L"'. Error code: " << GetLastError() << std::endl;
return false;
}
}
return true;
}
bool remove_scheduled_task(const std::wstring& taskName) {
HRESULT hr;
// Initialize COM
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (FAILED(hr)) {
std::cerr << "COM initialization failed with error code: " << hr << std::endl;
return false;
}
// Create an instance of the Task Service
ITaskService* pService = NULL;
hr = CoCreateInstance(CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskService, (void**)&pService);
if (FAILED(hr)) {
std::cerr << "Failed to create an instance of ITaskService: " << hr << std::endl;
CoUninitialize();
return false;
}
// Connect to the task service
hr = pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());
if (FAILED(hr)) {
std::cerr << "ITaskService::Connect failed with error code: " << hr << std::endl;
pService->Release();
CoUninitialize();
return false;
}
// Get the root task folder
ITaskFolder* pRootFolder = NULL;
hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder);
if (FAILED(hr)) {
std::cerr << "Cannot get Root Folder pointer: " << hr << std::endl;
pService->Release();
CoUninitialize();
return false;
}
// Delete the task
hr = pRootFolder->DeleteTask(_bstr_t(taskName.c_str()), 0);
if (FAILED(hr)) {
std::cerr << "Failed to delete the task: " << hr << std::endl;
pRootFolder->Release();
pService->Release();
CoUninitialize();
return false;
}
// Release COM objects
pRootFolder->Release();
pService->Release();
CoUninitialize();
return true;
}
int main()
{
printf("Welcome to the Cyberhex uninstaller!\n");
int error = 0;
if (!is_admin()) {
printf("We are not administrator, requesting UAC\n");
if (!run_as_admin()) {
printf("We did not get administrative rights. Please restart the uninstaller!\n");
MessageBox(NULL, L"Please start the uninstaller with amdin privileges!", L"Error", MB_OK);
exit(1);
}
else {
//we started the app as admin. This process can be terminated now
exit(0);
}
}
else {
printf("Stopping cyberhex");
system("taskkill /F /IM cyberhex.exe");
Sleep(1000);
printf("Removing directorys\n");
printf("Removing directory for application\n");
error = remove_dir(L"C:\\Program Files\\Cyberhex");
if (error == 0)
error = 4;
else
error = 0;
if (error == 0) {
printf("Removing background task\n");
if (!remove_scheduled_task(L"CyberhexBackgroundTask")) {
error = 5;
}
}
}
switch (error) {
case 0:
printf("Uninstall finished successfully!\n");
MessageBox(NULL, L"Uninstall finished successfully!", L"Success", MB_OK);
break;
case 1:
printf("Failed to open service control manager.\n");
MessageBox(NULL, L"Failed to open service control manager!", L"Error", MB_OK);
break;
case 2:
printf("Failed to open service.\n");
MessageBox(NULL, L"Failed to open service!", L"Error", MB_OK);
break;
case 3:
printf("Failed to delete service.\n");
MessageBox(NULL, L"Failed to delete service!", L"Error", MB_OK);
break;
case 4:
printf("Failed to remove directory.\n");
MessageBox(NULL, L"Failed to remove directory!", L"Error", MB_OK);
default:
printf("Unknown error\n");
MessageBox(NULL, L"Unknown error!", L"Error", MB_OK);
break;
}
}