Skip to content

Commit

Permalink
AntiVM implementation: WMI query parameters tracing (#41)
Browse files Browse the repository at this point in the history
* [FEATURE] AntiVM: added initial files

* [FEATURE] AntiVM: bug fix

* [FEATURE] AntiVm: WMI query hooking

* [FEATURE] AntiVm: WMI parameters tracing

* [FEATURE] AntiVm: removed redundant types/arguments

* [FEATURE] AntiVm: updated TinyTracer project files

* [FEATURE] AntiVm: resetted VS platform toolset

* Merge Anti-VM feature
  • Loading branch information
AndreaNaspi authored Aug 16, 2023
1 parent 49c8083 commit 8bdd5e3
Show file tree
Hide file tree
Showing 9 changed files with 229 additions and 3 deletions.
21 changes: 21 additions & 0 deletions AntiVm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

#include "pin.H"

//* ==================================================================== */
// Helpers
/* ===================================================================== */
#define GET_STR_TO_UPPER(c, buf, bufSize) do { \
size_t i; \
for (i = 0; i < bufSize; i++) { \
(buf)[i] = toupper((c)[i]); \
if ((c)[i] == '\0') break; \
} \
} while (0)

//* ==================================================================== */
// Prototypes
/* ===================================================================== */
namespace AntiVm {
VOID MonitorAntiVmFunctions(IMG Image);
};
178 changes: 178 additions & 0 deletions Antivm.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
#include "AntiVm.h"

#include <iostream>
#include <sstream>
#include <string>
#include <map>

#include "ProcessInfo.h"
#include "Util.h"
#include "TraceLog.h"
#include "Settings.h"
#include "PinLocker.h"
#include "TinyTracer.h"

#include "win/win_paths.h"

#define ANTIVM_LABEL "[ANTIVM] --> "

using namespace LEVEL_PINCLIENT;

/* ================================================================== */
// Global variables used by AntiVm
/* ================================================================== */
#define PATH_BUFSIZE 512
#define WMI_NUMBER_CORES "NUMBEROFCORES"
#define WMI_PROCESSOR "PROCESSORID"
#define WMI_SIZE "SIZE"
#define WMI_DEVICE_ID "DEVICEID"
#define WMI_MAC_ADDRESS "MACADDRESS"
#define WMI_TEMPERATURE "CURRENTTEMPERATURE"
#define WMI_SERIAL "SERIALNUMBER"
#define WMI_MODEL "MODEL"
#define WMI_MANUFACTURER "MANUFACTURER"
#define WMI_GPU_ADAPTER "ADAPTERCOMPATIBILITY"
#define WMI_PRODUCT "PRODUCT"
#define WMI_NAME "NAME"

typedef VOID AntiVmCallBack(const ADDRINT addr, const CHAR* name, uint32_t argCount, VOID* arg1, VOID* arg2, VOID* arg3, VOID* arg4, VOID* arg5, VOID* arg6);

/* ==================================================================== */
// Log info with AntiVm label
/* ==================================================================== */

VOID LogAntiVm(const WatchedType wType, const ADDRINT Address, const char* msg, const char* link = nullptr)
{
if (!msg) return;
if (wType == WatchedType::NOT_WATCHED) return;

std::stringstream ss;
ADDRINT rva = UNKNOWN_ADDR;
if (wType == WatchedType::WATCHED_MY_MODULE) {
rva = addr_to_rva(Address); // convert to RVA
}
else if (wType == WatchedType::WATCHED_SHELLCODE) {
const ADDRINT start = query_region_base(Address);
rva = Address - start;
if (start != UNKNOWN_ADDR) {
ss << "> " << std::hex << start << "+";
}
}
if (rva == UNKNOWN_ADDR) return;

ss << std::hex << rva << TraceLog::DELIMITER << ANTIVM_LABEL << msg;
if (link) {
ss << TraceLog::DELIMITER << link;
}
traceLog.logLine(ss.str());
}

/* ==================================================================== */
// Process API calls (related to AntiVm techniques)
/* ==================================================================== */

VOID AntiVm_WmiQueries(const ADDRINT addr, const CHAR* name, uint32_t argCount, VOID* arg1, VOID* arg2, VOID* arg3, VOID* arg4, VOID* arg5, VOID* arg6)
{
if (!argCount) return;

PinLocker locker;
const WatchedType wType = isWatchedAddress(addr);
if (wType == WatchedType::NOT_WATCHED) return;

using namespace WINDOWS;

LPCWSTR wmi_query = (LPCWSTR)arg2;

if (wmi_query == NULL) return;

char wmi_query_field[PATH_BUFSIZE];
GET_STR_TO_UPPER(wmi_query, wmi_query_field, PATH_BUFSIZE);

if (util::iequals(wmi_query_field, WMI_NUMBER_CORES) || util::iequals(wmi_query_field, WMI_PROCESSOR)) {
return LogAntiVm(wType, addr, "^ WMI query - number of CPU cores",
"https://evasions.checkpoint.com/techniques/wmi.html#generic-wmi-queries");
}
else if (util::iequals(wmi_query_field, WMI_SIZE)) {
return LogAntiVm(wType, addr, "^ WMI query - hard disk size",
"https://evasions.checkpoint.com/techniques/wmi.html#generic-wmi-queries");
}
else if (util::iequals(wmi_query_field, WMI_DEVICE_ID)) {
return LogAntiVm(wType, addr, "^ WMI query - device ID",
"https://evasions.checkpoint.com/techniques/wmi.html#generic-wmi-queries");
}
else if (util::iequals(wmi_query_field, WMI_MAC_ADDRESS)) {
return LogAntiVm(wType, addr, "^ WMI query - MAC address",
"https://evasions.checkpoint.com/techniques/wmi.html#generic-wmi-queries");
}
else if (util::iequals(wmi_query_field, WMI_TEMPERATURE)) {
return LogAntiVm(wType, addr, "^ WMI query - system temperatures",
"https://evasions.checkpoint.com/techniques/wmi.html#generic-wmi-queries");
}
else if (util::iequals(wmi_query_field, WMI_SERIAL)) {
return LogAntiVm(wType, addr, "^ WMI query - BIOS serial number",
"https://evasions.checkpoint.com/techniques/wmi.html#generic-wmi-queries");
}
else if (util::iequals(wmi_query_field, WMI_MODEL) || util::iequals(wmi_query_field, WMI_MANUFACTURER)) {
return LogAntiVm(wType, addr, "^ WMI query - system model and/or manufacturer",
"https://evasions.checkpoint.com/techniques/wmi.html#generic-wmi-queries");
}
else if (util::iequals(wmi_query_field, WMI_GPU_ADAPTER)) {
return LogAntiVm(wType, addr, "^ WMI query - video controller adapter",
"https://evasions.checkpoint.com/techniques/wmi.html#generic-wmi-queries");
}
else if (util::iequals(wmi_query_field, WMI_PRODUCT) || util::iequals(wmi_query_field, WMI_NAME)) {
return LogAntiVm(wType, addr, "^ WMI query - system device names",
"https://evasions.checkpoint.com/techniques/wmi.html#generic-wmi-queries");
}
}

/* ==================================================================== */
// Add single hooking function
/* ==================================================================== */

bool AntiVmAddCallbackBefore(IMG Image, char* fName, uint32_t argNum, AntiVmCallBack callback)
{
const size_t argMax = 6;
if (argNum > argMax) argNum = argMax;

RTN funcRtn = RTN_FindByName(Image, fName);
if (RTN_Valid(funcRtn)) {
RTN_Open(funcRtn);

RTN_InsertCall(funcRtn, IPOINT_BEFORE, AFUNPTR(callback),
IARG_RETURN_IP,
IARG_ADDRINT, fName,
IARG_UINT32, argNum,
IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
IARG_FUNCARG_ENTRYPOINT_VALUE, 1,
IARG_FUNCARG_ENTRYPOINT_VALUE, 2,
IARG_FUNCARG_ENTRYPOINT_VALUE, 3,
IARG_FUNCARG_ENTRYPOINT_VALUE, 4,
IARG_FUNCARG_ENTRYPOINT_VALUE, 5,
IARG_END
);

RTN_Close(funcRtn);
return true;
}

return false;
}

/* ==================================================================== */
// Add to monitored functions all the API calls or WMI queries needed for AntiVM.
// Called by ImageLoad
/* ==================================================================== */

VOID AntiVm::MonitorAntiVmFunctions(IMG Image)
{
// API needed to trace WMI queries
const std::string dllName = util::getDllName(IMG_Name(Image));
if (util::iequals(dllName, "fastprox")) {
#ifdef _WIN64
AntiVmAddCallbackBefore(Image, "?Get@CWbemObject@@UEAAJPEBGJPEAUtagVARIANT@@PEAJ2@Z", 6, AntiVm_WmiQueries);
#else
AntiVmAddCallbackBefore(Image, "?Get@CWbemObject@@UAGJPBGJPAUtagVARIANT@@PAJ2@Z", 6, AntiVm_WmiQueries);
#endif
}
}
7 changes: 6 additions & 1 deletion Settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#define HOOK_SLEEP "HOOK_SLEEP"
#define LOG_INDIRECT "LOG_INDIRECT_CALLS"
#define KEY_ANTIDEBUG "ANTIDEBUG"
#define KEY_ANTIVM "ANTIVM"
#define KEY_USE_DEBUG_SYMBOLS "USE_DEBUG_SYMBOLS"

t_shellc_options ConvertShcOption(int value)
Expand Down Expand Up @@ -154,6 +155,10 @@ bool fillSettings(Settings &s, std::string line)
s.antidebug = ConvertAntidebugOption(val);
isFilled = true;
}
if (util::iequals(valName, KEY_ANTIVM)) {
s.antivm = loadBoolean(valStr, s.antivm);
isFilled = true;
}
if (util::iequals(valName, KEY_USE_DEBUG_SYMBOLS)) {
s.useDebugSym = loadBoolean(valStr, s.useDebugSym);
isFilled = true;
Expand Down Expand Up @@ -189,7 +194,7 @@ bool Settings::saveINI(const std::string &filename)
myfile << SLEEP_TIME << DELIM << this->sleepTime << "\r\n";
myfile << LOG_INDIRECT << DELIM << this->logIndirect << "\r\n";
myfile << KEY_ANTIDEBUG << DELIM << this->antidebug << "\r\n";

myfile << KEY_ANTIVM << DELIM << this->antivm << "\r\n";
myfile.close();
return true;
}
Expand Down
2 changes: 2 additions & 0 deletions Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class Settings {
logIndirect(false),
hexdumpSize(8),
antidebug(ANTIDEBUG_DISABLED),
antivm(false),
useDebugSym(false)
{
}
Expand All @@ -91,6 +92,7 @@ class Settings {
bool hookSleep;
size_t sleepTime;
t_antidebug_options antidebug;
bool antivm; // Trace Anti-VM techniques (WMI queries)
bool useDebugSym;

SyscallsTable syscallsTable; //Syscalls table: mapping the syscall ID to the function name
Expand Down
13 changes: 13 additions & 0 deletions TinyTracer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,21 @@


#define USE_ANTIDEBUG
#define USE_ANTIVM

#ifndef _WIN32
#undef USE_ANTIDEBUG // works only for Windows!
#undef USE_ANTIVM
#endif

#ifdef USE_ANTIDEBUG
#include "AntiDebug.h"
#endif

#ifdef USE_ANTIVM
#include "AntiVm.h"
#endif

/* ================================================================== */
// Global variables
/* ================================================================== */
Expand Down Expand Up @@ -818,6 +824,13 @@ VOID ImageLoad(IMG Image, VOID *v)
AntiDbg::MonitorAntiDbgFunctions(Image);
}
#endif
#ifdef USE_ANTIVM
// ANTIVM: Register Function instrumentation needed for AntiVm
if (m_Settings.antivm) {
// Register functions
AntiVm::MonitorAntiVmFunctions(Image);
}
#endif
}

static void OnCtxChange(THREADID threadIndex,
Expand Down
2 changes: 2 additions & 0 deletions TinyTracer.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Antivm.cpp" />
<ClCompile Include="ModuleInfo.cpp" />
<ClCompile Include="ProcessInfo.cpp" />
<ClCompile Include="AntiDebug.cpp" />
Expand All @@ -290,6 +291,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="AntiDebug.h" />
<ClInclude Include="AntiVm.h" />
<ClInclude Include="TinyTracer.h" />
<ClInclude Include="ModuleInfo.h" />
<ClInclude Include="ProcessInfo.h" />
Expand Down
4 changes: 3 additions & 1 deletion TinyTracer_Pin3.18.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Antivm.cpp" />
<ClCompile Include="ModuleInfo.cpp" />
<ClCompile Include="ProcessInfo.cpp" />
<ClCompile Include="AntiDebug.cpp" />
Expand All @@ -289,6 +290,7 @@
<ClCompile Include="Settings.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="AntiVm.h" />
<ClInclude Include="ModuleInfo.h" />
<ClInclude Include="ProcessInfo.h" />
<ClInclude Include="AntiDebug.h" />
Expand All @@ -301,4 +303,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
4 changes: 3 additions & 1 deletion TinyTracer_Pin3.25.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Antivm.cpp" />
<ClCompile Include="ModuleInfo.cpp" />
<ClCompile Include="ProcessInfo.cpp" />
<ClCompile Include="AntiDebug.cpp" />
Expand All @@ -289,6 +290,7 @@
<ClCompile Include="Settings.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="AntiVm.h" />
<ClInclude Include="ModuleInfo.h" />
<ClInclude Include="ProcessInfo.h" />
<ClInclude Include="AntiDebug.h" />
Expand All @@ -301,4 +303,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
1 change: 1 addition & 0 deletions install32_64/TinyTracer.ini
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ SLEEP_TIME=10
; 1 : Standard
; 2 : Deep (may lead to some false positives)
ANTIDEBUG=0
ANTIVM=0

0 comments on commit 8bdd5e3

Please sign in to comment.