diff --git a/.vs/PFHook/v14/.suo b/.vs/PFHook/v14/.suo new file mode 100644 index 0000000..31f7f46 Binary files /dev/null and b/.vs/PFHook/v14/.suo differ diff --git a/PFHook.sln b/PFHook.sln new file mode 100644 index 0000000..4d571aa --- /dev/null +++ b/PFHook.sln @@ -0,0 +1,62 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PFHook_sys", "PFHook_sys\PFHook_sys.vcxproj", "{00AFD5A9-6927-417C-94DC-6C2E612352C9}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PFHook_exe", "PFHook\PFHook.vcxproj", "{3E420713-1E5E-4AF4-A151-2523FF1DB720}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|ARM = Release|ARM + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {00AFD5A9-6927-417C-94DC-6C2E612352C9}.Debug|ARM.ActiveCfg = Debug|ARM + {00AFD5A9-6927-417C-94DC-6C2E612352C9}.Debug|ARM.Build.0 = Debug|ARM + {00AFD5A9-6927-417C-94DC-6C2E612352C9}.Debug|ARM.Deploy.0 = Debug|ARM + {00AFD5A9-6927-417C-94DC-6C2E612352C9}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {00AFD5A9-6927-417C-94DC-6C2E612352C9}.Debug|ARM64.Build.0 = Debug|ARM64 + {00AFD5A9-6927-417C-94DC-6C2E612352C9}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {00AFD5A9-6927-417C-94DC-6C2E612352C9}.Debug|x64.ActiveCfg = Debug|x64 + {00AFD5A9-6927-417C-94DC-6C2E612352C9}.Debug|x64.Build.0 = Debug|x64 + {00AFD5A9-6927-417C-94DC-6C2E612352C9}.Debug|x64.Deploy.0 = Debug|x64 + {00AFD5A9-6927-417C-94DC-6C2E612352C9}.Debug|x86.ActiveCfg = Debug|Win32 + {00AFD5A9-6927-417C-94DC-6C2E612352C9}.Debug|x86.Build.0 = Debug|Win32 + {00AFD5A9-6927-417C-94DC-6C2E612352C9}.Debug|x86.Deploy.0 = Debug|Win32 + {00AFD5A9-6927-417C-94DC-6C2E612352C9}.Release|ARM.ActiveCfg = Release|ARM + {00AFD5A9-6927-417C-94DC-6C2E612352C9}.Release|ARM.Build.0 = Release|ARM + {00AFD5A9-6927-417C-94DC-6C2E612352C9}.Release|ARM.Deploy.0 = Release|ARM + {00AFD5A9-6927-417C-94DC-6C2E612352C9}.Release|ARM64.ActiveCfg = Release|ARM64 + {00AFD5A9-6927-417C-94DC-6C2E612352C9}.Release|ARM64.Build.0 = Release|ARM64 + {00AFD5A9-6927-417C-94DC-6C2E612352C9}.Release|ARM64.Deploy.0 = Release|ARM64 + {00AFD5A9-6927-417C-94DC-6C2E612352C9}.Release|x64.ActiveCfg = Release|x64 + {00AFD5A9-6927-417C-94DC-6C2E612352C9}.Release|x64.Build.0 = Release|x64 + {00AFD5A9-6927-417C-94DC-6C2E612352C9}.Release|x64.Deploy.0 = Release|x64 + {00AFD5A9-6927-417C-94DC-6C2E612352C9}.Release|x86.ActiveCfg = Release|Win32 + {00AFD5A9-6927-417C-94DC-6C2E612352C9}.Release|x86.Build.0 = Release|Win32 + {00AFD5A9-6927-417C-94DC-6C2E612352C9}.Release|x86.Deploy.0 = Release|Win32 + {3E420713-1E5E-4AF4-A151-2523FF1DB720}.Debug|ARM.ActiveCfg = Debug|Win32 + {3E420713-1E5E-4AF4-A151-2523FF1DB720}.Debug|ARM64.ActiveCfg = Debug|Win32 + {3E420713-1E5E-4AF4-A151-2523FF1DB720}.Debug|x64.ActiveCfg = Debug|x64 + {3E420713-1E5E-4AF4-A151-2523FF1DB720}.Debug|x64.Build.0 = Debug|x64 + {3E420713-1E5E-4AF4-A151-2523FF1DB720}.Debug|x86.ActiveCfg = Debug|Win32 + {3E420713-1E5E-4AF4-A151-2523FF1DB720}.Debug|x86.Build.0 = Debug|Win32 + {3E420713-1E5E-4AF4-A151-2523FF1DB720}.Release|ARM.ActiveCfg = Release|Win32 + {3E420713-1E5E-4AF4-A151-2523FF1DB720}.Release|ARM64.ActiveCfg = Release|Win32 + {3E420713-1E5E-4AF4-A151-2523FF1DB720}.Release|x64.ActiveCfg = Release|x64 + {3E420713-1E5E-4AF4-A151-2523FF1DB720}.Release|x64.Build.0 = Release|x64 + {3E420713-1E5E-4AF4-A151-2523FF1DB720}.Release|x86.ActiveCfg = Release|Win32 + {3E420713-1E5E-4AF4-A151-2523FF1DB720}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/PFHook/PFHook.aps b/PFHook/PFHook.aps new file mode 100644 index 0000000..0329888 Binary files /dev/null and b/PFHook/PFHook.aps differ diff --git a/PFHook/PFHook.cpp b/PFHook/PFHook.cpp new file mode 100644 index 0000000..1ebfb25 --- /dev/null +++ b/PFHook/PFHook.cpp @@ -0,0 +1,106 @@ + +// PFHook.cpp : ӦóΪ +// + +#include "stdafx.h" +#include "PFHook.h" +#include "PFHookDlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + + +// CPFHookApp + +BEGIN_MESSAGE_MAP(CPFHookApp, CWinApp) + ON_COMMAND(ID_HELP, &CWinApp::OnHelp) +END_MESSAGE_MAP() + + +// CPFHookApp + +CPFHookApp::CPFHookApp() +{ + // ֧ + m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART; + + // TODO: ڴ˴ӹ룬 + // Ҫijʼ InitInstance +} + + +// Ψһһ CPFHookApp + +CPFHookApp theApp; + + +// CPFHookApp ʼ + +BOOL CPFHookApp::InitInstance() +{ + // һ Windows XP ϵӦó嵥ָҪ + // ʹ ComCtl32.dll 汾 6 ߰汾ÿӻʽ + //Ҫ InitCommonControlsEx() 򣬽޷ڡ + INITCOMMONCONTROLSEX InitCtrls; + InitCtrls.dwSize = sizeof(InitCtrls); + // ΪҪӦóʹõ + // ؼࡣ + InitCtrls.dwICC = ICC_WIN95_CLASSES; + InitCommonControlsEx(&InitCtrls); + + CWinApp::InitInstance(); + + + AfxEnableControlContainer(); + + // shell ԷԻ + // κ shell ͼؼ shell бͼؼ + CShellManager *pShellManager = new CShellManager; + + // Windows NativeӾԱ MFC ؼ + CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows)); + + // ׼ʼ + // δʹЩܲϣС + // տִļĴСӦƳ + // Ҫضʼ + // ڴ洢õע + // TODO: Ӧʵ޸ĸַ + // ޸Ϊ˾֯ + SetRegistryKey(_T("ӦóɵıӦó")); + + CPFHookDlg dlg; + m_pMainWnd = &dlg; + INT_PTR nResponse = dlg.DoModal(); + if (nResponse == IDOK) + { + // TODO: ڴ˷ôʱ + // ȷرնԻĴ + } + else if (nResponse == IDCANCEL) + { + // TODO: ڴ˷ôʱ + // ȡرնԻĴ + } + else if (nResponse == -1) + { + TRACE(traceAppMsg, 0, ": Ի򴴽ʧܣӦóֹ\n"); + TRACE(traceAppMsg, 0, ": ڶԻʹ MFC ؼ޷ #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS\n"); + } + + // ɾ洴 shell + if (pShellManager != NULL) + { + delete pShellManager; + } + +#ifndef _AFXDLL + ControlBarCleanUp(); +#endif + + // ڶԻѹرգԽ FALSE Ա˳Ӧó + // ӦóϢá + return FALSE; +} + diff --git a/PFHook/PFHook.h b/PFHook/PFHook.h new file mode 100644 index 0000000..81d3dbf --- /dev/null +++ b/PFHook/PFHook.h @@ -0,0 +1,32 @@ + +// PFHook.h : PROJECT_NAME Ӧóͷļ +// + +#pragma once + +#ifndef __AFXWIN_H__ + #error "ڰļ֮ǰstdafx.h PCH ļ" +#endif + +#include "resource.h" // + + +// CPFHookApp: +// йشʵ֣ PFHook.cpp +// + +class CPFHookApp : public CWinApp +{ +public: + CPFHookApp(); + +// д +public: + virtual BOOL InitInstance(); + +// ʵ + + DECLARE_MESSAGE_MAP() +}; + +extern CPFHookApp theApp; \ No newline at end of file diff --git a/PFHook/PFHook.rc b/PFHook/PFHook.rc new file mode 100644 index 0000000..2f39311 Binary files /dev/null and b/PFHook/PFHook.rc differ diff --git a/PFHook/PFHook.vcxproj b/PFHook/PFHook.vcxproj new file mode 100644 index 0000000..36dbc8e --- /dev/null +++ b/PFHook/PFHook.vcxproj @@ -0,0 +1,224 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {3E420713-1E5E-4AF4-A151-2523FF1DB720} + PFHook + 8.1 + MFCProj + PFHook_exe + + + + Application + true + v140 + Unicode + Static + + + Application + false + v140 + true + Unicode + Static + + + Application + true + v140 + Unicode + Static + + + Application + false + v140 + true + Unicode + Static + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + Use + Level3 + Disabled + WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions) + true + + + Windows + RequireAdministrator + + + false + true + _DEBUG;%(PreprocessorDefinitions) + + + 0x0804 + _DEBUG;%(PreprocessorDefinitions) + $(IntDir);%(AdditionalIncludeDirectories) + + + + + Use + Level3 + Disabled + _WINDOWS;_DEBUG;%(PreprocessorDefinitions) + true + + + Windows + + + false + true + _DEBUG;%(PreprocessorDefinitions) + + + 0x0804 + _DEBUG;%(PreprocessorDefinitions) + $(IntDir);%(AdditionalIncludeDirectories) + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions) + true + + + Windows + true + true + RequireAdministrator + + + false + true + NDEBUG;%(PreprocessorDefinitions) + + + 0x0804 + NDEBUG;%(PreprocessorDefinitions) + $(IntDir);%(AdditionalIncludeDirectories) + + + + + Level3 + Use + MaxSpeed + true + true + _WINDOWS;NDEBUG;%(PreprocessorDefinitions) + true + + + Windows + true + true + + + false + true + NDEBUG;%(PreprocessorDefinitions) + + + 0x0804 + NDEBUG;%(PreprocessorDefinitions) + $(IntDir);%(AdditionalIncludeDirectories) + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PFHook/PFHook.vcxproj.filters b/PFHook/PFHook.vcxproj.filters new file mode 100644 index 0000000..35c9a7b --- /dev/null +++ b/PFHook/PFHook.vcxproj.filters @@ -0,0 +1,63 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 资源文件 + + + + + 资源文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/PFHook/PFHook.vcxproj.user b/PFHook/PFHook.vcxproj.user new file mode 100644 index 0000000..abe8dd8 --- /dev/null +++ b/PFHook/PFHook.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/PFHook/PFHookDlg.cpp b/PFHook/PFHookDlg.cpp new file mode 100644 index 0000000..2aab4a8 --- /dev/null +++ b/PFHook/PFHookDlg.cpp @@ -0,0 +1,533 @@ + +// PFHookDlg.cpp : 实现文件 +// + +#include "stdafx.h" +#include "PFHook.h" +#include "PFHookDlg.h" +#include "afxdialogex.h" +#include +#include +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + + +// CPFHookDlg 对话框 + +#define DRIVER_NAME TEXT("PFHook") +#define DRIVER_PATH TEXT("PFHook.sys") + +// 通信代码 +#define PFHOOK_CODE_CHECKVT 0x800 +#define PFHOOK_CODE_HOOK 0x801 +#define PFHOOK_CODE_UNHOOK 0x802 + + +#define PFHOOK_WELCOME_TEXT TEXT("Version:1.0a\nThe program and driver are made by Xiaobao.\nQQ:1121402724\nHave fun! O(∩_∩)O~~") + +BOOL LoadNTDriver(TCHAR* lpszDriverName, TCHAR* lpszDriverPath); +BOOL UnloadNTDriver(TCHAR* szSvrName); + +CPFHookDlg::CPFHookDlg(CWnd* pParent /*=NULL*/) + : CDialogEx(IDD_PFHOOK_DIALOG, pParent) + , m_iDriverStatus(0) +{ + m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); +} + +void CPFHookDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialogEx::DoDataExchange(pDX); + DDX_Control(pDX, IDC_COMBO_PROCESS, m_cbbProc); + DDX_Control(pDX, IDC_LIST_HOOK_LIST, m_lbHook); + DDX_Control(pDX, IDC_EDIT_HOOKED_ADDRESS2, m_editHookAddr); + DDX_Control(pDX, IDC_EDIT_JMP_ADDRESS, m_editJmpAddr); + DDX_Control(pDX, IDC_STATIC_DRIVER_STATUS, m_staticStatus); +} + +BEGIN_MESSAGE_MAP(CPFHookDlg, CDialogEx) + ON_WM_PAINT() + ON_WM_QUERYDRAGICON() + ON_WM_CLOSE() + ON_WM_CTLCOLOR() + ON_BN_CLICKED(IDC_BUTTON_REFRESH, &CPFHookDlg::OnBnClickedButtonRefresh) + ON_BN_CLICKED(IDC_BUTTON_HOOK, &CPFHookDlg::OnBnClickedButtonHook) + ON_BN_CLICKED(IDC_BUTTON_Unhook, &CPFHookDlg::OnBnClickedButtonUnhook) +END_MESSAGE_MAP() + + +// CPFHookDlg 消息处理程序 + +BOOL CPFHookDlg::OnInitDialog() +{ + CDialogEx::OnInitDialog(); + + // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动 + // 执行此操作 + SetIcon(m_hIcon, TRUE); // 设置大图标 + SetIcon(m_hIcon, FALSE); // 设置小图标 + + // TODO: 在此添加额外的初始化代码 + MessageBox(PFHOOK_WELCOME_TEXT, TEXT("Welcome"), MB_OK | MB_ICONINFORMATION); + RefreshProcess(); + + BOOL bRet = LoadNTDriver(DRIVER_NAME, DRIVER_PATH); + if (!bRet) + { + m_staticStatus.SetWindowText(TEXT("Fail to load the driver!")); + m_iDriverStatus = 1; + } + else if (!CheckVT()) + { + m_staticStatus.SetWindowText(TEXT("Fail to load the VT Engine!")); + m_iDriverStatus = 2; + } + else + { + m_staticStatus.SetWindowText(TEXT("The driver is active now.")); + m_iDriverStatus = 0; + } + + return TRUE; // 除非将焦点设置到控件,否则返回 TRUE +} + +// 如果向对话框添加最小化按钮,则需要下面的代码 +// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序, +// 这将由框架自动完成。 + +void CPFHookDlg::OnPaint() +{ + if (IsIconic()) + { + CPaintDC dc(this); // 用于绘制的设备上下文 + + SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0); + + // 使图标在工作区矩形中居中 + int cxIcon = GetSystemMetrics(SM_CXICON); + int cyIcon = GetSystemMetrics(SM_CYICON); + CRect rect; + GetClientRect(&rect); + int x = (rect.Width() - cxIcon + 1) / 2; + int y = (rect.Height() - cyIcon + 1) / 2; + + // 绘制图标 + dc.DrawIcon(x, y, m_hIcon); + } + else + { + CDialogEx::OnPaint(); + } +} + +//当用户拖动最小化窗口时系统调用此函数取得光标 +//显示。 +HCURSOR CPFHookDlg::OnQueryDragIcon() +{ + return static_cast(m_hIcon); +} + + + +void CPFHookDlg::OnOK() +{ + //CDialogEx::OnOK(); +} + + +BOOL CPFHookDlg::PreTranslateMessage(MSG* pMsg) +{ + // TODO: 在此添加专用代码和/或调用基类 + if (pMsg->message == WM_KEYDOWN) + { + if (pMsg->wParam == VK_ESCAPE) + { + return 0; + } + } + return CDialogEx::PreTranslateMessage(pMsg); +} + + +void CPFHookDlg::OnClose() +{ + if (m_iDriverStatus == 1) + { + CDialogEx::OnClose(); + return; + } + + UINT uResult = MessageBox(TEXT("You really wanna do this?"),TEXT("Warning"),MB_YESNO|MB_ICONQUESTION); + if (uResult == IDYES) + { + if (m_iDriverStatus == 0) + { + for (int i = 0;i < (int)m_vecHookItem.size();i++) + { + RemoveHookItem(m_vecHookItem.at(i).iHookID); + } + } + BOOL bRet = UnloadNTDriver(DRIVER_NAME); + if (!bRet) + MessageBox(TEXT("Opp! Fail to unload the driver!"), TEXT("Error"), MB_OK | MB_ICONERROR); + CDialogEx::OnClose(); + } +} + + + +BOOL LoadNTDriver(TCHAR* lpszDriverName, TCHAR* lpszDriverPath) +{ + TCHAR szDriverImagePath[256]; + //得到完整的驱动路径 + GetFullPathName(lpszDriverPath, 256, szDriverImagePath, NULL); + + BOOL bRet = FALSE; + + SC_HANDLE hServiceMgr = NULL;//SCM管理器的句柄 + SC_HANDLE hServiceDDK = NULL;//NT驱动程序的服务句柄 + + //打开服务控制管理器 + hServiceMgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + + if (hServiceMgr == NULL) + { + //OpenSCManager失败 + //printf("OpenSCManager() Faild %d ! \n", GetLastError()); + bRet = FALSE; + goto BeforeLeave; + } + else + { + ////OpenSCManager成功 + //printf("OpenSCManager() ok ! \n"); + } + + //创建驱动所对应的服务 + hServiceDDK = CreateService(hServiceMgr, + lpszDriverName, //驱动程序的在注册表中的名字  + lpszDriverName, // 注册表驱动程序的 DisplayName 值  + SERVICE_ALL_ACCESS, // 加载驱动程序的访问权限  + SERVICE_KERNEL_DRIVER,// 表示加载的服务是驱动程序  + SERVICE_DEMAND_START, // 注册表驱动程序的 Start 值  + SERVICE_ERROR_IGNORE, // 注册表驱动程序的 ErrorControl 值  + szDriverImagePath, // 注册表驱动程序的 ImagePath 值  + NULL, + NULL, + NULL, + NULL, + NULL); + + DWORD dwRtn; + //判断服务是否失败 + if (hServiceDDK == NULL) + { + dwRtn = GetLastError(); + if (dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS) + { + //由于其他原因创建服务失败 + //printf("CrateService() Faild %d ! \n", dwRtn); + bRet = FALSE; + goto BeforeLeave; + } + else + { + //服务创建失败,是由于服务已经创立过 + //printf("CrateService() Faild Service is ERROR_IO_PENDING or ERROR_SERVICE_EXISTS! \n"); + } + hServiceDDK = OpenService(hServiceMgr, lpszDriverName, SERVICE_ALL_ACCESS); + if (hServiceDDK == NULL) + { + //如果打开服务也失败,则意味错误 + dwRtn = GetLastError(); + //printf("OpenService() Faild %d ! \n", dwRtn); + bRet = FALSE; + goto BeforeLeave; + } + else + { + //printf("OpenService() ok ! \n"); + } + } + else + { + //printf("CrateService() ok ! \n"); + } + + //开启此项服务 + bRet = StartService(hServiceDDK, NULL, NULL); + if (!bRet) + { + DWORD dwRtn = GetLastError(); + if (dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_ALREADY_RUNNING) + { + //printf("StartService() Faild %d ! \n", dwRtn); + bRet = FALSE; + goto BeforeLeave; + } + else + { + if (dwRtn == ERROR_IO_PENDING) + { + //设备被挂住 + //printf("StartService() Faild ERROR_IO_PENDING ! \n"); + bRet = FALSE; + goto BeforeLeave; + } + else + { + //服务已经开启 + //printf("StartService() Faild ERROR_SERVICE_ALREADY_RUNNING ! \n"); + bRet = TRUE; + goto BeforeLeave; + + } + } + } + bRet = TRUE; + //离开前关闭句柄 +BeforeLeave: + if (hServiceDDK) + { + CloseServiceHandle(hServiceDDK); + } + if (hServiceMgr) + { + CloseServiceHandle(hServiceMgr); + } + return bRet; +} + +//卸载驱动程序  +BOOL UnloadNTDriver(TCHAR* szSvrName) +{ + BOOL bRet = FALSE; + SC_HANDLE hServiceMgr = NULL;//SCM管理器的句柄 + SC_HANDLE hServiceDDK = NULL;//NT驱动程序的服务句柄 + SERVICE_STATUS SvrSta; + //打开SCM管理器 + hServiceMgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + if (hServiceMgr == NULL) + { + //带开SCM管理器失败 + //printf("OpenSCManager() Faild %d ! \n", GetLastError()); + bRet = FALSE; + goto BeforeLeave; + } + else + { + //带开SCM管理器失败成功 + //printf("OpenSCManager() ok ! \n"); + } + //打开驱动所对应的服务 + hServiceDDK = OpenService(hServiceMgr, szSvrName, SERVICE_ALL_ACCESS); + + if (hServiceDDK == NULL) + { + //打开驱动所对应的服务失败 + //printf("OpenService() Faild %d ! \n", GetLastError()); + bRet = FALSE; + goto BeforeLeave; + } + else + { +// printf("OpenService() ok ! \n"); + } + //停止驱动程序,如果停止失败,只有重新启动才能,再动态加载。  + if (!ControlService(hServiceDDK, SERVICE_CONTROL_STOP, &SvrSta)) + { + //printf("ControlService() Faild %d !\n", GetLastError()); + } + else + { + //打开驱动所对应的失败 + //printf("ControlService() ok !\n"); + } + //动态卸载驱动程序。  + if (!DeleteService(hServiceDDK)) + { + //卸载失败 + //printf("DeleteSrevice() Faild %d !\n", GetLastError()); + } + else + { + //卸载成功 + //printf("DelServer:eleteSrevice() ok !\n"); + } + bRet = TRUE; +BeforeLeave: + //离开前关闭打开的句柄 + if (hServiceDDK) + { + CloseServiceHandle(hServiceDDK); + } + if (hServiceMgr) + { + CloseServiceHandle(hServiceMgr); + } + return bRet; +} + +HBRUSH CPFHookDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) +{ + HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor); + + if (pWnd->GetSafeHwnd() == m_staticStatus.GetSafeHwnd()) + { + if (m_iDriverStatus) + { + pDC->SetTextColor(RGB(255, 0, 0)); + } + else pDC->SetTextColor(RGB(0, 255, 0)); + + } + // TODO: 在此更改 DC 的任何特性 + + // TODO: 如果默认的不是所需画笔,则返回另一个画笔 + return hbr; +} + + +bool CPFHookDlg::RefreshProcess() +{ + HANDLE hSnapshot = NULL; + PROCESSENTRY32 proc; + BOOL bMore; + + ZeroMemory(&proc, sizeof(proc)); + proc.dwSize = sizeof(proc); + + hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + + if (!hSnapshot) return false; + m_cbbProc.ResetContent(); + m_cbbProc.SetCurSel(-1); + + bMore = Process32First(hSnapshot, &proc); + while (bMore) + { + int i = m_cbbProc.InsertString(-1, proc.szExeFile); + m_cbbProc.SetItemData(i, proc.th32ProcessID); + + bMore = Process32Next(hSnapshot, &proc); + } + CloseHandle(hSnapshot); + return true; +} + + +void CPFHookDlg::OnBnClickedButtonRefresh() +{ + RefreshProcess(); +} + + +void CPFHookDlg::OnBnClickedButtonHook() +{ + CString strTemp,strProcName; + int iRet; + HOOKITEM item; + int iID; + DWORD dwPID,dwHookedAddress, dwJmpAddress; + + if (m_cbbProc.GetCurSel() == -1 || m_iDriverStatus) + return; + + dwPID = m_cbbProc.GetItemData(m_cbbProc.GetCurSel()); + m_editHookAddr.GetWindowText(strTemp); + dwHookedAddress = wcstol(strTemp,NULL,16); + m_editJmpAddr.GetWindowText(strTemp); + dwJmpAddress = wcstol(strTemp, NULL, 16); + + if (dwHookedAddress == 0 || dwJmpAddress == 0) + return; + + iRet = AddHookItem(dwPID, (LPVOID)dwHookedAddress,(LPVOID)dwJmpAddress); + if (iRet!=-1) + { + MessageBeep(MB_OK); + m_cbbProc.GetLBText(m_cbbProc.GetCurSel(), strProcName); + strTemp.Format(TEXT("[%d] %s[%d] 0x%X --> 0x%X"), iRet,strProcName,dwPID,dwHookedAddress,dwJmpAddress); + iID = m_lbHook.InsertString(-1, strTemp); + + item.iID = iID; + item.iHookID = iRet; + item.dwPID = dwPID; + item.lpHookedAddr = (LPVOID)dwHookedAddress; + item.lpJmpAddr = (LPVOID)dwJmpAddress; + m_vecHookItem.push_back(item); + } + else MessageBeep(MB_ICONERROR); +} + + +void CPFHookDlg::OnBnClickedButtonUnhook() +{ + HOOKITEM item; + if (m_lbHook.GetCurSel() == -1 || m_iDriverStatus) + return; + + item = m_vecHookItem.at(m_lbHook.GetCurSel()); + + RemoveHookItem(item.iHookID); + + m_vecHookItem.erase(m_vecHookItem.begin() + m_lbHook.GetCurSel()); + m_lbHook.DeleteString(m_lbHook.GetCurSel()); +} + + +int CPFHookDlg::AddHookItem(DWORD dwPID, LPVOID lpHookedAddr, LPVOID lpJmpAddr) +{ + DWORD dwRet; + if (m_iDriverStatus) + return FALSE; + + __asm + { + xor esi,esi + dec esi + mov eax, PFHOOK_CODE_HOOK + mov ebx, dwPID + mov ecx,lpHookedAddr + mov edx,lpJmpAddr + cpuid + mov dwRet, esi + } + return dwRet; +} + + +BOOL CPFHookDlg::RemoveHookItem(int iItemID) +{ + BOOL bRet; + if (m_iDriverStatus) + return FALSE; + + __asm + { + xor esi, esi + mov eax, PFHOOK_CODE_UNHOOK + mov ecx, iItemID + cpuid + mov bRet, esi + } + return bRet; +} + + +BOOL CPFHookDlg::CheckVT() +{ + BOOL bRet; + if (m_iDriverStatus) + return FALSE; + + __asm + { + xor esi, esi + mov eax, PFHOOK_CODE_CHECKVT + cpuid + mov bRet, esi + } + return bRet; +} diff --git a/PFHook/PFHookDlg.h b/PFHook/PFHookDlg.h new file mode 100644 index 0000000..7f8b5fd --- /dev/null +++ b/PFHook/PFHookDlg.h @@ -0,0 +1,64 @@ + +// PFHookDlg.h : ͷļ +// + +#pragma once +#include "afxwin.h" +#include + +using namespace std; + +typedef struct _HOOKITEM +{ + int iID; + int iHookID; + DWORD dwPID; + LPVOID lpHookedAddr; + LPVOID lpJmpAddr; +}HOOKITEM, *PHOOKITEM; + +// CPFHookDlg Ի +class CPFHookDlg : public CDialogEx +{ +// +public: + CPFHookDlg(CWnd* pParent = NULL); // ׼캯 + +// Ի +#ifdef AFX_DESIGN_TIME + enum { IDD = IDD_PFHOOK_DIALOG }; +#endif + + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV ֧ + + +// ʵ +protected: + HICON m_hIcon; + + // ɵϢӳ亯 + virtual BOOL OnInitDialog(); + afx_msg void OnPaint(); + afx_msg HCURSOR OnQueryDragIcon(); + DECLARE_MESSAGE_MAP() +public: + CComboBox m_cbbProc; + virtual void OnOK(); + virtual BOOL PreTranslateMessage(MSG* pMsg); + afx_msg void OnClose(); + afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); + int m_iDriverStatus; + bool RefreshProcess(); + afx_msg void OnBnClickedButtonRefresh(); + afx_msg void OnBnClickedButtonHook(); + afx_msg void OnBnClickedButtonUnhook(); + CListBox m_lbHook; + CEdit m_editHookAddr; + CEdit m_editJmpAddr; + int AddHookItem(DWORD dwPID, LPVOID lpHookedAddr, LPVOID lpJmpAddr); + BOOL RemoveHookItem(int iItemID); + vector m_vecHookItem; + CStatic m_staticStatus; + BOOL CheckVT(); +}; diff --git a/PFHook/ReadMe.txt b/PFHook/ReadMe.txt new file mode 100644 index 0000000..130a2e0 --- /dev/null +++ b/PFHook/ReadMe.txt @@ -0,0 +1,67 @@ +================================================================================ + MICROSOFT 基础类库 : PFHook 项目概述 +=============================================================================== + +应用程序向导已为您创建了此 PFHook 应用程序。此应用程序不仅演示 Microsoft 基础类的基本使用方法,还可作为您编写应用程序的起点。 + +本文件概要介绍组成 PFHook 应用程序的每个文件的内容。 + +PFHook.vcxproj + 这是使用应用程序向导生成的 VC++ 项目的主项目文件,其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。 + +PFHook.vcxproj.filters + 这是使用“应用程序向导”生成的 VC++ 项目筛选器文件。它包含有关项目文件与筛选器之间的关联信息。在 IDE 中,通过这种关联,在特定节点下以分组形式显示具有相似扩展名的文件。例如,“.cpp”文件与“源文件”筛选器关联。 + +PFHook.h + 这是应用程序的主头文件。 + 其中包括其他项目特定的标头(包括 Resource.h),并声明 CPFHookApp 应用程序类。 + +PFHook.cpp + 这是包含应用程序类 CPFHookApp 的主应用程序源文件。 + +PFHook.rc + 这是程序使用的所有 Microsoft Windows 资源的列表。它包括 RES 子目录中存储的图标、位图和光标。此文件可以直接在 Microsoft Visual C++ 中进行编辑。项目资源包含在 2052 中。 + +res\PFHook.ico + 这是用作应用程序图标的图标文件。此图标包括在主资源文件 PFHook.rc 中。 + +res\PFHook.rc2 + 此文件包含不在 Microsoft Visual C++ 中进行编辑的资源。您应该将不可由资源编辑器编辑的所有资源放在此文件中。 + + +///////////////////////////////////////////////////////////////////////////// + +应用程序向导创建一个对话框类: + +PFHookDlg.h、PFHookDlg.cpp - 对话框 + 这些文件包含 CPFHookDlg 类。此类定义应用程序的主对话框的行为。对话框模板包含在 PFHook.rc 中,该文件可以在 Microsoft Visual C++ 中编辑。 + +///////////////////////////////////////////////////////////////////////////// + +其他功能: + +ActiveX 控件 + 该应用程序包含对使用 ActiveX 控件的支持。 + +///////////////////////////////////////////////////////////////////////////// + +其他标准文件: + +StdAfx.h, StdAfx.cpp + 这些文件用于生成名为 PFHook.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。 + +Resource.h + 这是标准头文件,可用于定义新的资源 ID。Microsoft Visual C++ 将读取并更新此文件。 + +PFHook.manifest + Windows XP 使用应用程序清单文件来描述特定版本的并行程序集的应用程序依赖项。加载程序使用这些信息来从程序集缓存中加载相应的程序集,并保护其不被应用程序访问。应用程序清单可能会包含在内,以作为与应用程序可执行文件安装在同一文件夹中的外部 .manifest 文件进行重新分发,它还可能以资源的形式包含在可执行文件中。 +///////////////////////////////////////////////////////////////////////////// + +其他注释: + +应用程序向导使用“TODO:”来指示应添加或自定义的源代码部分。 + +如果应用程序使用共享 DLL 中的 MFC,您将需要重新分发 MFC DLL。如果应用程序所使用的语言与操作系统的区域设置不同,则还需要重新分发相应的本地化资源 mfc110XXX.DLL。 +有关上述话题的更多信息,请参见 MSDN 文档中有关重新分发 Visual C++ 应用程序的部分。 + +///////////////////////////////////////////////////////////////////////////// diff --git a/PFHook/res/PFHook.ico b/PFHook/res/PFHook.ico new file mode 100644 index 0000000..d56fbcd Binary files /dev/null and b/PFHook/res/PFHook.ico differ diff --git a/PFHook/res/PFHook.rc2 b/PFHook/res/PFHook.rc2 new file mode 100644 index 0000000..64fd5a7 Binary files /dev/null and b/PFHook/res/PFHook.rc2 differ diff --git a/PFHook/resource.h b/PFHook/resource.h new file mode 100644 index 0000000..e4bcaea Binary files /dev/null and b/PFHook/resource.h differ diff --git a/PFHook/stdafx.cpp b/PFHook/stdafx.cpp new file mode 100644 index 0000000..4e69168 --- /dev/null +++ b/PFHook/stdafx.cpp @@ -0,0 +1,8 @@ + +// stdafx.cpp : ֻ׼ļԴļ +// PFHook.pch ΪԤͷ +// stdafx.obj ԤϢ + +#include "stdafx.h" + + diff --git a/PFHook/stdafx.h b/PFHook/stdafx.h new file mode 100644 index 0000000..7d8a96a --- /dev/null +++ b/PFHook/stdafx.h @@ -0,0 +1,54 @@ + +// stdafx.h : ׼ϵͳļİļ +// Ǿʹõĵ +// ضĿİļ + +#pragma once + +#ifndef VC_EXTRALEAN +#define VC_EXTRALEAN // Windows ͷųʹõ +#endif + +#include "targetver.h" + +#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // ijЩ CString 캯ʽ + +// ر MFC ijЩɷĺԵľϢ +#define _AFX_ALL_WARNINGS + +#include // MFC ͱ׼ +#include // MFC չ + + +#include // MFC Զ + + + +#ifndef _AFX_NO_OLE_SUPPORT +#include // MFC Internet Explorer 4 ؼ֧ +#endif +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC Windows ؼ֧ +#endif // _AFX_NO_AFXCMN_SUPPORT + +#include // Ϳؼ MFC ֧ + + + + + + + + + +#ifdef _UNICODE +#if defined _M_IX86 +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") +#elif defined _M_X64 +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") +#else +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") +#endif +#endif + + diff --git a/PFHook/targetver.h b/PFHook/targetver.h new file mode 100644 index 0000000..416cebf --- /dev/null +++ b/PFHook/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// SDKDDKVer.h õ߰汾 Windows ƽ̨ + +// ҪΪǰ Windows ƽ̨Ӧó WinSDKVer.h +// _WIN32_WINNT ΪҪֵ֧ƽ̨Ȼٰ SDKDDKVer.h + +#include diff --git a/PFHook_sys/Debug/PFHook_sys.inf b/PFHook_sys/Debug/PFHook_sys.inf new file mode 100644 index 0000000..92b0d95 --- /dev/null +++ b/PFHook_sys/Debug/PFHook_sys.inf @@ -0,0 +1,93 @@ +; +; PFHook_sys.inf +; + +[Version] +Signature="$WINDOWS NT$" +Class=Sample ; TODO: edit Class +ClassGuid={78A1C341-4539-11d3-B88D-00C04FAD5171} ; TODO: edit ClassGuid +Provider=%ManufacturerName% +CatalogFile=PFHook_sys.cat +DriverVer=10/16/2016,12.30.32.690 + +[DestinationDirs] +DefaultDestDir = 12 + +; ================= Class section ===================== + +[ClassInstall32] +Addreg=SampleClassReg + +[SampleClassReg] +HKR,,,0,%ClassName% +HKR,,Icon,,-5 + +[SourceDisksNames] +1 = %DiskName%,,,"" + +[SourceDisksFiles] +PFHook_sys.sys = 1,, + +;***************************************** +; Install Section +;***************************************** + +[Manufacturer] +%ManufacturerName%=Standard,NTx86 + +[Standard.NTx86] +%PFHook_sys.DeviceDesc%=PFHook_sys_Device, Root\PFHook_sys ; TODO: edit hw-id + +[PFHook_sys_Device.NT] +CopyFiles=Drivers_Dir + +[Drivers_Dir] +PFHook_sys.sys + +;-------------- Service installation +[PFHook_sys_Device.NT.Services] +AddService = PFHook_sys,%SPSVCINST_ASSOCSERVICE%, PFHook_sys_Service_Inst + +; -------------- PFHook_sys driver install sections +[PFHook_sys_Service_Inst] +DisplayName = %PFHook_sys.SVCDESC% +ServiceType = 1 ; SERVICE_KERNEL_DRIVER +StartType = 3 ; SERVICE_DEMAND_START +ErrorControl = 1 ; SERVICE_ERROR_NORMAL +ServiceBinary = %12%\PFHook_sys.sys + +; +;--- PFHook_sys_Device Coinstaller installation ------ +; + +[DestinationDirs] +PFHook_sys_Device_CoInstaller_CopyFiles = 11 + +[PFHook_sys_Device.NT.CoInstallers] +AddReg=PFHook_sys_Device_CoInstaller_AddReg +CopyFiles=PFHook_sys_Device_CoInstaller_CopyFiles + +[PFHook_sys_Device_CoInstaller_AddReg] +; + + +[PFHook_sys_Device_CoInstaller_CopyFiles] +; + + +[SourceDisksFiles] +; + + +[PFHook_sys_Device.NT.Wdf] +KmdfService = PFHook_sys, PFHook_sys_wdfsect +[PFHook_sys_wdfsect] +KmdfLibraryVersion = 1.15 + +[Strings] +SPSVCINST_ASSOCSERVICE= 0x00000002 +ManufacturerName="" ;TODO: Replace with your manufacturer name +ClassName="Samples" ; TODO: edit ClassName +DiskName = "PFHook_sys Installation Disk" +PFHook_sys.DeviceDesc = "PFHook_sys Device" +PFHook_sys.SVCDESC = "PFHook_sys Service" diff --git a/PFHook_sys/Debug/PFHook_sys.log b/PFHook_sys/Debug/PFHook_sys.log new file mode 100644 index 0000000..ac30311 --- /dev/null +++ b/PFHook_sys/Debug/PFHook_sys.log @@ -0,0 +1,47 @@ +C:\Users\Xiaobao\OneDrive\Code\VS2015\PFHook\PFHook_sys\PFHook_sys.vcxproj(113,5): warning MSB4011: 无法再次导入“C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\BuildCustomizations\masm.props”。可能已在“C:\Program Files (x86)\Windows Kits\10\build\WindowsDriver.Shared.props (463,3)”处导入过它。这很可能是生成创作错误。将忽略此后续导入。 +C:\Users\Xiaobao\OneDrive\Code\VS2015\PFHook\PFHook_sys\PFHook_sys.vcxproj(197,5): warning MSB4011: 无法再次导入“C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\BuildCustomizations\masm.targets”。可能已在“C:\Program Files (x86)\Windows Kits\10\build\WindowsDriver.common.targets (1832,3)”处导入过它。这很可能是生成创作错误。将忽略此后续导入。 + Building 'PFHook_sys' with toolset 'WindowsKernelModeDriver10.0' and the 'Universal' target platform. + Stamping Debug\PFHook_sys.inf [Version] section with DriverVer=10/16/2016,12.30.32.690 + Assembling base\vtasm.asm... +base\vtasm.asm(5): error A2013: .MODEL must precede this directive +base\vtasm.asm(6): error A2034: must be in segment block +base\vtasm.asm(7): error A2034: must be in segment block +base\vtasm.asm(9): error A2034: must be in segment block +base\vtasm.asm(10): error A2034: must be in segment block +base\vtasm.asm(11): error A2034: must be in segment block +base\vtasm.asm(12): error A2034: must be in segment block +base\vtasm.asm(13): error A2034: must be in segment block +base\vtasm.asm(14): error A2034: must be in segment block +base\vtasm.asm(15): error A2034: must be in segment block +base\vtasm.asm(16): error A2034: must be in segment block +base\vtasm.asm(17): error A2034: must be in segment block +base\vtasm.asm(18): error A2034: must be in segment block +base\vtasm.asm(19): error A2034: must be in segment block +base\vtasm.asm(20): error A2034: must be in segment block +base\vtasm.asm(21): error A2034: must be in segment block +base\vtasm.asm(22): error A2034: must be in segment block +base\vtasm.asm(23): error A2034: must be in segment block +base\vtasm.asm(24): error A2034: must be in segment block +base\vtasm.asm(25): error A2034: must be in segment block +base\vtasm.asm(27): error A2013: .MODEL must precede this directive +base\vtasm.asm(29): error A2034: must be in segment block : Asm_CPUID +base\vtasm.asm(30): error A2034: must be in segment block +base\vtasm.asm(31): error A2034: must be in segment block +base\vtasm.asm(32): error A2034: must be in segment block +base\vtasm.asm(33): error A2034: must be in segment block +base\vtasm.asm(35): error A2034: must be in segment block +base\vtasm.asm(36): error A2034: must be in segment block +base\vtasm.asm(37): error A2034: must be in segment block +base\vtasm.asm(38): error A2034: must be in segment block +base\vtasm.asm(39): error A2034: must be in segment block +base\vtasm.asm(40): error A2034: must be in segment block +base\vtasm.asm(41): error A2034: must be in segment block +base\vtasm.asm(42): error A2034: must be in segment block +base\vtasm.asm(43): error A2034: must be in segment block +base\vtasm.asm(45): error A2034: must be in segment block +base\vtasm.asm(46): error A2034: must be in segment block +base\vtasm.asm(47): error A2034: must be in segment block +base\vtasm.asm(48): error A2034: must be in segment block +base\vtasm.asm(49): error A2034: must be in segment block +base\vtasm.asm(50): fatal error A1010: unmatched block nesting : Asm_CPUID +C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\BuildCustomizations\masm.targets(50,5): error MSB3721: 命令“ml.exe /c /nologo /Zi /Fo"Debug\vtasm.obj" /W3 /errorReport:prompt /Tabase\vtasm.asm”已退出,返回代码为 1。 diff --git a/PFHook_sys/Debug/PFHook_sys.tlog/PFHook_sys.lastbuildstate b/PFHook_sys/Debug/PFHook_sys.tlog/PFHook_sys.lastbuildstate new file mode 100644 index 0000000..6e9547e --- /dev/null +++ b/PFHook_sys/Debug/PFHook_sys.tlog/PFHook_sys.lastbuildstate @@ -0,0 +1,2 @@ +#TargetFrameworkVersion=v4.5:PlatformToolSet=WindowsKernelModeDriver10.0:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit:WindowsTargetPlatformVersion=10.0.14393.0 +Debug|Win32|C:\Users\Xiaobao\OneDrive\Code\VS2015\PFHook\| diff --git a/PFHook_sys/Debug/PFHook_sys.tlog/PFHook_sys.write.1u.tlog b/PFHook_sys/Debug/PFHook_sys.tlog/PFHook_sys.write.1u.tlog new file mode 100644 index 0000000..1916087 Binary files /dev/null and b/PFHook_sys/Debug/PFHook_sys.tlog/PFHook_sys.write.1u.tlog differ diff --git a/PFHook_sys/Debug/PFHook_sys.tlog/stampinf.command.1.tlog b/PFHook_sys/Debug/PFHook_sys.tlog/stampinf.command.1.tlog new file mode 100644 index 0000000..c904401 Binary files /dev/null and b/PFHook_sys/Debug/PFHook_sys.tlog/stampinf.command.1.tlog differ diff --git a/PFHook_sys/Debug/PFHook_sys.tlog/stampinf.read.1.tlog b/PFHook_sys/Debug/PFHook_sys.tlog/stampinf.read.1.tlog new file mode 100644 index 0000000..75951c6 Binary files /dev/null and b/PFHook_sys/Debug/PFHook_sys.tlog/stampinf.read.1.tlog differ diff --git a/PFHook_sys/Debug/PFHook_sys.tlog/stampinf.write.1.tlog b/PFHook_sys/Debug/PFHook_sys.tlog/stampinf.write.1.tlog new file mode 100644 index 0000000..7ba7672 Binary files /dev/null and b/PFHook_sys/Debug/PFHook_sys.tlog/stampinf.write.1.tlog differ diff --git a/PFHook_sys/Debug/PFHook_sys.tlog/unsuccessfulbuild b/PFHook_sys/Debug/PFHook_sys.tlog/unsuccessfulbuild new file mode 100644 index 0000000..e69de29 diff --git a/PFHook_sys/Driver.cpp b/PFHook_sys/Driver.cpp new file mode 100644 index 0000000..e1f47cb --- /dev/null +++ b/PFHook_sys/Driver.cpp @@ -0,0 +1,20 @@ +#include "header.h" +#include "vtsystem.h" +extern "C" NTSTATUS DriverEntry(_In_ struct _DRIVER_OBJECT *DriverObject, _In_ PUNICODE_STRING RegisterPath); +void DriverUnload(_DRIVER_OBJECT * DriverObject); + +extern "C" NTSTATUS DriverEntry(_In_ struct _DRIVER_OBJECT *DriverObject,_In_ PUNICODE_STRING RegisterPath) +{ + NTSTATUS status = STATUS_SUCCESS; + + DriverObject->DriverUnload = DriverUnload; + KdPrint(("Exit DriverEntry.\n")); + StartVirtualTechnology(); + return status; +} + +void DriverUnload(_DRIVER_OBJECT * DriverObject) +{ + KdPrint(("Exit DriverUnload.\n")); + StopVirtualTechnology(); +} \ No newline at end of file diff --git a/PFHook_sys/PFHook_sys.inf b/PFHook_sys/PFHook_sys.inf new file mode 100644 index 0000000..e144fd5 --- /dev/null +++ b/PFHook_sys/PFHook_sys.inf @@ -0,0 +1,90 @@ +; +; PFHook_sys.inf +; + +[Version] +Signature="$WINDOWS NT$" +Class=Sample ; TODO: edit Class +ClassGuid={78A1C341-4539-11d3-B88D-00C04FAD5171} ; TODO: edit ClassGuid +Provider=%ManufacturerName% +CatalogFile=PFHook_sys.cat +DriverVer=3.6 + +[DestinationDirs] +DefaultDestDir = 12 + +; ================= Class section ===================== + +[ClassInstall32] +Addreg=SampleClassReg + +[SampleClassReg] +HKR,,,0,%ClassName% +HKR,,Icon,,-5 + +[SourceDisksNames] +1 = %DiskName%,,,"" + +[SourceDisksFiles] +PFHook_sys.sys = 1,, + +;***************************************** +; Install Section +;***************************************** + +[Manufacturer] +%ManufacturerName%=Standard,NT$ARCH$ + +[Standard.NT$ARCH$] +%PFHook_sys.DeviceDesc%=PFHook_sys_Device, Root\PFHook_sys ; TODO: edit hw-id + +[PFHook_sys_Device.NT] +CopyFiles=Drivers_Dir + +[Drivers_Dir] +PFHook_sys.sys + +;-------------- Service installation +[PFHook_sys_Device.NT.Services] +AddService = PFHook_sys,%SPSVCINST_ASSOCSERVICE%, PFHook_sys_Service_Inst + +; -------------- PFHook_sys driver install sections +[PFHook_sys_Service_Inst] +DisplayName = %PFHook_sys.SVCDESC% +ServiceType = 1 ; SERVICE_KERNEL_DRIVER +StartType = 3 ; SERVICE_DEMAND_START +ErrorControl = 1 ; SERVICE_ERROR_NORMAL +ServiceBinary = %12%\PFHook_sys.sys + +; +;--- PFHook_sys_Device Coinstaller installation ------ +; + +[DestinationDirs] +PFHook_sys_Device_CoInstaller_CopyFiles = 11 + +[PFHook_sys_Device.NT.CoInstallers] +AddReg=PFHook_sys_Device_CoInstaller_AddReg +CopyFiles=PFHook_sys_Device_CoInstaller_CopyFiles + +[PFHook_sys_Device_CoInstaller_AddReg] +HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" + +[PFHook_sys_Device_CoInstaller_CopyFiles] +WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll + +[SourceDisksFiles] +WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames + +[PFHook_sys_Device.NT.Wdf] +KmdfService = PFHook_sys, PFHook_sys_wdfsect +[PFHook_sys_wdfsect] +KmdfLibraryVersion = $KMDFVERSION$ + +[Strings] +SPSVCINST_ASSOCSERVICE= 0x00000002 +ManufacturerName="" ;TODO: Replace with your manufacturer name +ClassName="Samples" ; TODO: edit ClassName +DiskName = "PFHook_sys Installation Disk" +PFHook_sys.DeviceDesc = "PFHook_sys Device" +PFHook_sys.SVCDESC = "PFHook_sys Service" diff --git a/PFHook_sys/PFHook_sys.vcxproj b/PFHook_sys/PFHook_sys.vcxproj new file mode 100644 index 0000000..7704385 --- /dev/null +++ b/PFHook_sys/PFHook_sys.vcxproj @@ -0,0 +1,201 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM + + + Release + ARM + + + Debug + ARM64 + + + Release + ARM64 + + + + {00AFD5A9-6927-417C-94DC-6C2E612352C9} + {1bc93793-694f-48fe-9372-81e2b05556fd} + v4.5 + 12.0 + Debug + Win32 + PFHook_sys + + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + + + true + WindowsKernelModeDriver10.0 + Driver + KMDF + Desktop + + + Windows7 + false + WindowsKernelModeDriver10.0 + Driver + KMDF + Desktop + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + + + + + + + + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + true + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + + false + Level2 + base;$(IntDir);%(AdditionalIncludeDirectories) + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + Level2 + + + + + false + Disabled + base;$(IntDir);%(AdditionalIncludeDirectories) + + + false + $(OutDir)$(TargetName)$(TargetExt) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PFHook_sys/PFHook_sys.vcxproj.filters b/PFHook_sys/PFHook_sys.vcxproj.filters new file mode 100644 index 0000000..0873a91 --- /dev/null +++ b/PFHook_sys/PFHook_sys.vcxproj.filters @@ -0,0 +1,69 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {8E41214B-6785-4CFE-B992-037D68949A14} + inf;inv;inx;mof;mc; + + + + + Driver Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + + \ No newline at end of file diff --git a/PFHook_sys/PFHook_sys.vcxproj.user b/PFHook_sys/PFHook_sys.vcxproj.user new file mode 100644 index 0000000..d9cd657 --- /dev/null +++ b/PFHook_sys/PFHook_sys.vcxproj.user @@ -0,0 +1,6 @@ + + + + WindowsLocalDebugger + + \ No newline at end of file diff --git a/PFHook_sys/base/common.cpp b/PFHook_sys/base/common.cpp new file mode 100644 index 0000000..a53ea83 --- /dev/null +++ b/PFHook_sys/base/common.cpp @@ -0,0 +1,117 @@ +#include "header.h" +#include "common.h" +#include "vtasm.h" +#include "vtsystem.h" + +NTSTATUS InitializeSegmentSelector( PSEGMENT_SELECTOR SegmentSelector, USHORT Selector, ULONG64 GdtBase ) +{ + PSEGMENT_DESCRIPTOR2 SegDesc; + + if( !SegmentSelector ) + { + return STATUS_INVALID_PARAMETER; + } + + // + // ѡӵT1 = 1ʾLDTе, ûʵ + // + if( Selector & 0x4 ) + { + + return STATUS_INVALID_PARAMETER; + } + + // + // GDTȡԭʼĶ + // + SegDesc = ( PSEGMENT_DESCRIPTOR2 )( ( PUCHAR ) GdtBase + ( Selector & ~0x7 ) ); + + // + // ѡ + // + SegmentSelector->sel = Selector; + + // + // λַ15-39λ 55-63λ + // + SegmentSelector->base = SegDesc->base0 | SegDesc->base1 << 16 | SegDesc->base2 << 24; + + // + // ޳0-15λ 47-51λ, ȡ + // + SegmentSelector->limit = SegDesc->limit0 | ( SegDesc->limit1attr1 & 0xf ) << 16; + + // + // 39-47 51-55 ע۲ȡ + // + SegmentSelector->attributes.UCHARs = SegDesc->attr0 | ( SegDesc->limit1attr1 & 0xf0 ) << 4; + + // + // жԵDTλ, жǷϵͳǴݶ + // + if( !( SegDesc->attr0 & LA_STANDARD ) ) + { + ULONG64 tmp; + + // + // ʾϵͳ, оΪ64λ׼İ, + // 32λλַֻ32λ. ѵ64λʲô? + // + tmp = ( *( PULONG64 )( ( PUCHAR ) SegDesc + 8 ) ); + + SegmentSelector->base = ( SegmentSelector->base & 0xffffffff ) | ( tmp << 32 ); + } + + // + // Ƕν޵λ, 1Ϊ4K. 0Ϊ1BYTE + // + if( SegmentSelector->attributes.fields.g ) + { + // + // λΪ1, ôͳ4K. ƶ12λ + // + SegmentSelector->limit = ( SegmentSelector->limit << 12 ) + 0xfff; + } + + return STATUS_SUCCESS; +} + +ULONG NTAPI VmxAdjustControls( + ULONG64 Ctl, + ULONG64 Msr + ) +{ + LARGE_INTEGER MsrValue; + + MsrValue.QuadPart = Asm_ReadMsr(Msr); + Ctl &= MsrValue.HighPart; /* bit == 0 in high word ==> must be zero */ + Ctl |= MsrValue.LowPart; /* bit == 1 in low word ==> must be one */ + return Ctl; +} + + +NTSTATUS FillGuestSelectorData(ULONG64 GdtBase, ULONG Segreg, USHORT + Selector) +{ + SEGMENT_SELECTOR SegmentSelector = { 0 }; + ULONG uAccessRights; + + InitializeSegmentSelector(&SegmentSelector, Selector, GdtBase); + uAccessRights = ((PUCHAR)& SegmentSelector.attributes)[0] + (((PUCHAR)& + SegmentSelector.attributes)[1] << 12); + + if (!Selector) + uAccessRights |= 0x10000; + + Vmx_VmWrite(GUEST_ES_SELECTOR + Segreg * 2, Selector & 0xFFF8); + Vmx_VmWrite(GUEST_ES_BASE + Segreg * 2, SegmentSelector.base); + Vmx_VmWrite(GUEST_ES_LIMIT + Segreg * 2, SegmentSelector.limit); + Vmx_VmWrite(GUEST_ES_AR_BYTES + Segreg * 2, uAccessRights); + + +// if ((Segreg == LDTR) || (Segreg == TR)) +// // don't setup for FS/GS - their bases are stored in MSR values +// Vmx_VmWrite(GUEST_ES_BASE + Segreg * 2, SegmentSelector.base); + + return STATUS_SUCCESS; +} \ No newline at end of file diff --git a/PFHook_sys/base/common.h b/PFHook_sys/base/common.h new file mode 100644 index 0000000..a86827e --- /dev/null +++ b/PFHook_sys/base/common.h @@ -0,0 +1,265 @@ +#pragma once + + +#define LA_ACCESSED 0x01 +#define LA_READABLE 0x02 // for code segments +#define LA_WRITABLE 0x02 // for data segments +#define LA_CONFORMING 0x04 // for code segments +#define LA_EXPANDDOWN 0x04 // for data segments +#define LA_CODE 0x08 +#define LA_STANDARD 0x10 +#define LA_DPL_0 0x00 +#define LA_DPL_1 0x20 +#define LA_DPL_2 0x40 +#define LA_DPL_3 0x60 +#define LA_PRESENT 0x80 + +#define LA_LDT64 0x02 +#define LA_ATSS64 0x09 +#define LA_BTSS64 0x0b +#define LA_CALLGATE64 0x0c +#define LA_INTGATE64 0x0e +#define LA_TRAPGATE64 0x0f + +#define HA_AVAILABLE 0x01 +#define HA_LONG 0x02 +#define HA_DB 0x04 +#define HA_GRANULARITY 0x08 + +#define P_PRESENT 0x01 +#define P_WRITABLE 0x02 +#define P_USERMODE 0x04 +#define P_WRITETHROUGH 0x08 +#define P_CACHE_DISABLED 0x10 +#define P_ACCESSED 0x20 +#define P_DIRTY 0x40 +#define P_LARGE 0x80 +#define P_GLOBAL 0x100 + +#define PML4_BASE 0xFFFFF6FB7DBED000 //windowsں˵ĸӦ +#define PDP_BASE 0xFFFFF6FB7DA00000 //#define PXE_BASE 0xFFFFF6FB7DBED000UI64 +#define PD_BASE 0xFFFFF6FB40000000 //#define PPE_BASE 0xFFFFF6FB7DA00000UI64 +#define PT_BASE 0xFFFFF68000000000 //#define PDE_BASE 0xFFFFF6FB40000000UI64 +//#define PTE_BASE 0xFFFFF68000000000UI64 + +#define ITL_TAG 'LTI' + +#define BP_GDT_LIMIT 0x6f +#define BP_IDT_LIMIT 0xfff +#define BP_TSS_LIMIT 0x68 // 0x67 min + +#define BP_GDT_LIMIT 0x6f +#define BP_IDT_LIMIT 0xfff +#define BP_TSS_LIMIT 0x68 // 0x67 min + + +#define TRAP_MTF 0 +#define TRAP_DEBUG 1 +#define TRAP_INT3 3 +#define TRAP_INTO 4 +#define TRAP_GP 13 +#define TRAP_PAGE_FAULT 14 +#define TRAP_INVALID_OP 6 + +/* +* Attribute for segment selector. This is a copy of bit 40:47 & 52:55 of the +* segment descriptor. +*/ +typedef union +{ + USHORT UCHARs; + struct + { + USHORT type:4; /* 0; Bit 40-43 */ + USHORT s:1; /* 4; Bit 44 */ + USHORT dpl:2; /* 5; Bit 45-46 */ + USHORT p:1; /* 7; Bit 47 */ + // gap! + USHORT avl:1; /* 8; Bit 52 */ + USHORT l:1; /* 9; Bit 53 */ + USHORT db:1; /* 10; Bit 54 */ + USHORT g:1; /* 11; Bit 55 */ + USHORT Gap:4; + } fields; +} SEGMENT_ATTRIBUTES; + +typedef struct _SEGMENT_SELECTOR +{ + USHORT sel; + SEGMENT_ATTRIBUTES attributes; + ULONG limit; + ULONG64 base; +} SEGMENT_SELECTOR, *PSEGMENT_SELECTOR; + +typedef struct _SEGMENT_DESCRIPTOR +{ + USHORT limit0; + USHORT base0; + UCHAR base1; + UCHAR attr0; + UCHAR limit1attr1; + UCHAR base2; +} SEGMENT_DESCRIPTOR, *PSEGMENT_DESCRIPTOR; + +typedef struct _TSS64 +{ + ULONG Reserved0; + PVOID RSP0; + PVOID RSP1; + PVOID RSP2; + ULONG64 Reserved1; + PVOID IST1; + PVOID IST2; + PVOID IST3; + PVOID IST4; + PVOID IST5; + PVOID IST6; + PVOID IST7; + ULONG64 Reserved2; + USHORT Reserved3; + USHORT IOMapBaseAddress; +} TSS64, +*PTSS64; + +typedef struct _SEG_DESCRIPTOR +{ + unsigned LimitLo :16; + unsigned BaseLo :16; + unsigned BaseMid :8; + unsigned Type :4; + unsigned System :1; + unsigned DPL :2; + unsigned Present :1; + unsigned LimitHi :4; + unsigned AVL :1; + unsigned L :1; + unsigned DB :1; + unsigned Gran :1; // Granularity + unsigned BaseHi :8; + +} SEG_DESCRIPTOR; + +enum SEGREGS +{ + ES = 0, + CS, + SS, + DS, + FS, + GS, + LDTR, + TR +}; + +typedef struct _DEBUG_DR6_ +{ + unsigned B0 : 1;//Dr0ϵ + unsigned B1 : 1;//Dr1ϵ + unsigned B2 : 1;//Dr2ϵ + unsigned B3 : 1;//Dr3ϵ + unsigned Reverted : 9; + unsigned BD : 1;//DEBUGĴ#DB쳣 + unsigned BS : 1;//е#DB쳣 + unsigned BT : 1;//TASK switch л#DB쳣 + unsigned Reverted2 : 16; +}DEBUG_DR6, *PDEBUG_DR6; + +typedef struct _DEBUG_DR7_ +{ + + unsigned L0 : 1; //0 DR0ϵ#DB + unsigned G0 : 1; //1 + unsigned L1 : 1; //2 DR1ϵ#DB + unsigned G1 : 1; //3 + unsigned L2 : 1; //4 DR2ϵ#DB + unsigned G2 : 1; //5 + unsigned L3 : 1; //6 DR3ϵ#DB + unsigned G3 : 1; //7 + unsigned LE : 1; //8 + unsigned GE : 1; //9 + unsigned reserved : 3; //001 //10-11-12 + unsigned GD : 1; //13...DEBUGĴʲ#DB쳣 + unsigned reserved2 : 2; //00 + unsigned RW0 : 2;//DR0 00Bִжϵ 01Bдϵ 10B IO/дϵ11B /дϵ + unsigned LEN0 : 2;//DR0ֽڳ 00Bһֽ 01B WORD 10B QWORD 11B DWORD + unsigned RW1 : 2;//DR1 + unsigned LEN1 : 2;//DR1ֽڳ + unsigned RW2 : 2;//DR2 + unsigned LEN2 : 2;//DR2ֽڳ + unsigned RW3 : 2;//DR3 + unsigned LEN3 : 2;//DR3ֽڳ + +}DEBUG_DR7, *PDEBUG_DR7; + +typedef struct _INTERRUPT_INJECT_INFO_FIELD{ + unsigned Vector : 8; + unsigned InterruptionType : 3; + unsigned DeliverErrorCode : 1; + unsigned Reserved : 19; + unsigned Valid : 1; +} INTERRUPT_INJECT_INFO_FIELD, *PINTERRUPT_INJECT_INFO_FIELD; + +typedef struct _INTERRUPT_IBILITY_INFO { + unsigned STI : 1; + unsigned MOV_SS : 1; + unsigned SMI : 1; + unsigned NMI : 1; + unsigned Reserved : 27; +} INTERRUPT_IBILITY_INFO, *PINTERRUPT_IBILITY_INFO; + + +#define DIVIDE_ERROR_EXCEPTION 0 +#define DEBUG_EXCEPTION 1 +#define NMI_INTERRUPT 2 +#define BREAKPOINT_EXCEPTION 3 +#define OVERFLOW_EXCEPTION 4 +#define BOUND_EXCEPTION 5 +#define INVALID_OPCODE_EXCEPTION 6 +#define DEVICE_NOT_AVAILABLE_EXCEPTION 7 +#define DOUBLE_FAULT_EXCEPTION 8 +#define COPROCESSOR_SEGMENT_OVERRUN 9 +#define INVALID_TSS_EXCEPTION 10 +#define SEGMENT_NOT_PRESENT 11 +#define STACK_FAULT_EXCEPTION 12 +#define GENERAL_PROTECTION_EXCEPTION 13 +#define PAGE_FAULT_EXCEPTION 14 +#define X87_FLOATING_POINT_ERROR 16 +#define ALIGNMENT_CHECK_EXCEPTION 17 +//#define MACHINE_CHECK_EXCEPTION 18 +#define SIMD_FLOATING_POINT_EXCEPTION 19 + +#define EXTERNAL_INTERRUPT 0 +#define HARDWARE_EXCEPTION 3 +#define SOFTWARE_INTERRUPT 4 +#define PRIVILEGED_SOFTWARE_EXCEPTION 5 +#define SOFTWARE_EXCEPTION 6 +#define OTHER_EVENT 7 + +typedef struct _INTERRUPT_INFO_FIELD { + unsigned Vector : 8; + unsigned InterruptionType : 3; + unsigned ErrorCodeValid : 1; + unsigned NMIUnblocking : 1; + unsigned Reserved : 18; + unsigned Valid : 1; +} INTERRUPT_INFO_FIELD, *PINTERRUPT_INFO_FIELD; + +typedef struct +{ + USHORT limit0; + USHORT base0; + UCHAR base1; + UCHAR attr0; + UCHAR limit1attr1; + UCHAR base2; +} SEGMENT_DESCRIPTOR2, *PSEGMENT_DESCRIPTOR2; + + +ULONG NTAPI VmxAdjustControls( + ULONG64 Ctl, + ULONG64 Msr + ); + +NTSTATUS FillGuestSelectorData(ULONG64 GdtBase, ULONG Segreg, USHORT Selector); + +NTSTATUS InitializeSegmentSelector( PSEGMENT_SELECTOR SegmentSelector, USHORT Selector, ULONG64 GdtBase ); \ No newline at end of file diff --git a/PFHook_sys/base/ept.cpp b/PFHook_sys/base/ept.cpp new file mode 100644 index 0000000..db49df0 --- /dev/null +++ b/PFHook_sys/base/ept.cpp @@ -0,0 +1,324 @@ +#include "header.h" +#include "vtsystem.h" +#include "ept.h" +#include "common.h" +#include "vtasm.h" + +#define NUM_PAGES 24 // 24GB内存 注意这里,必须在系统物理内存以下 +#define NUM_MAX_HOOK 256 + +extern VMX_CPU g_VMXCPU[128]; +extern GUEST_REGS g_GuestRegs[128]; +EptPml4Entry* g_pPml4T; +EptPdpteEntry* g_pPdpteTable; +EptPdeEntry* g_pPdeTable[NUM_PAGES]; +EptPteEntry* g_pPteTable[NUM_PAGES][512]; + +EPTHOOKITEM g_EptHookItems[NUM_MAX_HOOK]; +PEPTREWATCHINFO g_EptRewatch[128]; +int g_nEptHookCount = 0; + +EptPml4Entry* EptInitialization() +{ + EptPml4Entry* ept_PML4T; + PHYSICAL_ADDRESS FirstPtePA, FirstPdePA, FirstPdptePA; + ept_PML4T = (EptPml4Entry*)(ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, 'aa')); + RtlZeroMemory(ept_PML4T, PAGE_SIZE); + + EptPdpteEntry* ept_PDPTE = (EptPdpteEntry*)(ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, 'aa')); + RtlZeroMemory(ept_PDPTE, PAGE_SIZE); + FirstPdptePA = MmGetPhysicalAddress(ept_PDPTE); + + ept_PML4T->Read = 1; + ept_PML4T->Write = 1; + ept_PML4T->Execute = 1; + ept_PML4T->PhysAddr = FirstPdptePA.QuadPart >> 12; + g_pPml4T = ept_PML4T; + g_pPdpteTable = ept_PDPTE; + for (ULONG64 a = 0;a < NUM_PAGES;a++) + { + EptPdeEntry* ept_PDE = (EptPdeEntry*)(ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, 'aa')); // 普通模式 + RtlZeroMemory(ept_PDE, PAGE_SIZE); + FirstPdePA = MmGetPhysicalAddress(ept_PDE); + + ept_PDPTE->Read = 1; + ept_PDPTE->Write = 1; + ept_PDPTE->Execute = 1; + ept_PDPTE->PhysAddr = FirstPdePA.QuadPart >> 12; + ept_PDPTE++; + g_pPdeTable[a] = ept_PDE; + + for (int b = 0;b < 512;b++) + { + EptPteEntry* ept_PTE = (EptPteEntry*)(ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, 'aa')); // 普通模式 + g_pPteTable[a][b] = ept_PTE; + RtlZeroMemory(ept_PTE, PAGE_SIZE); + FirstPtePA = MmGetPhysicalAddress(ept_PTE); + + ept_PDE->PhysAddr = FirstPtePA.QuadPart >> 12; + ept_PDE->Read = 1; + ept_PDE->Write = 1; + ept_PDE->Execute = 1; + + ept_PDE++; + + for (int c = 0;c < 512;c++) + { + ept_PTE->PhysAddr = (a*(1 << 30) + b*(1 << 21) + c*(1 << 12)) >> 12; + ept_PTE->Read = 1; + ept_PTE->Write = 1; + ept_PTE->Execute = 1; + ept_PTE->MemoryType = EPT_MEMORY_TYPE_WB; + ept_PTE++; + } + } + } + return ept_PML4T; +} + +BOOLEAN EptReleasePages() +{ + ExFreePoolWithTag(g_pPml4T,'aa'); + ExFreePoolWithTag(g_pPdpteTable,'aa'); + + for (int i = 0;i> 32; + lowPA.QuadPart = lowPA.QuadPart & 0xFFFFF000; + + Page_ID = (lowPA.QuadPart >> 21) * 8 + (highPA.QuadPart * 4 * 0x1000);// 得到页表偏移 + Page_Offset = (lowPA.QuadPart >> 9) & 0xFFF; + + PageFirstPte = (EptPteEntry*)(*(PULONG64)((ULONG64)(g_pPteTable)+Page_ID)); + PagePte = (EptPteEntry*)((ULONG64)PageFirstPte + Page_Offset); + return PagePte; + +} + +void HandleEptViolation() +{ + PHYSICAL_ADDRESS Guest_PA, Guest_LA; + ULONG uGuest_PA_Q, uGuest_PA_Q_H, uGuest_LA_Q; + ULONG64 Exit_Qualification; + PEPT_ATTRIBUTE_PAGE pEpt_Attribute; + EptPteEntry* pPte; + ULONG uCPUID; + ULONG uGuestRIP; + + uCPUID = KeGetCurrentProcessorNumber(); + uGuest_PA_Q = Vmx_VmRead(GUEST_PHYSICAL_ADDRESS); + uGuest_PA_Q_H = Vmx_VmRead(GUEST_PHYSICAL_ADDRESS_HIGH); + uGuest_LA_Q = Vmx_VmRead(GUEST_LINEAR_ADDRESS); + Exit_Qualification = Vmx_VmRead(EXIT_QUALIFICATION); + pEpt_Attribute = (PEPT_ATTRIBUTE_PAGE)&Exit_Qualification; + + Guest_PA.LowPart = uGuest_PA_Q; + Guest_PA.HighPart = uGuest_PA_Q_H; + Guest_LA.QuadPart = uGuest_LA_Q; + + uGuestRIP = Vmx_VmRead(GUEST_RIP); + pPte = EptGetPteAddressByPA(Guest_PA); + if (pEpt_Attribute->Read) + { + // Read Access + } + + if (pEpt_Attribute->Write) + { + // Write Access + } + + if (pEpt_Attribute->Execute) + { + // Execute Access + for (int i = 0;i < g_nEptHookCount;i++) + { + if ((ULONG64)g_EptHookItems[i].pHookedVA == uGuestRIP) + { + if (!g_EptHookItems[i].bDisabled) + { + KdPrint(("From 0x%p to 0x%p.\n", uGuestRIP, g_EptHookItems[i].pJmpVA)); + Vmx_VmWrite(GUEST_RIP, (ULONG64)g_EptHookItems[i].pJmpVA); + } + g_EptHookItems[i].nHitCount++; + } + if (g_EptHookItems[i].pPte == pPte) + { + g_EptRewatch[uCPUID] = SetRewathInfo(pPte, g_EptHookItems[i].pOldPte, (PVOID64)Guest_PA.QuadPart); + } + + } + } + + + pPte->Read = 1; + pPte->Write = 1; + pPte->Execute = 1; + + EptInvept(); + EnableMTF(); +} + +void HandleEptMisconfig() +{ + PHYSICAL_ADDRESS Guest_PA, Guest_LA; + ULONG uGuest_PA_Q, uGuest_LA_Q; + ULONG64 Exit_Qualification; + PEPT_ATTRIBUTE_PAGE pEpt_Attribute; + ULONG uCPUID; + // 如果程序运行到了这里,则说明ept表填写错误 + + uCPUID = KeGetCurrentProcessorNumber(); + uGuest_PA_Q = Vmx_VmRead(GUEST_PHYSICAL_ADDRESS); + uGuest_LA_Q = Vmx_VmRead(GUEST_LINEAR_ADDRESS); + Exit_Qualification = Vmx_VmRead(EXIT_QUALIFICATION); + + pEpt_Attribute = (PEPT_ATTRIBUTE_PAGE)&Exit_Qualification; + Guest_PA.QuadPart = uGuest_PA_Q; + Guest_LA.QuadPart = uGuest_LA_Q; + + KeBugCheck(0x12345678); +} + +void HandleMTF() +{ + ULONG64 GuestRip = Vmx_VmRead(GUEST_RIP); + ULONG64 GuestRsp = Vmx_VmRead(GUEST_RSP); // [rsp+8]储存有上一个地址 + + EPTREWATCHINFO RewatchInfo; + ULONG uCPUID = KeGetCurrentProcessorNumber(); + + if (g_EptRewatch[uCPUID] == NULL) + return; + + RewatchInfo = *(g_EptRewatch[uCPUID]); + *(RewatchInfo.pPte) = RewatchInfo.pOldPte; + EptInvept(); + + ExFreePoolWithTag(g_EptRewatch[uCPUID], 'info'); + g_EptRewatch[uCPUID] = NULL; + + DisableMTF(); +} + +void EptInvept() +{ + ULONG uCPUID; + uCPUID = KeGetCurrentProcessorNumber(); + EptTablePointer EPTP = { 0 }; + PHYSICAL_ADDRESS phys = MmGetPhysicalAddress((void *)g_VMXCPU[uCPUID].ept_PML4T); + + // Set up the EPTP + EPTP.Bits.PhysAddr = phys.QuadPart >> 12; + EPTP.Bits.PageWalkLength = 3; + + Vmx_Invept((PVOID)&EPTP, 2); +} + +PVOID EptAllocateNewPage() +{ + PVOID pPage; + pPage = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, 0); + if (!pPage) + return NULL; + RtlZeroMemory(pPage, PAGE_SIZE); + return pPage; +} + +void EnableMTF() +{ + ULONG64 uCPUBase; + uCPUBase = Vmx_VmRead(CPU_BASED_VM_EXEC_CONTROL); + uCPUBase |= CPU_BASED_MTF_TRAP_EXITING; + Vmx_VmWrite(CPU_BASED_VM_EXEC_CONTROL, uCPUBase); +} + +void DisableMTF() +{ + ULONG64 uCPUBase; + uCPUBase = Vmx_VmRead(CPU_BASED_VM_EXEC_CONTROL); + uCPUBase &= ~CPU_BASED_MTF_TRAP_EXITING; + Vmx_VmWrite(CPU_BASED_VM_EXEC_CONTROL, uCPUBase); +} + +VOID EnableTF()//开启TF单步调试功能 +{ + ULONG64 uTemp64; + _EFLAGS* Rflags; + uTemp64 = Vmx_VmRead(GUEST_RFLAGS); + Rflags = (_EFLAGS*)&uTemp64; + + Rflags->TF = 1; + Vmx_VmWrite(GUEST_RFLAGS, uTemp64); + +} + + +VOID DisableTF()//关闭TF单步调试功能 +{ + ULONG64 uTemp64; + _EFLAGS* Rflags; + uTemp64 = Vmx_VmRead(GUEST_RFLAGS); + Rflags = (_EFLAGS*)&uTemp64; + + Rflags->TF = 0; + Vmx_VmWrite(GUEST_RFLAGS, uTemp64); +} + +int AddEPTHookItem(IN PEPTHOOKITEM pItem) +{ + if (g_nEptHookCount > NUM_MAX_HOOK) + return -1; + + pItem->pPte->Execute = 0; + + pItem->pOldPte = *pItem->pPte; + pItem->bDisabled = FALSE; + + g_EptHookItems[g_nEptHookCount] = *pItem; + + g_nEptHookCount++; + return g_nEptHookCount - 1; +} + +BOOLEAN RemoveEPTHookItem(IN int uItemID) +{ + EptPteEntry* pPte; + if (g_nEptHookCount == 0) + return FALSE; + + pPte = g_EptHookItems[uItemID].pPte; + g_EptHookItems[uItemID].bDisabled = TRUE; + return TRUE; +} + +PEPTREWATCHINFO SetRewathInfo(IN EptPteEntry* pPte,IN EptPteEntry pOldPte,IN PVOID64 pContext) +{ + PEPTREWATCHINFO pInfo = (PEPTREWATCHINFO)ExAllocatePoolWithTag(NonPagedPool, sizeof(EPTREWATCHINFO),'info'); + if (pInfo == NULL) + return NULL; + RtlZeroMemory(pInfo, sizeof(EPTREWATCHINFO)); + + pInfo->pPte = pPte; + pInfo->pOldPte = pOldPte; + pInfo->pContext = pContext; + + return pInfo; +} \ No newline at end of file diff --git a/PFHook_sys/base/ept.h b/PFHook_sys/base/ept.h new file mode 100644 index 0000000..2d128b5 --- /dev/null +++ b/PFHook_sys/base/ept.h @@ -0,0 +1,210 @@ +/** +@file +Header which defines structures for handling EPT translations + +@date 1/17/2012 +***************************************************************/ + +#ifndef _MORE_EPT_H_ +#define _MORE_EPT_H_ + + +#define PML4_BASE 0xFFFFF6FB7DBED000 +#define PDP_BASE 0xFFFFF6FB7DA00000 +#define PD_BASE 0xFFFFF6FB40000000 +#define PT_BASE 0xFFFFF68000000000 + +#pragma pack(push, ept, 1) +struct EptTablePointer_s +{ + + ULONG64 MemoryType : 3;//2 + ULONG64 PageWalkLength : 3;//5 + ULONG64 D : 1;//6 + ULONG64 reserved : 5;//11 + ULONG64 PhysAddr : 28;//39 + ULONG64 reserved2 : 24;//63 +}; + +union EptTablePointer_u +{ + ULONG64 unsignedVal; + struct EptTablePointer_s Bits; +}; + +typedef union EptTablePointer_u EptTablePointer; + +struct EptPml4Entry_s +{ + ULONG64 Read : 1; // If the 512 GB region is Read (read access) + ULONG64 Write : 1; // If the 512 GB region is writable + ULONG64 Execute : 1; // If the 512 GB region is executable + ULONG64 reserved1 : 9; // Reserved + ULONG64 PhysAddr : 28; // Physical address + ULONG64 reserved2 : 24; // Reserved +}; + +typedef struct EptPml4Entry_s EptPml4Entry; + +struct EptPdpteEntry_s +{ + ULONG64 Read : 1; // If the 1 GB region is Read (read access) + ULONG64 Write : 1; // If the 1 GB region is writable + ULONG64 Execute : 1; // If the 1 GB region is executable + ULONG64 reserved1 : 9; // Reserved + ULONG64 PhysAddr : 28; // Physical address + ULONG64 reserved2 : 24; // Reserved +}; + +typedef struct EptPdpteEntry_s EptPdpteEntry; + +struct EptPdeEntry_s +{ + ULONG64 Read : 1; // If the 2 MB region is Read (read access) + ULONG64 Write : 1; // If the 2 MB region is writable + ULONG64 Execute : 1; // If the 2 MB region is executable + ULONG64 reserved1 : 9; // Reserved + ULONG64 PhysAddr : 28; // Physical address + ULONG64 reserved2 : 24; // Reserved +}; + +typedef struct EptPdeEntry_s EptPdeEntry; + +struct EptPteEntry_s +{ + ULONG64 Read : 1; // If the 1 GB region is Read (read access) + ULONG64 Write : 1; // If the 1 GB region is writable + ULONG64 Execute : 1; // If the 1 GB region is executable + ULONG64 MemoryType : 3; // EPT Memory type + ULONG64 IgnorePat : 1; // Flag for whether to ignore PAT + ULONGLONG LargePage : 1;//7ҳߴλ + ULONGLONG Accessed : 1;//// 8״̬ ҳδ/д=0 ҳѱ/д=1 + + ULONGLONG Dirty : 1;//// 9ҳ״̬ ҳδĶ=0 ҳѱĶ=1 + + ULONGLONG reserved1 : 2;//11 + ULONG64 PhysAddr : 28; // Physical address + ULONG64 reserved2 : 24; // Reserved +}; + +typedef struct EptPteEntry_s EptPteEntry; + +typedef struct _EPT_ATTRIBUTE_PAE { + ULONGLONG Read : 1; //0 + ULONGLONG Write : 1; //1д + ULONGLONG Execute : 1; //2ִ + ULONGLONG ReadAble : 1; //3Ϊ1ʱʾGPAɶ + ULONGLONG WriteAble : 1; //4Ϊ1ʱʾGPAд + ULONGLONG ExecuteAble : 1;//5Ϊ1ʱʾGPAִ + ULONGLONG reserved : 1;//// 6 + ULONGLONG Valid : 1;//Ϊ1ʱ 7һԵַ + ULONGLONG TranSlation : 1;////8Ϊ1ʱEPT VIOLATIONGPAתHPA Ϊ0ڶguest paging-stuctureַʻ + ULONGLONG reserved2 : 1;//9 Ϊ0 + ULONGLONG NMIunblocking : 1;//10Ϊ1ִIRETָNMIѾ + ULONGLONG reserved3 : 1;//11 + ULONGLONG reserved4 : 13;//23:11 + ULONGLONG GET_PTE : 1;//24 + ULONGLONG GET_PAGE_FRAME : 1;//25 + ULONGLONG FIX_ACCESS : 1;//26Ϊ1ʱ access ringht޸ + ULONGLONG FIX_MISCONF : 1;//27Ϊ1ʱ misconfiguration޸ + ULONGLONG FIX_FIXING : 1;//28Ϊ1ʱ ޸ Ϊ0ӳ + ULONGLONG EPT_FORCE : 1;//29Ϊ1ʱ ǿƽӳ + ULONGLONG reserved5 : 1; +} EPT_ATTRIBUTE_PAGE, *PEPT_ATTRIBUTE_PAGE; +#pragma pack(pop, ept) + +#pragma pack(push,1) +typedef struct _EPTREWATCHINFO +{ + EptPteEntry* pPte; + EptPteEntry pOldPte; + PVOID pHookedAddress; + PVOID pJmpAddress; + PVOID64 pContext; +}EPTREWATCHINFO,*PEPTREWATCHINFO; +#pragma pack(pop) +typedef struct _EPTHOOKITEM +{ + EptPteEntry* pPte; + EptPteEntry pOldPte; + + PVOID pHookedVA; + PVOID pJmpVA; + PHYSICAL_ADDRESS pPA; + + BOOLEAN bDisabled; + ULONG64 nHitCount; + char szName[100]; +}EPTHOOKITEM,*PEPTHOOKITEM; + +/** Intel-defined EPT memory types */ +enum EPT_MEMORY_TYPE_E +{ + EPT_MEMORY_TYPE_UC = 0, + EPT_MEMORY_TYPE_WC = 1, + EPT_MEMORY_TYPE_WT = 4, + EPT_MEMORY_TYPE_WP = 5, + EPT_MEMORY_TYPE_WB = 6, +}; + +typedef enum EPT_MEMORY_TYPE_E EPT_MEMORY_TYPE; + +/** Boolean for whether or not to split the TLB */ +#define SPLIT_TLB 1 +/** Maximum addressing width for the processor */ +#define PHYSICAL_ADDRESS_WIDTH 36 +/** Guest VPID value (must be non-zero) */ +#define VM_VPID 1 + +/** Number of pages to pre-allocate for later use */ +#define NUM_PAGES_ALLOC 1024 + + +// Defines for parsing the EPT violation exit qualification +/** Bitmask for data read violation */ +#define EPT_MASK_DATA_READ 0x1 +/** Bitmask for data write violation */ +#define EPT_MASK_DATA_WRITE (1 << 1) +/** Bitmask for data execute violation */ +#define EPT_MASK_DATA_EXEC (1 << 2) +/** Bitmask for if the guest linear address is valid */ +#define EPT_MASK_GUEST_LINEAR_VALID (1 << 7) + +#endif + +// This function can load our ept page system. +EptPml4Entry* EptInitialization(); + +// Release All EPT Pages +BOOLEAN EptReleasePages(); + +// We can get a physcial address with a PA +// If it is a usermode address,please change the cr3 and then MmGetPhysicalAddress to get its PA +EptPteEntry* EptGetPteAddressByPA(IN PHYSICAL_ADDRESS PA); + +PVOID EptAllocateNewPage(); + +// To refresh the ept page +void EptInvept(); + +// Handle EPT Violation Event +void HandleEptViolation(); +// Handle EPT Misconfig Event(remark:If it hit this function,it means that the PML4T is error.) +void HandleEptMisconfig(); +// Handle MTF to rewat +void HandleMTF(); + +void EnableMTF(); +void DisableMTF(); + +VOID EnableTF(); +VOID DisableTF(); + +// Add a EPTHook Item +int AddEPTHookItem(IN PEPTHOOKITEM pItem); + +// Remove a EPTHook Item +BOOLEAN RemoveEPTHookItem(IN int uItemID); + +// Set Rewatch Information +PEPTREWATCHINFO SetRewathInfo(IN EptPteEntry* pPte, IN EptPteEntry pOldPte, IN PVOID64 pContext); diff --git a/PFHook_sys/base/exithandler.h b/PFHook_sys/base/exithandler.h new file mode 100644 index 0000000..ebe6f8d --- /dev/null +++ b/PFHook_sys/base/exithandler.h @@ -0,0 +1,713 @@ +#pragma once +#include "common.h" +#include "ept.h" +#include "global.h" +GUEST_REGS g_GuestRegs[128]; +extern VMX_CPU g_VMXCPU[128]; + +void HandleCPUID() +{ + ULONG64 uCPUID; + uCPUID = KeGetCurrentProcessorNumber(); + if (g_GuestRegs[uCPUID].rax == 'Mini') + { + g_GuestRegs[uCPUID].rbx = 0x88888888; + g_GuestRegs[uCPUID].rcx = 0x11111111; + g_GuestRegs[uCPUID].rdx = 0x12345678; + } + if (g_GuestRegs[uCPUID].rax == PFHOOK_CODE_HOOK) + { + HandleEvent_Hook(&g_GuestRegs[uCPUID]); + } + else if (g_GuestRegs[uCPUID].rax == PFHOOK_CODE_UNHOOK) + { + HandleEvent_Unhook(&g_GuestRegs[uCPUID]); + } + else if (g_GuestRegs[uCPUID].rax == PFHOOK_CODE_CHECKVT) + { + HandleEvent_CheckVT(&g_GuestRegs[uCPUID]); + } + else Asm_CPUID(g_GuestRegs[uCPUID].rax,&g_GuestRegs[uCPUID].rax,&g_GuestRegs[uCPUID].rbx,&g_GuestRegs[uCPUID].rcx,&g_GuestRegs[uCPUID].rdx); +} + +void HandleInvd() +{ + Asm_Invd(); +} + +void HandleVmCall() +{ + ULONG64 JmpEIP; + ULONG64 uCPUID; + uCPUID = KeGetCurrentProcessorNumber(); + if (g_GuestRegs[uCPUID].rax == 'SVT') + { + JmpEIP = g_GuestRegs[uCPUID].rip + Vmx_VmRead(VM_EXIT_INSTRUCTION_LEN); + Vmx_VmxOff(); + Asm_AfterVMXOff(g_GuestRegs[uCPUID].rsp,JmpEIP); + } +} + +void HandleMsrRead() +{ + ULONG64 uCPUID; + uCPUID = KeGetCurrentProcessorNumber(); + switch(g_GuestRegs[uCPUID].rcx) + { + case MSR_IA32_SYSENTER_CS: + { + g_GuestRegs[uCPUID].rax = Vmx_VmRead(GUEST_SYSENTER_CS) & 0xFFFFFFFF; + g_GuestRegs[uCPUID].rdx = Vmx_VmRead(GUEST_SYSENTER_CS) >> 32; + break; + } + case MSR_IA32_SYSENTER_ESP: + { + g_GuestRegs[uCPUID].rax = Vmx_VmRead(GUEST_SYSENTER_ESP) & 0xFFFFFFFF; + g_GuestRegs[uCPUID].rdx = Vmx_VmRead(GUEST_SYSENTER_ESP) >> 32; + break; + } + case MSR_IA32_SYSENTER_EIP: // KiFastCallEntry + { + g_GuestRegs[uCPUID].rax = Vmx_VmRead(GUEST_SYSENTER_EIP) & 0xFFFFFFFF; + g_GuestRegs[uCPUID].rdx = Vmx_VmRead(GUEST_SYSENTER_EIP) >> 32; + break; + } + case MSR_FS_BASE: + { + g_GuestRegs[uCPUID].rax = Vmx_VmRead(GUEST_FS_BASE) & 0xFFFFFFFF; + g_GuestRegs[uCPUID].rdx = Vmx_VmRead(GUEST_FS_BASE) >> 32; + break; + } + case MSR_GS_BASE: + { + g_GuestRegs[uCPUID].rax = Vmx_VmRead(GUEST_GS_BASE) & 0xFFFFFFFF; + g_GuestRegs[uCPUID].rdx = Vmx_VmRead(GUEST_GS_BASE) >> 32; + break; + } + case MSR_EFER: + { + g_GuestRegs[uCPUID].rax = Asm_ReadMsr(MSR_EFER) & 0xFFFFFFFF; + g_GuestRegs[uCPUID].rdx = Asm_ReadMsr(MSR_EFER) >> 32; + break; + } + case MSR_SHADOW_GS_BASE: + { + g_GuestRegs[uCPUID].rax = Asm_ReadMsr(MSR_SHADOW_GS_BASE) & 0xFFFFFFFF; + g_GuestRegs[uCPUID].rdx = Asm_ReadMsr(MSR_SHADOW_GS_BASE) >> 32; + break; + } + default: + g_GuestRegs[uCPUID].rax = Asm_ReadMsr(g_GuestRegs[uCPUID].rcx) & 0xFFFFFFFF; + g_GuestRegs[uCPUID].rdx = Asm_ReadMsr(g_GuestRegs[uCPUID].rcx) >> 32; + } + +} + +void HandleMsrWrite() +{ + ULONG64 uCPUID; + ULONG64 uMsr; + uCPUID = KeGetCurrentProcessorNumber(); + uMsr = (g_GuestRegs[uCPUID].rax & 0xFFFFFFFF) | (g_GuestRegs[uCPUID].rdx << 32); + switch(g_GuestRegs[uCPUID].rcx) + { + case MSR_IA32_SYSENTER_CS: + { + Vmx_VmWrite(GUEST_SYSENTER_CS,uMsr); + break; + } + case MSR_IA32_SYSENTER_ESP: + { + Vmx_VmWrite(GUEST_SYSENTER_ESP, uMsr); + break; + } + case MSR_IA32_SYSENTER_EIP: // KiFastCallEntry + { + Vmx_VmWrite(GUEST_SYSENTER_EIP, uMsr); + break; + } + case MSR_FS_BASE: + { + Vmx_VmWrite(GUEST_FS_BASE, uMsr); + break; + } + case MSR_GS_BASE: + { + Vmx_VmWrite(GUEST_GS_BASE, uMsr); + break; + } + case MSR_EFER: + { + Asm_WriteMsr(MSR_EFER, uMsr | EFER_LME); + break; + } + case MSR_SHADOW_GS_BASE: + { + Asm_WriteMsr(g_GuestRegs[uCPUID].rcx, uMsr); + break; + } + default: + Asm_WriteMsr(g_GuestRegs[uCPUID].rcx, uMsr); + } +} + +void HandleCrAccess() +{ + ULONG64 movcrControlRegister; + ULONG64 movcrAccessType; + ULONG64 movcrOperandType; + ULONG64 movcrGeneralPurposeRegister; + ULONG64 ExitQualification; + ULONG64 uCPUID; + uCPUID = KeGetCurrentProcessorNumber(); + + ExitQualification = Vmx_VmRead(EXIT_QUALIFICATION) ; + movcrControlRegister = ( ExitQualification & 0x0000000F ); + movcrAccessType = ( ( ExitQualification & 0x00000030 ) >> 4 ); + movcrOperandType = ( ( ExitQualification & 0x00000040 ) >> 6 ); + movcrGeneralPurposeRegister = ( ( ExitQualification & 0x00000F00 ) >> 8 ); + if (movcrOperandType == 0) + { + if (movcrControlRegister == 3) + { + if (movcrAccessType == 0) // дCR3 + { + switch (movcrGeneralPurposeRegister) + { + case 0: + { + Vmx_VmWrite(GUEST_CR3, g_GuestRegs[uCPUID].rax); + break; + } + case 1: + { + Vmx_VmWrite(GUEST_CR3, g_GuestRegs[uCPUID].rcx); + break; + } + case 2: + { + Vmx_VmWrite(GUEST_CR3, g_GuestRegs[uCPUID].rdx); + break; + } + case 3: + { + Vmx_VmWrite(GUEST_CR3, g_GuestRegs[uCPUID].rbx); + break; + } + case 4: + { + Vmx_VmWrite(GUEST_CR3, g_GuestRegs[uCPUID].rsp); + break; + } + case 5: + { + Vmx_VmWrite(GUEST_CR3, g_GuestRegs[uCPUID].rbp); + break; + } + case 6: + { + Vmx_VmWrite(GUEST_CR3, g_GuestRegs[uCPUID].rsi); + break; + } + case 7: + { + Vmx_VmWrite(GUEST_CR3, g_GuestRegs[uCPUID].rdi); + break; + } + default: + break; + } + } + } + else if (movcrAccessType == 1) + { + switch (movcrGeneralPurposeRegister) + { + case 0: + { + g_GuestRegs[uCPUID].rax = g_GuestRegs[uCPUID].cr3; + break; + } + case 1: + { + g_GuestRegs[uCPUID].rcx = g_GuestRegs[uCPUID].cr3; + break; + } + case 2: + { + g_GuestRegs[uCPUID].rdx = g_GuestRegs[uCPUID].cr3; + break; + } + case 3: + { + g_GuestRegs[uCPUID].rbx = g_GuestRegs[uCPUID].cr3; + break; + } + case 4: + { + g_GuestRegs[uCPUID].rsp = g_GuestRegs[uCPUID].cr3; + break; + } + case 5: + { + g_GuestRegs[uCPUID].rbp = g_GuestRegs[uCPUID].cr3; + break; + } + case 6: + { + g_GuestRegs[uCPUID].rsi = g_GuestRegs[uCPUID].cr3; + break; + } + case 7: + { + g_GuestRegs[uCPUID].rdi = g_GuestRegs[uCPUID].cr3; + break; + } + default: + break; + } + } + } + +} + +void HandleRDTSC() +{ + ULONG uCPUID; + uCPUID = KeGetCurrentProcessorNumber(); + Asm_Rdtsc(&g_GuestRegs[uCPUID].rax, &g_GuestRegs[uCPUID].rdx); +} + +// Work for Windows 10 +void HandleRDTSCP() +{ + ULONG uCPUID; + uCPUID = KeGetCurrentProcessorNumber(); + g_GuestRegs[uCPUID].rax = (Asm_GetTSC() & 0xFFFFFFFF); + g_GuestRegs[uCPUID].rdx = (Asm_GetTSC() >> 32); +} + +VOID EventInject(ULONG32 trap) +{ + ULONG32 InjectEvent = (ULONG32)Vmx_VmRead(VM_EXIT_INTR_INFO); + PINTERRUPT_INJECT_INFO_FIELD pInjectEvent = (PINTERRUPT_INJECT_INFO_FIELD)&InjectEvent; + ULONG64 error_code = Vmx_VmRead(VM_EXIT_INTR_ERROR_CODE); + ULONG32 IInfo = (ULONG32)Vmx_VmRead(GUEST_INTERRUPTIBILITY_INFO); + PINTERRUPT_IBILITY_INFO pINTERRUPTIBILITY = (PINTERRUPT_IBILITY_INFO)&IInfo; + //ULONG32 IInfo = (ULONG32)Vmx_VmRead ( GUEST_INTERRUPTIBILITY_INFO ); + //PINTERRUPT_IBILITY_INFO pINTERRUPTIBILITY=(PINTERRUPT_IBILITY_INFO)&IInfo; + + if (trap == TRAP_INT3) + { + InjectEvent = 0; + pInjectEvent->Vector = BREAKPOINT_EXCEPTION; //7-0 + pInjectEvent->InterruptionType = SOFTWARE_EXCEPTION;//10-8 + pInjectEvent->DeliverErrorCode = 0;//11 + pInjectEvent->Reserved = 0;//32-12 + pInjectEvent->Valid = 1;//31 + + } + else if (trap == TRAP_INTO) + { + InjectEvent = 0; + pInjectEvent->Vector = OVERFLOW_EXCEPTION; //7-0 + pInjectEvent->InterruptionType = SOFTWARE_EXCEPTION;//10-8 + pInjectEvent->DeliverErrorCode = 0;//11 + pInjectEvent->Reserved = 0;//32-12 + pInjectEvent->Valid = 1;//31 + + } + else if (trap == TRAP_DEBUG) + { + InjectEvent = 0; + pInjectEvent->Vector = DEBUG_EXCEPTION; //7-0 + pInjectEvent->InterruptionType = HARDWARE_EXCEPTION;//10-8 + pInjectEvent->DeliverErrorCode = 0;//11 + pInjectEvent->Reserved = 0;//32-12 + pInjectEvent->Valid = 1;//31 + + + } + else if (trap == TRAP_PAGE_FAULT) + { + // + // ע#PF + // + + Asm_SetCr2(Vmx_VmRead(EXIT_QUALIFICATION)); + //VmxWrite( VM_ENTRY_EXCEPTION_ERROR_CODE, error_code ); + InjectEvent = 0; + pInjectEvent->Vector = PAGE_FAULT_EXCEPTION; + pInjectEvent->InterruptionType = HARDWARE_EXCEPTION; + pInjectEvent->DeliverErrorCode = 1; + pInjectEvent->Reserved = 0;//32-12 + pInjectEvent->Valid = 1;//31 + + } + else if (trap == TRAP_GP) + { + // + // ע#PF + // + + Asm_SetCr2(Vmx_VmRead(EXIT_QUALIFICATION)); + InjectEvent = 0; + pInjectEvent->Vector = GENERAL_PROTECTION_EXCEPTION; + pInjectEvent->InterruptionType = HARDWARE_EXCEPTION; + pInjectEvent->DeliverErrorCode = 1; + pInjectEvent->Reserved = 0;//32-12 + pInjectEvent->Valid = 1;//31 + + } + else if (trap == TRAP_MTF) + { + pInjectEvent->Vector = DIVIDE_ERROR_EXCEPTION; //7-0 + pInjectEvent->InterruptionType = OTHER_EVENT;//10-8 + pInjectEvent->DeliverErrorCode = 0; + pInjectEvent->Reserved = 0;//32-12 + pInjectEvent->Valid = 1;//31 + pINTERRUPTIBILITY->MOV_SS = 1; + Vmx_VmWrite(GUEST_INTERRUPTIBILITY_INFO, IInfo); + + } + else if (trap == 0x80) + { + pInjectEvent->Vector = 0x80; //7-0 + pInjectEvent->InterruptionType = OTHER_EVENT;//10-8 + pInjectEvent->DeliverErrorCode = 0; + pInjectEvent->Reserved = 0;//32-12 + pInjectEvent->Valid = 1;//31 + + } + + Vmx_VmWrite(VM_ENTRY_INSTRUCTION_LEN, Vmx_VmRead(VM_EXIT_INSTRUCTION_LEN));//Լĵ¼ȻͻῪʼһ + Vmx_VmWrite(VM_ENTRY_INTR_INFO_FIELD, InjectEvent); + + if (error_code != -1) + Vmx_VmWrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code); + + +} + +BOOLEAN DrnReadWriht(ULONG64 Drn, PGUEST_REGS pGuestRegs) +{ + if (pGuestRegs->rax == Drn) + { + return TRUE; + } + if (pGuestRegs->rbx == Drn) + { + return TRUE; + } + if (pGuestRegs->rcx == Drn) + { + return TRUE; + } + if (pGuestRegs->rdx == Drn) + { + return TRUE; + } + if (pGuestRegs->rsp == Drn) + { + return TRUE; + } + if (pGuestRegs->rbp == Drn) + { + return TRUE; + } + if (pGuestRegs->rsi == Drn) + { + return TRUE; + } + if (pGuestRegs->rdi == Drn) + { + return TRUE; + } + if (pGuestRegs->r8 == Drn) + { + return TRUE; + } + if (pGuestRegs->r9 == Drn) + { + return TRUE; + } + if (pGuestRegs->r10 == Drn) + { + return TRUE; + } + if (pGuestRegs->r11 == Drn) + { + return TRUE; + } + if (pGuestRegs->r12 == Drn) + { + return TRUE; + } + if (pGuestRegs->r13 == Drn) + { + return TRUE; + } + if (pGuestRegs->r14 == Drn) + { + return TRUE; + } + if (pGuestRegs->r15 == Drn) + { + return TRUE; + } + return FALSE; +} + +VOID DebugInt1DrnAccess(PGUEST_REGS pGuestRegs) +{ + ULONG64 RegDr0, RegDr1, RegDr2, RegDr3, RegDr6, RegDr7; + ULONG32 DebugDr6, GuestDr7; + PDEBUG_DR6 pRegDr6; + PDEBUG_DR7 pRegDr7; + ULONG64 GuestRip = Vmx_VmRead(GUEST_RIP); + DebugDr6 = (ULONG32)Asm_GetDr6(); + GuestDr7 = (ULONG32)Vmx_VmRead(GUEST_DR7); + pRegDr6 = (PDEBUG_DR6)&DebugDr6; + pRegDr7 = (PDEBUG_DR7)&GuestDr7; + RegDr0 = Asm_GetDr0(); + RegDr1 = Asm_GetDr1(); + RegDr2 = Asm_GetDr2(); + RegDr3 = Asm_GetDr3(); + RegDr6 = Asm_GetDr6(); + RegDr7 = Asm_GetDr7(); + if (GuestRip == RegDr0) + { + if (pRegDr7->L0 || pRegDr7->G0) + { + pRegDr6->B0 = 1; + } + } + else if (GuestRip == RegDr1) + { + if (pRegDr7->L1 || pRegDr7->G1) + { + pRegDr6->B1 = 1; + } + } + else if (GuestRip == RegDr2) + { + if (pRegDr7->L2 || pRegDr7->G2) + { + pRegDr6->B2 = 1; + } + } + else if (GuestRip == RegDr3) + { + if (pRegDr7->L2 || pRegDr7->G2) + { + pRegDr6->B2 = 1; + } + } + else if (DrnReadWriht(RegDr0, pGuestRegs)) + { + if (pRegDr7->L0 || pRegDr7->G0) + { + pRegDr6->B0 = 1; + } + } + else if (DrnReadWriht(RegDr1, pGuestRegs)) + { + if (pRegDr7->L1 || pRegDr7->G1) + { + pRegDr6->B1 = 1; + } + } + else if (DrnReadWriht(RegDr2, pGuestRegs)) + { + if (pRegDr7->L2 || pRegDr7->G2) + { + pRegDr6->B2 = 1; + } + } + else if (DrnReadWriht(RegDr3, pGuestRegs)) + { + if (pRegDr7->L3 || pRegDr7->G3) + { + pRegDr6->B3 = 1; + } + } + else + { + return; + } + pRegDr7->GD = 0; + Asm_SetDr7(GuestDr7); + Asm_SetDr6(DebugDr6); +} + +VOID HandleException() +{ + ULONG32 Event, InjectEvent, DebugDr6, GuestDr7; + ULONG64 ErrorCode, ExitQualification, GuestRip; + PINTERRUPT_INFO_FIELD pEvent; + PINTERRUPT_INJECT_INFO_FIELD pInjectEvent; + PDEBUG_DR6 pRegDr6; + PDEBUG_DR7 pRegDr7; + ULONG64 uCurCPU; + GuestDr7 = (ULONG32)Vmx_VmRead(GUEST_DR7); + pRegDr7 = (PDEBUG_DR7)&GuestDr7; + Event = (ULONG32)Vmx_VmRead(VM_EXIT_INTR_INFO); + pEvent = (PINTERRUPT_INFO_FIELD)&Event; + uCurCPU = KeGetCurrentProcessorNumber(); + + InjectEvent = 0; + pInjectEvent = (PINTERRUPT_INJECT_INFO_FIELD)&InjectEvent; + + GuestRip = Vmx_VmRead(GUEST_RIP); + switch (pEvent->InterruptionType) + { + case NMI_INTERRUPT: + { + InjectEvent = 0; + pInjectEvent->Vector = NMI_INTERRUPT; + pInjectEvent->InterruptionType = NMI_INTERRUPT; + pInjectEvent->DeliverErrorCode = 0; + pInjectEvent->Valid = 1; + Vmx_VmWrite(VM_ENTRY_INTR_INFO_FIELD, InjectEvent); + break; + } + case EXTERNAL_INTERRUPT: + break; + + case HARDWARE_EXCEPTION: + { + switch (pEvent->Vector) + { + case DEBUG_EXCEPTION: + { + DebugInt1DrnAccess(&g_GuestRegs[uCurCPU]); + DebugDr6 = (ULONG32)Asm_GetDr6(); + pRegDr6 = (PDEBUG_DR6)&DebugDr6; + EventInject(TRAP_DEBUG); + break; + } + + + case PAGE_FAULT_EXCEPTION: + { + EventInject(TRAP_PAGE_FAULT); + break; + } + + + default: + break; + } + break; + } + + case SOFTWARE_EXCEPTION: + { + switch (pEvent->Vector) + { + case BREAKPOINT_EXCEPTION: + EventInject(TRAP_INT3); // DzIDTHookҲԼint3ϵ + break; + + case OVERFLOW_EXCEPTION: + break; + default: + break; + } + break; + } + + + default: + break; + } +} + +extern "C" ULONG64 GetGuestRegsAddress() +{ + ULONG64 uCPUID; + uCPUID = KeGetCurrentProcessorNumber(); + return (ULONG64)&g_GuestRegs[uCPUID]; +} + +extern "C" void VMMEntryPoint() +{ + ULONG64 ExitReason; + ULONG64 ExitInstructionLength; + ULONG64 GuestResumeEIP; + ULONG64 uCPUID; + uCPUID = KeGetCurrentProcessorNumber(); + ExitReason = Vmx_VmRead(VM_EXIT_REASON); + ExitInstructionLength = Vmx_VmRead(VM_EXIT_INSTRUCTION_LEN); + + g_GuestRegs[uCPUID].rsp = Vmx_VmRead(GUEST_RSP); + g_GuestRegs[uCPUID].rip = Vmx_VmRead(GUEST_RIP); + g_GuestRegs[uCPUID].cr3 = Vmx_VmRead(GUEST_CR3); + switch (ExitReason) + { + case EXIT_REASON_EXCEPTION_NMI: + { + HandleException(); + return; + } + case EXIT_REASON_TRIPLE_FAULT: + { + break; + } + case EXIT_REASON_CPUID: + { + HandleCPUID(); + break; + } + case EXIT_REASON_INVD: + { + HandleInvd(); + break; + } + case EXIT_REASON_VMCALL: + { + HandleVmCall(); + break; + } + case EXIT_REASON_MSR_READ: + { + HandleMsrRead(); + break; + } + case EXIT_REASON_MSR_WRITE: + { + HandleMsrWrite(); + break; + } + case EXIT_REASON_RDTSC: // 16 + { + HandleRDTSC(); + break; + } + case EXIT_REASON_RDTSCP: // 51 + { + HandleRDTSCP(); + break; + } + case EXIT_REASON_EPT_VIOLATION: + { + HandleEptViolation(); + return; + } + case EXIT_REASON_EPT_MISCONFIG: + { + HandleEptMisconfig(); + return; + } + case EXIT_REASON_MTF_TRAP_FLAG: + { + HandleMTF(); + return; + } + default: + break; + } + GuestResumeEIP = g_GuestRegs[uCPUID].rip+ExitInstructionLength; + Vmx_VmWrite(GUEST_RIP,GuestResumeEIP); + Vmx_VmWrite(GUEST_RSP,g_GuestRegs[uCPUID].rsp); +} \ No newline at end of file diff --git a/PFHook_sys/base/global.cpp b/PFHook_sys/base/global.cpp new file mode 100644 index 0000000..2dae0d5 --- /dev/null +++ b/PFHook_sys/base/global.cpp @@ -0,0 +1,124 @@ +#include "header.h" +#include "global.h" +#include "vtsystem.h" +#include "vtasm.h" +#include "ept.h" + +BOOLEAN HandleEvent_Hook(IN OUT PGUEST_REGS pRegs) +{ + NTSTATUS status = STATUS_SUCCESS; + PEPROCESS proc; + EPTHOOKITEM item; + KAPC_STATE state; + PHYSICAL_ADDRESS pa; + ULONG uCPUID; + ULONG64 uPID, uHookedAddr, uJmpAddr; + int uItemID; + + uCPUID = KeGetCurrentProcessorNumber(); + uPID = pRegs->rbx; + uHookedAddr = pRegs->rcx; + uJmpAddr = pRegs->rdx; + + if (uHookedAddr == 0 || uJmpAddr == 0) + goto Error; + status = PsLookupProcessByProcessId((HANDLE)uPID, &proc); + if (NT_SUCCESS(status)) + { + KeStackAttachProcess(proc, &state); // л̣ܻȡַ + + pa = MmGetPhysicalAddress((PVOID)uHookedAddr); + if (!pa.QuadPart) + goto Error; + + item.pPte = EptGetPteAddressByPA(pa); + if (!item.pPte) + goto Error; + + item.pHookedVA = (PVOID)uHookedAddr; + item.pJmpVA = (PVOID)uJmpAddr; + + uItemID = AddEPTHookItem(&item); + if (uItemID == -1) + goto Error; + + KeUnstackDetachProcess(&state); + + KdPrint(("EPTHook %s[%d] 0x%llX --> 0x%llX\n", PsGetProcessImageFileName(proc), uPID, uHookedAddr, uJmpAddr)); + + pRegs->rsi = uItemID; + return TRUE; + } + +Error: + pRegs->rsi = -1; + return FALSE; +} + +BOOLEAN HandleEvent_Unhook(IN OUT PGUEST_REGS pRegs) +{ + PEPROCESS proc; + NTSTATUS status = STATUS_SUCCESS; + EPTHOOKITEM item; + KAPC_STATE state; + PHYSICAL_ADDRESS pa; + ULONG uCPUID; + ULONG64 uPID, uHookedAddr, uJmpAddr; + int uItemID; + + uCPUID = KeGetCurrentProcessorNumber(); + uItemID = pRegs->rcx; + + if (RemoveEPTHookItem(uItemID)) + { + pRegs->rsi = 1; + return TRUE; + } + +Error: + pRegs->rsi = 0; + return FALSE; +} + +void HandleEvent_CheckVT(IN OUT PGUEST_REGS pRegs) +{ + pRegs->rsi = 1; +} + +// ⲿִǰŪ޺R0 Hookʱд +ULONG64 GetKeServiceDescriptorTable64() +{ + ULONG64 pKiSystemCall64 = Asm_ReadMsr(0xc0000082); + ULONG uOffset; + UCHAR a1, a2, a3; + + for (int i = 0;i <= 0x500;i++) + { + if (MmIsAddressValid((PVOID)(i + pKiSystemCall64)) && MmIsAddressValid((PVOID)(i + pKiSystemCall64 + 1)) && MmIsAddressValid((PVOID)(i + pKiSystemCall64 + 2))) + { + a1 = *((UCHAR*)(i + pKiSystemCall64)); + a2 = *((UCHAR*)(i + 1 + pKiSystemCall64)); + a3 = *((UCHAR*)(i + 2 + pKiSystemCall64)); + if (a1 == 0x4C && a2 == 0x8D && a3 == 0x15) + { + uOffset = *((PULONG)(i + pKiSystemCall64 + 3)); + return i + pKiSystemCall64 + uOffset + 7; + } + } + } + return 0; +} + +ULONG64 GetSSDTFunctionAddr(IN ULONG uID) +{ + PSYSTEM_SERVICE_TABLE pKeServiceDescriptorTable64; + ULONG64 qwTemp; + ULONG dwTemp; + pKeServiceDescriptorTable64 = (PSYSTEM_SERVICE_TABLE)GetKeServiceDescriptorTable64(); + if (!pKeServiceDescriptorTable64) + return 0; + qwTemp = (ULONG64)pKeServiceDescriptorTable64->ServiceTableBase + 4 * uID; + dwTemp = *((PULONG)(qwTemp)); + dwTemp = dwTemp >> 4; + return (ULONG64)pKeServiceDescriptorTable64->ServiceTableBase + dwTemp; +} \ No newline at end of file diff --git a/PFHook_sys/base/global.h b/PFHook_sys/base/global.h new file mode 100644 index 0000000..a7d8f6d --- /dev/null +++ b/PFHook_sys/base/global.h @@ -0,0 +1,29 @@ +#include "vtsystem.h" +// ͨŴ +#define PFHOOK_CODE_CHECKVT 0x800 +#define PFHOOK_CODE_HOOK 0x801 +#define PFHOOK_CODE_UNHOOK 0x802 + +typedef struct _SYSTEM_SERVICE_TABLE { + PVOID ServiceTableBase; + PVOID ServiceCounterTableBase; + ULONGLONG NumberOfServices; + PVOID ParamTableBase; +} SYSTEM_SERVICE_TABLE, *PSYSTEM_SERVICE_TABLE; + +BOOLEAN HandleEvent_Hook(IN OUT PGUEST_REGS pRegs); +BOOLEAN HandleEvent_Unhook(IN OUT PGUEST_REGS pRegs); +void HandleEvent_CheckVT(IN OUT PGUEST_REGS pRegs); + +extern "C" +{ + NTSYSAPI + UCHAR * + NTAPI + PsGetProcessImageFileName( + IN PEPROCESS proc + ); +} + +ULONG64 GetKeServiceDescriptorTable64(); +ULONG64 GetSSDTFunctionAddr(IN ULONG uID); diff --git a/PFHook_sys/base/vtasm.asm b/PFHook_sys/base/vtasm.asm new file mode 100644 index 0000000..4acc290 --- /dev/null +++ b/PFHook_sys/base/vtasm.asm @@ -0,0 +1,563 @@ +GetGuestRegsAddress Proto +VMMEntryPoint Proto +SetupVMCS Proto + +.data +GuestRSP qword ? +GuestReturn qword ? + +EntryRAX qword ? +EntryRCX qword ? +EntryRDX qword ? +EntryRBX qword ? +EntryRSP qword ? +EntryEBP qword ? +EntryESI qword ? +EntryRDI qword ? +EntryR8 qword ? +EntryR9 qword ? +EntryR10 qword ? +EntryR11 qword ? +EntryR12 qword ? +EntryR13 qword ? +EntryR14 qword ? +EntryR15 qword ? +EntryRflags qword ? + +.code + +Asm_CPUID Proc + push rbp + mov rbp, rsp + push rbx + push rsi + + mov [rbp+18h], rdx + mov eax, ecx + cpuid + mov rsi, [rbp+18h] + mov [rsi], eax + mov [r8], ebx + mov [r9], ecx + mov rsi, [rbp+30h] + mov [rsi], edx + + pop rsi + pop rbx + mov rsp, rbp + pop rbp + ret +Asm_CPUID Endp + +Asm_ReadMsr Proc + xor rax,rax + xor rdx,rdx + + rdmsr + shl rdx,32 + or rax,rdx + ret +Asm_ReadMsr Endp + +Asm_WriteMsr Proc + xor rax,rax + + mov eax,edx + shr rdx,32 + wrmsr + ret +Asm_WriteMsr Endp + +Asm_Invd Proc + invd + ret +Asm_Invd Endp + +Asm_GetCs PROC + mov rax, cs + ret +Asm_GetCs ENDP + +Asm_GetDs PROC + mov rax, ds + ret +Asm_GetDs ENDP + +Asm_GetEs PROC + mov rax, es + ret +Asm_GetEs ENDP + +Asm_GetSs PROC + mov rax, ss + ret +Asm_GetSs ENDP + +Asm_GetFs PROC + mov rax, fs + ret +Asm_GetFs ENDP + +Asm_GetGs PROC + mov rax, gs + ret +Asm_GetGs ENDP + + +Asm_GetCr0 Proc + mov rax, cr0 + ret +Asm_GetCr0 Endp + +Asm_GetCr3 Proc + + mov rax, cr3 + ret +Asm_GetCr3 Endp + +Asm_GetCr4 Proc + mov rax, cr4 + ret +Asm_GetCr4 Endp + +Asm_SetCr0 Proc + mov cr0, rcx + ret +Asm_SetCr0 Endp + +Asm_SetCr2 Proc + mov cr2, rcx + ret +Asm_SetCr2 Endp + +Asm_SetCr3 Proc + mov cr3, rcx + ret +Asm_SetCr3 Endp + +Asm_SetCr4 Proc + mov cr4, rcx + ret +Asm_SetCr4 Endp + +Asm_GetDr0 PROC + mov rax, dr0 + ret +Asm_GetDr0 ENDP + +Asm_GetDr1 PROC + mov rax, dr1 + ret +Asm_GetDr1 ENDP + +Asm_GetDr2 PROC + mov rax, dr2 + ret +Asm_GetDr2 ENDP + +Asm_GetDr3 PROC + mov rax, dr3 + ret +Asm_GetDr3 ENDP + +Asm_GetDr6 PROC + mov rax, dr6 + ret +Asm_GetDr6 ENDP + +Asm_GetDr7 PROC + mov rax, dr7 + ret +Asm_GetDr7 ENDP + +Asm_SetDr0 PROC + mov dr0, rcx + ret +Asm_SetDr0 ENDP + +Asm_SetDr1 PROC + mov dr1, rcx + ret +Asm_SetDr1 ENDP + +Asm_SetDr2 PROC + mov dr2, rcx + ret +Asm_SetDr2 ENDP + +Asm_SetDr3 PROC + mov dr3, rcx + ret +Asm_SetDr3 ENDP + +Asm_SetDr6 PROC + mov dr6, rcx + ret +Asm_SetDr6 ENDP + +Asm_SetDr7 PROC + mov dr7, rcx + ret +Asm_SetDr7 ENDP + +Asm_GetRflags PROC + pushfq + pop rax + ret +Asm_GetRflags ENDP + +Asm_GetIdtBase PROC + LOCAL idtr[10]:BYTE + + sidt idtr + mov rax, qword PTR idtr[2] + ret +Asm_GetIdtBase ENDP + +Asm_GetIdtLimit PROC + LOCAL idtr[10]:BYTE + + xor rax,rax + sidt idtr + mov ax, WORD PTR idtr[0] + ret +Asm_GetIdtLimit ENDP + +Asm_GetGdtBase PROC + LOCAL gdtr[10]:BYTE + + sgdt gdtr + mov rax, qword PTR gdtr[2] + ret +Asm_GetGdtBase ENDP + +Asm_GetGdtLimit PROC + LOCAL gdtr[10]:BYTE + + xor rax,rax + sgdt gdtr + mov ax, WORD PTR gdtr[0] + ret +Asm_GetGdtLimit ENDP + +Asm_GetLdtr PROC + sldt rax + ret +Asm_GetLdtr ENDP + +Asm_GetTr PROC + str rax + ret +Asm_GetTr ENDP + +Asm_SetGdtr Proc + push rcx + shl rdx, 16 + push rdx + + lgdt fword ptr [rsp+2] + pop rax + pop rax + ret +Asm_SetGdtr Endp + +Asm_SetIdtr Proc + push rcx + shl rdx, 16 + push rdx + lidt fword ptr [rsp+2] + pop rax + pop rax + ret +Asm_SetIdtr Endp + +Asm_Rdtsc Proc + mov rbx,rcx + mov rsi,rdx + + xor rax,rax + xor rdx,rdx + + rdtsc + mov [rbx],rax + mov [rsi],rdx + ret +Asm_Rdtsc Endp + +Asm_GetTSC PROC +; rdtscp + rdtsc + shl rdx, 32 + or rax, rdx + ret +Asm_GetTSC ENDP + + +Vmx_VmxOn Proc + push rcx + Vmxon qword ptr [rsp] + add rsp,8 + ret +Vmx_VmxOn Endp + +Vmx_VmxOff Proc + Vmxoff + ret +Vmx_VmxOff Endp + +Vmx_VmPtrld Proc + push rcx + vmptrld qword ptr [rsp] + add rsp,8 + ret +Vmx_VmPtrld endp + +Vmx_VmClear Proc + push rcx + vmclear qword ptr [rsp] + add rsp,8 + ret +Vmx_VmClear endp + +Vmx_VmRead Proc + mov rax,rcx + vmread rcx,rax + mov rax,rcx + ret +Vmx_VmRead endp + +Vmx_VmWrite Proc + mov rax,rcx + mov rcx,rdx + vmwrite rax,rcx + ret +Vmx_VmWrite endp + +; CmInvept (PVOID Ep4ta(rcx), ULONG inval (rdx) ); +Vmx_Invept proc + push rbp + mov rbp, rsp + push rsi + mov rsi, rcx + mov rax, rdx + invept rax, xmmword ptr [rsi] + pop rsi + mov rsp, rbp + pop rbp + ret +Vmx_Invept endp + +Vmx_VmCall Proc + push rax + push rcx + push rdx + push rbx + push rsp ;HOST_RSP + push rbp + push rsi + push rdi + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 ;pushaq + + + pushfq + mov rax,rcx + vmcall + + popfq + + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop rdi + pop rsi + pop rbp + pop rsp + pop rbx + pop rdx + pop rcx + pop rax ;popaq + + ret +Vmx_VmCall endp + +Vmx_VmLaunch Proc + vmlaunch + ret +Vmx_VmLaunch endp + +Vmx_VmResume Proc + vmresume + ret +Vmx_VmResume endp + +Asm_GetGuestRSP Proc + mov rax,GuestRSP + ret +Asm_GetGuestRSP Endp + +Asm_GetGuestReturn Proc + mov rax,GuestReturn + ret +Asm_GetGuestReturn Endp + +Asm_AfterVMXOff Proc + mov rsp,rcx + jmp rdx + ret +Asm_AfterVMXOff Endp + +Asm_RunToVMCS Proc + mov rax,[rsp] + mov GuestReturn,rax ;ȡصַvmlaunchͻִصĴ + + call SetupVMCS + ret +Asm_RunToVMCS Endp + +Asm_SetupVMCS Proc + cli + mov GuestRSP,rsp + + mov EntryRAX,rax + mov EntryRCX,rcx + mov EntryRDX,rdx + mov EntryRBX,rbx + mov EntryRSP,rsp + mov EntryEBP,rbp + mov EntryESI,rsi + mov EntryRDI,rdi + mov EntryR8,r8 + mov EntryR9,r9 + mov EntryR10,r10 + mov EntryR11,r11 + mov EntryR12,r12 + mov EntryR13,r13 + mov EntryR14,r14 + mov EntryR15,r15 + + pushfq + pop EntryRflags + + call Asm_RunToVMCS + + push EntryRflags + popfq + mov rax,EntryRAX + mov rcx,EntryRCX + mov rdx,EntryRDX + mov rbx,EntryRBX + mov rsp,EntryRSP + mov rbp,EntryEBP + mov rsi,EntryESI + mov rdi,EntryRDI + mov r8,EntryR8 + mov r9,EntryR9 + mov r10,EntryR10 + mov r11,EntryR11 + mov r12,EntryR12 + mov r13,EntryR13 + mov r14,EntryR14 + mov r15,EntryR15 + + mov rsp,GuestRSP + sti + ret +Asm_SetupVMCS Endp + +Asm_VMMEntryPoint Proc + cli + push rax + push rcx + push rdx + push rbx + push rsp ;HOST_RSP + push rbp + push rsi + push rdi + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + + mov [rsp-1280h],rax + mov [rsp-1288h],rbx + mov [rsp-1290h],rcx + call GetGuestRegsAddress + mov rcx,[rsp-1290h] + mov [rax+8h],rcx + mov [rax+10h],rdx + mov [rax+18h],rbx + mov [rax+20h],rsp + mov [rax+28h],rbp + mov [rax+30h],rsi + mov [rax+38h],rdi + mov [rax+40h],r8 + mov [rax+48h],r9 + mov [rax+50h],r10 + mov [rax+58h],r11 + mov [rax+60h],r12 + mov [rax+68h],r13 + mov [rax+70h],r14 + mov [rax+78h],r15 + mov rbx,[rsp-1280h] + mov [rax],rbx + mov rax,[rsp-1280h] + mov rbx,[rsp-1288h] + + call VMMEntryPoint + + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop rdi + pop rsi + pop rbp + pop rsp + pop rbx + pop rdx + pop rcx + pop rax + + call GetGuestRegsAddress + mov rcx,[rax+8h] + mov rdx,[rax+10h] + mov rbx,[rax+18h] + mov rsp,[rax+20h] + mov rbp,[rax+28h] + mov rsi,[rax+30h] + mov rdi,[rax+38h] + mov r8,[rax+40h] + mov r9,[rax+48h] + mov r10,[rax+50h] + mov r11,[rax+58h] + mov r12,[rax+60h] + mov r13,[rax+68h] + mov r14,[rax+70h] + mov r15,[rax+78h] + mov rax,[rax] + sti + vmresume +Asm_VMMEntryPoint Endp + +END \ No newline at end of file diff --git a/PFHook_sys/base/vtasm.h b/PFHook_sys/base/vtasm.h new file mode 100644 index 0000000..29caf4e --- /dev/null +++ b/PFHook_sys/base/vtasm.h @@ -0,0 +1,191 @@ +/* +Author:Xiaobao +QQ:1121402724 +*/ +#pragma once + +typedef struct +{ + unsigned PE : 1; + unsigned MP : 1; + unsigned EM : 1; + unsigned TS : 1; + unsigned ET : 1; + unsigned NE : 1; + unsigned Reserved_1 : 10; + unsigned WP : 1; + unsigned Reserved_2 : 1; + unsigned AM : 1; + unsigned Reserved_3 : 10; + unsigned NW : 1; + unsigned CD : 1; + unsigned PG : 1; + unsigned Reserved_64 : 32; +}_CR0; + +typedef struct +{ + unsigned VME:1; + unsigned PVI:1; + unsigned TSD:1; + unsigned DE:1; + unsigned PSE:1; + unsigned PAE:1; + unsigned MCE:1; + unsigned PGE:1; + unsigned PCE:1; + unsigned OSFXSR:1; + unsigned PSXMMEXCPT:1; + unsigned UNKONOWN_1:1; //These are zero + unsigned UNKONOWN_2:1; //These are zero + unsigned VMXE:1; //It's zero in normal + unsigned Reserved:18; //These are zero + unsigned Reserved_64 : 32; +}_CR4; + +typedef struct +{ + unsigned CF:1; + unsigned Unknown_1:1; //Always 1 + unsigned PF:1; + unsigned Unknown_2:1; //Always 0 + unsigned AF:1; + unsigned Unknown_3:1; //Always 0 + unsigned ZF:1; + unsigned SF:1; + unsigned TF:1; + unsigned IF:1; + unsigned DF:1; + unsigned OF:1; + unsigned TOPL:2; + unsigned NT:1; + unsigned Unknown_4:1; + unsigned RF:1; + unsigned VM:1; + unsigned AC:1; + unsigned VIF:1; + unsigned VIP:1; + unsigned ID:1; + unsigned Reserved:10; //Always 0 + unsigned Reserved_64:32; //Always 0 +}_EFLAGS; + +typedef struct +{ + unsigned SSE3:1; + unsigned PCLMULQDQ:1; + unsigned DTES64:1; + unsigned MONITOR:1; + unsigned DS_CPL:1; + unsigned VMX:1; + unsigned SMX:1; + unsigned EIST:1; + unsigned TM2:1; + unsigned SSSE3:1; + unsigned Reserved:22; + unsigned Reserved_64:32; +}_CPUID_ECX; + +typedef struct _IA32_FEATURE_CONTROL_MSR +{ + unsigned Lock :1; // Bit 0 is the lock bit - cannot be modified once lock is set + unsigned Reserved1 :1; // Undefined + unsigned EnableVmxon :1; // Bit 2. If this bit is clear, VMXON causes a general protection exception + unsigned Reserved2 :29; // Undefined + unsigned Reserved3 :32; // Undefined + +} IA32_FEATURE_CONTROL_MSR; + +typedef struct _VMX_BASIC_MSR +{ + unsigned RevId: 32;//汾Ϣ + unsigned szVmxOnRegion: 12; + unsigned ClearBit: 1; + unsigned Reserved: 3; + unsigned PhysicalWidth: 1; + unsigned DualMonitor: 1; + unsigned MemoryType: 4; + unsigned VmExitInformation: 1; + unsigned Reserved2: 9; +} VMX_BASIC_MSR, *PVMX_BASIC_MSR; + +extern "C" ULONG64 Asm_GetRflags(); +extern "C" ULONG64 Asm_GetCs(); +extern "C" ULONG64 Asm_GetDs(); +extern "C" ULONG64 Asm_GetEs(); +extern "C" ULONG64 Asm_GetFs(); +extern "C" ULONG64 Asm_GetGs(); +extern "C" ULONG64 Asm_GetSs(); +extern "C" ULONG64 Asm_GetLdtr(); +extern "C" ULONG64 Asm_GetTr(); + +extern "C" void Asm_SetGdtr(ULONG64 uBase,ULONG64 uLimit); +extern "C" void Asm_SetIdtr(ULONG64 uBase,ULONG64 uLimit); + +extern "C" ULONG64 Asm_GetGdtBase(); +extern "C" ULONG64 Asm_GetIdtBase(); +extern "C" ULONG64 Asm_GetGdtLimit(); +extern "C" ULONG64 Asm_GetIdtLimit(); + +extern "C" ULONG64 Asm_GetCr0(); +extern "C" ULONG64 Asm_GetCr2(); +extern "C" ULONG64 Asm_GetCr3(); +extern "C" ULONG64 Asm_GetCr4(); +extern "C" void Asm_SetCr0(ULONG64 uNewCr0); +extern "C" void Asm_SetCr2(ULONG64 uNewCr2); +extern "C" void Asm_SetCr3(ULONG64 uNewCr3); +extern "C" void Asm_SetCr4(ULONG64 uNewCr4); + +extern "C" ULONG64 Asm_GetDr0(); +extern "C" ULONG64 Asm_GetDr1(); +extern "C" ULONG64 Asm_GetDr2(); +extern "C" ULONG64 Asm_GetDr3(); +extern "C" ULONG64 Asm_GetDr6(); +extern "C" ULONG64 Asm_GetDr7(); +extern "C" void Asm_SetDr0(ULONG64 uNewDr0); +extern "C" void Asm_SetDr1(ULONG64 uNewDr1); +extern "C" void Asm_SetDr2(ULONG64 uNewDr2); +extern "C" void Asm_SetDr3(ULONG64 uNewDr3); +extern "C" void Asm_SetDr6(ULONG64 uNewDr6); +extern "C" void Asm_SetDr7(ULONG64 uNewDr7); + +extern "C" ULONG64 Asm_ReadMsr(ULONG64 uIndex); +extern "C" void Asm_WriteMsr(ULONG64 uIndex,ULONG64 QuadPart); + +extern "C" void Asm_CPUID(ULONG64 uFn,PULONG64 uRet_EAX,PULONG64 uRet_EBX,PULONG64 uRet_ECX,PULONG64 uRet_EDX); +extern "C" void Asm_Invd(); +extern "C" void Asm_Rdtsc(PULONG64 uRet_EAX, PULONG64 uRet_EDX); +extern "C" ULONG64 Asm_GetTSC(); + +extern "C" void Vmx_VmxOn(ULONG64 QuadPart); +extern "C" void Vmx_VmxOff(); +extern "C" void Vmx_VmClear(ULONG64 QuadPart); +extern "C" void Vmx_VmPtrld(ULONG64 QuadPart); +extern "C" ULONG64 Vmx_VmRead(ULONG64 uField); +extern "C" void Vmx_VmWrite(ULONG64 uField,ULONG64 uValue); +extern "C" void Vmx_VmLaunch(); +extern "C" void Vmx_VmResume(); +extern "C" void Vmx_VmCall(ULONG64 uCallNumber); +extern "C" void Vmx_Invept(PVOID Ep4ta, ULONG64 inval); + +extern "C" void Asm_VMMEntryPoint(); + +extern "C" void Asm_SetupVMCS(); + +extern "C" ULONG64 Asm_GetGuestReturn(); +extern "C" ULONG64 Asm_GetGuestRSP(); + +extern "C" void Asm_AfterVMXOff(ULONG64 JmpESP,ULONG64 JmpEIP); + +extern "C" void Asm_MyNtOpenProcess(); +extern "C" void Asm_MyNtOpenThread(); +extern "C" void Asm_MyNtCreateUserProcess(); +extern "C" void Asm_MyNtCreateThreadEx(); +extern "C" void Asm_MyNtCreateFile_Win7(); +extern "C" void Asm_MyNtCreateFile_Win10(); +extern "C" void Asm_MyNtLoadDriver(); +extern "C" void Asm_MyNtCreateKey(); +extern "C" void Asm_MyNtQueryKey_Win7(); +extern "C" void Asm_MyNtQueryKey_Win10(); +extern "C" void Asm_MyNtDeleteFile(); +extern "C" void Asm_MyNtReadVirtualMemory(); \ No newline at end of file diff --git a/PFHook_sys/base/vtsystem.cpp b/PFHook_sys/base/vtsystem.cpp new file mode 100644 index 0000000..4fbac3e --- /dev/null +++ b/PFHook_sys/base/vtsystem.cpp @@ -0,0 +1,388 @@ +#include "header.h" +#include "vtsystem.h" +#include "vtasm.h" +#include "exithandler.h" +#include "common.h" +#include "ept.h" + +VMX_CPU g_VMXCPU[128]; + +KMUTEX g_GlobalMutex; +EptPml4Entry* g_Pml4; +NTSTATUS AllocateVMXRegion() +{ + PVOID pVMXONRegion; + PVOID pVMCSRegion; + PVOID pHostEsp; + ULONG64 uCPUID; + + uCPUID = KeGetCurrentProcessorNumber(); + pVMXONRegion = ExAllocatePoolWithTag(NonPagedPool,0x1000,'vmon'); //4KB + if (!pVMXONRegion) + { + return STATUS_MEMORY_NOT_ALLOCATED; + } + RtlZeroMemory(pVMXONRegion,0x1000); + + pVMCSRegion = ExAllocatePoolWithTag(NonPagedPool,0x1000,'vmcs'); + if (!pVMCSRegion) + { + ExFreePoolWithTag(pVMXONRegion,0x1000); + return STATUS_MEMORY_NOT_ALLOCATED; + } + RtlZeroMemory(pVMCSRegion,0x1000); + + pHostEsp = ExAllocatePoolWithTag(NonPagedPool,0x2000,'mini'); + if (!pHostEsp) + { + ExFreePoolWithTag(pVMXONRegion,0x1000); + ExFreePoolWithTag(pVMCSRegion,0x1000); + return STATUS_MEMORY_NOT_ALLOCATED; + } + RtlZeroMemory(pHostEsp,0x2000); + + g_VMXCPU[uCPUID].pVMXONRegion = pVMXONRegion; + g_VMXCPU[uCPUID].pVMXONRegion_PA = MmGetPhysicalAddress(pVMXONRegion); + g_VMXCPU[uCPUID].pVMCSRegion = pVMCSRegion; + g_VMXCPU[uCPUID].pVMCSRegion_PA = MmGetPhysicalAddress(pVMCSRegion); + g_VMXCPU[uCPUID].pHostEsp = pHostEsp; + g_VMXCPU[uCPUID].ept_PML4T = g_Pml4; + return STATUS_SUCCESS; +} + +void SetupVMXRegion() +{ + VMX_BASIC_MSR Msr; + ULONG uRevId; + _CR4 uCr4; + _EFLAGS uEflags; + ULONG64 uCPUID; + + uCPUID = KeGetCurrentProcessorNumber(); + + RtlZeroMemory(&Msr,sizeof(Msr)); + + *((PULONG64)&Msr) = Asm_ReadMsr(MSR_IA32_VMX_BASIC); + uRevId = Msr.RevId; + + *((PULONG)g_VMXCPU[uCPUID].pVMXONRegion) = uRevId; + *((PULONG)g_VMXCPU[uCPUID].pVMCSRegion) = uRevId; + + *((PULONG64)&uCr4) = Asm_GetCr4(); + uCr4.VMXE = 1; + Asm_SetCr4(*((PULONG64)&uCr4)); + + Vmx_VmxOn(g_VMXCPU[uCPUID].pVMXONRegion_PA.QuadPart); + *((PULONG64)&uEflags) = Asm_GetRflags(); + if (uEflags.CF != 0) + { + return; + } +} + +extern "C" void SetupVMCS() +{ + _EFLAGS uEflags; + ULONG64 GdtBase,IdtBase; + SEGMENT_SELECTOR SegmentSelector; + ULONG64 uCPUBase; + ULONG64 uCPUID; + ULONG64 uTemp64; + + uCPUID = KeGetCurrentProcessorNumber(); + + Vmx_VmClear(g_VMXCPU[uCPUID].pVMCSRegion_PA.QuadPart); + *((PULONG64)&uEflags) = Asm_GetRflags(); + if (uEflags.CF != 0 || uEflags.ZF != 0) + { + return; + } + Vmx_VmPtrld(g_VMXCPU[uCPUID].pVMCSRegion_PA.QuadPart); + + GdtBase = Asm_GetGdtBase(); + IdtBase = Asm_GetIdtBase(); + + // + // 1.Guest State Area + // + Vmx_VmWrite(GUEST_CR0,Asm_GetCr0()); + Vmx_VmWrite(GUEST_CR3,Asm_GetCr3()); + Vmx_VmWrite(GUEST_CR4,Asm_GetCr4()); + + Vmx_VmWrite(GUEST_DR7,0x400); + Vmx_VmWrite(GUEST_RFLAGS,Asm_GetRflags()); + + FillGuestSelectorData(GdtBase,ES,Asm_GetEs()); + FillGuestSelectorData(GdtBase,FS,Asm_GetFs()); + FillGuestSelectorData(GdtBase,DS,Asm_GetDs()); + FillGuestSelectorData(GdtBase,CS,Asm_GetCs()); + FillGuestSelectorData(GdtBase,SS,Asm_GetSs()); + FillGuestSelectorData(GdtBase,GS,Asm_GetGs()); + FillGuestSelectorData(GdtBase,TR,Asm_GetTr()); + FillGuestSelectorData(GdtBase,LDTR,Asm_GetLdtr()); + + Vmx_VmWrite(GUEST_CS_BASE,0); + Vmx_VmWrite(GUEST_DS_BASE,0); + Vmx_VmWrite(GUEST_ES_BASE,0); + Vmx_VmWrite(GUEST_SS_BASE,0); + Vmx_VmWrite(GUEST_FS_BASE,Asm_ReadMsr(MSR_FS_BASE)); + Vmx_VmWrite(GUEST_GS_BASE,Asm_ReadMsr(MSR_GS_BASE)); + Vmx_VmWrite(GUEST_GDTR_BASE,GdtBase); + Vmx_VmWrite(GUEST_GDTR_LIMIT,Asm_GetGdtLimit()); + Vmx_VmWrite(GUEST_IDTR_BASE,IdtBase); + Vmx_VmWrite(GUEST_IDTR_LIMIT,Asm_GetIdtLimit()); + + Vmx_VmWrite(GUEST_IA32_DEBUGCTL,Asm_ReadMsr(MSR_IA32_DEBUGCTL)); + Vmx_VmWrite(GUEST_IA32_DEBUGCTL_HIGH,Asm_ReadMsr(MSR_IA32_DEBUGCTL)>>32); + Vmx_VmWrite(GUEST_IA32_EFER,Asm_ReadMsr(MSR_EFER)); + + Vmx_VmWrite(GUEST_SYSENTER_CS,Asm_ReadMsr(MSR_IA32_SYSENTER_CS)); + Vmx_VmWrite(GUEST_SYSENTER_ESP,Asm_ReadMsr(MSR_IA32_SYSENTER_ESP)); + Vmx_VmWrite(GUEST_SYSENTER_EIP,Asm_ReadMsr(MSR_IA32_SYSENTER_EIP)); // KiFastCallEntry + + Vmx_VmWrite(GUEST_RSP,Asm_GetGuestRSP()); + Vmx_VmWrite(GUEST_RIP,Asm_GetGuestReturn());// ָvmlaunchͻڵ ÿͻִмĴ + + Vmx_VmWrite(GUEST_INTERRUPTIBILITY_INFO, 0); + Vmx_VmWrite(GUEST_ACTIVITY_STATE, 0); + Vmx_VmWrite(VMCS_LINK_POINTER, 0xffffffff); + Vmx_VmWrite(VMCS_LINK_POINTER_HIGH, 0xffffffff); + + // + // 2.Host State Area + // + Vmx_VmWrite(HOST_CR0,Asm_GetCr0()); + Vmx_VmWrite(HOST_CR3,Asm_GetCr3()); + Vmx_VmWrite(HOST_CR4,Asm_GetCr4()); + + Vmx_VmWrite(HOST_ES_SELECTOR,KGDT64_R0_DATA); + Vmx_VmWrite(HOST_CS_SELECTOR,KGDT64_R0_CODE); + Vmx_VmWrite(HOST_SS_SELECTOR,KGDT64_R0_DATA); + Vmx_VmWrite(HOST_DS_SELECTOR,KGDT64_R0_DATA); + Vmx_VmWrite(HOST_FS_SELECTOR,(Asm_GetFs()&0xF8)); + Vmx_VmWrite(HOST_GS_SELECTOR,(Asm_GetGs()&0xF8)); + Vmx_VmWrite(HOST_TR_SELECTOR,(Asm_GetTr()&0xF8)); + + Vmx_VmWrite(HOST_FS_BASE,Asm_ReadMsr(MSR_FS_BASE)); + Vmx_VmWrite(HOST_GS_BASE,Asm_ReadMsr(MSR_GS_BASE)); + InitializeSegmentSelector(&SegmentSelector,Asm_GetTr(),GdtBase); + Vmx_VmWrite(HOST_TR_BASE,SegmentSelector.base); + + Vmx_VmWrite(HOST_GDTR_BASE,GdtBase); + Vmx_VmWrite(HOST_IDTR_BASE,IdtBase); + + Vmx_VmWrite(HOST_IA32_EFER,Asm_ReadMsr(MSR_EFER)); + Vmx_VmWrite(HOST_IA32_SYSENTER_CS,Asm_ReadMsr(MSR_IA32_SYSENTER_CS)); + Vmx_VmWrite(HOST_IA32_SYSENTER_ESP,Asm_ReadMsr(MSR_IA32_SYSENTER_ESP)); + Vmx_VmWrite(HOST_IA32_SYSENTER_EIP,Asm_ReadMsr(MSR_IA32_SYSENTER_EIP)); // KiFastCallEntry + + Vmx_VmWrite(HOST_RSP,((ULONG64)g_VMXCPU[uCPUID].pHostEsp) + 0x1FFF);//8KB 0x2000 + Vmx_VmWrite(HOST_RIP,(ULONG64)&Asm_VMMEntryPoint);//ﶨǵVMM + + // + // 3.п + // + Vmx_VmWrite(PIN_BASED_VM_EXEC_CONTROL,VmxAdjustControls(0,MSR_IA32_VMX_PINBASED_CTLS)); + + Vmx_VmWrite(PAGE_FAULT_ERROR_CODE_MASK,0); + Vmx_VmWrite(PAGE_FAULT_ERROR_CODE_MATCH,0); + Vmx_VmWrite(TSC_OFFSET,0); + Vmx_VmWrite(TSC_OFFSET_HIGH,0); + + uCPUBase = VmxAdjustControls(0,MSR_IA32_VMX_PROCBASED_CTLS); + +/* uCPUBase &= ~CPU_BASED_ACTIVATE_MSR_BITMAP;*/ + uCPUBase &= ~CPU_BASED_CR3_LOAD_EXITING; + uCPUBase &= ~CPU_BASED_CR3_STORE_EXITING; + uCPUBase |= CPU_BASED_ACTIVATE_SECONDARY_CONTROLS; +// uCPUBase &= ~CPU_BASED_CR8_LOAD_EXITING; +// uCPUBase &= ~CPU_BASED_CR8_STORE_EXITING; // УȻزTF + uCPUBase |= CPU_BASED_RDTSC_EXITING; + //uCPUBase |= CPU_BASED_MOV_DR_EXITING; // صԼĴ + //uCPUBase |= CPU_BASED_USE_IO_BITMAPS; // ؼϢ + //uCPUBase |= CPU_BASED_ACTIVATE_MSR_BITMAP; // MSR + + Vmx_VmWrite(CPU_BASED_VM_EXEC_CONTROL,uCPUBase); + + uTemp64 = 0; + //ָEPT ڴҳ ڴõ ʱҪ + uTemp64 |= SECONDARY_EXEC_RDTSCP; + uTemp64 |= SECONDARY_EXEC_ENABLE_EPT; + uTemp64 |= SECONDARY_EXEC_ENABLE_VPID; + Vmx_VmWrite(SECONDARY_VM_EXEC_CONTROL, uTemp64); + + Vmx_VmWrite(IO_BITMAP_A,0); + Vmx_VmWrite(IO_BITMAP_A_HIGH,0); + Vmx_VmWrite(IO_BITMAP_B,0); + Vmx_VmWrite(IO_BITMAP_B_HIGH,0); + Vmx_VmWrite(MSR_BITMAP, 0); + Vmx_VmWrite(MSR_BITMAP_HIGH, 0); + + uTemp64 = 0; + uTemp64 |= 1 << DEBUG_EXCEPTION; + uTemp64 |= 1 << PAGE_FAULT_EXCEPTION; + + Vmx_VmWrite(EXCEPTION_BITMAP, uTemp64); + + + Vmx_VmWrite(CR3_TARGET_COUNT,0); + Vmx_VmWrite(CR3_TARGET_VALUE0,0); + Vmx_VmWrite(CR3_TARGET_VALUE1,0); + Vmx_VmWrite(CR3_TARGET_VALUE2,0); + Vmx_VmWrite(CR3_TARGET_VALUE3,0); + + // + // 4.VMEntryп + // + Vmx_VmWrite(VM_ENTRY_CONTROLS,VmxAdjustControls(VM_ENTRY_IA32E_MODE|VM_ENTRY_LOAD_IA32_EFER,MSR_IA32_VMX_ENTRY_CTLS)); + Vmx_VmWrite(VM_ENTRY_MSR_LOAD_COUNT,0); + Vmx_VmWrite(VM_ENTRY_INTR_INFO_FIELD,0); + + + // + // 5.VMExitп + // + Vmx_VmWrite(VM_EXIT_CONTROLS,VmxAdjustControls(VM_EXIT_IA32E_MODE|VM_EXIT_ACK_INTR_ON_EXIT,MSR_IA32_VMX_EXIT_CTLS)); + Vmx_VmWrite(VM_EXIT_MSR_LOAD_COUNT,0); + Vmx_VmWrite(VM_EXIT_MSR_STORE_COUNT,0); + + EptTablePointer EPTP = { 0 }; + PHYSICAL_ADDRESS phys = MmGetPhysicalAddress((void *)g_VMXCPU[uCPUID].ept_PML4T); + + // Set up the EPTP + EPTP.Bits.PhysAddr = phys.QuadPart >> 12; + EPTP.Bits.MemoryType = EPT_MEMORY_TYPE_WB; + EPTP.Bits.PageWalkLength = 3; + EPTP.Bits.D = 1; + Vmx_VmWrite(EPT_POINTER, EPTP.unsignedVal & 0xFFFFFFFF); + Vmx_VmWrite(EPT_POINTER_HIGH, EPTP.unsignedVal >> 32); + Vmx_VmWrite(VIRTUAL_PROCESSOR_ID, uCPUID + 1); + + Vmx_VmLaunch(); + + g_VMXCPU[uCPUID].bVTStartSuccess = FALSE; +} + +void SetupVT() +{ + ULONG64 uCPUID; + + uCPUID = KeGetCurrentProcessorNumber(); + NTSTATUS status = STATUS_SUCCESS; + if (!IsVTEnabled()) + return; + status = AllocateVMXRegion(); + if (!NT_SUCCESS(status)) + { + return; + } + SetupVMXRegion(); + g_VMXCPU[uCPUID].bVTStartSuccess = TRUE; + + Asm_SetupVMCS(); + + if (g_VMXCPU[uCPUID].bVTStartSuccess) + { + + } + else KdPrint(("VT Engine Error(%d)!\n",KeGetCurrentProcessorNumber())); +} + +void UnsetupVT() +{ + _CR4 uCr4; + ULONG64 uCPUID; + uCPUID = KeGetCurrentProcessorNumber(); + if(g_VMXCPU[uCPUID].bVTStartSuccess) + { + Vmx_VmCall('SVT'); + + *((PULONG64)&uCr4) = Asm_GetCr4(); + uCr4.VMXE = 0; + Asm_SetCr4(*((PULONG64)&uCr4)); + + ExFreePoolWithTag(g_VMXCPU[uCPUID].pVMXONRegion,'vmon'); + ExFreePoolWithTag(g_VMXCPU[uCPUID].pVMCSRegion,'vmcs'); + ExFreePoolWithTag(g_VMXCPU[uCPUID].pHostEsp,'mini'); + + } +} + +NTSTATUS StartVirtualTechnology() +{ + KeInitializeMutex(&g_GlobalMutex,0); + KeWaitForMutexObject(&g_GlobalMutex,Executive,KernelMode,FALSE,0); + g_Pml4 = EptInitialization(); + + for (int i = 0;i +#include +} +#endif \ No newline at end of file