Skip to main content
1 of 3
coderodde
  • 32k
  • 15
  • 78
  • 204

An improved sample C++/WinAPI malware program for Windows (includes the program that uninstalls it completely)

(See the GitHub repository for a Visual Studio (2022) solution/projects.)

Code

SampleMalwareV2\SampleMalwareV2Executable\main.cpp:

#include <Windows.h>
#include <sstream>

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   PSTR lpCmdLine,
                   int nCmdShow) {

    UNREFERENCED_PARAMETER(hInstance);
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);
    UNREFERENCED_PARAMETER(nCmdShow);

    std::stringstream ss;

    for (int i = 0; i < 3; i++) {
        ss << "This is the iteration "
            << (i + 1)
            << " out of 3 for SampleMalwareV2Executable.exe!";

        MessageBoxA(GetDesktopWindow(),
            ss.str().c_str(),
            "",
            MB_OK);

        ss.clear();
        ss.str(std::string());
    }

    return 0;
}

SampleMalwareV2\SampleMalwareV2Installer\main.cpp:

#include "../SampleMalwareV2Utils/RegistryUtils.h"
#include "../SampleMalwareV2Utils/FileSystemUtils.h"
#include "../SampleMalwareV2Utils/MiscUtils.h"
#include <Windows.h>
#include <cstdlib>
#include <filesystem>
#include <iostream>
#include <system_error>

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR     lpCmdLine,
                   int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hInstance);
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);
    UNREFERENCED_PARAMETER(nCmdShow);

    LSTATUS status = SetSampleMalwareRegistryKey();

    if (status != ERROR_SUCCESS) {
        std::string errorMsg = "Could not set a registry key.\n"
                               "Windows message: " + GetErrorMessage(status);

        ReportError(errorMsg);
        return EXIT_FAILURE;
    }

    std::error_code errorCode = CopySampleMalwareFileToSystemFolder();

    if (errorCode.value() != ERROR_SUCCESS) {
        std::string errorMsg = "Could not copy the executable.\n"
                               "Windows message: "
                               + GetErrorMessage(errorCode.value());

        ReportError(errorMsg.c_str());

        status = DeleteSampleMalwareRegistryKey();

        if (status != ERROR_SUCCESS) {
            std::string errorMsg = "Could not clean created registry key.\n"
                                   "Windows message: "
                                   + GetErrorMessage(status);

            ReportError(errorMsg.c_str());
        }

        return EXIT_FAILURE;
    }

    ReportInfo("Successfully installed SampleMalwareV2Executable.exe!");

    return EXIT_SUCCESS;
}

SampleMalwareV2\SampleMalwareV2Uninstaller\main.cpp:

#include "../SampleMalwareV2Utils/RegistryUtils.h"
#include "../SampleMalwareV2Utils/FileSystemUtils.h"
#include "../SampleMalwareV2Utils/MiscUtils.h"
#include <Windows.h>
#include <iostream>
#include <string>

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   PSTR lpCmdLine,
                   int nCmdShow) {

    UNREFERENCED_PARAMETER(hInstance);
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);
    UNREFERENCED_PARAMETER(nCmdShow);

    const bool deletionSucceeded = DeleteSampleMalwareFileFromSystemFolder();

    int exitStatus = EXIT_SUCCESS;

    if (deletionSucceeded == false) {
        std::string errorMessage =
            "Could not delete SampleMalwareV2Executable.exe from "
            + GetTargetPath().string()
            + "!";

        ReportError(errorMessage.c_str());
        exitStatus = EXIT_FAILURE;
    }

    const LSTATUS status = DeleteSampleMalwareRegistryKey();

    if (status != ERROR_SUCCESS) {
        ReportError(GetErrorMessage(status));
        exitStatus = EXIT_FAILURE;
    }

    if (exitStatus == EXIT_SUCCESS) {
        ReportInfo("Successfully removed SampleMalwareV2Executable.exe from your system.");
    }

    return exitStatus;
}

SampleMalwareV2\SampleMalwareV2Utils\FileSystemUtils.h:

#ifndef COM_GITHUB_CODERODDE_SAMPLE_MALWARE_FS_UTILS_HPP
#define COM_GITHUB_CODERODDE_SAMPLE_MALWARE_FS_UTILS_HPP

#include "../SampleMalwareV2Utils/MiscUtils.h"
#include <Windows.h>
#include <cstdlib>
#include <filesystem>
#include <string>
#include <system_error>

namespace fs = std::filesystem;

static const std::string SAMPLE_MALWARE_NAME = "SampleMalwareV2Executable.exe";
static const fs::path SAMPLE_MALWARE_PATH = SAMPLE_MALWARE_NAME;

static fs::path GetTargetPath() {
    CHAR pathBuffer[MAX_PATH];

    UINT ret = GetSystemDirectoryA(pathBuffer, sizeof(pathBuffer));

    if (ret > sizeof(pathBuffer)) {
        ReportError(GetErrorMessage(GetLastError()));
        std::exit(EXIT_FAILURE);
    }

    std::string pathString =
        std::string(pathBuffer) + "\\" + SAMPLE_MALWARE_NAME;

    return fs::path(pathString);
}

const std::error_code CopySampleMalwareFileToSystemFolder() {
    fs::path sourcePath = SAMPLE_MALWARE_NAME;
    fs::path targetPath = GetTargetPath();
    fs::copy_options copyOptions = fs::copy_options::overwrite_existing;
    std::error_code errorCode;

    fs::copy(sourcePath,
        targetPath,
        copyOptions,
        errorCode);

    return std::error_code(errorCode);
}

const bool DeleteSampleMalwareFileFromSystemFolder() {
    fs::path targetPath = GetTargetPath();
    return fs::remove(targetPath);
}

#endif

SampleMalwareV2\SampleMalwareV2Utils\MiscUtils.h:

#ifndef COM_GITHUB_CODERODDE_SAMPLE_MALWARE_MISC_UTILS_HPP
#define COM_GITHUB_CODERODDE_SAMPLE_MALWARE_MISC_UTILS_HPP

#include <Windows.h>
#include <string>

std::string GetErrorMessage(DWORD dwErrorCode) {
    LPSTR psz{ nullptr };

    FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
        0,
        dwErrorCode,
        MAKELANGID(LANG_NEUTRAL,
            SUBLANG_DEFAULT),
        reinterpret_cast<LPSTR>(&psz),
        0,
        NULL);

    return std::string(static_cast<char*>(psz));
}

void ReportError(const std::string& errorMessage) {

    MessageBoxA(GetDesktopWindow(),
        errorMessage.c_str(),
        "",
        MB_OK | MB_ICONEXCLAMATION);
}

void ReportInfo(const std::string& infoMessage) {

    MessageBoxA(GetDesktopWindow(),
        infoMessage.c_str(),
        "",
        MB_OK | MB_ICONINFORMATION);
}

#endif  

SampleMalwareV2\SampleMalwareV2Utils\RegistryUtils.h:

#ifndef COM_GITHUB_CODERODDE_SAMPLE_MALWARE_REGISTRY_UTILS_HPP
#define COM_GITHUB_CODERODDE_SAMPLE_MALWARE_REGISTRY_UTILS_HPP

#include "MiscUtils.h"
#include <Windows.h>
#include <string>

static const std::string REGISTRY_KEY_PATH =
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";

static const std::string REGISTRY_KEY_VALUE =
"%windir%\\System32\\SampleMalwareV2Executable.exe";

static const std::string REGISTRY_KEY_NAME = "SampleMalware";

LSTATUS SetSampleMalwareRegistryKey() {

    const std::string keyName = REGISTRY_KEY_PATH 
                              + "\\" 
                              + REGISTRY_KEY_NAME;
    LSTATUS status = 
    RegSetKeyValueA(HKEY_LOCAL_MACHINE, 
                    REGISTRY_KEY_PATH.c_str(),
                    REGISTRY_KEY_NAME.c_str(),
                    REG_EXPAND_SZ, 
                    REGISTRY_KEY_VALUE.c_str(),
                    REGISTRY_KEY_VALUE.length() + 1);

    return status;
}
 
LSTATUS DeleteSampleMalwareRegistryKey() {

    HKEY hKey;

    LSTATUS status = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
                                   REGISTRY_KEY_PATH.c_str(),
                                   0,
                                   KEY_ALL_ACCESS,
                                   &hKey);
    
    if (status != ERROR_SUCCESS) {
        return status;
    }

    status = RegDeleteValueA(hKey, "SampleMalware");

    RegCloseKey(hKey);
    return status;
}

#endif

Critique request

As always, I am eager to hear any constructive commentary on my attempt.

coderodde
  • 32k
  • 15
  • 78
  • 204