mirror of
https://github.com/HyperDbg/HyperDbg.git
synced 2026-07-11 10:09:26 +00:00
229 lines
5.3 KiB
C++
229 lines
5.3 KiB
C++
/**
|
|
* @file transparency.cpp
|
|
* @author Sina Karvandi (sina@hyperdbg.org)
|
|
* @brief Measurements for debugger transparency
|
|
* @details
|
|
* @version 0.1
|
|
* @date 2020-07-07
|
|
*
|
|
* @copyright This project is released under the GNU Public License v3.
|
|
*
|
|
*/
|
|
#include "pch.h"
|
|
|
|
using namespace std;
|
|
|
|
/**
|
|
* @brief get the difference clock cycles between two rdtsc(s)
|
|
*
|
|
* @return UINT64
|
|
*/
|
|
UINT64
|
|
TransparentModeRdtscDiffVmexit()
|
|
{
|
|
UINT64 Ret, Ret2;
|
|
INT CpuidResult[4] = {0};
|
|
|
|
//
|
|
// GCC
|
|
//
|
|
// __asm__ volatile("rdtsc" : "=a" (eax), "=d" (edx));
|
|
// ret = ((unsigned long long)eax) | (((unsigned long long)edx) << 32);
|
|
|
|
//
|
|
// Win32
|
|
//
|
|
Ret = CpuReadTsc();
|
|
|
|
/* vm exit forced here. it uses: eax = 0; cpuid; */
|
|
|
|
//
|
|
// GCC
|
|
//
|
|
//__asm__ volatile("cpuid" : /* no output */ : "a"(0x00));
|
|
|
|
//
|
|
// WIN32
|
|
//
|
|
CpuCpuId(CpuidResult, 0);
|
|
|
|
//
|
|
// GCC
|
|
//
|
|
// __asm__ volatile("rdtsc" : "=a" (eax), "=d" (edx));
|
|
// ret2 = ((unsigned long long)eax) | (((unsigned long long)edx) << 32);
|
|
|
|
//
|
|
// WIN32
|
|
//
|
|
Ret2 = CpuReadTsc();
|
|
|
|
return Ret2 - Ret;
|
|
}
|
|
|
|
/**
|
|
* @brief get the difference clock cycles between rdtsc+cpuid+rdtsc
|
|
*
|
|
* @return UINT64
|
|
*/
|
|
UINT64
|
|
TransparentModeRdtscVmexitTracing()
|
|
{
|
|
UINT64 Ret, Ret2;
|
|
|
|
//
|
|
// WIN32
|
|
//
|
|
Ret = CpuReadTsc();
|
|
|
|
//
|
|
// WIN32
|
|
//
|
|
Ret2 = CpuReadTsc();
|
|
|
|
return Ret2 - Ret;
|
|
}
|
|
|
|
/**
|
|
* @brief compute the average, standard deviation and median if
|
|
* rdtsc+cpuid+rdtsc
|
|
*
|
|
* @param Average a pointer to save average on it
|
|
* @param StandardDeviation a pointer to standard deviation average on it
|
|
* @param Median a pointer to save median on it
|
|
* @return INT
|
|
*/
|
|
INT
|
|
TransparentModeCpuidTimeStampCounter(UINT64 * Average,
|
|
UINT64 * StandardDeviation,
|
|
UINT64 * Median)
|
|
{
|
|
double Avg = 0;
|
|
double MeasuredTime = 0;
|
|
vector<double> Results;
|
|
|
|
for (int i = 0; i < TestCount; i++)
|
|
{
|
|
MeasuredTime = (double)TransparentModeRdtscDiffVmexit();
|
|
Avg = Avg + MeasuredTime;
|
|
|
|
Results.push_back(MeasuredTime);
|
|
|
|
/*
|
|
ShowMessages("(%d) Measured time : %d\n", i, MeasuredTime);
|
|
*/
|
|
}
|
|
|
|
if (Average != NULL && StandardDeviation != NULL && Median != NULL)
|
|
{
|
|
//
|
|
// Compute the average and variance
|
|
//
|
|
GuassianGenerateRandom(Results, Average, StandardDeviation, Median);
|
|
}
|
|
|
|
Avg = Avg / TestCount;
|
|
return (Avg < 1000 && Avg > 0) ? FALSE : TRUE;
|
|
}
|
|
|
|
/**
|
|
* @brief compute the average, standard deviation and median if
|
|
* rdtsc+rdtsc
|
|
*
|
|
* @param Average a pointer to save average on it
|
|
* @param StandardDeviation a pointer to standard deviation average on it
|
|
* @param Median a pointer to save median on it
|
|
* @return INT
|
|
*/
|
|
INT
|
|
TransparentModeRdtscEmulationDetection(UINT64 * Average,
|
|
UINT64 * StandardDeviation,
|
|
UINT64 * Median)
|
|
{
|
|
double Avg = 0;
|
|
double MeasuredTime = 0;
|
|
vector<double> Results;
|
|
|
|
for (int i = 0; i < TestCount; i++)
|
|
{
|
|
MeasuredTime = (double)TransparentModeRdtscVmexitTracing();
|
|
Avg = Avg + MeasuredTime;
|
|
|
|
Results.push_back(MeasuredTime);
|
|
|
|
/*
|
|
ShowMessages("(%d) Measured time : %d\n", i, MeasuredTime);
|
|
*/
|
|
}
|
|
|
|
if (Average != NULL && StandardDeviation != NULL && Median != NULL)
|
|
{
|
|
//
|
|
// Compute the average and variance
|
|
//
|
|
GuassianGenerateRandom(Results, Average, StandardDeviation, Median);
|
|
}
|
|
|
|
Avg = Avg / TestCount;
|
|
return (Avg < 750 && Avg > 0) ? FALSE : TRUE;
|
|
}
|
|
|
|
/**
|
|
* @brief compute the average, standard deviation and median if
|
|
* rdtsc+cpuid+rdtsc
|
|
* @details detects the presence of hypervisor
|
|
*
|
|
* @param Average a pointer to save average on it
|
|
* @param StandardDeviation a pointer to standard deviation average on it
|
|
* @param Median a pointer to save median on it
|
|
* @return int
|
|
*/
|
|
BOOLEAN
|
|
TransparentModeCheckHypervisorPresence(UINT64 * Average,
|
|
UINT64 * StandardDeviation,
|
|
UINT64 * Median)
|
|
{
|
|
//
|
|
// Check whether the hypervisor is detected or not
|
|
//
|
|
if (TransparentModeCpuidTimeStampCounter(Average, StandardDeviation, Median))
|
|
{
|
|
ShowMessages("hypervisor detected\n");
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
ShowMessages("hypervisor not detected\n");
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief compute the average, standard deviation and median if
|
|
* rdtsc+rdtsc
|
|
* @details detects the presence of rdtsc/p vm-exits
|
|
*
|
|
* @param Average a pointer to save average on it
|
|
* @param StandardDeviation a pointer to standard deviation average on it
|
|
* @param Median a pointer to save median on it
|
|
* @return int
|
|
*/
|
|
BOOLEAN
|
|
TransparentModeCheckRdtscpVmexit(UINT64 * Average,
|
|
UINT64 * StandardDeviation,
|
|
UINT64 * Median)
|
|
{
|
|
//
|
|
// Check whether the system emulating rdtsc/p or not
|
|
//
|
|
if (TransparentModeRdtscEmulationDetection(Average, StandardDeviation, Median))
|
|
{
|
|
ShowMessages("rdtsc/p emulation detected\n");
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
ShowMessages("rdtsc/p emulation not detected\n");
|
|
return FALSE;
|
|
}
|
|
}
|