Skip to content

Commit f394147

Browse files
authored
Merge pull request #414 from kernelwernel/dev
Fixed firmware checks on Linux
2 parents 77514c2 + 339a85c commit f394147

File tree

3 files changed

+23
-23
lines changed

3 files changed

+23
-23
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ This project also provides a tiny, but handy CLI tool utilising the full potenti
7777

7878
<img src="assets/demo.jpg" title="cli">
7979

80-
Try it out on [Compiler Explorer](https://godbolt.org/z/4sKa1sqrW)!
80+
<!-- Try it out on [Compiler Explorer](https://godbolt.org/z/4sKa1sqrW)!-->
8181

8282
<br>
8383

@@ -171,11 +171,11 @@ If you want to learn about the architecture and design of the library, head over
171171
<br>
172172

173173
> There's already loads of projects that have the same goal such as
174-
<a href="https://github.com/CheckPointSW/InviZzzible">InviZzzible</a>, <a href="https://github.com/a0rtega/pafish">pafish</a> and <a href="https://github.com/LordNoteworthy/al-khaser">Al-Khaser</a>. But the difference between the aforementioned projects is that they don't provide a programmable interface to interact with the detection mechanisms, on top of having little to no support for non-Windows systems. Additionally, the VM detections in all those projects are often not sophisticated enough to be practically applied to real-world scenarios while not providing enough VM detection techniques. An additional issue is that they are all GPL projects.
174+
<a href="https://github.com/CheckPointSW/InviZzzible">InviZzzible</a>, <a href="https://github.com/a0rtega/pafish">pafish</a> and <a href="https://github.com/LordNoteworthy/al-khaser">Al-Khaser</a>. But the difference between the aforementioned projects is that they don't provide a programmable interface to interact with the detection mechanisms, on top of having little to no support for non-Windows systems. Additionally, the VM detections in all those projects are often not sophisticated enough to be practically applied to real-world scenarios while not providing enough VM detection techniques. An additional hurdle is that they are all GPL projects, so using them for proprietary projects (which would be the main audience for such a functionality), is out of the question.
175175
>
176176
> Pafish and InviZzzible have been abandoned for years. Although Al-Khaser does receive occasional updates and has a wide scope of detections that VMAware doesn't provide (anti-debugging, anti-injection, and so on), it still falls short due to the previously mentioned problems above.
177177
>
178-
> While those projects have been useful to VMAware as a baseline, we wanted to make them far better. My goal was to make the detection techniques to be accessible programmatically in a cross-platform and flexible way for everybody to get something useful out of it rather than providing just a CLI tool. It also contains a larger quantity of techniques, so it's basically just a VM detection framework on steroids that focuses on practical and realistic usability for any scenario.
178+
> While those projects have been useful to VMAware to some extent, we wanted to make them far better. My goal was to make the detection techniques to be accessible programmatically in a cross-platform and flexible way for everybody to get something useful out of it rather than providing just a CLI tool. It also contains a larger quantity of techniques, so it's basically just a VM detection framework on steroids that focuses on practical and realistic usability for any scenario.
179179
180180
</details>
181181

@@ -196,7 +196,7 @@ If you want to learn about the architecture and design of the library, head over
196196
>
197197
> All of this combined has further advanced the forefront innovations in the field of VM detections much more productively, compared to having it closed source. This is what made the project the best VM detection framework out there, and bypassing it has shown to be an immense challenge due to the sheer number of sophisticated and never-before-seen techniques we employ that other VM detectors don't use whether open or closed source (to our knowledge).
198198
>
199-
> In other words, it's about better quality AND quantity, better feedback, and better openness over security through obfuscation.
199+
> In other words, it's about better quality AND quantity, better feedback, and better openness over security through obfuscation. It's the same reason why OpenSSH, OpenSSL, the Linux kernel, and other security-based software projects are relatively secure because of how there's more people helping to make it better compared to people trying to probe the source code with malicious intent. VMAware has this philosophy, and if you know anything about security, you should be familiar with the phrase: "Security through obfuscation is NOT security".
200200
201201
</details>
202202

assets/demo.jpg

100755100644
666 KB
Loading

src/vmaware.hpp

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5864,32 +5864,30 @@ struct VM {
58645864
return false;
58655865
#elif (LINUX)
58665866
// Author: dmfrpro
5867-
if (!util::is_admin()) {
5868-
return false;
5869-
}
5870-
58715867
DIR* dir = opendir("/sys/firmware/acpi/tables/");
58725868
if (!dir) {
58735869
debug("FIRMWARE: could not open ACPI tables directory");
58745870
return false;
58755871
}
58765872

5877-
// Same targets as the Windows branch but without "WAET"
58785873
constexpr const char* targets[] = {
5879-
"Parallels Software International","Parallels(R)","innotek",
5880-
"Oracle","VirtualBox","vbox","VBOX","VS2005R2",
5874+
"Parallels Software International","Parallels(R)",
5875+
"innotek","Oracle","VirtualBox","vbox","VBOX","VS2005R2",
58815876
"VMware, Inc.","VMware","VMWARE",
58825877
"S3 Corp.","Virtual Machine","QEMU","pc-q35","BOCHS","BXPC"
58835878
};
58845879

58855880
struct dirent* entry;
58865881
while ((entry = readdir(dir)) != nullptr) {
58875882
// Skip "." and ".."
5888-
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
5883+
if (strcmp(entry->d_name, ".") == 0 ||
5884+
strcmp(entry->d_name, "..") == 0)
58895885
continue;
58905886

58915887
char path[PATH_MAX];
5892-
snprintf(path, sizeof(path), "/sys/firmware/acpi/tables/%s", entry->d_name);
5888+
snprintf(path, sizeof(path),
5889+
"/sys/firmware/acpi/tables/%s",
5890+
entry->d_name);
58935891

58945892
int fd = open(path, O_RDONLY);
58955893
if (fd == -1) {
@@ -5898,17 +5896,11 @@ struct VM {
58985896
}
58995897

59005898
struct stat statbuf;
5901-
if (fstat(fd, &statbuf) != 0) {
5899+
if (fstat(fd, &statbuf) != 0 || S_ISDIR(statbuf.st_mode)) {
59025900
debug("FIRMWARE: skipped ", entry->d_name);
59035901
close(fd);
59045902
continue;
59055903
}
5906-
if (S_ISDIR(statbuf.st_mode)) {
5907-
debug("FIRMWARE: skipped directory ", entry->d_name);
5908-
close(fd);
5909-
continue;
5910-
}
5911-
59125904
long file_size = statbuf.st_size;
59135905
if (file_size <= 0) {
59145906
debug("FIRMWARE: file empty or error ", entry->d_name);
@@ -5922,13 +5914,20 @@ struct VM {
59225914
close(fd);
59235915
continue;
59245916
}
5917+
5918+
ssize_t n = read(fd, buffer, file_size);
59255919
close(fd);
5920+
if (n != file_size) {
5921+
debug("FIRMWARE: could not read full table ", entry->d_name);
5922+
free(buffer);
5923+
continue;
5924+
}
59265925

59275926
for (const char* target : targets) {
59285927
size_t targetLen = strlen(target);
5929-
if (targetLen == 0 || file_size < static_cast<long>(targetLen))
5928+
if ((long)targetLen > file_size)
59305929
continue;
5931-
for (long j = 0; j <= file_size - static_cast<long>(targetLen); ++j) {
5930+
for (long j = 0; j <= file_size - (long)targetLen; ++j) {
59325931
if (memcmp(buffer + j, target, targetLen) == 0) {
59335932
const char* brand = nullptr;
59345933
if (strcmp(target, "Parallels Software International") == 0 ||
@@ -5947,13 +5946,14 @@ struct VM {
59475946
strcmp(target, "VMWARE") == 0) {
59485947
brand = brands::VMWARE;
59495948
}
5950-
else if (strcmp(target, "QEMU")) {
5949+
else if (strcmp(target, "QEMU") == 0) {
59515950
brand = brands::QEMU;
59525951
}
59535952
else if (strcmp(target, "BOCHS") == 0 ||
59545953
strcmp(target, "BXPC") == 0) {
59555954
brand = brands::BOCHS;
59565955
}
5956+
59575957
free(buffer);
59585958
closedir(dir);
59595959
if (brand)

0 commit comments

Comments
 (0)