Advertisement
Guest User

C_code_vm

a guest
Jul 25th, 2019
462
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.55 KB | None | 0 0
  1. //#include <stdio.h>
  2. //#include <stdlib.h>
  3.  
  4.  
  5. // http://charette.no-ip.com:81/programming/2009-12-30_Virtualization
  6.  
  7. // $Id: 2009-12-30_Virtualization.c 13 2010-01-01 15:38:51Z stephane $
  8.  
  9. //
  10. // Code to walk through the CPUs/cores and gcc inline assembly is loosely
  11.  
  12. // based on this:  http://nibbles.tuxfamily.org/?tag=gdt
  13.  
  14.  
  15. //
  16. // *** PLEASE NOTE ***
  17.  
  18. //
  19. //  1)  This code assumes it is being compiled for AMD64.  If compiling for
  20.  
  21. //      i386 then you'll need to edit the "dt" structure.  See documentation.
  22.  
  23. //
  24. //  2)  This "C" file has inline assembly written for gcc v4.4.1.  If using
  25.  
  26. //      a different compiler, you'll neeed to modify the source.
  27.  
  28. #define _GNU_SOURCE
  29. // needed for CPU_... macros
  30. #include <sched.h>
  31. #include <errno.h>
  32. #include <stdio.h>
  33.  
  34.  
  35. //*****************************************************************************************************************************
  36. #define __SLONGWORD_TYPE        long int
  37. #define __ULONGWORD_TYPE        unsigned long int
  38.  
  39. /* X32 kernel interface is 64-bit.  */
  40. #if defined __x86_64__ && defined __ILP32__
  41. # define __SYSCALL_SLONG_TYPE        __SQUAD_TYPE
  42. # define __SYSCALL_ULONG_TYPE        __UQUAD_TYPE
  43. #else
  44. # define __SYSCALL_SLONG_TYPE        __SLONGWORD_TYPE
  45. # define __SYSCALL_ULONG_TYPE        __ULONGWORD_TYPE
  46. #endif
  47.  
  48. //cpu-set.h
  49.  
  50. /* Size definition for CPU sets.  */
  51. #define __CPU_SETSIZE        1024
  52. #define __NCPUBITS        (8 * sizeof (__cpu_mask))
  53.  
  54. #define __CPU_MASK_TYPE         __SYSCALL_ULONG_TYPE
  55.  
  56. /* Type for array elements in 'cpu_set_t'.  */
  57. typedef __CPU_MASK_TYPE __cpu_mask;
  58.  
  59. /* Data structure to describe CPU mask.  */
  60. typedef struct
  61. {
  62.     __cpu_mask __bits[__CPU_SETSIZE / __NCPUBITS];
  63. } cpu_set_t;
  64. //******************************************************************************************************************************
  65.  
  66.  
  67. typedef struct
  68. {
  69. // Lots of *really bad* examples on the web where they use char[2]
  70. // to store the output of SIDT and SGDT.  This is wrong!
  71. //
  72. // In 32-bit mode, the output is 6 bytes, where the first 2 is
  73. // the limit and the upper 4 bytes is the 32-bit base address.
  74. //
  75. // In 64-bit mode, the output is 10 bytes, where the first 2 is
  76. // the limit and the upper 8 bytes is the 64-bit base address.
  77. //
  78. // This is described on page 299 of AMD64 Architecture Programmer's
  79. // Manual Volume 3: General-Purpose and System Instructions:
  80. // http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/24594.pdf
  81.  
  82.     unsigned long   limit : 16;
  83.     unsigned long   base  : 64;
  84. } __attribute__((packed)) dt;
  85.  
  86.  
  87. unsigned long getIDT( void )
  88. {
  89.     // Interrupt Descriptor Table Register
  90. //
  91. // This is the original "red pill" and "scoopy_doo" method of determining
  92. // whether or not we're running in a VM.  The check would be against the
  93. // base address returned by SIDT.  If the table was not at the usual
  94. // location, then it was assumed we were running in a VM.  However, this
  95. // check can return false-positives with multi-core and multi-processor,
  96. // since the table is per-cpu/core.
  97.  
  98.     dt idt = {0, 0};
  99.     asm volatile( "sidt %0" : "=m"(idt) );
  100.     printf( "IDT: limit=%04d, base=%016lx\n", idt.limit, idt.base );
  101.     return idt.base;
  102. }
  103.  
  104. unsigned long getGDT( void )
  105. {
  106. // Global Descriptor Table Register
  107. //
  108. // This is the "no pill" variation on the original "red pill".
  109.     dt gdt = {0, 0};
  110.     asm volatile( "sgdt %0" : "=m"(gdt) );
  111.     printf( "GDT: limit=%04d, base=%016lx\n", gdt.limit, gdt.base );
  112.     return gdt.base;
  113. }
  114.  
  115.  
  116. unsigned short getLDT( void )
  117. {
  118. // Local Descriptor Table Register
  119. //
  120. // This one is slightly different than IDT and GDT.  It returns to us just
  121. // the 16-bit segment selector.  This is always a 16-bit value, regardless
  122. // of whether or not we're running in legacy i386 or in AMD64.
  123.     unsigned long ldt = -1;
  124. // -1 will help us "see" this is a 16-bit value
  125.     asm volatile( "sldt %0" : "=m"(ldt) );
  126.     printf( "LDT: %04lx\n", ldt );
  127.     return ldt;
  128. }
  129.  
  130.  
  131. unsigned short getSTR( void )
  132. {
  133. // Task Register Selector
  134. //
  135. // Apparently this can be used to determine if this is within or outside
  136. // the "Matrix, but I get the same value whether I'm running natively or
  137. // within VirtualBox.
  138. // http://www.s21sec.com/descargas/vmware-eng.pdf
  139. unsigned long str = -1;
  140. // -1 will help us "see" this is a 16-bit value
  141. asm volatile( "str %0" : "=m"(str) );
  142.     printf( "STR: %04lx\n", str );
  143.     return str;
  144. }
  145.  
  146. int main(void)
  147. {
  148.     int result  = 0;
  149.     int cpu     = 0;
  150.     int cpu2    = 0;
  151.     cpu_set_t cs, cs2;
  152.  
  153.     if( sched_getaffinity( getpid(), sizeof( cs ), &cs ) != 0 )
  154.     {
  155.         printf( "sched_getaffinity() failed\n" );
  156.         return -1;
  157.     }
  158.  
  159.  
  160. // loop through all of the CPUs
  161.     while( CPU_COUNT( &cs ) != 0 )
  162.     {
  163.         // if we have this CPU...
  164.         if ( CPU_ISSET( cpu, &cs ) )
  165.         {
  166.             printf("\nCPU: %d\n", cpu );
  167.  
  168.             // set affinity -- schedule us to run on this specific CPU
  169.             CPU_ZERO( &cs2 );
  170.             CPU_SET( cpu, &cs2 );
  171.  
  172.             if( sched_setaffinity( getpid(), sizeof( cs2 ), &cs2 ) != 0)
  173.             {
  174.                 printf( "setaffinity(%d) failed\n", cpu);
  175.                 result = -1;
  176.             }
  177.  
  178.             // determine on which CPU we're running
  179.             cpu2 = sched_getcpu ();
  180.             if (cpu2 == -1 && errno == ENOSYS)
  181.             {
  182.                 printf( "getcpu syscall not implemented" );
  183.                 return -1;
  184.             }
  185.  
  186. // ensure we're running on the CPU we think we should be using
  187.             if (cpu2 != cpu)
  188.             {
  189.                 printf( "getcpu result is %d; expected %d\n", cpu2, cpu );
  190.                 result = 1;
  191.             }
  192.  
  193. // display the results
  194.             getIDT();
  195.             getGDT();
  196.             getLDT();
  197.             getSTR();
  198.  
  199. // clear affinity
  200.             CPU_CLR(cpu, &cs);
  201.         }
  202.         // move on to the next CPU
  203.         cpu ++;
  204.     }
  205.     return 0;
  206. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement