一个简单的无限弹窗整蛊程序的C++实现

简介

本文将为您介绍一个通过 C++ 编写的有趣整蛊程序。它会在屏幕上创建多个动态弹窗,并通过智能定位算法避免弹窗重叠,达到无限弹窗的效果。程序充分利用了多线程、随机数生成以及自定义窗口创建等技术。如果您对 Windows 开发、系统事件处理和螺旋算法感兴趣,这将是一个极好的学习案例。

警告: 本程序仅供学习和研究使用,严禁将其用于任何非法用途或骚扰他人。

功能亮点

  • 智能窗口位置计算: 使用螺旋路径算法,结合随机扰动,确保弹窗的分布尽量均匀,并避免位置重复或过于密集。
  • 多线程弹窗生成: 主线程负责维持程序运行,多个工作线程持续生成弹窗,模拟病毒式扩散。
  • 动态窗口内容与尺寸: 每个弹窗显示特定文本,且大小随机,增强视觉冲击力。
  • 隐身运行: 程序启动后会隐藏控制台窗口,悄悄运行在后台。

核心功能代码解析

1. 螺旋路径算法

程序设计了一个基于极坐标的螺旋路径生成器,计算弹窗初始位置:

POINT PolarToCartesian(int radius, double angle) {
    return {
        static_cast<LONG>(radius * cos(angle)),
        static_cast<LONG>(radius * sin(angle))};
}

通过逐步增加极角 θ 和半径 r,生成螺旋路径点:

POINT NextSpiralPoint() {
    const double theta = tracker.spiralStep * 0.1;
    const int radius = SPIRAL_DENSITY * theta;
    POINT pt = PolarToCartesian(radius, theta);
    // 更新螺旋步进状态
    tracker.spiralStep++;
    return pt;
}

2. 智能定位与碰撞检测

螺旋算法生成的弹窗位置会经过碰撞检测,避免与其他弹窗重叠:

bool CheckCollision(const POINT &newPos, const SIZE &newSize) {
    for (size_t i = 0; i < tracker.positions.size(); ++i) {
        const POINT &existPos = tracker.positions[i];
        const SIZE &existSize = tracker.sizes[i];
        bool xOverlap = abs(newPos.x - existPos.x) * 2 < (newSize.cx + existSize.cx);
        bool yOverlap = abs(newPos.y - existPos.y) * 2 < (newSize.cy + existSize.cy);
        if (xOverlap && yOverlap) return true;
    }
    return false;
}

若某次计算的螺旋点存在重叠,程序会在随机位置生成弹窗。

3. 自定义窗口创建

每个弹窗使用 Windows API 的 CreateWindowExW 创建,显示用户定义的内容:

void CreateCustomWindow(POINT pos, SIZE size, const std::wstring &text) {
    WNDCLASSW wc = {};  // 定义窗口类
    wc.lpfnWndProc = WindowProc; // 自定义窗口过程
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    RegisterClassW(&wc);  // 注册窗口类
    // 创建窗口
    CreateWindowExW(
        WS_EX_TOPMOST, L"CustomWindowClass", NULL, WS_POPUP | WS_VISIBLE,
        pos.x, pos.y, size.cx, size.cy,
        NULL, NULL, GetModuleHandle(NULL), const_cast<LPWSTR>(text.c_str()));
}

窗口内容通过 WM_PAINT 消息处理显示红色字体警告:

case WM_PAINT: {
    SetTextColor(hdc, RGB(255, 0, 0)); // 红色字体
    DrawTextW(hdc, content.c_str(), -1, &ps.rcPaint, DT_CENTER | DT_VCENTER);
}

4. 弹窗线程与隐身模式

弹窗生成逻辑运行在独立线程中,程序启动时隐藏控制台窗口以增加隐蔽性:

void StealthMode() {
    HWND console = GetConsoleWindow();
    ShowWindow(console, SW_HIDE);  // 隐藏控制台窗口
    FreeConsole();                // 释放控制台资源
}

5. 无限循环弹窗

主线程启动一个弹窗生成线程,后者以随机间隔反复创建窗口:

void MessageBoxThread() {
    for (;;) {
        SIZE windowSize = {sizeDist(rng), sizeDist(rng)};
        POINT pos = SmartPositioning(windowSize);
        CreateCustomWindow(pos, windowSize, L"SYSTEM COMPROMISED!");
        this_thread::sleep_for(chrono::milliseconds(rng() % 50));
    }
}

运行效果

程序运行后,屏幕将随机出现多个弹窗,内容为红色警告信息,窗口尺寸和位置动态变化。弹窗生成迅速且分布均匀,不会产生堆叠效果。

源码

#include <windows.h>
#include <thread>
#include <vector>
#include <atomic>
#include <cmath>
#include <random>
#include <mutex>

using namespace std;

// 窗口位置追踪器
struct WindowTracker {
    mutex mtx;
    vector<POINT> positions;  // 已存在窗口的中心坐标
    vector<SIZE> sizes;       // 已存在窗口的尺寸
    POINT lastSpiral{0, 0};   // 螺旋生成器状态
    int spiralStep = 0;       // 螺旋步进计数器
};

WindowTracker tracker;  // 全局追踪器

// 螺旋算法参数
const int SPIRAL_DENSITY = 50;  // 螺旋密度系数
const int MIN_DISTANCE = 100;   // 窗口间最小间距

// 获取伪随机数生成器
mt19937 &GetRNG() {
    static thread_local mt19937 rng(random_device{}());
    return rng;
}

// 极坐标转笛卡尔坐标
POINT PolarToCartesian(int radius, double angle) {
    return {
        static_cast<LONG>(radius * cos(angle)),
        static_cast<LONG>(radius * sin(angle))};
}

// 生成螺旋路径坐标
POINT NextSpiralPoint() {
    lock_guard<mutex> lock(tracker.mtx);

    // 阿基米德螺旋公式:r = a + bθ
    const double theta = tracker.spiralStep * 0.1;
    const int radius = SPIRAL_DENSITY * theta;

    POINT pt = PolarToCartesian(radius, theta);
    pt.x += tracker.lastSpiral.x;
    pt.y += tracker.lastSpiral.y;

    // 步进控制
    tracker.spiralStep++;
    if (tracker.spiralStep % 100 == 0) {
        tracker.lastSpiral = pt;
        tracker.spiralStep = 0;
    }
    return pt;
}

// 碰撞检测算法
bool CheckCollision(const POINT &newPos, const SIZE &newSize) {
    for (size_t i = 0; i < tracker.positions.size(); ++i) {
        const POINT &existPos = tracker.positions[i];
        const SIZE &existSize = tracker.sizes[i];

        // 快速AABB碰撞检测
        bool xOverlap = abs(newPos.x - existPos.x) * 2 <
                        (newSize.cx + existSize.cx);
        bool yOverlap = abs(newPos.y - existPos.y) * 2 <
                        (newSize.cy + existSize.cy);

        if (xOverlap && yOverlap)
            return true;
    }
    return false;
}

// 智能定位引擎
POINT SmartPositioning(SIZE windowSize) {
    uniform_int_distribution<int> dist(-50, 50);
    uniform_int_distribution<int> screenX(0, GetSystemMetrics(SM_CXSCREEN));
    uniform_int_distribution<int> screenY(0, GetSystemMetrics(SM_CYSCREEN));
    POINT candidate;

    // 混合策略:80%螺旋定位 + 20%随机扰动
    for (int attempt = 0; attempt < 100; ++attempt) {
        if (attempt < 80) {
            candidate = NextSpiralPoint();
            // 添加随机扰动
            candidate.x += dist(GetRNG());
            candidate.y += dist(GetRNG());
        } else {
            // 使用分布对象生成随机位置
            candidate.x = screenX(GetRNG());
            candidate.y = screenY(GetRNG());
        }

        // 边界检查(显式类型转换)
        candidate.x = max(0L, min(
                               static_cast<LONG>(candidate.x),
                               GetSystemMetrics(SM_CXSCREEN) - windowSize.cx));
        candidate.y = max(0L, min(
                               static_cast<LONG>(candidate.y),
                               GetSystemMetrics(SM_CYSCREEN) - windowSize.cy));

        // 碰撞检测
        if (!CheckCollision(candidate, windowSize))
            return candidate;
    }
    return candidate; // 强制返回最后位置
}

// 自定义窗口过程
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    static wstring content = L"";

    switch (uMsg) {
    case WM_CREATE: {
        // 获取创建窗口时传递的文本
        content = reinterpret_cast<LPCWSTR>(reinterpret_cast<CREATESTRUCT *>(lParam)->lpCreateParams);
        break;
    }
    case WM_PAINT: {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps);

        // 设置字体与颜色
        SetBkMode(hdc, TRANSPARENT);
        SetTextColor(hdc, RGB(255, 0, 0)); // 红色字体
        DrawTextW(hdc, content.c_str(), -1, &ps.rcPaint, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

        EndPaint(hwnd, &ps);
        break;
    }
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    return 0;
}

// 注册并创建窗口
// 注册并创建窗口
void CreateCustomWindow(POINT pos, SIZE size, const std::wstring &text) {
    static bool isRegistered = false;

    if (!isRegistered) {
        WNDCLASSW wc = {};  // 使用宽字符版本的 WNDCLASS
        wc.lpfnWndProc = WindowProc;
        wc.hInstance = GetModuleHandle(NULL);
        wc.lpszClassName = L"CustomWindowClass";  // 窗口类名也必须是宽字符
        wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
        RegisterClassW(&wc);  // 使用宽字符版本的 RegisterClass
        isRegistered = true;
    }

    // 创建窗口
    CreateWindowExW(
        WS_EX_TOPMOST, L"CustomWindowClass", NULL, WS_POPUP | WS_VISIBLE,
        pos.x, pos.y, size.cx, size.cy,
        NULL, NULL, GetModuleHandle(NULL), const_cast<LPWSTR>(text.c_str()));
}

// 弹窗线程(带智能定位)
void MessageBoxThread() {
    auto &rng = GetRNG();
    uniform_int_distribution<int> sizeDist(300, 600);

    for (;;) {
        // 动态窗口尺寸
        SIZE windowSize = {
            sizeDist(rng), // 宽度 300-600
            sizeDist(rng)  // 高度 300-600
        };

        // 获取智能位置
        POINT pos = SmartPositioning(windowSize);

        // 动态文本内容
        wstring text = L"SYSTEM COMPROMISED!\nImmediate shutdown required!";

        // 创建窗口并显示内容
        CreateCustomWindow(pos, windowSize, text);

        // 动态间隔控制(0-50ms随机)
        this_thread::sleep_for(chrono::milliseconds(rng() % 50));
    }
}

// 启动隐身模式
void StealthMode() {
    HWND console = GetConsoleWindow();
    ShowWindow(console, SW_HIDE);
    FreeConsole();
}

int main() {
    StealthMode();

    // 启动弹窗线程
    vector<thread> pool;
    pool.emplace_back(MessageBoxThread);

    // 防止主线程退出
    for (;;) {
        this_thread::sleep_for(1h);
    }
}

 注意,由于使用了gdi,所以编译脚本有所改变:g++ -o BlackZone.exe BlackZone.cpp -lgdi32 -luser32

总结

本文展示的 C++ 程序是一个有趣的整蛊项目,融合了螺旋算法、碰撞检测、多线程处理等多项技术,展现了复杂系统中窗口管理的核心思路。在编写过程中,需要注意资源管理(如线程与窗口对象的清理)、边界检测和性能优化。

再次提醒: 本程序仅限于学习用途,请勿在未经许可的情况下运行于他人设备。

阅读剩余
THE END