Go back

Contents

Processes and libraries detection methods
1. Check specific running processes and loaded libraries
1.1. Check if specific processes are running
1.2. Check if specific libraries are loaded in the process address space
1.3. Check if specific functions are present in specific libraries
1.4. Check if certain libraries can be loaded and others not
1.5. Countermeasures
2. Check if specific artifacts are present in process address space (Sandboxie only)
2.1. Countermeasures
Credits

Processes and libraries detection methods

Virtual environment launches some specific helper processes which are not being executed in usual host OS. There are also some specific modules which are loaded into processes address spaces.


1. Check specific running processes and loaded libraries


1.1. Check if specific processes are running

Functions used:

  • CreateToolhelp32Snapshot
  • psapi.EnumProcesses (WinXP, Vista)
  • kernel32.EnumProcesses (Win7+)

Code sample

check_process_is_running("vmtoolsd.exe");  // sample value from the table

bool check_process_is_running(const std::string &proc_name) {
    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;
}

Signature recommendations

Signature recommendations are not provided as it’s hard to say what exactly is queried in the processes’ snapshot.


Detections table

Check if the following processes are running:
Detect Process
JoeBox joeboxserver.exe
joeboxcontrol.exe
Parallels prl_cc.exe
prl_tools.exe
VirtualBox vboxservice.exe
vboxtray.exe
VirtualPC vmsrvc.exe
vmusrvc.exe
VMware vmtoolsd.exe
vmacthlp.exe
vmwaretray.exe
vmwareuser.exe
vmware.exe
vmount2.exe
Xen xenservice.exe
xsvc_depriv.exe
WPE Pro WPE Pro.exe


Note: WPE Pro is a sniffer, not VM, however it is used along with VM detects.


1.2. Check if specific libraries are loaded in the process address space

Functions used:

  • GetModuleHandle

Code sample

VOID loaded_dlls()
{
    /* Some vars */
    HMODULE hDll;

    /* Array of strings of blacklisted dlls */
    TCHAR* szDlls[] = {
        _T("sbiedll.dll"),
        _T("dbghelp.dll"),
        _T("api_log.dll"),
        _T("dir_watch.dll"),
        _T("pstorec.dll"),
        _T("vmcheck.dll"),
        _T("wpespy.dll"),
    };

    WORD dwlength = sizeof(szDlls) / sizeof(szDlls[0]);
    for (int i = 0; i < dwlength; i++)
    {
        TCHAR msg[256] = _T("");
        _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking if process loaded modules contains: %s "), 
                    szDlls[i]);

        /* Check if process loaded modules contains the blacklisted dll */
        hDll = GetModuleHandle(szDlls[i]);
        if (hDll == NULL)
            print_results(FALSE, msg);
        else
            print_results(TRUE, msg);
    }
}

Credits for this code sample: al-khaser project


Signature recommendations

If the following function contains its only argument from the table column `Library`:

  • GetModuleHandle(module_name)

then it’s an indication of application trying to use this evasion technique.


Detections table

Check if the following libraries are loaded in the process address space:
Detect Library
CWSandbox api_log.dll
dir_watch.dll
pstorec.dll
Sandboxie sbiedll.dll
ThreatExpert dbghelp.dll
VirtualPC vmcheck.dll
WPE Pro wpespy.dll


Note: WPE Pro is a sniffer, not VM, however it is used along with VM detects.


1.3. Check if specific functions are present in specific libraries

Functions used (see note about native functions):

  • kernel32.GetProcAddress
  • kernel32.LdrGetProcedureAddress (called internally)
  • ntdll.LdrGetProcedureAddress
  • ntdll.LdrpGetProcedureAddress (called internally)

Code sample

BOOL wine_exports()
{
    /* Some vars */
    HMODULE hKernel32;

    /* Get kernel32 module handle */
    hKernel32 = GetModuleHandle(_T("kernel32.dll"));
    if (hKernel32 == NULL) {
        print_last_error(_T("GetModuleHandle"));
        return FALSE;
    }

    /* Check if wine_get_unix_file_name is exported by this dll */
    if (GetProcAddress(hKernel32, "wine_get_unix_file_name") == NULL)  // sample value from the table
        return FALSE;
    else
        return TRUE;
}

Credits for this code sample: al-khaser project


Signature recommendations

If the following functions contain 2nd argument from the table column “Function” and the 1st argument is the address of matching “Library” name from the table:

  • kernel32.GetProcAddress(lib_handle, func_name)
  • kernel32.LdrGetProcedureAddress(lib_handle, func_name)
  • ntdll.LdrGetProcedureAddress(lib_handle, func_name)
  • ntdll.LdrpGetProcedureAddress(lib_handle, func_name)

then it’s an indication of application trying to use this evasion technique.


Detections table

Check if the following functions are present in the following libraries:
Detect Library Function
Wine kernel32.dll wine_get_unix_file_name
ntdll.dll wine_get_version


1.4. Check if certain libraries can be loaded and others

Function used:

  • LoadLibraryA/W

This technique relies on the assumption that there are some common system libraries in the usual system that can be loaded – and there are also some fake ones, that should not be really present in a usual system. However, in a sandbox, when trying to load some fake libraries, they may be reported as loaded - which is different from how it should be on a usual host.

In other words, if a system library that is usually present (but not so widely used) in non-emulated machines is not loaded, then the application is likely in a sandbox. And if a fake DLL is reported to be loaded, then it is likely a sandbox, as such DLL will not be loaded in a usual machine.

Code sample

bool Generic::CheckLoadedDLLs() const {
    std::vector<std::string> real_dlls = {
        "kernel32.dll",
        "networkexplorer.dll",
        "NlsData0000.dll"
    };
    std::vector<std::string> false_dlls = {
        "NetProjW.dll",
        "Ghofr.dll",
        "fg122.dll"
    };
    HMODULE lib_inst;

    for (auto &dll : real_dlls) {
        lib_inst = LoadLibraryA(dll.c_str());
        if (lib_inst == nullptr) {
            return true;
        }
        FreeLibrary(lib_inst);
    }

    for (auto &dll : false_dlls) {
        lib_inst = LoadLibraryA(dll.c_str());
        if (lib_inst != nullptr) {
            return true;
        }
    }

    return false;
}

Signature recommendations

Signature recommendations are not provided as it’s hard to say that evasion tehnique is being applied when libraries are just loaded.



1.5. Countermeasures

  • for processes: exclude target processes from enumeration or terminate them;
  • for libraries: exclude them from enumeration lists in PEB;
  • for functions in libraries: hook appropriate functions and compare their arguments against target ones;
  • for libraries that must and must not be loaded: store a list of exclusions for libraries that should not be reported as loaded.


2. Check if specific artifacts are present in process address space (Sandboxie only)

Functions used:

  • NtQueryVirtualMemory

Code sample

BOOL AmISandboxied(LPVOID lpMinimumApplicationAddress, LPVOID lpMaximumApplicationAddress)
{
  BOOL IsSB = FALSE;
  MEMORY_BASIC_INFORMATION RegionInfo;
  ULONG_PTR i, k;
  SIZE_T Length = 0L;

  i = (ULONG_PTR)lpMinimumApplicationAddress;
  do {

    NTSTATUS Status = NtQueryVirtualMemory(GetCurrentProcess(), 
                                           (PVOID)i, 
                                           MemoryBasicInformation,
                                           &RegionInfo, 
                                           sizeof(MEMORY_BASIC_INFORMATION), 
                                           &Length);
    if (NT_SUCCESS(Status)) {

      // Check if executable code
      if (((RegionInfo.AllocationProtect & PAGE_EXECUTE_READWRITE) == PAGE_EXECUTE_READWRITE) &&
          ((RegionInfo.State & MEM_COMMIT) == MEM_COMMIT)) {

        for (k = i; k < i + RegionInfo.RegionSize; k += sizeof(DWORD)) {
          if (
            (*(PDWORD)k == 'kuzt') ||
            (*(PDWORD)k == 'xobs')
            )
          {
            IsSB = TRUE;
            break;
          }
        }
      }
      i += RegionInfo.RegionSize;
    }
    else {
      i += 0x1000;
    }
  } while (i < (ULONG_PTR)lpMaximumApplicationAddress);

  return IsSB;
}

Take a look at VMDE project sources.


Signature recommendations

Signature recommendations are not provided as it’s hard to say what exactly is queried when memory buffer is being examined.


2.1. Countermeasures

Erase present artifacts from memory.


Credits

Credits go to open-source project from where code samples were taken:

Though Check Point tool InviZzzible has them all implemented, due to modular structure of the code it would require more space to show a code sample from this tool for the same purposes. That’s why we’ve decided to use other great open-source projects for examples throughout the encyclopedia.


Go back