Any Ideas, please?

Discussion in 'C++' started by Pete Dashwood, Feb 6, 2011.

  1. I have a passing acquaintance with C++ but am far from expert. I collected
    various bits of code and modified them as below.

    The trouble is, I don't know enough about the C++ environment (directives
    etc. - it took me 2 days to figure out that I needed to export the Method I
    want to invoke, and to find the directive for it. :) I have configured
    VS2008 (VC++) to use the entrypoint name ("runTests()")

    The code below compiles clean with 3 warnings (which I don't totally
    understand) and it executes fine on both real and virtual platforms. The
    only problem is that it ALWAYS returns zero :) It SHOULD return 1 if it is
    running on a VM. It is built as a normal .DLL (Not COM).

    The "test8()" Method calls somethng called "InVirtualBox" which was supposed
    to return a bool. It just wouldn't compile with a type of bool so I changed
    it to int. This indicates I am missing some fundamental stuff here and I'd
    really appreciate if someone with an experienced C++ eye could just have a
    look and confirm that the code should run or not. I have no idea how to
    debug this and I need to call it from C#. (I do this via DllImport and it
    seems to work fine. (I put it in a try/catch block and it gives no
    exceptions))

    Here's the code:

    #include <windows.h>

    #include <excpt.h>

    #include <stdio.h>

    #include <Tlhelp32.h>


    #define DEBUG 0

    #define EndUserModeAddress (*(UINT_PTR*)0x7FFE02B4)

    typedef LONG (NTAPI *NTSETLDTENTRIES)(DWORD, DWORD, DWORD, DWORD, DWORD,
    DWORD);

    // global int will be 1 if we are running on VM, 0 if we are not...

    int result = 0;

    int

    InVirtualBox (void)

    {

    HANDLE handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);

    PROCESSENTRY32 procinfo = { sizeof(PROCESSENTRY32) };

    while(Process32Next(handle, &procinfo))

    {


    if(!strcmp(procinfo.szExeFile, "VBoxService.exe"))

    {

    CloseHandle(handle);

    return 1;

    }

    }

    CloseHandle(handle);

    return 0;

    }



    unsigned long

    get_idt_base (void)

    {

    unsigned char idtr[6];

    unsigned long idt = 0;

    _asm sidt idtr

    idt = *((unsigned long *)&idtr[2]);


    return (idt);

    }

    unsigned long

    get_ldtr_base (void)

    {

    unsigned char ldtr[5] = "\xef\xbe\xad\xde";

    unsigned long ldt = 0;

    _asm sldt ldtr

    ldt = *((unsigned long *)&ldtr[0]);

    return (ldt);

    }

    unsigned long

    get_gdt_base (void)

    {

    unsigned char gdtr[6];

    unsigned long gdt = 0;

    _asm sgdt gdtr

    gdt = *((unsigned long *)&gdtr[2]);

    return (gdt);

    }

    int

    test1 (void)

    {

    unsigned int idt_base = 0;

    idt_base = get_idt_base ();

    //printf ("[+] Test 1: IDT\n");

    //printf ("IDT base: 0x%x\n", idt_base);


    if ((idt_base >> 24) == 0xff) {

    //printf ("Result : VMware detected\n\n");


    return 1;

    }

    /*

    else {

    printf ("Result : Native OS\n\n");

    return;

    }

    */

    return 0;

    }

    int

    test2 (void)

    {

    unsigned int ldt_base = 0;

    ldt_base = get_ldtr_base ();

    //printf ("\n[+] Test 2: LDT\n");

    //printf ("LDT base: 0x%x\n", ldt_base);


    if (ldt_base == 0xdead0000) {

    //printf ("Result : Native OS\n\n");

    return 0;

    }

    else {

    //printf ("Result : VMware detected\n\n");

    //result = 1;

    return 1;

    }

    }

    int

    test3 (void)

    {

    unsigned int gdt_base = 0;

    gdt_base = get_gdt_base ();

    //printf ("\n[+] Test 3: GDT\n");

    //printf ("GDT base: 0x%x\n", gdt_base);

    if ((gdt_base >> 24) == 0xff) {

    //printf ("Result : VMware detected\n\n");

    //result = 1;

    return 1;

    }

    /*

    else {

    printf ("Result : Native OS\n\n");

    return;

    }

    */

    return 0;

    }

    // Alfredo Andrs Omella's (S21sec) STR technique

    int

    test4 (void)

    {

    unsigned char mem[4] = {0, 0, 0, 0};

    __asm str mem;

    //printf ("\n[+] Test 4: STR\n");

    //printf ("STR base: 0x%02x%02x%02x%02x\n", mem[0], mem[1], mem[2], mem[3]);

    if ((mem[0] == 0x00) && (mem[1] == 0x40))

    //printf ("Result : VMware detected\n\n");

    return 1;

    //else

    //printf ("Result : Native OS\n\n");

    return 0;

    }

    int

    test5 (void)

    {

    unsigned int a, b;

    __try {

    __asm {

    // save register values on the stack

    push eax

    push ebx

    push ecx

    push edx


    // perform fingerprint

    mov eax, 'VMXh' // VMware magic value (0x564D5868)

    mov ecx, 0Ah // special version cmd (0x0a)

    mov dx, 'VX' // special VMware I/O port (0x5658)


    in eax, dx // special I/O cmd


    mov a, ebx // data

    mov b, ecx // data (eax gets also modified but will not be evaluated)

    // restore register values from the stack

    pop edx

    pop ecx

    pop ebx

    pop eax

    }

    } __except (EXCEPTION_EXECUTE_HANDLER) {}

    #if DEBUG == 1

    printf ("\n [ a=%x ; b=%d ]\n\n", a, b);

    #endif

    //printf ("\n[+] Test 5: VMware \"get version\" command\n");


    if (a == 'VMXh') { // is the value equal to the VMware magic value?

    //printf ("Result : VMware detected\nVersion : ");

    return 1;

    /*

    if (b == 1)

    printf ("Express\n\n");

    else if (b == 2)

    printf ("ESX\n\n");

    else if (b == 3)

    printf ("GSX\n\n");

    else if (b == 4)

    printf ("Workstation\n\n");

    else

    printf ("unknown version\n\n");

    */

    }

    //else

    //printf ("Result : Native OS\n\n");

    return 0;

    }

    int

    test6 (void)

    {

    unsigned int a = 0;

    __try {

    __asm {

    // save register values on the stack

    push eax

    push ebx

    push ecx

    push edx


    // perform fingerprint

    mov eax, 'VMXh' // VMware magic value (0x564D5868)

    mov ecx, 14h // get memory size command (0x14)

    mov dx, 'VX' // special VMware I/O port (0x5658)


    in eax, dx // special I/O cmd


    mov a, eax // data

    // restore register values from the stack

    pop edx

    pop ecx

    pop ebx

    pop eax

    }

    } __except (EXCEPTION_EXECUTE_HANDLER) {}

    //printf ("\n[+] Test 6: VMware \"get memory size\" command\n");


    if (a > 0)

    //printf ("Result : VMware detected\n\n");

    return 1;

    else

    return 0;

    //printf ("Result : Native OS\n\n");

    }



    /*

    int

    test7_detect (LPEXCEPTION_POINTERS lpep)

    {

    //printf ("\n[+] Test 7: VMware emulation mode\n");


    if ((UINT_PTR)(lpep->ExceptionRecord->ExceptionAddress) >
    EndUserModeAddress)

    //printf ("Result : VMware detected (emulation mode detected)\n\n");

    result = 1;


    else

    printf ("Result : Native OS or VMware without emulation mode\n"

    " (enabled acceleration)\n\n");

    return (EXCEPTION_EXECUTE_HANDLER);

    }

    void __declspec(naked)

    test7_switchcs ()

    {

    __asm {

    pop eax

    push 0x000F

    push eax

    retf

    }

    }

    // Derek Soeder's (eEye Digital Security) VMware emulation test

    // removed... didn't work

    int

    test7 (void)

    {

    NTSETLDTENTRIES ZwSetLdtEntries;

    LDT_ENTRY csdesc;

    ZwSetLdtEntries = (NTSETLDTENTRIES)GetProcAddress (GetModuleHandle
    ("ntdll.dll"), "ZwSetLdtEntries");

    memset (&csdesc, 0, sizeof (csdesc));


    csdesc.LimitLow = (WORD)(EndUserModeAddress >> 12);

    csdesc.HighWord.Bytes.Flags1 = 0xFA;

    csdesc.HighWord.Bytes.Flags2 = 0xC0 | ((EndUserModeAddress >> 28) & 0x0F);


    ZwSetLdtEntries (0x000F, ((DWORD*)&csdesc)[0], ((DWORD*)&csdesc)[1], 0, 0,
    0);

    __try {

    test7_switchcs();

    __asm {

    or eax, -1

    jmp eax

    }

    }

    __except (test7_detect (GetExceptionInformation())) { }

    }

    */

    /**********************************

    ** Detect if your application **

    ** is running in Virtual Box. **

    ** **

    ** E0N 2008 **

    **********************************/

    //#include &lt;windows.h&gt;

    //#include &lt;Tlhelp32.h&gt;

    int test8 ()

    {

    if (InVirtualBox() == 1)

    {

    return 1;

    }

    return 0;

    }

    extern __declspec(dllexport) int runTests();

    runTests ()

    {

    /*

    The code here has been sourced from various places.Much available code was
    rejected

    as being too unstable or transient and likely to be overtaken by new VM
    releases.

    The final tests here were reviewed and amended by Peter E. C. Dashwood, for
    PRIMA

    Computing, (NZ) Ltd.

    The following authors should be acknowledged, and we thank them for making
    their code and knowledge

    public:

    Joanna Rutkovska (the Red Pill 2004)

    Tom Liston / Ed Skoudis

    Tobias Klein

    Alfredo Andres Omella

    Derek Soeder (unfortunately, we couldn't get this approach to work

    and it is not used here. Neverthless, the code was of

    value for educational purposes.)

    */

    result = test1 (); //good code

    if (result == 1)

    return result;

    result = test2 (); //good code

    if (result == 1)

    return result;

    result = test3 (); //good code

    if (result == 1)

    return result;


    result = test4 (); //good code

    if (result == 1)

    return result;

    result = test5 (); //good code

    if (result == 1)

    return result;


    result = test6 (); //good code

    //test7 (); //bad code don't use (Causes Access Violation)

    result = test8 ();

    return result;

    // result will be zero if the machine is real, 1 if it is virtual, and 2 if
    it is impossible to tell.

    }


    Sorry post has reformatted the code. Any comments or help greatly
    appreciated,

    Pete.
    --
     
    Pete Dashwood, Feb 6, 2011
    #1
    1. Advertising

  2. Pete Dashwood

    Ian Collins Guest

    On 02/ 6/11 02:02 PM, Pete Dashwood wrote:
    > I have a passing acquaintance with C++ but am far from expert. I collected
    > various bits of code and modified them as below.
    >
    > The trouble is, I don't know enough about the C++ environment (directives
    > etc. - it took me 2 days to figure out that I needed to export the Method I
    > want to invoke, and to find the directive for it. :) I have configured
    > VS2008 (VC++) to use the entrypoint name ("runTests()")
    >
    > The code below compiles clean with 3 warnings (which I don't totally
    > understand) and it executes fine on both real and virtual platforms. The
    > only problem is that it ALWAYS returns zero :) It SHOULD return 1 if it is
    > running on a VM. It is built as a normal .DLL (Not COM).


    Hang on, it looks like you have something windows specific going on.
    You'll have more luck on one of the windows groups.

    --
    Ian Collins
     
    Ian Collins, Feb 6, 2011
    #2
    1. Advertising

  3. Pete Dashwood

    Jorgen Grahn Guest

    On Sun, 2011-02-06, Pete Dashwood wrote:
    > I have a passing acquaintance with C++ but am far from expert. I collected
    > various bits of code and modified them as below.
    >
    > The trouble is, I don't know enough about the C++ environment (directives
    > etc. - it took me 2 days to figure out that I needed to export the Method I
    > want to invoke, and to find the directive for it. :) I have configured
    > VS2008 (VC++) to use the entrypoint name ("runTests()")
    >
    > The code below compiles clean with 3 warnings (which I don't totally
    > understand)


    Note: you're not really compiling cleanly if you get warnings which
    you don't understand. Warnings usually tell you something is wrong,
    even if the program seems to work correctly.

    The actual code seems so Windows-specific and contains so much x86
    assembly that I couldn't have commented on it even if it was formatted
    properly. Sorry.

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
     
    Jorgen Grahn, Feb 6, 2011
    #3
  4. Jorgen Grahn wrote:
    > On Sun, 2011-02-06, Pete Dashwood wrote:
    >> I have a passing acquaintance with C++ but am far from expert. I
    >> collected various bits of code and modified them as below.
    >>
    >> The trouble is, I don't know enough about the C++ environment
    >> (directives etc. - it took me 2 days to figure out that I needed to
    >> export the Method I want to invoke, and to find the directive for
    >> it. :) I have configured VS2008 (VC++) to use the entrypoint name
    >> ("runTests()")
    >>
    >> The code below compiles clean with 3 warnings (which I don't totally
    >> understand)

    >
    > Note: you're not really compiling cleanly if you get warnings which
    > you don't understand. Warnings usually tell you something is wrong,
    > even if the program seems to work correctly.


    Exactly, that's why I asked for help :)
    >
    > The actual code seems so Windows-specific and contains so much x86
    > assembly that I couldn't have commented on it even if it was formatted
    > properly. Sorry.


    Never Mind. I do appreciate your time. Thanks.

    Pete

    --
    "I used to write COBOL...now I can do anything."
     
    Pete Dashwood, Feb 6, 2011
    #4
  5. Ian Collins wrote:
    > On 02/ 6/11 02:02 PM, Pete Dashwood wrote:
    >> I have a passing acquaintance with C++ but am far from expert. I
    >> collected various bits of code and modified them as below.
    >>
    >> The trouble is, I don't know enough about the C++ environment
    >> (directives etc. - it took me 2 days to figure out that I needed to
    >> export the Method I want to invoke, and to find the directive for
    >> it. :) I have configured VS2008 (VC++) to use the entrypoint name
    >> ("runTests()") The code below compiles clean with 3 warnings (which I
    >> don't totally
    >> understand) and it executes fine on both real and virtual platforms.
    >> The only problem is that it ALWAYS returns zero :) It SHOULD return
    >> 1 if it is running on a VM. It is built as a normal .DLL (Not COM).

    >
    > Hang on, it looks like you have something windows specific going on.
    > You'll have more luck on one of the windows groups.


    Sorry, Ididn't realise that might be a problem.

    Thanks for yur response;I'll look for a Windows oriented group.

    Pete.

    --
    "I used to write COBOL...now I can do anything."
     
    Pete Dashwood, Feb 6, 2011
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jasper
    Replies:
    0
    Views:
    516
    Jasper
    Jun 28, 2004
  2. =?Utf-8?B?U3VlQG9qZC5zdGF0ZS5vci51cw==?=

    Error message - any ideas?

    =?Utf-8?B?U3VlQG9qZC5zdGF0ZS5vci51cw==?=, May 5, 2004, in forum: ASP .Net
    Replies:
    2
    Views:
    578
    =?Utf-8?B?U3VlQG9qZC5zdGF0ZS5vci51cw==?=
    May 5, 2004
  3. David Hearn
    Replies:
    2
    Views:
    757
    Lau Lei Cheong
    Jun 24, 2004
  4. brin
    Replies:
    2
    Views:
    271
    Hans Kesting
    Jun 28, 2004
  5. KK
    Replies:
    2
    Views:
    706
    Big Brian
    Oct 14, 2003
Loading...

Share This Page