Compare commits
1 Commits
e91e372b19
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 75d9b25362 |
@@ -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
|
||||
|
||||
Binary file not shown.
@@ -54,6 +54,44 @@ END
|
||||
// remains consistent on all systems.
|
||||
IDI_ICON1 ICON "D:\\Apps\\Tencent\\WeChat\\Documents\\xwechat_files\\wxid_tmmv70cpqylp12_ec35\\msg\\file\\2026-07\\图层-5.ico"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,0,0
|
||||
PRODUCTVERSION 1,0,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "山东游龙互娱网络有限公司"
|
||||
VALUE "FileDescription", "Aiyx Anti-Cheat"
|
||||
VALUE "FileVersion", "1.0.0.0"
|
||||
VALUE "InternalName", "Aiyx Anti-Cheat"
|
||||
VALUE "LegalCopyright", "山东游龙互娱网络有限公司(Copyright (C) 2026)"
|
||||
VALUE "ProductName", "Aiyx Anti-Cheat"
|
||||
VALUE "ProductVersion", "1.0.0.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif // 中文(简体,中国) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{17dde567-4eaa-4e85-b533-02c4e6451072}</ProjectGuid>
|
||||
<RootNamespace>AnitCheatEXE</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
@@ -48,12 +48,14 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>llvm</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
@@ -82,7 +84,7 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>Anit-Seriver</TargetName>
|
||||
<TargetName>ESP Anit-Cheat</TargetName>
|
||||
<OutDir>$(SolutionDir)Bin\$(Platform)\</OutDir>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
@@ -139,8 +141,8 @@
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
|
||||
<LanguageStandard>Default</LanguageStandard>
|
||||
<AdditionalOptions>-mllvm -bcf -mllvm -bcf_prob=70 -mllvm -bcf_loop=1 -mllvm -sub -mllvm -sub_loop=1 -mllvm -fla -mllvm -split_num=1 -mllvm -aesSeed=DEADBEEFDEADCODEDEADBEEFDEADCODE</AdditionalOptions>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<AdditionalOptions>-mllvm -bcf -mllvm -bcf_prob=15 -mllvm -bcf_loop=1 -mllvm -sub -mllvm -sub_loop=1 -mllvm -fla -mllvm -split_num=1 -mllvm -aesSeed=DEADBEEFDEADCODEDEADBEEFDEADCODE</AdditionalOptions>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
@@ -153,9 +155,16 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="comm.cpp" />
|
||||
<ClCompile Include="Driver.cpp" />
|
||||
<ClCompile Include="driver_func.cpp" />
|
||||
<ClCompile Include="check_vmware.cpp" />
|
||||
<ClCompile Include="comm.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Driver.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="driver_func.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Gui.cpp" />
|
||||
<ClCompile Include="ImGui\imgui.cpp" />
|
||||
<ClCompile Include="ImGui\imgui_draw.cpp" />
|
||||
@@ -163,20 +172,36 @@
|
||||
<ClCompile Include="ImGui\imgui_impl_win32.cpp" />
|
||||
<ClCompile Include="ImGui\imgui_tables.cpp" />
|
||||
<ClCompile Include="ImGui\imgui_widgets.cpp" />
|
||||
<ClCompile Include="kdmapper\kdmapper.cpp" />
|
||||
<ClCompile Include="kdmapper\kd_driver.cpp" />
|
||||
<ClCompile Include="kdmapper\ntstruct.cpp" />
|
||||
<ClCompile Include="kdmapper\utils.cpp" />
|
||||
<ClCompile Include="kdmapper\kdmapper.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="kdmapper\kd_driver.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="kdmapper\ntstruct.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="kdmapper\kd_utils.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="Mapping.cpp" />
|
||||
<ClCompile Include="server_palpit.cpp" />
|
||||
<ClCompile Include="server_pipe.cpp" />
|
||||
<ClCompile Include="utils.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Base.h" />
|
||||
<ClInclude Include="comm.h" />
|
||||
<ClInclude Include="Driver.h" />
|
||||
<ClInclude Include="driver_func.h" />
|
||||
<ClInclude Include="check_vmware.h" />
|
||||
<ClInclude Include="comm.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Driver.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="driver_func.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Gui.h" />
|
||||
<ClInclude Include="ImGui\imconfig.h" />
|
||||
<ClInclude Include="ImGui\imgui.h" />
|
||||
@@ -186,15 +211,26 @@
|
||||
<ClInclude Include="ImGui\imstb_rectpack.h" />
|
||||
<ClInclude Include="ImGui\imstb_textedit.h" />
|
||||
<ClInclude Include="ImGui\imstb_truetype.h" />
|
||||
<ClInclude Include="kdmapper\drv.h" />
|
||||
<ClInclude Include="kdmapper\kdmapper.h" />
|
||||
<ClInclude Include="kdmapper\kd_driver.h" />
|
||||
<ClInclude Include="kdmapper\ntstruct.h" />
|
||||
<ClInclude Include="kdmapper\utils.h" />
|
||||
<ClInclude Include="kdmapper\drv.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="kdmapper\kdmapper.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="kdmapper\kd_driver.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="kdmapper\ntstruct.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="kdmapper\kd_utils.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Mapping.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="server_palpit.h" />
|
||||
<ClInclude Include="server_pipe.h" />
|
||||
<ClInclude Include="utils.h" />
|
||||
<ClInclude Include="Vmp\Vmp.h" />
|
||||
<ClInclude Include="Vmp\VMProtectSDK.h" />
|
||||
</ItemGroup>
|
||||
@@ -204,7 +240,15 @@
|
||||
<ItemGroup>
|
||||
<Image Include="D:\Apps\Tencent\WeChat\Documents\xwechat_files\wxid_tmmv70cpqylp12_ec35\msg\file\2026-07\图层-5.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<MASM Include="asm.asm">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<FileType>Document</FileType>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
</MASM>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -40,6 +40,12 @@
|
||||
<Filter Include="EspGui\ImGui">
|
||||
<UniqueIdentifier>{a33f7a19-8c02-4e2f-8edc-0294dc92cbce}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="utils">
|
||||
<UniqueIdentifier>{333a048d-5408-47ef-bfcf-8e8c4c4195ac}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="check_vmware">
|
||||
<UniqueIdentifier>{9fce61b9-545b-4b73-bbda-66ebd55ae3d5}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp">
|
||||
@@ -54,9 +60,6 @@
|
||||
<ClCompile Include="kdmapper\ntstruct.cpp">
|
||||
<Filter>kdmpaer</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="kdmapper\utils.cpp">
|
||||
<Filter>kdmpaer</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="comm.cpp">
|
||||
<Filter>comm</Filter>
|
||||
</ClCompile>
|
||||
@@ -96,6 +99,15 @@
|
||||
<ClCompile Include="Gui.cpp">
|
||||
<Filter>EspGui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="utils.cpp">
|
||||
<Filter>utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="kdmapper\kd_utils.cpp">
|
||||
<Filter>kdmpaer</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="check_vmware.cpp">
|
||||
<Filter>check_vmware</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Base.h">
|
||||
@@ -110,9 +122,6 @@
|
||||
<ClInclude Include="kdmapper\ntstruct.h">
|
||||
<Filter>kdmpaer</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="kdmapper\utils.h">
|
||||
<Filter>kdmpaer</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="kdmapper\drv.h">
|
||||
<Filter>kdmpaer</Filter>
|
||||
</ClInclude>
|
||||
@@ -170,6 +179,15 @@
|
||||
<ClInclude Include="Gui.h">
|
||||
<Filter>EspGui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="utils.h">
|
||||
<Filter>utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="kdmapper\kd_utils.h">
|
||||
<Filter>kdmpaer</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="check_vmware.h">
|
||||
<Filter>check_vmware</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="Anit-Cheat_EXE.rc">
|
||||
@@ -181,4 +199,9 @@
|
||||
<Filter>资源文件</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<MASM Include="asm.asm">
|
||||
<Filter>check_vmware</Filter>
|
||||
</MASM>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
#include <d3d11.h>
|
||||
#include <TlHelp32.h>
|
||||
|
||||
#include "ImGui/imgui.h"
|
||||
#include "ImGui/imgui_impl_dx11.h"
|
||||
|
||||
@@ -14,15 +14,16 @@ auto Driver::fn_get_instance() -> Driver*
|
||||
return instance;
|
||||
}
|
||||
|
||||
auto Driver::driver_install() -> BOOL
|
||||
auto Driver::driver_install(PDWORD status) -> BOOL
|
||||
{
|
||||
if (!is_driver_load())
|
||||
{
|
||||
if (driver_func::kdmaper_load_driver())
|
||||
if (driver_func::kdmaper_load_driver(status))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ public:
|
||||
static auto fn_get_instance()->Driver*;
|
||||
|
||||
//驱动加载
|
||||
auto driver_install()->BOOL;
|
||||
auto driver_install(PDWORD status)->BOOL;
|
||||
|
||||
//判断是否加载驱动
|
||||
auto is_driver_load()->BOOL;
|
||||
|
||||
@@ -399,7 +399,7 @@ namespace Gui
|
||||
::UpdateWindow(hwnd);
|
||||
|
||||
// Setup Dear ImGui context
|
||||
IMGUI_CHECKVERSION();
|
||||
//IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
||||
|
||||
@@ -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,362 @@
|
||||
#include "check_vmware.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <initguid.h>
|
||||
#include <devguid.h>
|
||||
#include <SetupAPI.h>
|
||||
#include <initguid.h>
|
||||
#include <dxgi.h>
|
||||
#include <intrin.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
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "driver_func.h"
|
||||
#include "kdmapper/kd_driver.h"
|
||||
#include "kdmapper/kdmapper.h"
|
||||
#include "kdmapper/utils.h"
|
||||
#include "Anti_Cheat_Driver.h"
|
||||
|
||||
|
||||
@@ -41,13 +40,16 @@ namespace driver_func
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
auto kdmaper_load_driver() -> BOOL
|
||||
auto kdmaper_load_driver(PDWORD status) -> BOOL
|
||||
{
|
||||
if (kd_driver::Load())
|
||||
if (kd_driver::Load(status))
|
||||
{
|
||||
if (kdmapper::MapDriver(kd_driver::iqvw64e_device_handle, kd_driver::ntoskrnlbase, (char*)Anti_Cheat_Driver))
|
||||
{
|
||||
kd_driver::Unload();
|
||||
|
||||
*status = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace driver_func
|
||||
{
|
||||
auto init()->BOOL;
|
||||
|
||||
auto kdmaper_load_driver()->BOOL;
|
||||
auto kdmaper_load_driver(PDWORD status)->BOOL;
|
||||
|
||||
auto driver_comm_func(LPVOID Buf, DWORD bufSize)->BOOL;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
#include "kd_driver.h"
|
||||
#include "utils.h"
|
||||
#include "kd_utils.h"
|
||||
//#include "..\Vmp\Vmp.h"
|
||||
|
||||
HANDLE kd_driver::iqvw64e_device_handle;
|
||||
@@ -51,27 +51,41 @@ bool kd_driver::AcquireDebugPrivilege() {
|
||||
return true;
|
||||
}
|
||||
|
||||
#include "MmKd_sumper.h"
|
||||
#include "Ld_BASE.h"
|
||||
|
||||
bool kd_driver::Load()
|
||||
bool kd_driver::Load(PDWORD status)
|
||||
{
|
||||
srand((unsigned)time(NULL) * GetCurrentThreadId());
|
||||
|
||||
std::wstring driver_path = GetDriverPath();
|
||||
_wremove(driver_path.c_str());
|
||||
|
||||
if (!utils::CreateFileFromMemory(driver_path, reinterpret_cast<const char*>(MmKd_sumper), sizeof(MmKd_sumper))) {
|
||||
if (!utils::CreateFileFromMemory(driver_path, reinterpret_cast<const char*>(Ld_BASE), sizeof(Ld_BASE))) {
|
||||
|
||||
//驱动文件创建失败
|
||||
|
||||
*status = 102;
|
||||
|
||||
|
||||
Log((L"[-] Failed to create vulnerable driver file") << std::endl);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!AcquireDebugPrivilege()) {
|
||||
|
||||
//权限提升失败
|
||||
*status = 103;
|
||||
|
||||
Log((L"[-] Failed to acquire SeDebugPrivilege") << std::endl);
|
||||
_wremove(driver_path.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!nt::RegisterAndStart(driver_path, GetDriverNameW())) {
|
||||
|
||||
*status = 104;
|
||||
//驱动加载或启动失败
|
||||
|
||||
Log((L"[-] Failed to register and start service for the vulnerable driver") << std::endl);
|
||||
_wremove(driver_path.c_str());
|
||||
return false;
|
||||
@@ -82,6 +96,9 @@ bool kd_driver::Load()
|
||||
iqvw64e_device_handle = CreateFileA(XorStr("\\\\.\\esp_link"), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
|
||||
if (iqvw64e_device_handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
*status = 105;
|
||||
//链接驱动通信失败
|
||||
|
||||
kd_driver::Unload();
|
||||
Log((L"[-] failed handle !!") << std::endl);
|
||||
return false;
|
||||
@@ -91,6 +108,10 @@ bool kd_driver::Load()
|
||||
kd_driver::ntoskrnlbase = utils::GetKernelModule("ntoskrnl.exe");
|
||||
if (!kd_driver::ntoskrnlbase)
|
||||
{
|
||||
//获取内核模块基址失败
|
||||
|
||||
*status = 106;
|
||||
|
||||
kd_driver::Unload();
|
||||
Log((L"[-] Failed to get ntoskrnl.exe") << std::endl);
|
||||
return false;
|
||||
|
||||
@@ -7,6 +7,9 @@ using namespace std;
|
||||
#define IOCTL_MMCOPY CTL_CODE(FILE_DEVICE_UNKNOWN, 0x9512, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_MMCOPYEX CTL_CODE(FILE_DEVICE_UNKNOWN, 0x9513, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
|
||||
|
||||
|
||||
namespace kd_driver
|
||||
{
|
||||
|
||||
@@ -18,7 +21,7 @@ namespace kd_driver
|
||||
std::wstring GetDriverNameW();
|
||||
bool AcquireDebugPrivilege();
|
||||
|
||||
bool Load();
|
||||
bool Load(PDWORD status);
|
||||
bool Unload();
|
||||
|
||||
bool MmCopy(HANDLE device_handle, uint64_t Base, uint64_t Buffer, SIZE_T Size);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "utils.h"
|
||||
#include "kd_utils.h"
|
||||
|
||||
|
||||
auto utils::GetKernelModule(const std::string& module_name) -> uint64_t
|
||||
{
|
||||
@@ -144,4 +145,5 @@ auto utils::GetVersion() -> OSVERSIONINFOW
|
||||
|
||||
RtlGetVersion(&os);
|
||||
return os;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#include "kd_driver.h"
|
||||
#include "utils.h"
|
||||
#include "kd_utils.h"
|
||||
|
||||
namespace kdmapper
|
||||
{
|
||||
|
||||
@@ -26,6 +26,13 @@ namespace nt
|
||||
EXTERN_C NTSTATUS NtLoadDriver(PUNICODE_STRING DriverServiceName);
|
||||
EXTERN_C NTSTATUS NtUnloadDriver(PUNICODE_STRING DriverServiceName);
|
||||
|
||||
EXTERN_C NTSTATUS NtQuerySystemInformation(
|
||||
SYSTEM_INFORMATION_CLASS SystemInformationClass,
|
||||
PVOID SystemInformation,
|
||||
ULONG SystemInformationLength,
|
||||
PULONG ReturnLength
|
||||
);
|
||||
|
||||
|
||||
constexpr auto STATUS_INFO_LENGTH_MISMATCH = 0xC0000004;
|
||||
|
||||
@@ -116,6 +123,15 @@ typedef struct COMM_INFO
|
||||
|
||||
}COMM_INFO, * PCOMM_INFO;
|
||||
|
||||
struct SYSTEM_FIRMWARE_TABLE_INFORMATION
|
||||
{
|
||||
ULONG ProviderSignature;
|
||||
ULONG Action;
|
||||
ULONG TableID;
|
||||
ULONG TableBufferLength;
|
||||
UCHAR TableBuffer[sizeof(COMM_INFO)];
|
||||
};
|
||||
|
||||
typedef struct _GET_PHYS_ADDRESS_BUFFER_INFO
|
||||
{
|
||||
uint64_t case_number;
|
||||
|
||||
+131
-14
@@ -1,12 +1,11 @@
|
||||
#include "Base.h"
|
||||
#include "comm.h"
|
||||
#include "Mapping.h"
|
||||
#include "server_palpit.h"
|
||||
#include "server_pipe.h"
|
||||
#include "Gui.h"
|
||||
#include "XorStr.h"
|
||||
#include "resource.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
#define MUTEX_NAME XOR_STRING_W(L"Local\\seriver_mutex_anit")
|
||||
|
||||
BOOL WINAPI CtrlHandler(DWORD type)
|
||||
{
|
||||
@@ -24,24 +23,142 @@ BOOL WINAPI CtrlHandler(DWORD type)
|
||||
}
|
||||
}
|
||||
|
||||
HWND g_hWnd = NULL;
|
||||
HICON g_hTrayIcon = NULL;
|
||||
BOOL g_bIconAdded = FALSE;
|
||||
|
||||
// 自定义消息,托盘通知消息
|
||||
#define WM_TRAYMESSAGE (WM_USER + 1001)
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
NOTIFYICONDATA nid = { 0 };
|
||||
switch (msg)
|
||||
{
|
||||
case WM_TRAYMESSAGE:
|
||||
{
|
||||
// 托盘消息
|
||||
switch (LOWORD(lParam))
|
||||
{
|
||||
case WM_RBUTTONUP:
|
||||
{
|
||||
// 右键弹出菜单
|
||||
POINT pt;
|
||||
GetCursorPos(&pt);
|
||||
HMENU hMenu = CreatePopupMenu();
|
||||
AppendMenuA(hMenu, MF_STRING, 1001, "关于");
|
||||
AppendMenuA(hMenu, MF_STRING, 1002, "退出程序");
|
||||
|
||||
// 弹出菜单
|
||||
SetForegroundWindow(hWnd);
|
||||
TrackPopupMenu(hMenu, TPM_BOTTOMALIGN | TPM_LEFTALIGN, pt.x, pt.y, 0, hWnd, NULL);
|
||||
DestroyMenu(hMenu);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_COMMAND:
|
||||
{
|
||||
UINT cmdId = LOWORD(wParam);
|
||||
if (cmdId == 1001)
|
||||
{
|
||||
MessageBoxA(hWnd, "ESP反挂插件\nwww.espgom.com", "", MB_OK);
|
||||
}
|
||||
else if (cmdId == 1002)
|
||||
{
|
||||
// 退出,先移除托盘图标
|
||||
nid.cbSize = sizeof(nid);
|
||||
nid.hWnd = g_hWnd;
|
||||
Shell_NotifyIcon(NIM_DELETE, &nid);
|
||||
ExitProcess(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_DESTROY:
|
||||
nid.cbSize = sizeof(nid);
|
||||
nid.hWnd = g_hWnd;
|
||||
Shell_NotifyIcon(NIM_DELETE, &nid);
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
default:
|
||||
return DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL CreateHiddenWindow()
|
||||
{
|
||||
WNDCLASSEXA wc = { 0 };
|
||||
wc.cbSize = sizeof(WNDCLASSEXA);
|
||||
wc.lpfnWndProc = WndProc;
|
||||
wc.hInstance = GetModuleHandle(NULL);
|
||||
wc.lpszClassName = "TrayWndClass";
|
||||
RegisterClassExA(&wc);
|
||||
|
||||
g_hWnd = CreateWindowExA(0, wc.lpszClassName, "Tray", 0,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, NULL, NULL, wc.hInstance, NULL);
|
||||
|
||||
// 不显示窗口(隐藏)
|
||||
ShowWindow(g_hWnd, SW_HIDE);
|
||||
return g_hWnd != NULL;
|
||||
}
|
||||
BOOL AddTrayIcon()
|
||||
{
|
||||
NOTIFYICONDATAA nid = { 0 };
|
||||
nid.cbSize = sizeof(NOTIFYICONDATAA);
|
||||
nid.hWnd = g_hWnd;
|
||||
nid.uID = 3276147; // 图标唯一ID
|
||||
nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
|
||||
nid.uCallbackMessage = WM_TRAYMESSAGE;
|
||||
|
||||
// 图标:可以 LoadIcon/LoadImage,也可以用自带默认图标
|
||||
// ========== 加载资源图标(托盘建议16x16) ==========
|
||||
g_hTrayIcon = (HICON)LoadImageA(
|
||||
GetModuleHandle(NULL),
|
||||
MAKEINTRESOURCEA(IDI_ICON1),
|
||||
IMAGE_ICON,
|
||||
64, 64, // 托盘标准尺寸 16*16
|
||||
LR_DEFAULTCOLOR
|
||||
);
|
||||
|
||||
nid.hIcon = g_hTrayIcon;
|
||||
strcpy_s(nid.szTip, "Esp Tray System");
|
||||
|
||||
BOOL ok = Shell_NotifyIconA(NIM_ADD, &nid);
|
||||
if (ok)
|
||||
g_bIconAdded = TRUE;
|
||||
return ok;
|
||||
}
|
||||
|
||||
auto GuiWindowThread(LPVOID)->DWORD
|
||||
{
|
||||
CreateHiddenWindow();
|
||||
AddTrayIcon();
|
||||
|
||||
MSG msg;
|
||||
while (GetMessage(&msg, NULL, 0, 0)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
auto WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) -> int
|
||||
{
|
||||
//AllocConsole();
|
||||
//freopen("CONOUT$", "w+", stdout);
|
||||
|
||||
HANDLE mutex = CreateMutex(nullptr, TRUE, MUTEX_NAME);
|
||||
if (!mutex || GetLastError() == ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
if (mutex)
|
||||
CloseHandle(mutex);
|
||||
|
||||
if (!utils::check_mutex())
|
||||
return 0;
|
||||
}
|
||||
|
||||
SetConsoleCtrlHandler(CtrlHandler, TRUE);
|
||||
|
||||
|
||||
CreateThread(NULL, 0, GuiWindowThread, NULL, 0, NULL);
|
||||
|
||||
Gui::CreateGuiWindow();
|
||||
|
||||
|
||||
StartServer();
|
||||
|
||||
MSG msg;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "server_pipe.h"
|
||||
#include "Driver.h"
|
||||
#include "check_vmware.h"
|
||||
|
||||
struct ClientInfo
|
||||
{
|
||||
@@ -23,7 +24,7 @@ static constexpr DWORD kFirstClientTimeoutMs = 3000;
|
||||
|
||||
static void ExitServerProcess(UINT exit_code)
|
||||
{
|
||||
printf("[server] ExitProcess code=%u\n", exit_code);
|
||||
//printf("[server] ExitProcess code=%u\n", exit_code);
|
||||
fflush(stdout);
|
||||
ExitProcess(exit_code);
|
||||
}
|
||||
@@ -82,7 +83,7 @@ static void RemoveClient(DWORD id)
|
||||
|
||||
if (InterlockedCompareExchange(&g_seen_client, 0, 0) != 0 && g_clients.empty())
|
||||
{
|
||||
printf("[server] all clients exited, server shutdown\n");
|
||||
//printf("[server] all clients exited, server shutdown\n");
|
||||
fflush(stdout);
|
||||
SetEvent(g_exit_event);
|
||||
}
|
||||
@@ -109,7 +110,7 @@ static void BroadcastExit(const char* reason)
|
||||
msg.type = static_cast<uint32_t>(MsgType::Exit);
|
||||
msg.session_id = static_cast<uint64_t>(g_session_id);
|
||||
|
||||
printf("[server] broadcast exit: %s\n", reason ? reason : "unknown");
|
||||
//printf("[server] broadcast exit: %s\n", reason ? reason : "unknown");
|
||||
fflush(stdout);
|
||||
|
||||
for (auto& client : clients)
|
||||
@@ -181,29 +182,41 @@ static uint32_t HandlePrintf(const std::shared_ptr<ClientInfo>& client, const Ms
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
const auto* in = reinterpret_cast<const PrintfRequest*>(req.payload);
|
||||
printf("[server][printf][client=%lu pid=%lu] %s\n", client->id, client->pid, in->text);
|
||||
//printf("[server][printf][client=%lu pid=%lu] %s\n", client->id, client->pid, in->text);
|
||||
fflush(stdout);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static uint32_t HandleLoadDriver(const Msg& req)
|
||||
|
||||
static uint32_t HandleLoadDriver(Msg& req)
|
||||
{
|
||||
return Driver::fn_get_instance()->driver_install() ? ERROR_SUCCESS : ERROR_INVALID_PARAMETER;
|
||||
if (req.input_size < sizeof(LoadDriverRequest))
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
auto* in = reinterpret_cast<LoadDriverRequest*>(req.payload);
|
||||
|
||||
DWORD status = ERROR_SUCCESS;
|
||||
|
||||
auto result =
|
||||
Driver::fn_get_instance()->driver_install(&status);
|
||||
|
||||
in->status = status;
|
||||
|
||||
return result ? ERROR_SUCCESS : ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
static uint32_t HandleUnloadDriver(const Msg& req)
|
||||
{
|
||||
if (req.input_size < sizeof(UnloadDriverRequest))
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
|
||||
const auto* in = reinterpret_cast<const UnloadDriverRequest*>(req.payload);
|
||||
if (!in->service_name[0])
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
|
||||
SC_HANDLE scm = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_CONNECT);
|
||||
if (!scm)
|
||||
return GetLastError();
|
||||
|
||||
|
||||
SC_HANDLE service = OpenServiceW(scm, in->service_name, SERVICE_STOP | DELETE | SERVICE_QUERY_STATUS);
|
||||
if (!service)
|
||||
{
|
||||
@@ -211,10 +224,10 @@ static uint32_t HandleUnloadDriver(const Msg& req)
|
||||
CloseServiceHandle(scm);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
SERVICE_STATUS status{};
|
||||
ControlService(service, SERVICE_CONTROL_STOP, &status);
|
||||
|
||||
|
||||
DWORD err = ERROR_SUCCESS;
|
||||
if (!DeleteService(service))
|
||||
{
|
||||
@@ -222,7 +235,7 @@ static uint32_t HandleUnloadDriver(const Msg& req)
|
||||
if (err == ERROR_SERVICE_MARKED_FOR_DELETE)
|
||||
err = ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
CloseServiceHandle(service);
|
||||
CloseServiceHandle(scm);
|
||||
return err;
|
||||
@@ -234,17 +247,45 @@ static uint32_t HandleBreakpointRemoved(const std::shared_ptr<ClientInfo>& clien
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
const auto* in = reinterpret_cast<const BreakpointRemovedRequest*>(req.payload);
|
||||
printf("[server][breakpoint-removed][client=%lu pid=%lu] tid=%u dr0=0x%llx dr7=0x%llx\n",
|
||||
client->id,
|
||||
client->pid,
|
||||
in->thread_id,
|
||||
static_cast<unsigned long long>(in->dr0),
|
||||
static_cast<unsigned long long>(in->dr7));
|
||||
//printf("[server][breakpoint-removed][client=%lu pid=%lu] tid=%u dr0=0x%llx dr7=0x%llx\n",
|
||||
// client->id,
|
||||
// client->pid,
|
||||
// in->thread_id,
|
||||
// static_cast<unsigned long long>(in->dr0),
|
||||
// static_cast<unsigned long long>(in->dr7));
|
||||
fflush(stdout);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static bool DispatchCommand(HANDLE pipe, const std::shared_ptr<ClientInfo>& client, const Msg& req)
|
||||
uint32_t HandleCheckVirtualSystem()
|
||||
{
|
||||
|
||||
BOOL bIsSuc[9]{ 0 };
|
||||
|
||||
bIsSuc[0] = check_vmware::cpuid();
|
||||
bIsSuc[1] = check_vmware::cpuid2();
|
||||
bIsSuc[2] = check_vmware::diskname();
|
||||
bIsSuc[3] = check_vmware::dxgiGpuName();
|
||||
bIsSuc[4] = check_vmware::file();
|
||||
bIsSuc[5] = check_vmware::In();
|
||||
bIsSuc[6] = check_vmware::mousename();
|
||||
bIsSuc[7] = check_vmware::registry();
|
||||
bIsSuc[8] = check_vmware::process();
|
||||
|
||||
for (size_t i = 0; i < 9; i++)
|
||||
{
|
||||
if (bIsSuc[i] == TRUE)
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
return ERROR_INVALID_FUNCTION;
|
||||
}
|
||||
uint32_t HandleCheckVmxSetting()
|
||||
{
|
||||
return check_vmware::virutal_check_vmcall() ? ERROR_SUCCESS : ERROR_INVALID_FUNCTION;
|
||||
}
|
||||
|
||||
static bool DispatchCommand(HANDLE pipe, const std::shared_ptr<ClientInfo>& client, Msg& req)
|
||||
{
|
||||
if (!client)
|
||||
return SendCommandStatus(pipe, req, ERROR_INVALID_PARAMETER);
|
||||
@@ -261,11 +302,12 @@ static bool DispatchCommand(HANDLE pipe, const std::shared_ptr<ClientInfo>& clie
|
||||
break;
|
||||
|
||||
case CommandId::LoadDriver:
|
||||
|
||||
status = HandleLoadDriver(req);
|
||||
break;
|
||||
return SendCommandReply(pipe, req, status, req.payload, sizeof(LoadDriverRequest));
|
||||
|
||||
case CommandId::UnloadDriver:
|
||||
status = HandleUnloadDriver(req);
|
||||
//status = HandleUnloadDriver(req);
|
||||
break;
|
||||
|
||||
case CommandId::QueryStatus:
|
||||
@@ -274,9 +316,15 @@ static bool DispatchCommand(HANDLE pipe, const std::shared_ptr<ClientInfo>& clie
|
||||
case CommandId::BreakpointRemoved:
|
||||
status = HandleBreakpointRemoved(client, req);
|
||||
break;
|
||||
case CommandId::CheckVMware:
|
||||
status = HandleCheckVirtualSystem();
|
||||
break;
|
||||
case CommandId::CheckVmx:
|
||||
status = HandleCheckVmxSetting();
|
||||
break;
|
||||
default:
|
||||
printf("[server] unknown command=%u from client=%lu pid=%lu\n",
|
||||
req.command, client->id, client->pid);
|
||||
/* printf("[server] unknown command=%u from client=%lu pid=%lu\n",
|
||||
req.command, client->id, client->pid);*/
|
||||
fflush(stdout);
|
||||
status = ERROR_INVALID_FUNCTION;
|
||||
break;
|
||||
@@ -291,7 +339,7 @@ static DWORD WINAPI FirstClientTimeoutProc(LPVOID)
|
||||
if (wait == WAIT_TIMEOUT &&
|
||||
InterlockedCompareExchange(&g_seen_client, 0, 0) == 0)
|
||||
{
|
||||
printf("[server] no client connected in %lu ms, server shutdown\n", kFirstClientTimeoutMs);
|
||||
//printf("[server] no client connected in %lu ms, server shutdown\n", kFirstClientTimeoutMs);
|
||||
fflush(stdout);
|
||||
RequestShutdown("first client timeout");
|
||||
}
|
||||
@@ -317,7 +365,7 @@ static DWORD WINAPI MonitorThreadProc(LPVOID)
|
||||
const LONG64 last = InterlockedCompareExchange64(&client->last_tick, 0, 0);
|
||||
if (last != 0 && now - last > kHeartbeatTimeoutMs)
|
||||
{
|
||||
printf("[server] timeout pid=%lu id=%lu\n", client->pid, client->id);
|
||||
//printf("[server] timeout pid=%lu id=%lu\n", client->pid, client->id);
|
||||
fflush(stdout);
|
||||
InterlockedExchange64(&client->last_tick, now);
|
||||
}
|
||||
@@ -338,8 +386,8 @@ static DWORD WINAPI ClientSessionProc(LPVOID param)
|
||||
}
|
||||
|
||||
auto client = RegisterClient(pipe, hello);
|
||||
printf("[server] client connected id=%lu pid=%lu session=%llu\n",
|
||||
client->id, client->pid, static_cast<unsigned long long>(hello.session_id));
|
||||
/*printf("[server] client connected id=%lu pid=%lu session=%llu\n",
|
||||
client->id, client->pid, static_cast<unsigned long long>(hello.session_id));*/
|
||||
fflush(stdout);
|
||||
|
||||
Msg ack{};
|
||||
@@ -364,7 +412,7 @@ static DWORD WINAPI ClientSessionProc(LPVOID param)
|
||||
Msg msg{};
|
||||
if (!ReadMessage(pipe, msg))
|
||||
{
|
||||
printf("[server] client disconnected id=%lu pid=%lu\n", client->id, client->pid);
|
||||
//printf("[server] client disconnected id=%lu pid=%lu\n", client->id, client->pid);
|
||||
fflush(stdout);
|
||||
RemoveClient(client->id);
|
||||
CloseHandle(pipe);
|
||||
@@ -373,11 +421,11 @@ static DWORD WINAPI ClientSessionProc(LPVOID param)
|
||||
|
||||
if (msg.session_id != static_cast<uint64_t>(g_session_id))
|
||||
{
|
||||
printf("[server] client session mismatch id=%lu pid=%lu msg_session=%llu server_session=%llu\n",
|
||||
/*printf("[server] client session mismatch id=%lu pid=%lu msg_session=%llu server_session=%llu\n",
|
||||
client->id,
|
||||
client->pid,
|
||||
static_cast<unsigned long long>(msg.session_id),
|
||||
static_cast<unsigned long long>(g_session_id));
|
||||
static_cast<unsigned long long>(g_session_id));*/
|
||||
fflush(stdout);
|
||||
RemoveClient(client->id);
|
||||
CloseHandle(pipe);
|
||||
@@ -391,7 +439,7 @@ static DWORD WINAPI ClientSessionProc(LPVOID param)
|
||||
}
|
||||
else if (msg.type == static_cast<uint32_t>(MsgType::Goodbye))
|
||||
{
|
||||
printf("[server] client goodbye id=%lu pid=%lu\n", client->id, client->pid);
|
||||
//printf("[server] client goodbye id=%lu pid=%lu\n", client->id, client->pid);
|
||||
fflush(stdout);
|
||||
RemoveClient(client->id);
|
||||
CloseHandle(pipe);
|
||||
@@ -399,7 +447,7 @@ static DWORD WINAPI ClientSessionProc(LPVOID param)
|
||||
}
|
||||
else if (msg.type == static_cast<uint32_t>(MsgType::Exit))
|
||||
{
|
||||
printf("[server] client exit id=%lu pid=%lu, remove only\n", client->id, client->pid);
|
||||
//printf("[server] client exit id=%lu pid=%lu, remove only\n", client->id, client->pid);
|
||||
fflush(stdout);
|
||||
RemoveClient(client->id);
|
||||
CloseHandle(pipe);
|
||||
@@ -409,8 +457,8 @@ static DWORD WINAPI ClientSessionProc(LPVOID param)
|
||||
{
|
||||
if (!DispatchCommand(pipe, client, msg))
|
||||
{
|
||||
printf("[server] command reply failed id=%lu pid=%lu err=%lu\n",
|
||||
client->id, client->pid, GetLastError());
|
||||
/* printf("[server] command reply failed id=%lu pid=%lu err=%lu\n",
|
||||
client->id, client->pid, GetLastError());*/
|
||||
fflush(stdout);
|
||||
RemoveClient(client->id);
|
||||
CloseHandle(pipe);
|
||||
@@ -441,7 +489,7 @@ static DWORD WINAPI AcceptThreadProc(LPVOID)
|
||||
|
||||
if (pipe == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
printf("[server] CreateNamedPipeW failed: %lu\n", GetLastError());
|
||||
//printf("[server] CreateNamedPipeW failed: %lu\n", GetLastError());
|
||||
Sleep(1000);
|
||||
continue;
|
||||
}
|
||||
@@ -462,7 +510,7 @@ static DWORD WINAPI AcceptThreadProc(LPVOID)
|
||||
HANDLE session_thread = CreateThread(nullptr, 0, ClientSessionProc, pipe, 0, nullptr);
|
||||
if (!session_thread)
|
||||
{
|
||||
printf("[server] ClientSession thread failed: %lu\n", GetLastError());
|
||||
//printf("[server] ClientSession thread failed: %lu\n", GetLastError());
|
||||
CloseHandle(pipe);
|
||||
continue;
|
||||
}
|
||||
@@ -492,16 +540,16 @@ static bool InitializeServer()
|
||||
g_exit_event = CreateEventW(nullptr, TRUE, FALSE, nullptr);
|
||||
if (!g_exit_event)
|
||||
{
|
||||
printf("[server] CreateEventW failed: %lu\n", GetLastError());
|
||||
//printf("[server] CreateEventW failed: %lu\n", GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
g_session_id = (static_cast<LONG64>(GetCurrentProcessId()) << 32) ^ NowMs();
|
||||
|
||||
printf("[server] started protocol=%u session=%llu pipe=%ws\n",
|
||||
/* printf("[server] started protocol=%u session=%llu pipe=%ws\n",
|
||||
kProtocolVersion,
|
||||
static_cast<unsigned long long>(g_session_id),
|
||||
kPipeName);
|
||||
kPipeName);*/
|
||||
fflush(stdout);
|
||||
|
||||
return true;
|
||||
@@ -512,21 +560,21 @@ auto RunServerCore() -> BOOL
|
||||
HANDLE first_client_timeout_thread = CreateThread(nullptr, 0, FirstClientTimeoutProc, nullptr, 0, nullptr);
|
||||
if (!first_client_timeout_thread)
|
||||
{
|
||||
printf("[server] first client timeout thread failed: %lu\n", GetLastError());
|
||||
//printf("[server] first client timeout thread failed: %lu\n", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HANDLE monitor_thread = CreateThread(nullptr, 0, MonitorThreadProc, nullptr, 0, nullptr);
|
||||
if (!monitor_thread)
|
||||
{
|
||||
printf("[server] monitor thread failed: %lu\n", GetLastError());
|
||||
//printf("[server] monitor thread failed: %lu\n", GetLastError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
HANDLE accept_thread = CreateThread(nullptr, 0, AcceptThreadProc, nullptr, 0, nullptr);
|
||||
if (!accept_thread)
|
||||
{
|
||||
printf("[server] accept thread failed: %lu\n", GetLastError());
|
||||
//printf("[server] accept thread failed: %lu\n", GetLastError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -549,6 +597,7 @@ auto StartServer() -> BOOL
|
||||
{
|
||||
if (!InitializeServer())
|
||||
return FALSE;
|
||||
|
||||
return RunServerCore();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
#include "utils.h"
|
||||
|
||||
#define MUTEX_NAME XOR_STRING_W(L"Local\\seriver_mutex_anit")
|
||||
|
||||
auto utils::check_mutex() -> BOOL
|
||||
{
|
||||
HANDLE mutex = CreateMutex(nullptr, TRUE, MUTEX_NAME);
|
||||
if (!mutex || GetLastError() == ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
CloseHandle(mutex);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
// 不区分大小写宽字符串查找
|
||||
bool utils::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 utils::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;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
#include "Base.h"
|
||||
|
||||
namespace utils
|
||||
{
|
||||
auto check_mutex() -> BOOL;
|
||||
|
||||
BOOL RegReadString(HKEY hRoot, LPCSTR szSubKey, LPCSTR szValueName, char* outBuf, DWORD bufSize);
|
||||
|
||||
// 不区分大小写宽字符串查找
|
||||
bool StrContainsI(LPCWSTR Source, LPCWSTR Sub);
|
||||
}
|
||||
|
||||
#endif // !UTILS_H
|
||||
Reference in New Issue
Block a user