Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 23 additions & 29 deletions src/cli/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,39 +179,33 @@ int main(int argc, char* argv[]) {
}

if (rich_requested) {
char env_buf[4];
bool already_spawned = GetEnvironmentVariableA("VMAWARE_RICH_SPAWN", env_buf, sizeof(env_buf)) > 0;
char exePath[MAX_PATH];
GetModuleFileNameA(NULL, exePath, MAX_PATH);

if (!already_spawned) {
char exePath[MAX_PATH];
GetModuleFileNameA(NULL, exePath, MAX_PATH);
char currentDir[MAX_PATH];
GetCurrentDirectoryA(MAX_PATH, currentDir);

char currentDir[MAX_PATH];
GetCurrentDirectoryA(MAX_PATH, currentDir);

std::string args = "\"" + std::string(exePath) + "\"";
for (int i = 1; i < argc; ++i) {
args += " \"";
args += argv[i];
args += "\"";
}

SHELLEXECUTEINFOA sei = { sizeof(sei) };
sei.fMask = 0;
sei.hwnd = NULL;
sei.lpVerb = "open";
sei.lpFile = "conhost.exe";
sei.lpParameters = args.c_str();
sei.lpDirectory = currentDir;
sei.nShow = SW_SHOWNORMAL;

SetEnvironmentVariableA("VMAWARE_RICH_SPAWN", "1");

if (!IsDebuggerPresent() && ShellExecuteExA(&sei)) {
ExitProcess(0);
std::string args = "\"" + std::string(exePath) + "\"";
for (int i = 1; i < argc; ++i) {
if (std::strcmp(argv[i], "--rich") == 0) {
continue;
}
args += " \"";
args += argv[i];
args += "\"";
}

SetEnvironmentVariableA("VMAWARE_RICH_SPAWN", nullptr);
SHELLEXECUTEINFOA sei = { sizeof(sei) };
sei.fMask = 0;
sei.hwnd = NULL;
sei.lpVerb = "open";
sei.lpFile = "conhost.exe";
sei.lpParameters = args.c_str();
sei.lpDirectory = currentDir;
sei.nShow = SW_SHOWNORMAL;

if (!IsDebuggerPresent() && ShellExecuteExA(&sei)) {
ExitProcess(0);
}
}

Expand Down
76 changes: 0 additions & 76 deletions src/cli/output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,82 +14,6 @@
#include <unistd.h>
#endif

#if (CLI_WINDOWS)
#include <dbghelp.h>

static void print_thread_stacktrace(HANDLE hThread, const std::string& label) {
// Freeze the thread so GetThreadContext returns a consistent snapshot.
SuspendThread(hThread);

CONTEXT ctx = {};
ctx.ContextFlags = CONTEXT_FULL;
if (!GetThreadContext(hThread, &ctx)) {
std::cerr << "[STACKTRACE] GetThreadContext failed (err " << GetLastError() << ")\n" << std::flush;
return; // caller will TerminateThread; no Resume needed
}

HANDLE hProc = GetCurrentProcess();

// SymInitialize must be called once per process.
static bool sym_ready = false;
if (!sym_ready) {
SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES);
sym_ready = SymInitialize(hProc, nullptr, TRUE) != FALSE;
}

STACKFRAME64 sf = {};
DWORD machine;

#if defined(_M_X64)
machine = IMAGE_FILE_MACHINE_AMD64;
sf.AddrPC.Offset = ctx.Rip; sf.AddrPC.Mode = AddrModeFlat;
sf.AddrFrame.Offset = ctx.Rbp; sf.AddrFrame.Mode = AddrModeFlat;
sf.AddrStack.Offset = ctx.Rsp; sf.AddrStack.Mode = AddrModeFlat;
#elif defined(_M_IX86)
machine = IMAGE_FILE_MACHINE_I386;
sf.AddrPC.Offset = ctx.Eip; sf.AddrPC.Mode = AddrModeFlat;
sf.AddrFrame.Offset = ctx.Ebp; sf.AddrFrame.Mode = AddrModeFlat;
sf.AddrStack.Offset = ctx.Esp; sf.AddrStack.Mode = AddrModeFlat;
#else
std::cerr << "[STACKTRACE] unsupported architecture\n" << std::flush;
return;
#endif

std::cerr << "[STACKTRACE] hung in " << label << ":\n";

alignas(SYMBOL_INFO) char sym_buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
SYMBOL_INFO* sym = reinterpret_cast<SYMBOL_INFO*>(sym_buf);

IMAGEHLP_LINE64 line_info = {};
line_info.SizeOfStruct = sizeof(IMAGEHLP_LINE64);

for (int n = 0; n < 32; ++n) {
if (!StackWalk64(machine, hProc, hThread, &sf, &ctx,
nullptr, SymFunctionTableAccess64, SymGetModuleBase64, nullptr)) {
break;
}
if (sf.AddrPC.Offset == 0) { break; }

std::cerr << " #" << std::dec << n
<< " 0x" << std::hex << std::setw(16) << std::setfill('0') << sf.AddrPC.Offset;

sym->SizeOfStruct = sizeof(SYMBOL_INFO);
sym->MaxNameLen = MAX_SYM_NAME;
DWORD64 sym_disp = 0;
if (sym_ready && SymFromAddr(hProc, sf.AddrPC.Offset, &sym_disp, sym)) {
std::cerr << " " << sym->Name << "+" << std::dec << sym_disp;
DWORD line_disp = 0;
if (SymGetLineFromAddr64(hProc, sf.AddrPC.Offset, &line_disp, &line_info)) {
std::cerr << " (" << line_info.FileName << ":" << line_info.LineNumber << ")";
}
}
std::cerr << "\n";
}
std::cerr << std::dec << std::setfill(' ') << std::flush;
// Caller TerminateThread; intentionally not ResumeThread here.
}
#endif

const char* color(const u8 score, const bool is_hardened) {
if (arg_bitset.test(NO_ANSI)) {
return "";
Expand Down
89 changes: 55 additions & 34 deletions src/vmaware.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12483,41 +12483,66 @@ struct VM {
return nullptr;
};

const HDEVINFO devs = SetupDiGetClassDevsW(nullptr, nullptr, nullptr, DIGCF_PRESENT | DIGCF_ALLCLASSES);
if (devs == INVALID_HANDLE_VALUE) return false;
const HDEVINFO devs =
SetupDiGetClassDevsW(nullptr, nullptr, nullptr,
DIGCF_PRESENT | DIGCF_ALLCLASSES);

if (devs == INVALID_HANDLE_VALUE)
return false;

SP_DEVINFO_DATA dev_info{};
dev_info.cbSize = sizeof(SP_DEVINFO_DATA);

DWORD buf_bytes = 4096;
BYTE* buffer = static_cast<BYTE*>(malloc(buf_bytes));
DWORD alloc_size = 4096 + 4;
BYTE* buffer = static_cast<BYTE*>(malloc(alloc_size));

if (!buffer) {
SetupDiDestroyDeviceInfoList(devs);
return false;
}

bool found = false;

for (DWORD idx = 0; SetupDiEnumDeviceInfo(devs, idx, &dev_info); ++idx) {
DWORD property_type = 0;
DWORD required = 0;
if (!SetupDiGetDeviceRegistryPropertyW(devs, &dev_info, SPDRP_HARDWAREID,
&property_type, buffer, buf_bytes, nullptr))

if (!SetupDiGetDeviceRegistryPropertyW(
devs,
&dev_info,
SPDRP_HARDWAREID,
&property_type,
buffer,
alloc_size > 4 ? alloc_size - 4 : 0,
&required))
{
const DWORD err = GetLastError();

if (err == ERROR_INSUFFICIENT_BUFFER) {
SetupDiGetDeviceRegistryPropertyW(devs, &dev_info, SPDRP_HARDWAREID,
&property_type, nullptr, 0, &required);
if (required > buf_bytes) {
BYTE* new_buffer = static_cast<BYTE*>(realloc(buffer, required + 4));
if (!new_buffer) {
found = false;
break;
}
const DWORD needed_size = required + 4;

if (needed_size > alloc_size) {
BYTE* new_buffer =
static_cast<BYTE*>(realloc(buffer, needed_size));

if (!new_buffer) {
found = false;
break;
}

buffer = new_buffer;
buf_bytes = required;
alloc_size = needed_size;
}
if (!SetupDiGetDeviceRegistryPropertyW(devs, &dev_info, SPDRP_HARDWAREID,
&property_type, buffer, buf_bytes, nullptr)) {

if (!SetupDiGetDeviceRegistryPropertyW(
devs,
&dev_info,
SPDRP_HARDWAREID,
&property_type,
buffer,
alloc_size > 4 ? alloc_size - 4 : 0,
&required))
{
continue;
}
}
Expand All @@ -12526,30 +12551,35 @@ struct VM {
}
}

if (property_type != REG_MULTI_SZ) continue;
if (property_type != REG_MULTI_SZ)
continue;

if (required <= buf_bytes) {
buffer[required] = 0;
if (required + 4 <= alloc_size) {
buffer[required + 0] = 0;
buffer[required + 1] = 0;
buffer[required + 2] = 0;
buffer[required + 3] = 0;
}

wchar_t* cur = reinterpret_cast<wchar_t*>(buffer);

while (*cur) {
if (wcsstr_ci_ascii(cur)) {
found = true;
break;
}

cur += wcslen(cur) + 1;
}
if (found) break;

if (found)
break;
}

free(buffer);
SetupDiDestroyDeviceInfoList(devs);
return !found;
free(buffer);
SetupDiDestroyDeviceInfoList(devs);

return !found;
#endif
}

Expand Down Expand Up @@ -13596,11 +13626,6 @@ struct VM {

// run every VM detection mechanism in the technique table
static u16 run_all(const flagset& flags, const bool shortcut = false) {
for (size_t i = 0; i < MAX_BRANDS; ++i) {
brand_scoreboard.at(i).score = 0;
}
detected_count_num.store(0);

u16 points = 0;

u16 threshold_points = threshold_score;
Expand Down Expand Up @@ -13630,10 +13655,6 @@ struct VM {

if (data.result) {
points += data.points;
detected_count_num++;
if (data.brand_name != brand_enum::NULL_BRAND) {
core::add(data.brand_name, data.points);
}
}

continue;
Expand Down
Loading