Fix some further typos
[grml-scripts.git] / compile / vmware-detect.c
1 /* Filename:      vmware-detect.c
2 *  Purpose:       Detect if running inside vmware
3 *  Authors:       grml-team (grml.org), (c) Michael Gebetsroither <gebi@grml.org>
4 *  Bug-Reports:   see http://grml.org/bugs/
5 *  License:       This file is licensed under the GPL v2.
6 *******************************************************************************/
7 // return 0 if running inside vmware, 1 otherwise
8
9 #include "string.h"
10 #include "unistd.h"
11 #include "stdio.h"
12 #include "stdlib.h"
13 #include "signal.h"
14
15 #define WRITE(x) write(1, x, strlen(x))
16 #define DWRITE(x) do{ \
17     if(debug) { \
18         WRITE(x); \
19     } \
20 } while(0);
21 #define FALSE 0
22 #define TRUE !FALSE
23
24 /* doc:
25  * vmware IO backdoor: http://chitchat.at.infoseek.co.jp/vmware/backdoor.html
26  * http://www.honeynet.org/papers/bots/botnet-code.html
27  * http://www.codegurus.be/codegurus/Programming/virtualpc&vmware_en.htm
28  */
29
30 // from libowfat {{{
31 static inline char tohex(char c) {
32   return c>=10?c-10+'a':c+'0';
33 }
34
35 unsigned int fmt_xlong(char *dest,unsigned long i) {
36   register unsigned long len,tmp;
37   /* first count the number of bytes needed */
38   for (len=1, tmp=i; tmp>15; ++len) tmp>>=4;
39   if (dest)
40     for (tmp=i, dest+=len; ; ) {
41       *--dest = tohex(tmp&15);
42       if (!(tmp>>=4)) break;
43     }
44   return len;
45 }
46 // }}}
47
48 void printIdtr(const unsigned char* idtr, unsigned size)
49 {
50     unsigned i;
51     for(i=0; i<size; ++i) {
52         char out[4] = {0};
53         fmt_xlong(out, idtr[i]);
54         if(strlen(out) == 1)
55             WRITE("0");
56         WRITE(out);
57     }
58     WRITE("\n");
59 }
60
61 // i386 and x86-64 {{{
62 #if defined (__i386__) || defined (__x86_64__)
63 int checkVmware(const int debug)
64 {
65     unsigned char idtr[10] = {0};
66     asm("sidt %0" : "=m" (idtr));
67     if(debug)
68         printIdtr(idtr, sizeof(idtr));
69     // should normally be the case on amd64, but does not work
70     //return (0xff==idtr[9]) ? 1 : 0;
71     return (0xff==idtr[5]) ? 1 : 0;
72 }
73 int checkVmwareIO()
74 {
75     unsigned int vmaj, vmin, magic, dout = 11;
76     __asm__ __volatile__(
77             "mov $0x564D5868, %%eax; /* magic number */"
78             "mov $0x3c6cf712, %%ebx; /* random number */"
79             "mov $0x0000000A, %%ecx; /* specifies command */"
80             "mov $0x5658, %%edx; /* VMware I/O port */"
81             "in %%dx, %%eax;"
82             "mov %%eax, %0;"
83             "mov %%ebx, %1;"
84             "mov %%ecx, %2;"
85             "mov %%edx, %3;"
86         : "=r"(vmaj), "=r"(magic), "=r"(vmin), "=r"(dout));
87 #ifdef DEBUG
88     fprintf(stderr, "version: major=%x, minor=%x, magic=%x, dout=%x\n",
89             vmaj, vmin, magic, dout);
90 #endif
91     return (0x564D5868 == magic) ? 1 : 0;
92 }
93 // }}}
94
95 // others {{{
96 #else
97 // vmware runs only on the archs above
98 int checkVmware(const int) { return 0; }
99 int checkVmwareIO() { return 0; }
100 #endif
101 // }}}
102
103 static int Killed = FALSE;
104
105 // returns 0 if running inside vmware, 1 otherwise
106 int main(int argc, char* argv[]) {
107     int debug = FALSE;
108     if(argc == 2 && !strcmp(argv[1], "--debug"))
109         debug = TRUE;
110
111     int a, b;
112     // known to be false positives
113     a = checkVmware(debug);
114     DWRITE("idt-check: ")
115     if(!a) {
116         DWRITE("false\n");
117         if(!debug)
118             return EXIT_FAILURE;
119     } else
120         DWRITE("true\n");
121
122     // never returns if not running under vmware
123     void dummy() { Killed=TRUE; DWRITE("false\n"); exit(1); }
124     signal(SIGSEGV, dummy);
125     DWRITE("ioport-check: ");
126     b = checkVmwareIO();
127     if(b) {
128         DWRITE("true\n");
129         return EXIT_SUCCESS;
130     } else {
131         if(!Killed) {
132             // check unusable or not implemented
133             DWRITE("false\n");
134             DWRITE("Check not implemented, yet!\n");
135             return a ? EXIT_SUCCESS : EXIT_FAILURE;
136         } else {
137             // never reached
138             WRITE("Error: IO check hasn't killed the program but no vmware found either!\n");
139             return EXIT_FAILURE;
140         }
141     }
142 }
143 // vim: foldmethod=marker