工具不好用的话,自己从零开始写一个吧

  • 注册表是系统定义的数据库,应用程序和系统组件在其中存储和检索配置数据。 存储在注册表中的数据因 Microsoft Windows 版本而异。 应用程序使用注册表 API 检索、修改或删除注册表数据。

注册表自启动(一个需要管理员权限,另一个不需要)

注册表介绍

结构

根键作用
HKEY_LOCAL_MACHINE是一个显示控制系统和软件的处理键。HKLM 键保存着计算机的系统信息。它包括网络和硬件上所有的软件设置
HKEY_CLASSES_ROOT是系统中控制所有数据文件的项。用于定义系统中所有已经注册的文件扩展名,文件类型,文件图标等,包含用于各种 OLE 技术和文件类关联数据的信息是从 hkey_local_machine\software\classes复制分离出来的
HKEY_USERS将缺省用户和目前登陆用户的信息输入到注册表编辑器。包含了所有独立用户(使用计算机的用户)的设置信息等是从 hkey_users\ 当前用户子树复制分离出的
HKEY_CURRENT_USER包含着在 HKEY_USERS 安全辨别里列出的同样信息。保存了本地计算机中存放的当前登录的用户信息,包括用户登录用户名和暂存的密码等
HKEY_CURRENT_CONFIG包括了系统中现有的所有配置文件的细节。HKEY_CURRENT_CONFIG 允许软件和设备驱动程序员很方便的更新注册表,而不涉及到多个配置文件信息。 HKEY_LOCAL_MACHINE 中同样的数据和任何注册表的变化都会同时的变化。如字体设置、显示器类型、打印机设置,显示的分辨率等是从 hkey_local_machine\config 复制分离出来的
  • 根键下面是项
根键注册表计算机下的分支,可以理解为文件夹,HKEY 作为前缀名的叫做根键
根键当中的子文件夹,项下面同样可以包含项和值
每个注册表项或子项都可以包含称为值的数据,部分值可以应用与某个用户的信息 或 应用与计算机中的所有用户的信息,可影响系统的实际数据

数据类型

显示类型说明
REG_SZ (字符串)文本字符串
REG_MULTI_SZ (多字符串)含有多个文本值的字符串
REG_BINARY (二进制数 )二进制值,以十六进制显示
REG_DWORD(双字)一个 32 位的二进制值,显示为 8 位的十六进制值
REG_LINK (链接)符号链接
REG_RESOURCE_LIST(二进制值)设备驱动程序资源列表
REG_EXPAND_SZ(可扩充字符串)扩展字符串,可以加入变量如 %PATH%

自启动方法

#include <iostream>
#include <Windows.h>

void ComputerStart(const char* pathName)
{
    // 路径   HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
    // 路径2  HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
    const char* szSubKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";
    HKEY phkResult;

    int k = RegOpenKeyExA(HKEY_CURRENT_USER, szSubKey, 0, KEY_ALL_ACCESS, &phkResult);
    // int k = RegOpenKeyExA(HKEY_LOCAL_MACHINE, szSubKey, 0, KEY_ALL_ACCESS, &phkResult); //需要管理员权限
    std::cout << phkResult << std::endl;
    if (k == ERROR_SUCCESS)
    {
        DWORD cbData = MAX_PATH;
        char ownerGet[MAX_PATH];
        DWORD valueType;

        // 查询启动项是否已经存在
        int ret = RegQueryValueExA(phkResult, "WeChat", NULL, &valueType, (BYTE*)ownerGet, &cbData);
        if (ret == ERROR_SUCCESS)
        {
            std::cout << "已注册" << std::endl;
            RegCloseKey(phkResult);
            return;
        }

        // 添加新的启动项
        if (RegSetValueExA(phkResult, "WeChat", 0, REG_SZ, (BYTE*)pathName, strlen(pathName) + 1) == ERROR_SUCCESS)
        {
            std::cout << "函数执行成功" << std::endl;
        }
        else
        {
            std::cout << "函数执行失败" << std::endl;
        }
        // 再次查询启动项是否写入成功
        DWORD cbData2 = MAX_PATH;
        char ownerGet2[MAX_PATH];
        DWORD valueType2;

        int ret2 = RegQueryValueExA(phkResult, "WeChat", NULL, &valueType2, (BYTE*)ownerGet2, &cbData2);
        if (ret2 == ERROR_SUCCESS)
        {
            std::cout << "写入成功" << std::endl;
        }
        else
        {
            std::cout << "已拦截" << std::endl;
        }
    }
    RegCloseKey(phkResult);
}

int main()
{
    ComputerStart("\"D:\\Tencent\\WeChat\\WeChat.exe\"");
    return 0;
}
  • 效果:嗯,很好,联想电脑管家给我拦截了,nnd。
  • 有关这个拦截,有必要再说一下,代码中写入后立刻查询会显示写入成功,所以估计是联想电脑管家实时监控注册表而非 HOOK 函数并拦截。联想电脑管家一旦拒绝自启动后,后续再执行就不会有弹窗了(离谱!),但是多次执行发现,“写入成功”和“已拦截”都会出现,可以见的联想电脑管家是对注册表进行恢复,而非拒绝写入。

自启动目录