#include <windows.h>
#include <tlhelp32.h>
#include <shellapi.h>
#include <stdio.h>

#pragma comment(linker, "/MANIFESTUAC:level='requireAdministrator'")

BOOL IsRunningAsAdmin() {
    BOOL isAdmin = FALSE;
    HANDLE hToken = NULL;
    if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
        TOKEN_ELEVATION elevation;
        DWORD size = sizeof(TOKEN_ELEVATION);
        if (GetTokenInformation(hToken, TokenElevation, &elevation, size, &size)) {
            isAdmin = elevation.TokenIsElevated;
        }
        CloseHandle(hToken);
    }
    return isAdmin;
}

void ElevatePrivileges() {
    if (IsRunningAsAdmin()) return;

    char path[MAX_PATH];
    GetModuleFileNameA(NULL, path, MAX_PATH);

    SHELLEXECUTEINFOA sei = { sizeof(SHELLEXECUTEINFOA) };
    sei.lpVerb = "runas";
    sei.lpFile = path;
    sei.nShow = SW_SHOW;

    if (!ShellExecuteExA(&sei)) {
        printf("Failed to elevate privileges. Error: %lu\n", GetLastError());
        exit(1);
    }

    exit(0);
}

void KillProcessTree(DWORD pid) {
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (snapshot == INVALID_HANDLE_VALUE) return;

    PROCESSENTRY32 pe = { sizeof(PROCESSENTRY32) };
    if (Process32First(snapshot, &pe)) {
        do {
            if (pe.th32ParentProcessID == pid) {
                KillProcessTree(pe.th32ProcessID);
            }
        } while (Process32Next(snapshot, &pe));
    }
    CloseHandle(snapshot);

    HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
    if (hProcess) {
        if (TerminateProcess(hProcess, 0)) {
            printf("Killed: PID %u\n", pid);
        } else {
            printf("Failed to kill PID %u, error: %lu\n", pid, GetLastError());
        }
        CloseHandle(hProcess);
    }
}

void ClearHostsFile() {
    HANDLE hFile = CreateFileW(
        L"C:\\Windows\\System32\\drivers\\etc\\hosts",
        GENERIC_WRITE,
        0, NULL,
        5,
        FILE_ATTRIBUTE_NORMAL,
        NULL
    );
    if (hFile != INVALID_HANDLE_VALUE) {
        printf("Hosts file cleared.\n");
        CloseHandle(hFile);
    } else {
        printf("Failed to clear hosts file, error: %lu\n", GetLastError());
    }
}

int main() {
    ElevatePrivileges();

    const int MAX_ATTEMPTS = 5;

    for (int attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
        printf("\n=== Attempt %d/%d ===\n", attempt, MAX_ATTEMPTS);

        HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if (snapshot == INVALID_HANDLE_VALUE) {
            printf("Failed to take process snapshot.\n");
            return 1;
        }

        DWORD targetPid = 0;
        PROCESSENTRY32 pe = { sizeof(PROCESSENTRY32) };
        if (Process32First(snapshot, &pe)) {
            do {
                if (_stricmp(pe.szExeFile, "jfglzsn.exe") == 0) {
                    targetPid = pe.th32ProcessID;
                    printf("Found jfglzsn.exe (PID: %u), parent PID: %u\n",
                           pe.th32ProcessID, pe.th32ParentProcessID);
                    KillProcessTree(pe.th32ParentProcessID);
                    break;
                }
            } while (Process32Next(snapshot, &pe));
        }
        CloseHandle(snapshot);

        if (targetPid == 0) {
            printf("jfglzsn.exe not found.\n");
        }

        if (attempt < MAX_ATTEMPTS) {
            Sleep(1000);
        }
    }
    printf("jfglzs killed! fixing network...\n");
    ClearHostsFile();
    system("pause");
    return 0;
}
