Skip to content

Commit

Permalink
added proc matcher technique
Browse files Browse the repository at this point in the history
  • Loading branch information
kernelwernel committed Oct 17, 2023
1 parent 2cb2db6 commit 12c6a35
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 23 deletions.
6 changes: 3 additions & 3 deletions docs/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ int main() {
# `VM::check()`
This takes a single flag argument and returns a `bool`. It's essentially the same as `VM::detect()` but it doesn't have a scoring system. It only returns the technique's effective output. The reason why this exists is because it allows end-users to have fine-grained control over what is being executed and what isn't.

`VM::detect()` is meant for a range of techniques to be evaluated in the bigger picture with weights and biases in its scoring system, while `VM::check()` is meant for a single technique to be evaluated without any weighted points or anything extra. It just gives you what the technique has found on its own. For example:
`VM::detect()` is meant for a range of techniques to be evaluated in the bigger picture with weights and biases in its scoring system, while `VM::check()` is meant for a single technique to be evaluated without any points or anything extra. It just gives you what the technique has found on its own. For example:

```cpp
if (VM::check(VM::VMID)) {
Expand Down Expand Up @@ -118,10 +118,10 @@ VMAware provides a convenient way to not only check for VMs, but also have the f
| `VM::VBOX_NETWORK` | Check VBox network provider string | Windows | 70% |
| `VM::COMPUTER_NAME` | Check for computer name string | Windows | 40% |
| `VM::MEMORY` | Check if memory space is far too low for a physical machine | Windows | 35% |

| `VM::VM_PROCESSES` | Check for any VM processes that are active | Windows | 30% |

# Non-technique flags
| Flag | Description |
|------|-------------|
| `VM::ALL` | This will enable all the flags technique flags, including the cursor check. |
| `VM::ALL` | This will enable all the technique flags, including the cursor check. |
| `VM::NO_MEMO` | This will disable memoization, meaning the result will not be fetched through a previous computation of the VM::detect function. Not sure why you'd need this, but it will take a performance hit if enabled. |
5 changes: 5 additions & 0 deletions src/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ int main(int argc, char* argv[]) {
checker(VM::HWMODEL, "hw.model");
checker(VM::DISK_SIZE, "disk size");
checker(VM::VBOX_DEFAULT, "VBox default specs");
checker(VM::VBOX_NETWORK, "VBox network provider match");
checker(VM::COMPUTER_NAME, "computer name");
checker(VM::HOSTNAME, "hostname");
checker(VM::MEMORY, "low memory space");
checker(VM::VM_PROCESSES, "VM processes");
std::printf("\n");

std::cout << "VM brand: " << (std::string(VM::brand()) == "Unknown" ? red : green) << VM::brand() << ansi_exit << "\n\n";
Expand Down
123 changes: 103 additions & 20 deletions src/vmaware.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ struct VM {
WINE = "Wine",
VAPPLE = "Virtual Apple",
VPC = "Virtual PC",
ANUBIS = "Anubis";
ANUBIS = "Anubis",
JOEBOX = "JoeBox";

// VM scoreboard table specifically for VM::brand()
static inline std::map<sv, u8> scoreboard {
Expand All @@ -226,8 +227,8 @@ struct VM {
{ WINE, 0 },
{ VAPPLE, 0 },
{ VPC, 0 },
{ ANUBIS, 0 }

{ ANUBIS, 0 },
{ JOEBOX, 0 }
};

// check if cpuid is supported
Expand Down Expand Up @@ -302,8 +303,8 @@ struct VM {
#if (!LINUX)
return false;
#else
uid_t uid = getuid();
uid_t euid = geteuid();
const uid_t uid = getuid();
const uid_t euid = geteuid();

return (
(uid != euid) ||
Expand Down Expand Up @@ -460,8 +461,8 @@ struct VM {
GlobalMemoryStatusEx(&statex); // calls NtQuerySystemInformation
return statex.ullTotalPhys;
#elif (LINUX)
i64 pages = sysconf(_SC_PHYS_PAGES);
i64 page_size = sysconf(_SC_PAGE_SIZE);
const i64 pages = sysconf(_SC_PHYS_PAGES);
const i64 page_size = sysconf(_SC_PAGE_SIZE);
return (pages * page_size);
#elif (APPLE)
i32 mib[2] = { CTL_HW, HW_MEMSIZE };
Expand Down Expand Up @@ -548,6 +549,7 @@ struct VM {
COMPUTER_NAME = 1ULL << 33,
HOSTNAME = 1ULL << 34,
MEMORY = 1ULL << 35,
VM_PROCESSES = 1ULL << 36,

// settings
NO_MEMO = 1ULL << 63,
Expand Down Expand Up @@ -2098,6 +2100,7 @@ struct VM {
/**
* @brief Check if memory is too low
* @author Al-Khaser project
* @category x86?
*/
[[nodiscard]] static bool low_memory_space() try {
if (disabled(MEMORY)) {
Expand All @@ -2110,16 +2113,90 @@ struct VM {
} catch (...) { return false; }


/**
* @brief Check for any VM processes that are active
* @category Windows
*/
[[nodiscard]] static bool vm_processes() try {
if (disabled(VM_PROCESSES)) {
return false;
}

#if (!MSVC)
return false;
#else
auto check_proc = [](const char* proc) -> bool {
HANDLE hSnapshot;
PROCESSENTRY32 pe = {};

pe.dwSize = sizeof(pe);
bool present = false;
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if (hSnapshot == INVALID_HANDLE_VALUE) {
return false;
}

if (Process32First(hSnapshot, &pe)) {
do {
if (!StrCmpI(pe.szExeFile, proc_name.c_str())) {
present = true;
break;
}
} while (Process32Next(hSnapshot, &pe));
}

CloseHandle(hSnapshot);

return present;
};

if (check_proc("joeboxserver.exe") || check_proc("joeboxcontrol.exe")) {
return add(JOEBOX);
}

if (check_proc("prl_cc.exe") || check_proc("prl_tools.exe")) {
return add(PARALLELS);
}

if (check_proc("vboxservice.exe") || check_proc("vboxtray.exe")) {
return add(VBOX);
}

if (check_proc("vmsrvc.exe") || check_proc("vmusrvc.exe")) {
return add(VPC);
}

if (
check_proc("vmtoolsd.exe") ||
check_proc("vmacthlp.exe") ||
check_proc("vmwaretray.exe") ||
check_proc("vmwareuser.exe") ||
check_proc("vmware.exe") ||
check_proc("vmount2.exe")
) {
return add(VMWARE);
}

if (check_proc("xenservice.exe") || check_proc("xsvc_depriv.exe")) {
return add(XEN);
}

return false;
#endif
} catch (...) { return false; }


// __LABEL (ignore this, it's just a label so I can easily teleport to this line on my IDE with CTRL+F)


struct data {
struct technique {
u8 points;
bool(*ptr)(); // function pointer
};

// the points are debatable, but I think it's fine how it is. Feel free to disagree.
static inline std::map<u64, data> table = {
static inline std::map<u64, technique> table = {
{ VM::VMID, { 100, vmid }},
{ VM::BRAND, { 50, cpu_brand }},
{ VM::HYPERV_BIT, { 95, cpuid_hyperv }},
Expand Down Expand Up @@ -2155,7 +2232,8 @@ struct VM {
{ VM::VBOX_NETWORK, { 70, vbox_network_share }},
{ VM::COMPUTER_NAME, { 40, computer_name_match }},
{ VM::HOSTNAME, { 25, hostname_match }},
{ VM::MEMORY, { 35, low_memory_space }}
{ VM::MEMORY, { 35, low_memory_space }},
{ VM::VM_PROCESSES, { 30, vm_processes }}

// { VM::, { , }}
// ^ line template for personal use
Expand Down Expand Up @@ -2198,7 +2276,7 @@ struct VM {
throw std::invalid_argument("Flag argument must be a technique flag and not a settings flag, consult the documentation's flag list");
}

// count should only have a single flag at this point
// count should only have a single flag at this stage
assert(count == 1);

// temporarily enable all flags so that every technique is enabled
Expand All @@ -2213,7 +2291,7 @@ struct VM {
throw std::invalid_argument("Flag is not known, consult the documentation's flag list");
}

const data &pair = it->second;
const technique &pair = it->second;
result = pair.ptr();

VM::flags = tmp_flags;
Expand Down Expand Up @@ -2255,7 +2333,10 @@ struct VM {
* execution of VM::detect(). This can save around
* 5~10x speed depending on the circumstances.
*/
if (disabled(NO_MEMO) && (memo.find(true) != memo.end())) {
if (
disabled(NO_MEMO) && \
memo.find(true) != memo.end()
) {
debug("memoization: returned cached result in detect()");
return memo[true].first;
}
Expand All @@ -2267,13 +2348,13 @@ struct VM {
u8 points = 0;

for (auto it = table.cbegin(); it != table.cend(); ++it) {
const data &pair = it->second;
const technique &pair = it->second;
if (pair.ptr()) {
points += pair.points;
};
}

// arbitrary threshold score
// threshold score
const bool result = (points >= 100);

sv current_brand = "";
Expand All @@ -2293,11 +2374,13 @@ struct VM {
);

if (it != scoreboard.end()) {
if (std::none_of(scoreboard.cbegin(), scoreboard.cend(),
[](const auto &pair) {
return pair.second;
}
)) {
if (
std::none_of(scoreboard.cbegin(), scoreboard.cend(),
[](const auto &pair) {
return pair.second;
}
)
) {
current_brand = "Unknown";
} else {
current_brand = it->first;
Expand Down

0 comments on commit 12c6a35

Please sign in to comment.