init
This commit is contained in:
@@ -54,6 +54,7 @@
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
@@ -111,6 +112,7 @@
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -118,6 +120,7 @@
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalDependencies>ntdll.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
@@ -153,10 +156,12 @@
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalDependencies>ntdll.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="active_check.cpp" />
|
||||
<ClCompile Include="check_vmware.cpp" />
|
||||
<ClCompile Include="client_comm_shared.cpp" />
|
||||
<ClCompile Include="client_palpit.cpp" />
|
||||
<ClCompile Include="client_pipe.cpp" />
|
||||
@@ -170,6 +175,7 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="active_check.h" />
|
||||
<ClInclude Include="Base.h" />
|
||||
<ClInclude Include="check_vmware.h" />
|
||||
<ClInclude Include="client_comm_shared.h" />
|
||||
<ClInclude Include="client_driver.h" />
|
||||
<ClInclude Include="client_palpit.h" />
|
||||
@@ -179,7 +185,15 @@
|
||||
<ClInclude Include="private_funcion.h" />
|
||||
<ClInclude Include="utils.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<MASM Include="asm.asm">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
<FileType>Document</FileType>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</MASM>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -31,12 +31,12 @@
|
||||
<Filter Include="client_palpit">
|
||||
<UniqueIdentifier>{f04162c8-3fb0-4100-822c-af77bb70dbf5}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="active_check">
|
||||
<UniqueIdentifier>{bdfbbba6-e274-4b3c-9f2e-0c2285fb3868}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="client_pipe">
|
||||
<UniqueIdentifier>{f1272f12-b056-43cc-840b-af2cacdf461e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="check class">
|
||||
<UniqueIdentifier>{bdfbbba6-e274-4b3c-9f2e-0c2285fb3868}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
@@ -64,11 +64,14 @@
|
||||
<Filter>Driver</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="active_check.cpp">
|
||||
<Filter>active_check</Filter>
|
||||
<Filter>check class</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="client_pipe.cpp">
|
||||
<Filter>client_pipe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="check_vmware.cpp">
|
||||
<Filter>check class</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Base.h">
|
||||
@@ -96,10 +99,18 @@
|
||||
<Filter>Driver</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="active_check.h">
|
||||
<Filter>active_check</Filter>
|
||||
<Filter>check class</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="client_pipe.h">
|
||||
<Filter>client_pipe</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="check_vmware.h">
|
||||
<Filter>check class</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<MASM Include="asm.asm">
|
||||
<Filter>check class</Filter>
|
||||
</MASM>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -9,6 +9,9 @@
|
||||
#include <mutex>
|
||||
#include <deque>
|
||||
#include <vector>
|
||||
#include "ntdll.h"
|
||||
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#include "active_check.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
static const NTSTATUS StatusInfoLengthMismatch = 0xC0000004L;
|
||||
|
||||
namespace active_check
|
||||
{
|
||||
auto check_awesun_process() -> bool
|
||||
@@ -65,4 +68,175 @@ namespace active_check
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD GetProcessIdFromHandle(
|
||||
HANDLE ProcessHandle
|
||||
)
|
||||
{
|
||||
PROCESS_BASIC_INFORMATION_CUSTOM
|
||||
_ProcessBasicInformation{};
|
||||
|
||||
ULONG ReturnLength = 0;
|
||||
|
||||
|
||||
NTSTATUS Status =
|
||||
NtQueryInformationProcess(
|
||||
ProcessHandle,
|
||||
ProcessBasicInformation,
|
||||
&_ProcessBasicInformation,
|
||||
sizeof(_ProcessBasicInformation),
|
||||
&ReturnLength
|
||||
);
|
||||
|
||||
|
||||
if (Status < 0)
|
||||
return 0;
|
||||
|
||||
|
||||
return _ProcessBasicInformation.UniqueProcessId;
|
||||
}
|
||||
|
||||
auto ScanProcessHandles(DWORD CurrentProcessId, PROCESS_HANDLE_RESULTS* Results) -> BOOL
|
||||
{
|
||||
if (!Results)
|
||||
return FALSE;
|
||||
|
||||
ZeroMemory(
|
||||
Results,
|
||||
sizeof(PROCESS_HANDLE_RESULTS)
|
||||
);
|
||||
|
||||
ULONG BufferSize = 1024 * 1024;
|
||||
ULONG ReturnLength = 0;
|
||||
PVOID Buffer = nullptr;
|
||||
NTSTATUS Status;
|
||||
|
||||
|
||||
while (true)
|
||||
{
|
||||
Buffer = HeapAlloc(
|
||||
GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
BufferSize
|
||||
);
|
||||
|
||||
if (!Buffer)
|
||||
return FALSE;
|
||||
|
||||
|
||||
Status = NtQuerySystemInformation(
|
||||
SystemExtendedHandleInformation,
|
||||
Buffer,
|
||||
BufferSize,
|
||||
&ReturnLength
|
||||
);
|
||||
|
||||
|
||||
if (Status != StatusInfoLengthMismatch)
|
||||
break;
|
||||
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, Buffer);
|
||||
|
||||
Buffer = nullptr;
|
||||
|
||||
BufferSize =
|
||||
ReturnLength > BufferSize
|
||||
? ReturnLength + 0x10000
|
||||
: BufferSize * 2;
|
||||
}
|
||||
|
||||
|
||||
if (Status < 0)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, Buffer);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
SYSTEM_HANDLE_INFORMATION_EX*
|
||||
HandleInformation =
|
||||
(SYSTEM_HANDLE_INFORMATION_EX*)Buffer;
|
||||
|
||||
|
||||
for (ULONG_PTR Index = 0;
|
||||
Index < HandleInformation->NumberOfHandles;
|
||||
++Index)
|
||||
{
|
||||
SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX*
|
||||
HandleEntry =
|
||||
&HandleInformation->Handles[Index];
|
||||
|
||||
|
||||
auto OwnerProcessId = HandleEntry->UniqueProcessId;
|
||||
|
||||
if (OwnerProcessId == CurrentProcessId)
|
||||
continue;
|
||||
|
||||
|
||||
HANDLE OwnerProcessHandle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, OwnerProcessId);
|
||||
|
||||
|
||||
if (!OwnerProcessHandle)
|
||||
continue;
|
||||
|
||||
|
||||
HANDLE DuplicatedHandle = nullptr;
|
||||
|
||||
|
||||
BOOL DuplicateResult =
|
||||
DuplicateHandle(
|
||||
OwnerProcessHandle,
|
||||
(HANDLE)HandleEntry->HandleValue,
|
||||
GetCurrentProcess(),
|
||||
&DuplicatedHandle,
|
||||
0,
|
||||
FALSE,
|
||||
DUPLICATE_SAME_ACCESS
|
||||
);
|
||||
|
||||
|
||||
if (DuplicateResult)
|
||||
{
|
||||
auto TargetProcessId = GetProcessIdFromHandle(DuplicatedHandle);
|
||||
|
||||
if (TargetProcessId == CurrentProcessId)
|
||||
{
|
||||
if (Results->Count < MAX_PROCESS_HANDLE_RESULTS)
|
||||
{
|
||||
auto Result = &Results->Items[Results->Count];
|
||||
|
||||
|
||||
Result->ProcessId = OwnerProcessId;
|
||||
|
||||
Result->TargetProcessId = TargetProcessId;
|
||||
|
||||
Result->HandleValue = HandleEntry->HandleValue;
|
||||
|
||||
Result->GrantedAccess = HandleEntry->GrantedAccess;
|
||||
|
||||
|
||||
utils::GetProcessName(
|
||||
OwnerProcessId,
|
||||
Result->ProcessName,
|
||||
sizeof(Result->ProcessName)
|
||||
);
|
||||
|
||||
|
||||
Results->Count++;
|
||||
}
|
||||
}
|
||||
CloseHandle(DuplicatedHandle);
|
||||
}
|
||||
CloseHandle(OwnerProcessHandle);
|
||||
}
|
||||
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, Buffer);
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,37 @@
|
||||
#pragma once
|
||||
#include "Base.h"
|
||||
#define MAX_PROCESS_HANDLE_RESULTS 256
|
||||
|
||||
typedef struct _PROCESS_BASIC_INFORMATION_CUSTOM
|
||||
{
|
||||
NTSTATUS ExitStatus;
|
||||
PVOID PebBaseAddress;
|
||||
ULONG_PTR AffinityMask;
|
||||
LONG BasePriority;
|
||||
ULONG_PTR UniqueProcessId;
|
||||
ULONG_PTR InheritedFromUniqueProcessId;
|
||||
|
||||
} PROCESS_BASIC_INFORMATION_CUSTOM,
|
||||
* PPROCESS_BASIC_INFORMATION_CUSTOM;
|
||||
|
||||
typedef struct _PROCESS_HANDLE_RESULT
|
||||
{
|
||||
DWORD ProcessId;
|
||||
DWORD TargetProcessId;
|
||||
ULONG_PTR HandleValue;
|
||||
ULONG GrantedAccess;
|
||||
char ProcessName[MAX_PATH];
|
||||
|
||||
} PROCESS_HANDLE_RESULT;
|
||||
|
||||
typedef struct _PROCESS_HANDLE_RESULTS
|
||||
{
|
||||
DWORD Count;
|
||||
PROCESS_HANDLE_RESULT Items[MAX_PROCESS_HANDLE_RESULTS];
|
||||
|
||||
} PROCESS_HANDLE_RESULTS;
|
||||
|
||||
|
||||
|
||||
namespace active_check
|
||||
{
|
||||
@@ -18,4 +50,6 @@ namespace active_check
|
||||
//检测远程软件进程
|
||||
auto check_remote_app_process() -> bool;
|
||||
|
||||
//检测已打开的进程句柄的进程
|
||||
auto ScanProcessHandles(DWORD CurrentProcessId, PROCESS_HANDLE_RESULTS* Results)->BOOL;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
.CODE
|
||||
|
||||
Asm_CheckVmWare PROC
|
||||
|
||||
mov rax, 0564D5868h ; 魔法值 'VMXh',VMware端口通信固定标识
|
||||
mov rbx, 0FFFFFFFFh ; RBX初始值,用于接收Hypervisor返回标识
|
||||
mov rcx, 10 ; 命令号 10 = CMD_GetVersion(获取VMware版本)
|
||||
mov rdx, 05658h ; VMware专属I/O端口号 0x5658
|
||||
in eax, dx ; 向VMware端口发起通信请求
|
||||
cmp rbx, 0564D5868h ; 判断RBX是否被改写为'VMXh'魔法值
|
||||
jz vm_found ; 相等 = 检测到VMware,跳转
|
||||
|
||||
xor al, al ; 未找到,AL置0(FALSE)
|
||||
jmp vm_end
|
||||
|
||||
vm_found:
|
||||
mov al, 1 ; 找到VMware,AL置1(TRUE)
|
||||
vm_end:
|
||||
ret
|
||||
|
||||
Asm_CheckVmWare ENDP
|
||||
|
||||
|
||||
Asm_VMCall PROC
|
||||
vmcall
|
||||
ret
|
||||
Asm_VMCall ENDP
|
||||
|
||||
|
||||
|
||||
END
|
||||
@@ -0,0 +1,360 @@
|
||||
#include "check_vmware.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <initguid.h>
|
||||
#include <devguid.h>
|
||||
#include <SetupAPI.h>
|
||||
#include <initguid.h>
|
||||
#include <dxgi.h>
|
||||
|
||||
#pragma comment(lib, "dxgi.lib")
|
||||
#pragma comment(lib, "Setupapi.lib")
|
||||
|
||||
|
||||
CONST WCHAR* processList[] =
|
||||
{
|
||||
L"vmtoolsd.exe",
|
||||
L"vm3dservice.exe",
|
||||
L"VGAuthService.exe",
|
||||
};
|
||||
|
||||
CONST CHAR* filePathName[] =
|
||||
{
|
||||
"C:\\Program Files\\VMware",
|
||||
|
||||
"C:\\Windows\\System32\\drivers\\vmmouse.sys",
|
||||
"C:\\Windows\\System32\\drivers\\vmusbmouse.sys",
|
||||
|
||||
"C:\\Windows\\System32\\drivers\\vm3dmp.sys",
|
||||
"C:\\Windows\\System32\\drivers\\vm3dmp_loader.sys",
|
||||
"C:\\Windows\\System32\\drivers\\vm3dmp-debug.sys",
|
||||
"C:\\Windows\\System32\\drivers\\vm3dmp-stats.sys",
|
||||
};
|
||||
|
||||
namespace check_vmware
|
||||
{
|
||||
bool registry()
|
||||
{
|
||||
char szBuf[256]{ 0 };
|
||||
if (utils::RegReadString(HKEY_LOCAL_MACHINE,
|
||||
"HARDWARE\\DESCRIPTION\\System\\BIOS",
|
||||
"SystemManufacturer",
|
||||
szBuf, sizeof(szBuf)))
|
||||
{
|
||||
if (strstr(szBuf, "VMware"))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (utils::RegReadString(HKEY_LOCAL_MACHINE,
|
||||
"HARDWARE\\DESCRIPTION\\System\\BIOS",
|
||||
"SystemProductName",
|
||||
szBuf, sizeof(szBuf)))
|
||||
{
|
||||
if (strstr(szBuf, "VMware"))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool process()
|
||||
{
|
||||
auto Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
|
||||
if (Snapshot == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
PROCESSENTRY32 pe32{ 0 };
|
||||
pe32.dwSize = sizeof(pe32);
|
||||
|
||||
|
||||
if (Process32First(Snapshot, &pe32))
|
||||
{
|
||||
do {
|
||||
for (size_t i = 0; i < sizeof(processList) / sizeof(processList[0]); i++)
|
||||
{
|
||||
if (!wcscmp(processList[i], pe32.szExeFile))
|
||||
{
|
||||
CloseHandle(Snapshot);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} while (Process32Next(Snapshot, &pe32));
|
||||
}
|
||||
|
||||
CloseHandle(Snapshot);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cpuid()
|
||||
{
|
||||
int info[4]{ 0 };
|
||||
CHAR szHypervisorVendor[256];
|
||||
|
||||
__cpuid(info, 0x40000000);
|
||||
SecureZeroMemory(szHypervisorVendor, sizeof(szHypervisorVendor));
|
||||
memcpy(szHypervisorVendor, info + 1, 12);
|
||||
|
||||
if (!_strcmpi(szHypervisorVendor, "VMwareVMware"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cpuid2()
|
||||
{
|
||||
int info[4]{ 0 };
|
||||
|
||||
__cpuid(info, 1);
|
||||
|
||||
if ((info[2] >> 31) & 1)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool diskname()
|
||||
{
|
||||
HDEVINFO hDevInfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_DISKDRIVE, NULL, NULL, DIGCF_PRESENT);
|
||||
if (hDevInfo == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
SP_DEVINFO_DATA devInfo = { 0 };
|
||||
devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
|
||||
|
||||
DWORD dwIndex = 0;
|
||||
// 循环枚举全部磁盘设备
|
||||
while (SetupDiEnumDeviceInfo(hDevInfo, dwIndex, &devInfo))
|
||||
{
|
||||
WCHAR szBuffer[1024] = { 0 };
|
||||
DWORD dwDataType = 0;
|
||||
DWORD dwBufSize = sizeof(szBuffer);
|
||||
|
||||
// 读取设备友好名称 SPDRP_FRIENDLYNAME
|
||||
if (SetupDiGetDeviceRegistryPropertyW(
|
||||
hDevInfo,
|
||||
&devInfo,
|
||||
SPDRP_FRIENDLYNAME,
|
||||
&dwDataType,
|
||||
(PBYTE)szBuffer,
|
||||
dwBufSize,
|
||||
&dwBufSize))
|
||||
{
|
||||
if (utils::StrContainsI(szBuffer, L"VBOX") ||
|
||||
utils::StrContainsI(szBuffer, L"QEMU") ||
|
||||
utils::StrContainsI(szBuffer, L"VMWARE") ||
|
||||
utils::StrContainsI(szBuffer, L"VIRTUAL HD"))
|
||||
{
|
||||
SetupDiDestroyDeviceInfoList(hDevInfo);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
dwIndex++;
|
||||
}
|
||||
SetupDiDestroyDeviceInfoList(hDevInfo);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool mousename()
|
||||
{
|
||||
HDEVINFO hDevInfo = SetupDiGetClassDevs(
|
||||
&GUID_DEVCLASS_MOUSE,
|
||||
NULL,
|
||||
NULL,
|
||||
DIGCF_PRESENT);
|
||||
|
||||
if (hDevInfo == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
SP_DEVINFO_DATA DeviceInfoData;
|
||||
DeviceInfoData.cbSize = sizeof(DeviceInfoData);
|
||||
|
||||
bool bVirtual = false;
|
||||
|
||||
for (DWORD i = 0;
|
||||
SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData);
|
||||
i++)
|
||||
{
|
||||
WCHAR Name[512] = { 0 };
|
||||
|
||||
// FriendlyName
|
||||
if (!SetupDiGetDeviceRegistryPropertyW(
|
||||
hDevInfo,
|
||||
&DeviceInfoData,
|
||||
SPDRP_FRIENDLYNAME,
|
||||
NULL,
|
||||
(PBYTE)Name,
|
||||
sizeof(Name),
|
||||
NULL))
|
||||
{
|
||||
// 有些设备没有 FriendlyName
|
||||
SetupDiGetDeviceRegistryPropertyW(
|
||||
hDevInfo,
|
||||
&DeviceInfoData,
|
||||
SPDRP_DEVICEDESC,
|
||||
NULL,
|
||||
(PBYTE)Name,
|
||||
sizeof(Name),
|
||||
NULL);
|
||||
}
|
||||
|
||||
std::wstring str = Name;
|
||||
|
||||
if (str.find(L"VMware") != std::wstring::npos ||
|
||||
str.find(L"VirtualBox") != std::wstring::npos ||
|
||||
str.find(L"Hyper-V") != std::wstring::npos ||
|
||||
str.find(L"Virtual") != std::wstring::npos ||
|
||||
str.find(L"QEMU") != std::wstring::npos ||
|
||||
str.find(L"Xen") != std::wstring::npos ||
|
||||
str.find(L"Parallels") != std::wstring::npos)
|
||||
{
|
||||
bVirtual = true;
|
||||
}
|
||||
}
|
||||
|
||||
SetupDiDestroyDeviceInfoList(hDevInfo);
|
||||
return bVirtual;
|
||||
}
|
||||
|
||||
|
||||
bool dxgiGpuName()
|
||||
{
|
||||
HRESULT hr;
|
||||
IDXGIFactory1* pFactory = nullptr;
|
||||
|
||||
hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pFactory);
|
||||
if (FAILED(hr) || !pFactory)
|
||||
return false;
|
||||
|
||||
UINT adapterIndex = 0;
|
||||
IDXGIAdapter1* pAdapter = nullptr;
|
||||
|
||||
// 遍历所有显卡适配器
|
||||
while (pFactory->EnumAdapters1(adapterIndex, &pAdapter) != DXGI_ERROR_NOT_FOUND)
|
||||
{
|
||||
DXGI_ADAPTER_DESC1 desc;
|
||||
hr = pAdapter->GetDesc1(&desc);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// 虚拟机显卡特征关键词
|
||||
if (wcsstr(desc.Description, L"VMware") != nullptr
|
||||
|| wcsstr(desc.Description, L"VBox") != nullptr
|
||||
|| wcsstr(desc.Description, L"VirtualBox") != nullptr
|
||||
|| wcsstr(desc.Description, L"Basic Display Adapter") != nullptr)
|
||||
{
|
||||
pAdapter->Release();
|
||||
pFactory->Release();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
pAdapter->Release();
|
||||
adapterIndex++;
|
||||
}
|
||||
|
||||
pFactory->Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool In()
|
||||
{
|
||||
#if _WIN64
|
||||
__try
|
||||
{
|
||||
Asm_CheckVmWare();
|
||||
return true;
|
||||
}
|
||||
__except (1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
__try
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov eax, 0x564D5868; //魔法值 'VMXh',VMware端口通信固定标识
|
||||
mov ebx, 0xFFFFFFFF; //EBX初始值,用于接收Hypervisor返回标识
|
||||
mov ecx, 10; //命令号 10 = CMD_GetVersion(获取VMware版本)
|
||||
mov edx, 0x5658; //VMware专属I / O端口号 0x5658
|
||||
in eax, dx; //向VMware端口发起通信请求
|
||||
cmp ebx, 0x564D5868; //判断EBX是否被改写为'VMXh'魔法值
|
||||
je vm_found; //相等 = 检测到VMware,跳转
|
||||
xor al, al; //未找到,AL置0(FALSE)
|
||||
jmp vm_end; //跳转到结尾
|
||||
vm_found:
|
||||
mov al, 1; //找到VMware,AL置1(TRUE)
|
||||
vm_end:
|
||||
}
|
||||
}
|
||||
__except (GetExceptionCode() == EXCEPTION_PRIV_INSTRUCTION)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool file()
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(filePathName) / sizeof(filePathName[0]); i++)
|
||||
{
|
||||
if (GetFileAttributesA(filePathName[i]) != INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned long long rdtsc_exit()
|
||||
{
|
||||
int info[4]{ 0 };
|
||||
DWORD64 tsc1, tsc2;
|
||||
DWORD64 sum = 0;
|
||||
|
||||
for (size_t i = 0; i < 200; i++)
|
||||
{
|
||||
tsc1 = __rdtsc();
|
||||
__cpuid(info, 0);
|
||||
tsc2 = __rdtsc();
|
||||
sum += (tsc2 - tsc1);
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
bool virutal_check_vmcall()
|
||||
{
|
||||
#if _WIN64
|
||||
|
||||
__try
|
||||
{
|
||||
Asm_VMCall();
|
||||
return true;
|
||||
}
|
||||
__except (1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
|
||||
__try
|
||||
{
|
||||
_asm
|
||||
{
|
||||
_emit 0x0F
|
||||
_emit 0x01
|
||||
_emit 0xC1
|
||||
|
||||
mov eax, 1
|
||||
}
|
||||
}
|
||||
__except (1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
#ifndef CHECK_VMWARE_H
|
||||
#define CHECK_VMWARE_H
|
||||
#include "Base.h"
|
||||
|
||||
EXTERN_C VOID Asm_CheckVmWare();
|
||||
EXTERN_C VOID Asm_VMCall();
|
||||
|
||||
namespace check_vmware
|
||||
{
|
||||
//注册表环境检测
|
||||
bool registry();
|
||||
|
||||
//进程检测
|
||||
bool process();
|
||||
|
||||
//CPUID检测
|
||||
bool cpuid();
|
||||
bool cpuid2();
|
||||
|
||||
//硬盘名检测
|
||||
bool diskname();
|
||||
|
||||
//鼠标名检测
|
||||
bool mousename();
|
||||
|
||||
//显卡名检测
|
||||
bool dxgiGpuName();
|
||||
|
||||
//In指令检测
|
||||
bool In();
|
||||
|
||||
//文件特征检测
|
||||
bool file();
|
||||
|
||||
//获取guest到host层的开销
|
||||
unsigned long long rdtsc_exit();
|
||||
|
||||
//vmcall检测虚拟化行为
|
||||
bool virutal_check_vmcall();
|
||||
}
|
||||
|
||||
|
||||
#endif // !CHECK_VMWARE_H
|
||||
@@ -41,12 +41,12 @@ namespace client_shared_mapping
|
||||
return pData;
|
||||
}
|
||||
|
||||
auto StartServerProcess(CONST char* Path) -> BOOL
|
||||
auto StartServerProcess(CONST char* Path, PDWORD status)->BOOL
|
||||
{
|
||||
if (GetFileAttributesA(Path) != INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
char buf[256]{ 0 };
|
||||
sprintf_s(buf, "%s\\Anit-Seriver.exe", Path);
|
||||
sprintf_s(buf, "%s\\ESP Anit-Cheat.exe", Path);
|
||||
|
||||
if (private_funcion::create_start_process(buf))
|
||||
{
|
||||
@@ -61,10 +61,24 @@ namespace client_shared_mapping
|
||||
|
||||
}
|
||||
}*/
|
||||
|
||||
//启动成功
|
||||
*status = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
//进程启动失败 | 权限不足
|
||||
*status = 100;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*status = 101;
|
||||
//文件不存在
|
||||
|
||||
|
||||
auto string = "[Anit-Cheat]系统运行发生致命错误,错误代码:" + to_string(GetLastError());
|
||||
MessageBoxA(NULL, string.c_str(), "您似乎遇到了一些问题", MB_OK);
|
||||
return FALSE;
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace client_shared_mapping
|
||||
auto mapping_shared_memory(HANDLE hMap)->PMAPPING_USER_MEMORY;
|
||||
|
||||
//启动服务进程
|
||||
auto StartServerProcess(CONST char* Path)->BOOL;
|
||||
auto StartServerProcess(CONST char* Path, PDWORD status)->BOOL;
|
||||
|
||||
//启动目标通信进程
|
||||
auto anit_cheat_create_process()->BOOL;
|
||||
|
||||
@@ -19,9 +19,9 @@ auto client_driver::fn_get_instance() -> client_driver*
|
||||
return instance;
|
||||
}
|
||||
|
||||
auto client_driver::driver_map_load() -> BOOL
|
||||
auto client_driver::driver_map_load(PDWORD status) -> BOOL
|
||||
{
|
||||
return HBClientLoadDriverW();
|
||||
return HBClientLoadDriverW(status);
|
||||
}
|
||||
|
||||
auto client_driver::check_load_driver() -> BOOL
|
||||
|
||||
@@ -10,7 +10,7 @@ class client_driver
|
||||
public:
|
||||
static auto fn_get_instance()->client_driver*;
|
||||
|
||||
auto driver_map_load()->BOOL;
|
||||
auto driver_map_load(PDWORD status)->BOOL;
|
||||
|
||||
auto check_load_driver()->BOOL;
|
||||
|
||||
|
||||
@@ -482,11 +482,13 @@ BOOL HBClientCall(
|
||||
DWORD wait = WaitForMultipleObjects(2, waits, FALSE, 10000);
|
||||
BOOL ok = (wait == WAIT_OBJECT_0 && cmd->status == ERROR_SUCCESS);
|
||||
|
||||
if (ok && output && !cmd->output.empty())
|
||||
if (output && !cmd->output.empty())
|
||||
{
|
||||
memcpy(output, cmd->output.data(), cmd->output.size());
|
||||
|
||||
if (bytes_returned)
|
||||
*bytes_returned = static_cast<uint32_t>(cmd->output.size());
|
||||
*bytes_returned =
|
||||
static_cast<uint32_t>(cmd->output.size());
|
||||
}
|
||||
|
||||
CloseHandle(cmd->done_event);
|
||||
@@ -589,19 +591,26 @@ BOOL QueryServerAlreadyOpen()
|
||||
}
|
||||
|
||||
|
||||
BOOL HBClientLoadDriverW()
|
||||
BOOL HBClientLoadDriverW(PDWORD status)
|
||||
{
|
||||
LoadDriverRequest req{};
|
||||
//wcsncpy_s(req.service_name, service_name, _TRUNCATE);
|
||||
//wcsncpy_s(req.driver_path, driver_path, _TRUNCATE);
|
||||
|
||||
return HBClientCall(
|
||||
LoadDriverRequest req{};
|
||||
LoadDriverRequest response{};
|
||||
|
||||
uint32_t bytes_returned = 0;
|
||||
|
||||
BOOL result = HBClientCall(
|
||||
static_cast<uint32_t>(CommandId::LoadDriver),
|
||||
&req,
|
||||
sizeof(req),
|
||||
nullptr,
|
||||
0,
|
||||
nullptr);
|
||||
&response,
|
||||
sizeof(response),
|
||||
&bytes_returned);
|
||||
|
||||
if (bytes_returned == sizeof(response))
|
||||
*status = response.status;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL HBClientUnloadDriverW(const wchar_t* service_name)
|
||||
|
||||
@@ -25,6 +25,8 @@ enum class CommandId : uint32_t
|
||||
UnloadDriver = 3,
|
||||
QueryStatus = 4,
|
||||
BreakpointRemoved = 5,
|
||||
CheckVMware = 6,
|
||||
CheckVmx = 7,
|
||||
};
|
||||
|
||||
#pragma pack(push, 8)
|
||||
@@ -53,7 +55,10 @@ struct PrintfRequest
|
||||
struct LoadDriverRequest
|
||||
{
|
||||
wchar_t service_name[128];
|
||||
|
||||
wchar_t driver_path[MAX_PATH];
|
||||
|
||||
DWORD status;
|
||||
};
|
||||
|
||||
struct UnloadDriverRequest
|
||||
@@ -113,6 +118,6 @@ bool WideToUtf8(const std::wstring& input, char* output, size_t output_size);
|
||||
|
||||
BOOL DllClientPrintfW(const wchar_t* text);
|
||||
|
||||
BOOL HBClientLoadDriverW();
|
||||
BOOL HBClientLoadDriverW(PDWORD status);
|
||||
|
||||
BOOL QueryServerAlreadyOpen();
|
||||
@@ -12,10 +12,8 @@ auto MainThread()->void
|
||||
MessageBoxA(NULL, string.c_str(), "您似乎遇到了一些问题", MB_OK);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
BOOL APIENTRY DllMain( HMODULE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
|
||||
@@ -3,10 +3,27 @@
|
||||
#include "client_comm_shared.h"
|
||||
#include "active_check.h"
|
||||
#include "client_pipe.h"
|
||||
#include "check_vmware.h"
|
||||
|
||||
MYAPI_API BOOL set_server_process_path(const char* Path)
|
||||
string g_Version = "1.0.0.0";
|
||||
|
||||
MYAPI_API VOID Init(std::string& Version, bool& IsOsAvailable)
|
||||
{
|
||||
return client_shared_mapping::StartServerProcess(Path);
|
||||
Version = g_Version;
|
||||
|
||||
OSVERSIONINFOW os{ 0 };
|
||||
RtlGetVersion(&os);
|
||||
|
||||
if (os.dwBuildNumber == 7601 || os.dwBuildNumber == 7600)
|
||||
IsOsAvailable = true;
|
||||
else if(os.dwBuildNumber >= 14393)
|
||||
IsOsAvailable = true;
|
||||
else IsOsAvailable = false;
|
||||
}
|
||||
|
||||
MYAPI_API BOOL set_server_process_path(CONST char* Path, PDWORD status)
|
||||
{
|
||||
return client_shared_mapping::StartServerProcess(Path, status);
|
||||
}
|
||||
|
||||
MYAPI_API BOOL check_server_process()
|
||||
@@ -14,9 +31,9 @@ MYAPI_API BOOL check_server_process()
|
||||
return QueryServerAlreadyOpen();
|
||||
}
|
||||
|
||||
MYAPI_API BOOL driver_install_load()
|
||||
MYAPI_API BOOL driver_install_load(PDWORD status)
|
||||
{
|
||||
return client_driver::fn_get_instance()->driver_map_load();
|
||||
return client_driver::fn_get_instance()->driver_map_load(status);
|
||||
}
|
||||
|
||||
MYAPI_API BOOL check_install_status()
|
||||
@@ -63,3 +80,35 @@ MYAPI_API BOOL check_remote_app_process()
|
||||
{
|
||||
return active_check::check_remote_app_process();
|
||||
}
|
||||
|
||||
MYAPI_API BOOL check_virtual_system()
|
||||
{
|
||||
uint64_t req;
|
||||
|
||||
return HBClientCall(
|
||||
static_cast<uint32_t>(CommandId::CheckVMware),
|
||||
&req,
|
||||
sizeof(req),
|
||||
nullptr,
|
||||
0,
|
||||
nullptr);
|
||||
|
||||
}
|
||||
|
||||
MYAPI_API BOOL check_vmx_setting()
|
||||
{
|
||||
uint64_t req;
|
||||
|
||||
return HBClientCall(
|
||||
static_cast<uint32_t>(CommandId::CheckVmx),
|
||||
&req,
|
||||
sizeof(req),
|
||||
nullptr,
|
||||
0,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
MYAPI_API BOOL check_scan_process(DWORD Pid, void* Results)
|
||||
{
|
||||
return active_check::ScanProcessHandles(Pid, (PROCESS_HANDLE_RESULTS*)Results);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
|
||||
#ifndef EXPROTS_API_FUNC
|
||||
#define EXPROTS_API_FUNC
|
||||
@@ -10,14 +11,17 @@
|
||||
#define MYAPI_API __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
//初始化函数
|
||||
EXTERN_C MYAPI_API VOID Init(std::string& Version, bool& IsOsAvailable);
|
||||
|
||||
//设置服务进程目录
|
||||
EXTERN_C MYAPI_API BOOL set_server_process_path(CONST char* Path);
|
||||
EXTERN_C MYAPI_API BOOL set_server_process_path(CONST char* Path, PDWORD status);
|
||||
|
||||
//服务进程是否已加载
|
||||
EXTERN_C MYAPI_API BOOL check_server_process();
|
||||
|
||||
//驱动安装
|
||||
EXTERN_C MYAPI_API BOOL driver_install_load();
|
||||
EXTERN_C MYAPI_API BOOL driver_install_load(PDWORD status);
|
||||
|
||||
//驱动是否安装成功
|
||||
EXTERN_C MYAPI_API BOOL check_install_status();
|
||||
@@ -46,6 +50,15 @@ EXTERN_C MYAPI_API BOOL anit_window_scrren(HWND hwnd, UINT Flags);
|
||||
//检测远程软件进程
|
||||
EXTERN_C MYAPI_API BOOL check_remote_app_process();
|
||||
|
||||
//检测是否在虚拟机环境
|
||||
EXTERN_C MYAPI_API BOOL check_virtual_system();
|
||||
|
||||
//检测是否在VT环境中
|
||||
EXTERN_C MYAPI_API BOOL check_vmx_setting();
|
||||
|
||||
//检测持有进程句柄的进程
|
||||
EXTERN_C MYAPI_API BOOL check_scan_process(DWORD Pid, void* Results);
|
||||
|
||||
#endif // !exprots_api_func
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -148,4 +148,105 @@ namespace utils
|
||||
return Pid;
|
||||
|
||||
}
|
||||
|
||||
// 不区分大小写查找子串
|
||||
bool StrContainsI(const char* src, const char* sub)
|
||||
{
|
||||
char* p = strstr(_strlwr((char*)src), _strlwr((char*)sub));
|
||||
return p != nullptr;
|
||||
}
|
||||
|
||||
// 不区分大小写宽字符串查找
|
||||
bool StrContainsI(LPCWSTR Source, LPCWSTR Sub)
|
||||
{
|
||||
if (!Source || !Sub)
|
||||
return FALSE;
|
||||
WCHAR srcBuf[1024] = { 0 };
|
||||
WCHAR subBuf[1024] = { 0 };
|
||||
lstrcpyW(srcBuf, Source);
|
||||
lstrcpyW(subBuf, Sub);
|
||||
_wcslwr(srcBuf);
|
||||
_wcslwr(subBuf);
|
||||
return wcsstr(srcBuf, subBuf) != nullptr;
|
||||
}
|
||||
|
||||
|
||||
// 读取注册表字符串值
|
||||
BOOL RegReadString(HKEY hRoot, LPCSTR szSubKey, LPCSTR szValueName, char* outBuf, DWORD bufSize)
|
||||
{
|
||||
HKEY hKey;
|
||||
LONG ret = RegOpenKeyExA(hRoot, szSubKey, 0, KEY_READ, &hKey);
|
||||
if (ret != ERROR_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
DWORD dataType = REG_SZ;
|
||||
DWORD dataLen = bufSize;
|
||||
ret = RegQueryValueExA(hKey, szValueName, nullptr, &dataType, (LPBYTE)outBuf, &dataLen);
|
||||
RegCloseKey(hKey);
|
||||
|
||||
if (ret != ERROR_SUCCESS)
|
||||
return FALSE;
|
||||
outBuf[dataLen] = '\0';
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void GetProcessName(
|
||||
DWORD ProcessId,
|
||||
char* ProcessName,
|
||||
DWORD ProcessNameSize
|
||||
)
|
||||
{
|
||||
ProcessName[0] = '\0';
|
||||
|
||||
HANDLE ProcessHandle =
|
||||
OpenProcess(
|
||||
PROCESS_QUERY_LIMITED_INFORMATION,
|
||||
FALSE,
|
||||
ProcessId
|
||||
);
|
||||
|
||||
if (!ProcessHandle)
|
||||
{
|
||||
strcpy_s(
|
||||
ProcessName,
|
||||
ProcessNameSize,
|
||||
"Unknown"
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD Size = ProcessNameSize;
|
||||
|
||||
if (!QueryFullProcessImageNameA(
|
||||
ProcessHandle,
|
||||
0,
|
||||
ProcessName,
|
||||
&Size))
|
||||
{
|
||||
strcpy_s(
|
||||
ProcessName,
|
||||
ProcessNameSize,
|
||||
"Unknown"
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
char* FileName =
|
||||
strrchr(ProcessName, '\\');
|
||||
|
||||
if (FileName)
|
||||
{
|
||||
memmove(
|
||||
ProcessName,
|
||||
FileName + 1,
|
||||
strlen(FileName)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle(ProcessHandle);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -11,6 +11,17 @@ namespace utils
|
||||
BOOL CreateDirectoryRecursive(const char* path);
|
||||
|
||||
auto GetProcessByName(CONST wchar_t* Name)->DWORD;
|
||||
|
||||
BOOL RegReadString(HKEY hRoot, LPCSTR szSubKey, LPCSTR szValueName, char* outBuf, DWORD bufSize);
|
||||
|
||||
// 不区分大小写宽字符串查找
|
||||
bool StrContainsI(LPCWSTR Source, LPCWSTR Sub);
|
||||
|
||||
void GetProcessName(
|
||||
DWORD ProcessId,
|
||||
char* ProcessName,
|
||||
DWORD ProcessNameSize
|
||||
);
|
||||
}
|
||||
|
||||
#endif // !UTILS_h
|
||||
|
||||
Reference in New Issue
Block a user