初衷:

之前windows有些问题,下了个金山毒霸来了套全家福,但是由于它每次开机都会自动启动,本人又不忍心一下删了它(其实是不想下次急需时再安装=。=),觉得每次开机后都要手动关太心累了!!!于是乎便写了个弱弱的程序让电脑开机自动执行—— Kill Kingsoft。(ps:其实没有太多含量,只是能按需求work,和我有一样烦恼的小伙伴可以参考。。。大神请绕道😳 )

代码:

// KillKingSoft.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <Windows.h>
#include <tlhelp32.h>

DWORD GetProcessIdFromName(TCHAR *szTargetProcessName)
{
    HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if(hSnap == INVALID_HANDLE_VALUE)
        return 0;

    PROCESSENTRY32 pe;
    pe.dwSize = sizeof(pe);

    DWORD dwProcessId = 0;
    BOOL bResult = Process32First(hSnap, &pe);

    while(bResult){
        if(!lstrcmp(pe.szExeFile, szTargetProcessName)){
            dwProcessId = pe.th32ProcessID;
            break;
        }
        bResult = Process32Next(hSnap, &pe);
    }
    CloseHandle(hSnap);

    return dwProcessId;
}


void killProcessByName(TCHAR *szTargetProcessName)
{
    HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if(hSnap == INVALID_HANDLE_VALUE)
        return;

    PROCESSENTRY32 pe;
    pe.dwSize = sizeof(pe);

    DWORD dwProcessId = 0;
    BOOL bResult = Process32First(hSnap, &pe);

    while(bResult){
        if(!lstrcmp(pe.szExeFile, szTargetProcessName)){
            wprintf(L"processname: %s -- pid: %d       ", szTargetProcessName, pe.th32ProcessID);
            HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, (DWORD)pe.th32ProcessID);
            if (hProcess != NULL)
            {
                int res = TerminateProcess(hProcess, 0);
                wprintf(L"terminate res: %d\n", res);
                CloseHandle(hProcess);
            }
        }
        bResult = Process32Next(hSnap, &pe);
    }
    CloseHandle(hSnap);
}


int _tmain(int argc, _TCHAR* argv[])
{
    Sleep(60000); //wait 1 min for process kxescore.exe... starting up
    TCHAR processNames[6][20] = {L"kxescore.exe"L"kxetray.exe",L"kwsprotect64.exe",L"kislive.exe",L"ntsd.exe"};
    DWORD pids[6],
    for(int i=0;i<3;i++)
    {
        pids[i] = GetProcessIdFromName(processNames[i]);
        wprintf(L"process: %s  |  pid:%d\n", processNames[i], pids[i]);
        CHAR kill_cmd[20] = "ntsd -c q -p ";
        CHAR pid_str[6];
        _itoa_s(pids[i], pid_str, 10);
        strcat_s(kill_cmd,pid_str);
        printf("kill cmd: %s\n", kill_cmd);
        WinExec(kill_cmd, SW_HIDE);
    }
    Sleep(2000);
    killProcessByName(processNames[4]);
    return 0;
}

将编译生成的可执行程序放在 【开始菜单->启动】文件夹下即可。

简单分析:

GetProcessIdFromName()这个没什么好说的,就是遍历系统当前所有进程,逐一匹配进程名,一旦相同即返回进行pid。

当获得pid时,直接调用OpenProcess()和TerminateProcess()来杀死金山毒霸的几个进程是会失败的,因为权限不够(和你直接在任务管理器或process explorer里手动杀掉进程是一样的)

网上查到有这么一个用户态进程调试工具ntsd,它能杀掉除几个系统进程之外的所有进程;由于工作在用户态,因此对于拥有内核态保护机制的程序(主要指杀毒软件),ntsd无法将其结束。

工具原理:调试器关闭时,由它打开的进程会随着调试器一起退出,因此能起到关闭进程的作用。

命令:ntsd -c q -p pid

-c:表示执行接下来的调试命令

q:表示quit的命令,即-c q表示退出调试器

-p:表示添加要调试的进程pid

(后来一查,它还支持利用进程名结束进程:ntsd -c q -pn xxx.exe,那就不用先获取pid了=。=)

这里我们使用WinExec来执行命令,其中第一个参数为命令行,第二个参数为窗口显示。由于我们希望该程序能在后台执行,不需要人参与,因此第二个参数设置为SW_HIDE,即隐藏窗口。

正常来说,若存在目标进程,ntsd即能正常运行,然后自己就退出了;但如果目标进程不存在,ntsd会打开一个窗口,输出错误信息,等待用户按键退出,但又由于我们设置为隐藏窗口了,因此该ntsd.exe进程会一直存在,所以这里我们最后还通过TerminateProcess()把可能未正常结束的ntsd.exe进程关闭。又由于ntds是调试工具,执行命令需要些时间,因此我们等待2s后再关闭ntsd.exe进程。

最后一点:由于金山毒霸相关进程开启需要一些时间,而我们的KillKingsoft.exe进程运行得会比它早,因此这里我们先sleep1分钟等待相关进程启动后再work。

最后的最后:对于开机启动的程序,它们一般有这几种常见的途径来实现开机启动(下面展示是window7版本的)

(1) “启动”文件夹:【开始菜单->启动】,对应的文件夹:"C:\Users\<用户名字>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup"

(2) 注册表: 最常见的为 "HKEY_LOCALMACHINE(或 HKEY_CURRENT_USER)-> SOFTWARE -> Micrsoft (或 Wow6432Node -> Microsoft) -> Windows -> CurrentVersion -> Run"

(3) 任务计划程序:输入Taskschd.msc命令,或者打开【控制面板->系统和安全->管理工具->任务计划程序】,可以创建任务,选择只在用户登录时运行,这样的话也能实现开机用户登录启动目标程序

上面前2种设置方法,最后可以在启动项中查看到。查看启动项的方法:msconfig命令,或者打开 【控制面板->系统和安全->管理工具->系统配置->启动】

【后记】

后来有一次偶然发现,在它的设置中可以选择“取消开机启动”。。。。。。

这个故事告诉我们,凡事还是要搞清楚再行动,不然就是吃力不讨好了zzz

results matching ""

    No results matching ""