updates and moves

n/a
This commit is contained in:
vxunderground
2022-04-11 20:00:13 -05:00
parent 1275ea2e03
commit 900263ea6f
809 changed files with 149115 additions and 1594 deletions
@@ -0,0 +1,20 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CheckKernelHook", "CheckKernelHook\CheckKernelHook.vcxproj", "{D49C7CB9-A5C2-4377-A234-7C440407A30E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D49C7CB9-A5C2-4377-A234-7C440407A30E}.Debug|Win32.ActiveCfg = Debug|Win32
{D49C7CB9-A5C2-4377-A234-7C440407A30E}.Debug|Win32.Build.0 = Debug|Win32
{D49C7CB9-A5C2-4377-A234-7C440407A30E}.Release|Win32.ActiveCfg = Release|Win32
{D49C7CB9-A5C2-4377-A234-7C440407A30E}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
@@ -0,0 +1,114 @@
#include "AddService.h"
#include "stdafx.h"
#include "CheckKernelHookDlg.h"
#include <Winsvc.h>
#pragma once
BOOL Release(){
// HRSRC res = FindResource(NULL,MAKEINTRESOURCE(IDR_SYS),TEXT("BINARY"));
// if(!res)
// return FALSE;
// HGLOBAL resGlobal = LoadResource(NULL,res);
// if(!resGlobal)
// return FALSE;
// DWORD size=SizeofResource(NULL,res);
// BYTE* ptr=(BYTE*)LockResource(resGlobal);
// if(!ptr)
// return FALSE;
HANDLE hFile=CreateFile(TEXT("ReloadKernel.sys"), GENERIC_WRITE,
0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile==INVALID_HANDLE_VALUE)
return FALSE;
DWORD dw;
// if(!WriteFile(hFile,ptr,size,&dw,NULL)){
// CloseHandle(hFile);
// return FALSE;
// }
CloseHandle(hFile);
return TRUE;
}
BOOL UnloadDrv(TCHAR* DriverName){
SC_HANDLE hSCManager;
SC_HANDLE hService;
SERVICE_STATUS ss;
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (!hSCManager){
return FALSE;
}
hService = OpenService( hSCManager,DriverName,SERVICE_ALL_ACCESS);
if( !hService ) {
CloseServiceHandle(hSCManager);
return FALSE;
}
ControlService(hService, SERVICE_CONTROL_STOP, &ss);
DeleteService(hService);
CloseServiceHandle(hService);
CloseServiceHandle(hSCManager);
return TRUE;
}
BOOL LoadDrv(TCHAR* DriverName){
TCHAR DrvFullPathName[MAX_PATH];
SC_HANDLE schSCManager;
SC_HANDLE schService;
UnloadDrv(L"CheckKernelHook");
// if(!Release())
// return FALSE;
GetFullPathName(TEXT("CheckKernelHook.sys"), MAX_PATH, DrvFullPathName, NULL);
schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (!schSCManager)
return FALSE;
schService = CreateService(
schSCManager,DriverName,DriverName,
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
DrvFullPathName,
NULL,NULL,NULL,NULL,NULL
);
if (!schService){
if (GetLastError() == ERROR_SERVICE_EXISTS){
schService = OpenService(schSCManager,DriverName,SERVICE_ALL_ACCESS);
if (!schService){
CloseServiceHandle(schSCManager);
return FALSE;
}
}else{
CloseServiceHandle(schSCManager);
return FALSE;
}
}
if (!StartService(schService,0,NULL)){
if ( !(GetLastError()==ERROR_SERVICE_ALREADY_RUNNING ) ){
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return FALSE;
}
}
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return TRUE;
}
@@ -0,0 +1,5 @@
#include "stdafx.h"
BOOL Release();
BOOL UnloadDrv(TCHAR* DriverName);
BOOL LoadDrv(TCHAR* DriverName);
@@ -0,0 +1,94 @@
// CheckKernelHook.cpp : 定义应用程序的类行为。
//
#include "stdafx.h"
#include "CheckKernelHook.h"
#include "CheckKernelHookDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CCheckKernelHookApp
BEGIN_MESSAGE_MAP(CCheckKernelHookApp, CWinApp)
ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()
// CCheckKernelHookApp 构造
CCheckKernelHookApp::CCheckKernelHookApp()
{
// 支持重新启动管理器
m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
// TODO: 在此处添加构造代码,
// 将所有重要的初始化放置在 InitInstance 中
}
// 唯一的一个 CCheckKernelHookApp 对象
CCheckKernelHookApp theApp;
// CCheckKernelHookApp 初始化
BOOL CCheckKernelHookApp::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;
// 标准初始化
// 如果未使用这些功能并希望减小
// 最终可执行文件的大小,则应移除下列
// 不需要的特定初始化例程
// 更改用于存储设置的注册表项
// TODO: 应适当修改该字符串,
// 例如修改为公司或组织名
SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
CCheckKernelHookDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: 在此放置处理何时用
// “确定”来关闭对话框的代码
}
else if (nResponse == IDCANCEL)
{
// TODO: 在此放置处理何时用
// “取消”来关闭对话框的代码
}
// 删除上面创建的 shell 管理器。
if (pShellManager != NULL)
{
delete pShellManager;
}
// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
// 而不是启动应用程序的消息泵。
return FALSE;
}
@@ -0,0 +1,32 @@
// CheckKernelHook.h : PROJECT_NAME 应用程序的主头文件
//
#pragma once
#ifndef __AFXWIN_H__
#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
#endif
#include "resource.h" // 主符号
// CCheckKernelHookApp:
// 有关此类的实现,请参阅 CheckKernelHook.cpp
//
class CCheckKernelHookApp : public CWinApp
{
public:
CCheckKernelHookApp();
// 重写
public:
virtual BOOL InitInstance();
// 实现
DECLARE_MESSAGE_MAP()
};
extern CCheckKernelHookApp theApp;
@@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{D49C7CB9-A5C2-4377-A234-7C440407A30E}</ProjectGuid>
<RootNamespace>CheckKernelHook</RootNamespace>
<Keyword>MFCProj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>Dynamic</UseOfMfc>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>Dynamic</UseOfMfc>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Midl>
<MkTypLibCompatible>false</MkTypLibCompatible>
<ValidateAllParameters>true</ValidateAllParameters>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</Midl>
<ResourceCompile>
<Culture>0x0804</Culture>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<Midl>
<MkTypLibCompatible>false</MkTypLibCompatible>
<ValidateAllParameters>true</ValidateAllParameters>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</Midl>
<ResourceCompile>
<Culture>0x0804</Culture>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="ReadMe.txt" />
<None Include="res\CheckKernelHook.ico" />
<None Include="res\CheckKernelHook.rc2" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="AddService.h" />
<ClInclude Include="CheckKernelHook.h" />
<ClInclude Include="CheckKernelHookDlg.h" />
<ClInclude Include="Resource.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="AddService.cpp" />
<ClCompile Include="CheckKernelHook.cpp" />
<ClCompile Include="CheckKernelHookDlg.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="CheckKernelHook.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<ProjectExtensions>
<VisualStudio>
<UserProperties RESOURCE_FILE="CheckKernelHook.rc" />
</VisualStudio>
</ProjectExtensions>
</Project>
@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="源文件">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="头文件">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="资源文件">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="ReadMe.txt" />
<None Include="res\CheckKernelHook.rc2">
<Filter>资源文件</Filter>
</None>
<None Include="res\CheckKernelHook.ico">
<Filter>资源文件</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ClInclude Include="CheckKernelHook.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="CheckKernelHookDlg.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="stdafx.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="Resource.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="AddService.h">
<Filter>源文件</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="CheckKernelHook.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="CheckKernelHookDlg.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="stdafx.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="AddService.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="CheckKernelHook.rc">
<Filter>资源文件</Filter>
</ResourceCompile>
</ItemGroup>
</Project>
@@ -0,0 +1,283 @@
// CheckKernelHookDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "CheckKernelHook.h"
#include "CheckKernelHookDlg.h"
#include "afxdialogex.h"
#include "AddService.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
HANDLE g_hDevice = NULL;
typedef struct
{
WCHAR* szTitle; //列表的名称
int nWidth; //列表的宽度
}COLUMNSTRUCT;
COLUMNSTRUCT g_Column_Data_Online[] =
{
{L"原始地址", 148 },
{L"函数名称", 150 },
{L"Hook地址", 160 },
{L"模块名称", 300 },
{L"模块基址", 80 },
{L"模块大小", 81 },
{L"类型", 81 }
};
int g_Column_Count_Online = 7; //列表的个数
int g_Column_Online_Width = 0;
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// 对话框数据
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CCheckKernelHookDlg 对话框
CCheckKernelHookDlg::CCheckKernelHookDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CCheckKernelHookDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CCheckKernelHookDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST, m_List);
}
BEGIN_MESSAGE_MAP(CCheckKernelHookDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
END_MESSAGE_MAP()
// CCheckKernelHookDlg 消息处理程序
BOOL CCheckKernelHookDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
m_List.SetExtendedStyle(LVS_EX_FULLROWSELECT);
for (int i = 0; i < g_Column_Count_Online; i++)
{
m_List.InsertColumn(i, g_Column_Data_Online[i].szTitle,LVCFMT_CENTER,g_Column_Data_Online[i].nWidth);
g_Column_Online_Width+=g_Column_Data_Online[i].nWidth;
}
//LoadDrv(L"CheckKernelHook");
g_hDevice = OpenDevice(L"\\\\.\\CheckKernelHookLinkName");
if (g_hDevice==(HANDLE)-1)
{
MessageBox(L"打开设备失败");
return TRUE;
}
CheckKernelHook();
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
VOID CCheckKernelHookDlg::CheckKernelHook()
{
ULONG_PTR ulCount = 0x1000;
PINLINEHOOKINFO PInlineHookInfo = NULL;
BOOL bRet = FALSE;
DWORD ulReturnSize = 0;
do
{
ULONG_PTR ulSize = 0;
if (PInlineHookInfo)
{
free(PInlineHookInfo);
PInlineHookInfo = NULL;
}
ulSize = sizeof(INLINEHOOKINFO) + ulCount * sizeof(INLINEHOOKINFO_INFORMATION);
PInlineHookInfo = (PINLINEHOOKINFO)malloc(ulSize);
if (!PInlineHookInfo)
{
break;
}
memset(PInlineHookInfo,0,ulSize);
bRet = DeviceIoControl(g_hDevice,CTL_CHECKKERNELMODULE,
NULL,
0,
PInlineHookInfo,
ulSize,
&ulReturnSize,
NULL);
ulCount = PInlineHookInfo->ulCount + 1000;
} while (bRet == FALSE && GetLastError() == ERROR_INSUFFICIENT_BUFFER);
if(PInlineHookInfo->ulCount==0)
{
MessageBox(L"当前内核安全",L"");
}
else
{
InsertDataToList(PInlineHookInfo);
}
if (PInlineHookInfo)
{
free(PInlineHookInfo);
PInlineHookInfo = NULL;
}
}
VOID CCheckKernelHookDlg::InsertDataToList(PINLINEHOOKINFO PInlineHookInfo)
{
CString OrgAddress,CurAddress,ModuleBase,ModuleSize;
for(int i=0;i<PInlineHookInfo->ulCount;i++)
{
OrgAddress.Format(L"0x%p",PInlineHookInfo->InlineHook[i].ulMemoryFunctionBase);
CurAddress.Format(L"0x%p",PInlineHookInfo->InlineHook[i].ulMemoryHookBase);
ModuleBase.Format(L"0x%p",PInlineHookInfo->InlineHook[i].ulHookModuleBase);
ModuleSize.Format(L"%d",PInlineHookInfo->InlineHook[i].ulHookModuleSize);
int n = m_List.InsertItem(m_List.GetItemCount(),OrgAddress,0); //注意这里的i 就是Icon 在数组的位置
CString szFunc=L"";
CString ModuleName = L"";
szFunc +=PInlineHookInfo->InlineHook[i].lpszFunction;
ModuleName += PInlineHookInfo->InlineHook[i].lpszHookModuleImage;
m_List.SetItemText(n,1,szFunc);
m_List.SetItemText(n,2,CurAddress);
m_List.SetItemText(n,3,ModuleName);
m_List.SetItemText(n,4,ModuleBase);
m_List.SetItemText(n,5,ModuleSize);
CString Type= L"";
if(PInlineHookInfo->InlineHook[i].ulHookType==1)
{
Type +=L"SSDT Hook";
}
else if(PInlineHookInfo->InlineHook[i].ulHookType==2)
{
Type +=L"Next Call Hook";
}
else if(PInlineHookInfo->InlineHook[i].ulHookType==0)
{
Type +=L"Inline Hook";
}
m_List.SetItemText(n,6,Type);
}
UpdateData(TRUE);
}
void CCheckKernelHookDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CCheckKernelHookDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(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 CCheckKernelHookDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
@@ -0,0 +1,76 @@
// CheckKernelHookDlg.h : 头文件
//
#pragma once
#include "afxcmn.h"
#include "resource.h"
#include <WinIoCtl.h>
typedef struct _INLINEHOOKINFO_INFORMATION { //INLINEHOOKINFO_INFORMATION
ULONG ulHookType;
ULONG ulMemoryFunctionBase; //原始地址
ULONG ulMemoryHookBase; //HOOK 地址
CHAR lpszFunction[256];
CHAR lpszHookModuleImage[256];
ULONG ulHookModuleBase;
ULONG ulHookModuleSize;
} INLINEHOOKINFO_INFORMATION, *PINLINEHOOKINFO_INFORMATION;
typedef struct _INLINEHOOKINFO { //InlineHook
ULONG ulCount;
INLINEHOOKINFO_INFORMATION InlineHook[1];
} INLINEHOOKINFO, *PINLINEHOOKINFO;
#define CTL_CHECKKERNELMODULE \
CTL_CODE(FILE_DEVICE_UNKNOWN,0x830,METHOD_NEITHER,FILE_ANY_ACCESS)
// CCheckKernelHookDlg 对话框
class CCheckKernelHookDlg : public CDialogEx
{
// 构造
public:
CCheckKernelHookDlg(CWnd* pParent = NULL); // 标准构造函数
// 对话框数据
enum { IDD = IDD_CHECKKERNELHOOK_DIALOG };
VOID CheckKernelHook();
VOID InsertDataToList(PINLINEHOOKINFO PInlineHookInfo);
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
HANDLE OpenDevice(LPCTSTR wzLinkPath)
{
HANDLE hDevice = CreateFile(wzLinkPath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hDevice == INVALID_HANDLE_VALUE)
{
}
return hDevice;
}
// 实现
protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
CListCtrl m_List;
};
Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

@@ -0,0 +1 @@
Check Kernel EAT Hook
@@ -0,0 +1,8 @@
// stdafx.cpp : 只包括标准包含文件的源文件
// CheckKernelHook.pch 将作为预编译头
// stdafx.obj 将包含预编译类型信息
#include "stdafx.h"
@@ -0,0 +1,58 @@
// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
#pragma once
#ifndef _SECURE_ATL
#define _SECURE_ATL 1
#endif
#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN // 从 Windows 头中排除极少使用的资料
#endif
#include "targetver.h"
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // 某些 CString 构造函数将是显式的
// 关闭 MFC 对某些常见但经常可放心忽略的警告消息的隐藏
#define _AFX_ALL_WARNINGS
#include <afxwin.h> // MFC 核心组件和标准组件
#include <afxext.h> // MFC 扩展
#include <afxdisp.h> // MFC 自动化类
#ifndef _AFX_NO_OLE_SUPPORT
#include <afxdtctl.h> // MFC 对 Internet Explorer 4 公共控件的支持
#endif
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC 对 Windows 公共控件的支持
#endif // _AFX_NO_AFXCMN_SUPPORT
#include <afxcontrolbars.h> // 功能区和控件条的 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
@@ -0,0 +1,8 @@
#pragma once
// 包括 SDKDDKVer.h 将定义最高版本的可用 Windows 平台。
// 如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h,并将
// WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。
#include <SDKDDKVer.h>
@@ -0,0 +1,20 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CheckKernelHook", "CheckKernelHook\CheckKernelHook.vcxproj", "{4EE67C57-BE79-4CD7-B3B0-94AECE62DB41}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4EE67C57-BE79-4CD7-B3B0-94AECE62DB41}.Debug|Win32.ActiveCfg = WinDDK|Win32
{4EE67C57-BE79-4CD7-B3B0-94AECE62DB41}.Debug|Win32.Build.0 = WinDDK|Win32
{4EE67C57-BE79-4CD7-B3B0-94AECE62DB41}.Release|Win32.ActiveCfg = WinDDK|Win32
{4EE67C57-BE79-4CD7-B3B0-94AECE62DB41}.Release|Win32.Build.0 = WinDDK|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
@@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="WinDDK|Win32">
<Configuration>WinDDK</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Common.c" />
<ClCompile Include="DriverEntry.c" />
<ClCompile Include="FileSystem.c" />
<ClCompile Include="FixRelocation.c" />
<ClCompile Include="KernelHookCheck.c" />
<ClCompile Include="KernelReload.c" />
<ClCompile Include="libdasm.c" />
<ClCompile Include="Reload.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Common.h" />
<ClInclude Include="DriverEntry.h" />
<ClInclude Include="FileSystem.h" />
<ClInclude Include="FixRelocation.h" />
<ClInclude Include="KernelHookCheck.h" />
<ClInclude Include="KernelReload.h" />
<ClInclude Include="libdasm.h" />
<ClInclude Include="Reload.h" />
<ClInclude Include="tables.h" />
</ItemGroup>
<ItemGroup>
<None Include="sources" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{4EE67C57-BE79-4CD7-B3B0-94AECE62DB41}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>"CheckKernelHook"</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='WinDDK|Win32'">
<TargetExt>.sys</TargetExt>
<GenerateManifest>false</GenerateManifest>
<ExecutablePath>$(WLHBASE)\bin\x86\x86;$(WLHBASE)\bin\x86</ExecutablePath>
<IncludePath>$(WLHBASE)\inc\api;$(WLHBASE)\inc\crt;$(WLHBASE)\inc\ddk;$(WLHBASE)\inc</IncludePath>
<ReferencePath />
<LibraryPath>$(WLHBASE)\lib\win7\i386</LibraryPath>
<SourcePath />
<ExcludePath />
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='WinDDK|Win32'">
<ClCompile>
<PreprocessorDefinitions>_X86_;DBG=1</PreprocessorDefinitions>
<ExceptionHandling>false</ExceptionHandling>
<BufferSecurityCheck>false</BufferSecurityCheck>
<CallingConvention>StdCall</CallingConvention>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>ntoskrnl.lib;hal.lib;wdm.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Link>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<SubSystem>Native</SubSystem>
<Driver>Driver</Driver>
<EntryPointSymbol>DriverEntry</EntryPointSymbol>
<SetChecksum>true</SetChecksum>
<BaseAddress>0x10000</BaseAddress>
<RandomizedBaseAddress>
</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="Common.c" />
<ClCompile Include="DriverEntry.c" />
<ClCompile Include="KernelHookCheck.c" />
<ClCompile Include="libdasm.c" />
<ClCompile Include="FileSystem.c">
<Filter>Reload</Filter>
</ClCompile>
<ClCompile Include="FixRelocation.c">
<Filter>Reload</Filter>
</ClCompile>
<ClCompile Include="KernelReload.c">
<Filter>Reload</Filter>
</ClCompile>
<ClCompile Include="Reload.c">
<Filter>Reload</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Common.h" />
<ClInclude Include="DriverEntry.h" />
<ClInclude Include="KernelHookCheck.h" />
<ClInclude Include="libdasm.h" />
<ClInclude Include="tables.h" />
<ClInclude Include="FileSystem.h">
<Filter>Reload</Filter>
</ClInclude>
<ClInclude Include="FixRelocation.h">
<Filter>Reload</Filter>
</ClInclude>
<ClInclude Include="KernelReload.h">
<Filter>Reload</Filter>
</ClInclude>
<ClInclude Include="Reload.h">
<Filter>Reload</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="sources" />
</ItemGroup>
<ItemGroup>
<Filter Include="Reload">
<UniqueIdentifier>{7f84aa62-4fe1-452a-a193-32b7b7a3e2db}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>
@@ -0,0 +1,783 @@
#include "Common.h"
#include "Reload.h"
UCHAR OpcodeFlags[256] =
{
OP_MODRM, // 00
OP_MODRM, // 01
OP_MODRM, // 02
OP_MODRM, // 03
OP_DATA_I8, // 04
OP_DATA_PRE66_67, // 05
OP_NONE, // 06
OP_NONE, // 07
OP_MODRM, // 08
OP_MODRM, // 09
OP_MODRM, // 0A
OP_MODRM, // 0B
OP_DATA_I8, // 0C
OP_DATA_PRE66_67, // 0D
OP_NONE, // 0E
OP_NONE, // 0F
OP_MODRM, // 10
OP_MODRM, // 11
OP_MODRM, // 12
OP_MODRM, // 13
OP_DATA_I8, // 14
OP_DATA_PRE66_67, // 15
OP_NONE, // 16
OP_NONE, // 17
OP_MODRM, // 18
OP_MODRM, // 19
OP_MODRM, // 1A
OP_MODRM, // 1B
OP_DATA_I8, // 1C
OP_DATA_PRE66_67, // 1D
OP_NONE, // 1E
OP_NONE, // 1F
OP_MODRM, // 20
OP_MODRM, // 21
OP_MODRM, // 22
OP_MODRM, // 23
OP_DATA_I8, // 24
OP_DATA_PRE66_67, // 25
OP_NONE, // 26
OP_NONE, // 27
OP_MODRM, // 28
OP_MODRM, // 29
OP_MODRM, // 2A
OP_MODRM, // 2B
OP_DATA_I8, // 2C
OP_DATA_PRE66_67, // 2D
OP_NONE, // 2E
OP_NONE, // 2F
OP_MODRM, // 30
OP_MODRM, // 31
OP_MODRM, // 32
OP_MODRM, // 33
OP_DATA_I8, // 34
OP_DATA_PRE66_67, // 35
OP_NONE, // 36
OP_NONE, // 37
OP_MODRM, // 38
OP_MODRM, // 39
OP_MODRM, // 3A
OP_MODRM, // 3B
OP_DATA_I8, // 3C
OP_DATA_PRE66_67, // 3D
OP_NONE, // 3E
OP_NONE, // 3F
OP_NONE, // 40
OP_NONE, // 41
OP_NONE, // 42
OP_NONE, // 43
OP_NONE, // 44
OP_NONE, // 45
OP_NONE, // 46
OP_NONE, // 47
OP_NONE, // 48
OP_NONE, // 49
OP_NONE, // 4A
OP_NONE, // 4B
OP_NONE, // 4C
OP_NONE, // 4D
OP_NONE, // 4E
OP_NONE, // 4F
OP_NONE, // 50
OP_NONE, // 51
OP_NONE, // 52
OP_NONE, // 53
OP_NONE, // 54
OP_NONE, // 55
OP_NONE, // 56
OP_NONE, // 57
OP_NONE, // 58
OP_NONE, // 59
OP_NONE, // 5A
OP_NONE, // 5B
OP_NONE, // 5C
OP_NONE, // 5D
OP_NONE, // 5E
OP_NONE, // 5F
OP_NONE, // 60
OP_NONE, // 61
OP_MODRM, // 62
OP_MODRM, // 63
OP_NONE, // 64
OP_NONE, // 65
OP_NONE, // 66
OP_NONE, // 67
OP_DATA_PRE66_67, // 68
OP_MODRM | OP_DATA_PRE66_67, // 69
OP_DATA_I8, // 6A
OP_MODRM | OP_DATA_I8, // 6B
OP_NONE, // 6C
OP_NONE, // 6D
OP_NONE, // 6E
OP_NONE, // 6F
OP_DATA_I8, // 70
OP_DATA_I8, // 71
OP_DATA_I8, // 72
OP_DATA_I8, // 73
OP_DATA_I8, // 74
OP_DATA_I8, // 75
OP_DATA_I8, // 76
OP_DATA_I8, // 77
OP_DATA_I8, // 78
OP_DATA_I8, // 79
OP_DATA_I8, // 7A
OP_DATA_I8, // 7B
OP_DATA_I8, // 7C
OP_DATA_I8, // 7D
OP_DATA_I8, // 7E
OP_DATA_I8, // 7F
OP_MODRM | OP_DATA_I8, // 80
OP_MODRM | OP_DATA_PRE66_67, // 81
OP_MODRM | OP_DATA_I8, // 82
OP_MODRM | OP_DATA_I8, // 83
OP_MODRM, // 84
OP_MODRM, // 85
OP_MODRM, // 86
OP_MODRM, // 87
OP_MODRM, // 88
OP_MODRM, // 89
OP_MODRM, // 8A
OP_MODRM, // 8B
OP_MODRM, // 8C
OP_MODRM, // 8D
OP_MODRM, // 8E
OP_MODRM, // 8F
OP_NONE, // 90
OP_NONE, // 91
OP_NONE, // 92
OP_NONE, // 93
OP_NONE, // 94
OP_NONE, // 95
OP_NONE, // 96
OP_NONE, // 97
OP_NONE, // 98
OP_NONE, // 99
OP_DATA_I16 | OP_DATA_PRE66_67,// 9A
OP_NONE, // 9B
OP_NONE, // 9C
OP_NONE, // 9D
OP_NONE, // 9E
OP_NONE, // 9F
OP_DATA_PRE66_67, // A0
OP_DATA_PRE66_67, // A1
OP_DATA_PRE66_67, // A2
OP_DATA_PRE66_67, // A3
OP_NONE, // A4
OP_NONE, // A5
OP_NONE, // A6
OP_NONE, // A7
OP_DATA_I8, // A8
OP_DATA_PRE66_67, // A9
OP_NONE, // AA
OP_NONE, // AB
OP_NONE, // AC
OP_NONE, // AD
OP_NONE, // AE
OP_NONE, // AF
OP_DATA_I8, // B0
OP_DATA_I8, // B1
OP_DATA_I8, // B2
OP_DATA_I8, // B3
OP_DATA_I8, // B4
OP_DATA_I8, // B5
OP_DATA_I8, // B6
OP_DATA_I8, // B7
OP_DATA_PRE66_67, // B8
OP_DATA_PRE66_67, // B9
OP_DATA_PRE66_67, // BA
OP_DATA_PRE66_67, // BB
OP_DATA_PRE66_67, // BC
OP_DATA_PRE66_67, // BD
OP_DATA_PRE66_67, // BE
OP_DATA_PRE66_67, // BF
OP_MODRM | OP_DATA_I8, // C0
OP_MODRM | OP_DATA_I8, // C1
OP_DATA_I16, // C2
OP_NONE, // C3
OP_MODRM, // C4
OP_MODRM, // C5
OP_MODRM | OP_DATA_I8, // C6
OP_MODRM | OP_DATA_PRE66_67, // C7
OP_DATA_I8 | OP_DATA_I16, // C8
OP_NONE, // C9
OP_DATA_I16, // CA
OP_NONE, // CB
OP_NONE, // CC
OP_DATA_I8, // CD
OP_NONE, // CE
OP_NONE, // CF
OP_MODRM, // D0
OP_MODRM, // D1
OP_MODRM, // D2
OP_MODRM, // D3
OP_DATA_I8, // D4
OP_DATA_I8, // D5
OP_NONE, // D6
OP_NONE, // D7
OP_WORD, // D8
OP_WORD, // D9
OP_WORD, // DA
OP_WORD, // DB
OP_WORD, // DC
OP_WORD, // DD
OP_WORD, // DE
OP_WORD, // DF
OP_DATA_I8, // E0
OP_DATA_I8, // E1
OP_DATA_I8, // E2
OP_DATA_I8, // E3
OP_DATA_I8, // E4
OP_DATA_I8, // E5
OP_DATA_I8, // E6
OP_DATA_I8, // E7
OP_DATA_PRE66_67 | OP_REL32, // E8
OP_DATA_PRE66_67 | OP_REL32, // E9
OP_DATA_I16 | OP_DATA_PRE66_67,// EA
OP_DATA_I8, // EB
OP_NONE, // EC
OP_NONE, // ED
OP_NONE, // EE
OP_NONE, // EF
OP_NONE, // F0
OP_NONE, // F1
OP_NONE, // F2
OP_NONE, // F3
OP_NONE, // F4
OP_NONE, // F5
OP_MODRM, // F6
OP_MODRM, // F7
OP_NONE, // F8
OP_NONE, // F9
OP_NONE, // FA
OP_NONE, // FB
OP_NONE, // FC
OP_NONE, // FD
OP_MODRM, // FE
OP_MODRM | OP_REL32 // FF
};
UCHAR OpcodeFlagsExt[256] =
{
OP_MODRM, // 00
OP_MODRM, // 01
OP_MODRM, // 02
OP_MODRM, // 03
OP_NONE, // 04
OP_NONE, // 05
OP_NONE, // 06
OP_NONE, // 07
OP_NONE, // 08
OP_NONE, // 09
OP_NONE, // 0A
OP_NONE, // 0B
OP_NONE, // 0C
OP_MODRM, // 0D
OP_NONE, // 0E
OP_MODRM | OP_DATA_I8, // 0F
OP_MODRM, // 10
OP_MODRM, // 11
OP_MODRM, // 12
OP_MODRM, // 13
OP_MODRM, // 14
OP_MODRM, // 15
OP_MODRM, // 16
OP_MODRM, // 17
OP_MODRM, // 18
OP_NONE, // 19
OP_NONE, // 1A
OP_NONE, // 1B
OP_NONE, // 1C
OP_NONE, // 1D
OP_NONE, // 1E
OP_NONE, // 1F
OP_MODRM, // 20
OP_MODRM, // 21
OP_MODRM, // 22
OP_MODRM, // 23
OP_MODRM, // 24
OP_NONE, // 25
OP_MODRM, // 26
OP_NONE, // 27
OP_MODRM, // 28
OP_MODRM, // 29
OP_MODRM, // 2A
OP_MODRM, // 2B
OP_MODRM, // 2C
OP_MODRM, // 2D
OP_MODRM, // 2E
OP_MODRM, // 2F
OP_NONE, // 30
OP_NONE, // 31
OP_NONE, // 32
OP_NONE, // 33
OP_NONE, // 34
OP_NONE, // 35
OP_NONE, // 36
OP_NONE, // 37
OP_NONE, // 38
OP_NONE, // 39
OP_NONE, // 3A
OP_NONE, // 3B
OP_NONE, // 3C
OP_NONE, // 3D
OP_NONE, // 3E
OP_NONE, // 3F
OP_MODRM, // 40
OP_MODRM, // 41
OP_MODRM, // 42
OP_MODRM, // 43
OP_MODRM, // 44
OP_MODRM, // 45
OP_MODRM, // 46
OP_MODRM, // 47
OP_MODRM, // 48
OP_MODRM, // 49
OP_MODRM, // 4A
OP_MODRM, // 4B
OP_MODRM, // 4C
OP_MODRM, // 4D
OP_MODRM, // 4E
OP_MODRM, // 4F
OP_MODRM, // 50
OP_MODRM, // 51
OP_MODRM, // 52
OP_MODRM, // 53
OP_MODRM, // 54
OP_MODRM, // 55
OP_MODRM, // 56
OP_MODRM, // 57
OP_MODRM, // 58
OP_MODRM, // 59
OP_MODRM, // 5A
OP_MODRM, // 5B
OP_MODRM, // 5C
OP_MODRM, // 5D
OP_MODRM, // 5E
OP_MODRM, // 5F
OP_MODRM, // 60
OP_MODRM, // 61
OP_MODRM, // 62
OP_MODRM, // 63
OP_MODRM, // 64
OP_MODRM, // 65
OP_MODRM, // 66
OP_MODRM, // 67
OP_MODRM, // 68
OP_MODRM, // 69
OP_MODRM, // 6A
OP_MODRM, // 6B
OP_MODRM, // 6C
OP_MODRM, // 6D
OP_MODRM, // 6E
OP_MODRM, // 6F
OP_MODRM | OP_DATA_I8, // 70
OP_MODRM | OP_DATA_I8, // 71
OP_MODRM | OP_DATA_I8, // 72
OP_MODRM | OP_DATA_I8, // 73
OP_MODRM, // 74
OP_MODRM, // 75
OP_MODRM, // 76
OP_NONE, // 77
OP_NONE, // 78
OP_NONE, // 79
OP_NONE, // 7A
OP_NONE, // 7B
OP_MODRM, // 7C
OP_MODRM, // 7D
OP_MODRM, // 7E
OP_MODRM, // 7F
OP_DATA_PRE66_67 | OP_REL32, // 80
OP_DATA_PRE66_67 | OP_REL32, // 81
OP_DATA_PRE66_67 | OP_REL32, // 82
OP_DATA_PRE66_67 | OP_REL32, // 83
OP_DATA_PRE66_67 | OP_REL32, // 84
OP_DATA_PRE66_67 | OP_REL32, // 85
OP_DATA_PRE66_67 | OP_REL32, // 86
OP_DATA_PRE66_67 | OP_REL32, // 87
OP_DATA_PRE66_67 | OP_REL32, // 88
OP_DATA_PRE66_67 | OP_REL32, // 89
OP_DATA_PRE66_67 | OP_REL32, // 8A
OP_DATA_PRE66_67 | OP_REL32, // 8B
OP_DATA_PRE66_67 | OP_REL32, // 8C
OP_DATA_PRE66_67 | OP_REL32, // 8D
OP_DATA_PRE66_67 | OP_REL32, // 8E
OP_DATA_PRE66_67 | OP_REL32, // 8F
OP_MODRM, // 90
OP_MODRM, // 91
OP_MODRM, // 92
OP_MODRM, // 93
OP_MODRM, // 94
OP_MODRM, // 95
OP_MODRM, // 96
OP_MODRM, // 97
OP_MODRM, // 98
OP_MODRM, // 99
OP_MODRM, // 9A
OP_MODRM, // 9B
OP_MODRM, // 9C
OP_MODRM, // 9D
OP_MODRM, // 9E
OP_MODRM, // 9F
OP_NONE, // A0
OP_NONE, // A1
OP_NONE, // A2
OP_MODRM, // A3
OP_MODRM | OP_DATA_I8, // A4
OP_MODRM, // A5
OP_NONE, // A6
OP_NONE, // A7
OP_NONE, // A8
OP_NONE, // A9
OP_NONE, // AA
OP_MODRM, // AB
OP_MODRM | OP_DATA_I8, // AC
OP_MODRM, // AD
OP_MODRM, // AE
OP_MODRM, // AF
OP_MODRM, // B0
OP_MODRM, // B1
OP_MODRM, // B2
OP_MODRM, // B3
OP_MODRM, // B4
OP_MODRM, // B5
OP_MODRM, // B6
OP_MODRM, // B7
OP_NONE, // B8
OP_NONE, // B9
OP_MODRM | OP_DATA_I8, // BA
OP_MODRM, // BB
OP_MODRM, // BC
OP_MODRM, // BD
OP_MODRM, // BE
OP_MODRM, // BF
OP_MODRM, // C0
OP_MODRM, // C1
OP_MODRM | OP_DATA_I8, // C2
OP_MODRM, // C3
OP_MODRM | OP_DATA_I8, // C4
OP_MODRM | OP_DATA_I8, // C5
OP_MODRM | OP_DATA_I8, // C6
OP_MODRM, // C7
OP_NONE, // C8
OP_NONE, // C9
OP_NONE, // CA
OP_NONE, // CB
OP_NONE, // CC
OP_NONE, // CD
OP_NONE, // CE
OP_NONE, // CF
OP_MODRM, // D0
OP_MODRM, // D1
OP_MODRM, // D2
OP_MODRM, // D3
OP_MODRM, // D4
OP_MODRM, // D5
OP_MODRM, // D6
OP_MODRM, // D7
OP_MODRM, // D8
OP_MODRM, // D9
OP_MODRM, // DA
OP_MODRM, // DB
OP_MODRM, // DC
OP_MODRM, // DD
OP_MODRM, // DE
OP_MODRM, // DF
OP_MODRM, // E0
OP_MODRM, // E1
OP_MODRM, // E2
OP_MODRM, // E3
OP_MODRM, // E4
OP_MODRM, // E5
OP_MODRM, // E6
OP_MODRM, // E7
OP_MODRM, // E8
OP_MODRM, // E9
OP_MODRM, // EA
OP_MODRM, // EB
OP_MODRM, // EC
OP_MODRM, // ED
OP_MODRM, // EE
OP_MODRM, // EF
OP_MODRM, // F0
OP_MODRM, // F1
OP_MODRM, // F2
OP_MODRM, // F3
OP_MODRM, // F4
OP_MODRM, // F5
OP_MODRM, // F6
OP_MODRM, // F7
OP_MODRM, // F8
OP_MODRM, // F9
OP_MODRM, // FA
OP_MODRM, // FB
OP_MODRM, // FC
OP_MODRM, // FD
OP_MODRM, // FE
OP_NONE // FF
};
NTSTATUS
MapFileInUserSpace(WCHAR* wzFilePath,IN HANDLE hProcess OPTIONAL,
OUT PVOID *BaseAddress,
OUT PSIZE_T ViewSize OPTIONAL)
{
NTSTATUS Status = STATUS_INVALID_PARAMETER;
HANDLE hFile = NULL;
HANDLE hSection = NULL;
OBJECT_ATTRIBUTES oa;
SIZE_T MapViewSize = 0;
IO_STATUS_BLOCK Iosb;
UNICODE_STRING uniFilePath;
if (!wzFilePath || !BaseAddress){
return Status;
}
RtlInitUnicodeString(&uniFilePath, wzFilePath);
InitializeObjectAttributes(&oa,
&uniFilePath,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL
);
Status = IoCreateFile(&hFile,
GENERIC_READ | SYNCHRONIZE,
&oa,
&Iosb,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0,
CreateFileTypeNone,
NULL,
IO_NO_PARAMETER_CHECKING
);
if (!NT_SUCCESS(Status))
{
return Status;
}
oa.ObjectName = NULL;
Status = ZwCreateSection(&hSection,
SECTION_QUERY | SECTION_MAP_READ,
&oa,
NULL,
PAGE_WRITECOPY,
SEC_IMAGE,
hFile
);
ZwClose(hFile);
if (!NT_SUCCESS(Status))
{
return Status;
}
if (!hProcess){
hProcess = NtCurrentProcess();
}
Status = ZwMapViewOfSection(hSection,
hProcess,
BaseAddress,
0,
0,
0,
ViewSize ? ViewSize : &MapViewSize,
ViewUnmap,
0,
PAGE_WRITECOPY
);
ZwClose(hSection);
if (!NT_SUCCESS(Status))
{
return Status;
}
return Status;
}
//通过指令获得函数大小
unsigned long __fastcall GetFunctionCodeSize(void *Proc)
{
ULONG Length;
PUCHAR pOpcode;
ULONG Result = 0;
ULONG CCINT3Count=0;
do
{
Length = SizeOfCode(Proc, &pOpcode);
Result += Length;
if ((Length == 1) && (*pOpcode == 0xCC||*pOpcode==0x90)) CCINT3Count++;
if (CCINT3Count>1 ||
*pOpcode == 0x00)
{
break; //判断退出指令
}
Proc = (PVOID)((ULONG)Proc + Length);
} while (Length);
return Result;
}
unsigned long __fastcall SizeOfCode(void *Code, unsigned char **pOpcode)
{
PUCHAR cPtr;
UCHAR Flags;
BOOLEAN PFX66, PFX67;
BOOLEAN SibPresent;
UCHAR iMod, iRM, iReg;
UCHAR OffsetSize, Add;
UCHAR Opcode;
OffsetSize = 0;
PFX66 = FALSE;
PFX67 = FALSE;
cPtr = (PUCHAR)Code;
while ((*cPtr == 0x2E) || (*cPtr == 0x3E) || (*cPtr == 0x36) ||
(*cPtr == 0x26) || (*cPtr == 0x64) || (*cPtr == 0x65) ||
(*cPtr == 0xF0) || (*cPtr == 0xF2) || (*cPtr == 0xF3) ||
(*cPtr == 0x66) || (*cPtr == 0x67))
{
if (*cPtr == 0x66) PFX66 = TRUE;
if (*cPtr == 0x67) PFX67 = TRUE;
cPtr++;
if (cPtr > (PUCHAR)Code + 16) return 0;
}
Opcode = *cPtr;
if (pOpcode) *pOpcode = cPtr;
if (*cPtr == 0x0F)
{
cPtr++;
Flags = OpcodeFlagsExt[*cPtr];
} else
{
Flags = OpcodeFlags[Opcode];
if (Opcode >= 0xA0 && Opcode <= 0xA3) PFX66 = PFX67;
}
cPtr++;
if (Flags & OP_WORD) cPtr++;
if (Flags & OP_MODRM)
{
iMod = *cPtr >> 6;
iReg = (*cPtr & 0x38) >> 3;
iRM = *cPtr & 7;
cPtr++;
if ((Opcode == 0xF6) && !iReg) Flags |= OP_DATA_I8;
if ((Opcode == 0xF7) && !iReg) Flags |= OP_DATA_PRE66_67;
SibPresent = !PFX67 & (iRM == 4);
switch (iMod)
{
case 0:
if ( PFX67 && (iRM == 6)) OffsetSize = 2;
if (!PFX67 && (iRM == 5)) OffsetSize = 4;
break;
case 1: OffsetSize = 1;
break;
case 2: if (PFX67) OffsetSize = 2; else OffsetSize = 4;
break;
case 3: SibPresent = FALSE;
}
if (SibPresent)
{
if (((*cPtr & 7) == 5) && ( (!iMod) || (iMod == 2) )) OffsetSize = 4;
cPtr++;
}
cPtr = (PUCHAR)(ULONG)cPtr + OffsetSize;
}
if (Flags & OP_DATA_I8) cPtr ++;
if (Flags & OP_DATA_I16) cPtr += 2;
if (Flags & OP_DATA_I32) cPtr += 4;
if (PFX66) Add = 2;
else Add = 4;
if (Flags & OP_DATA_PRE66_67) cPtr += Add;
return (ULONG)cPtr - (ULONG)Code;
}
BOOL IsAddressInSystem(ULONG ulDriverBase,ULONG *ulSysModuleBase,ULONG *ulSize,char *lpszSysModuleImage)
{
NTSTATUS status;
ULONG NeededSize,i;
PMODULES pModuleList;
BOOL bRet = FALSE;
BOOL bInit = FALSE;
if (ZwQuerySystemInformation &&
ExAllocatePool &&
ExFreePool)
{
bInit = TRUE;
}
if (!bInit)
return FALSE;
__try
{
status=ZwQuerySystemInformation(
SystemModuleInformation,
NULL,
0,
&NeededSize);
if (status!=STATUS_INFO_LENGTH_MISMATCH)
{
//KdPrint(("ZwQuerySystemInformation failed:%d",RtlNtStatusToDosError(status)));
return bRet;
}
pModuleList=(PMODULES)ExAllocatePool(NonPagedPool,NeededSize);
if (pModuleList)
{
status=ZwQuerySystemInformation(
SystemModuleInformation,
pModuleList,
NeededSize,
&NeededSize);
if (NT_SUCCESS(status))
{
for (i=0;i<pModuleList->ulCount;i++)
{
if (ulDriverBase > pModuleList->smi[i].Base && ulDriverBase < pModuleList->smi[i].Base + pModuleList->smi[i].Size)
{
bRet = TRUE;
__try
{
*ulSysModuleBase = pModuleList->smi[i].Base;
*ulSize = pModuleList->smi[i].Size;
memset(lpszSysModuleImage,0,sizeof(lpszSysModuleImage));
strcat(lpszSysModuleImage,pModuleList->smi[i].ImageName);
}__except(EXCEPTION_EXECUTE_HANDLER){
}
break;
}
}
}
//else
// KdPrint(("@@ZwQuerySystemInformation failed:%d",RtlNtStatusToDosError(status)));
ExFreePool(pModuleList);
pModuleList = NULL;
}
//else
// KdPrint(("ExAllocatePool failed"));
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
if (pModuleList)
ExFreePool(pModuleList);
return bRet;
}
@@ -0,0 +1,31 @@
#include "DriverEntry.h"
#include <ntimage.h>
typedef unsigned long DWORD;
typedef void *HANDLE;
typedef unsigned char BOOL, *PBOOL;
#define SEC_IMAGE 0x01000000
NTSYSAPI
PIMAGE_NT_HEADERS
NTAPI
RtlImageNtHeader(PVOID Base);
NTSTATUS
MapFileInUserSpace(WCHAR* wzFilePath,IN HANDLE hProcess OPTIONAL,
OUT PVOID *BaseAddress,
OUT PSIZE_T ViewSize OPTIONAL);
LONG GetSSDTApiFunctionIndexFromNtdll(char* szFindFunctionName);
BOOL IsAddressInSystem(ULONG ulDriverBase,ULONG *ulSysModuleBase,ULONG *ulSize,char *lpszSysModuleImage);
#define OP_NONE 0x00
#define OP_MODRM 0x01
#define OP_DATA_I8 0x02
#define OP_DATA_I16 0x04
#define OP_DATA_I32 0x08
#define OP_DATA_PRE66_67 0x10
#define OP_WORD 0x20
#define OP_REL32 0x40
unsigned long __fastcall GetFunctionCodeSize(void *Proc);
unsigned long __fastcall SizeOfCode(void *Code, unsigned char **pOpcode);
@@ -0,0 +1,136 @@
#include "DriverEntry.h"
#include "KernelHookCheck.h"
#include "Reload.h"
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegisterPath)
{
ULONG ImageBase = 0;
NTSTATUS Status = STATUS_SUCCESS;
UNICODE_STRING uniDeviceName;
UNICODE_STRING uniLinkName;
PDEVICE_OBJECT DeviceObject = NULL;
ULONG_PTR i = 0;
RtlInitUnicodeString(&uniDeviceName,DEVICE_NAME);
RtlInitUnicodeString(&uniLinkName,LINK_NAME);
for (i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++)
{
DriverObject->MajorFunction[i] = DefaultPassThrough;
}
DriverObject->DriverUnload = UnloadDriver;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ControlPassThrough;
//´´½¨É豸¶ÔÏó
Status = IoCreateDevice(DriverObject,0,&uniDeviceName,FILE_DEVICE_UNKNOWN,0,FALSE,&DeviceObject);
if (!NT_SUCCESS(Status))
{
return Status;
}
Status = IoCreateSymbolicLink(&uniLinkName,&uniDeviceName);
if (!NT_SUCCESS(Status))
{
IoDeleteDevice(DeviceObject);
return Status;
}
//PINLINEHOOKINFO InlineHookInfo ;
//InlineHookInfo = ExAllocatePool(1,sizeof(INLINEHOOKINFO)+0x1000*sizeof(INLINEHOOKINFO_INFORMATION));
//memset(InlineHookInfo,0,sizeof(INLINEHOOKINFO)+0x1000*sizeof(INLINEHOOKINFO_INFORMATION));
//DriverObject->DriverUnload = UnloadDriver;
ReLoadNtos(DriverObject,ImageBase);
//KernelHookCheck(InlineHookInfo);
return STATUS_SUCCESS;
}
NTSTATUS
ControlPassThrough(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
NTSTATUS Status = STATUS_SUCCESS;
PIO_STACK_LOCATION IrpSp;
PVOID InputBuffer = NULL;
PVOID OutputBuffer = NULL;
ULONG_PTR InputSize = 0;
ULONG_PTR OutputSize = 0;
ULONG_PTR IoControlCode = 0;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
InputBuffer = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
OutputBuffer = Irp->UserBuffer;
InputSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
OutputSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
IoControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
switch(IoControlCode)
{
case CTL_CHECKKERNELMODULE:
{
if (!MmIsAddressValid(OutputBuffer))
{
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
Irp->IoStatus.Information = 0;
break;
}
__try
{
ProbeForWrite(OutputBuffer,OutputSize,sizeof(PVOID));
Status = KernelHookCheck((PINLINEHOOKINFO)OutputBuffer);
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = Status;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
}
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = Status;
break;
}
default:
{
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
Irp->IoStatus.Information = 0;
break;
}
}
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return Status;
}
NTSTATUS
DefaultPassThrough(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
VOID UnloadDriver(PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING uniLinkName;
PDEVICE_OBJECT CurrentDeviceObject;
PDEVICE_OBJECT NextDeviceObject;
RtlInitUnicodeString(&uniLinkName,LINK_NAME);
IoDeleteSymbolicLink(&uniLinkName);
if (DriverObject->DeviceObject!=NULL)
{
CurrentDeviceObject = DriverObject->DeviceObject;
while(CurrentDeviceObject!=NULL)
{
NextDeviceObject = CurrentDeviceObject->NextDevice;
IoDeleteDevice(CurrentDeviceObject);
CurrentDeviceObject = NextDeviceObject;
}
}
DbgPrint("UnloadDriver\r\n");
}
@@ -0,0 +1,35 @@
#include <ntifs.h>
#include <devioctl.h>
#pragma once
#define DEVICE_NAME L"\\Device\\CheckKernelHookDeviceName"
#define LINK_NAME L"\\DosDevices\\CheckKernelHookLinkName"
#define CTL_CHECKKERNELMODULE \
CTL_CODE(FILE_DEVICE_UNKNOWN,0x830,METHOD_NEITHER,FILE_ANY_ACCESS)
NTSTATUS
DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegisterPath);
VOID UnloadDriver(PDRIVER_OBJECT DriverObject);
NTSTATUS
DefaultPassThrough(PDEVICE_OBJECT DeviceObject,PIRP Irp);
NTSTATUS
ControlPassThrough(PDEVICE_OBJECT DeviceObject,PIRP Irp);
typedef struct _INLINEHOOKINFO_INFORMATION { //INLINEHOOKINFO_INFORMATION
ULONG ulHookType;
ULONG ulMemoryFunctionBase; //ԭʼµØÖ·
ULONG ulMemoryHookBase; //HOOK µØÖ·
CHAR lpszFunction[256];
CHAR lpszHookModuleImage[256];
ULONG ulHookModuleBase;
ULONG ulHookModuleSize;
} INLINEHOOKINFO_INFORMATION, *PINLINEHOOKINFO_INFORMATION;
typedef struct _INLINEHOOKINFO { //InlineHook
ULONG ulCount;
INLINEHOOKINFO_INFORMATION InlineHook[1];
} INLINEHOOKINFO, *PINLINEHOOKINFO;
@@ -0,0 +1,306 @@
#include "FileSystem.h"
/*创建文件对象,相当于自己实现了IoCreateFile FileObject中的IrpList循环指向自身*/
NTSTATUS
IrpCreateFile(
IN PUNICODE_STRING FilePath,
IN ACCESS_MASK DesiredAccess,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PDEVICE_OBJECT DeviceObject,
IN PDEVICE_OBJECT RealDevice,
OUT PFILE_OBJECT *FileObject
)
{
NTSTATUS ntStatus;
HANDLE hFile;
PFILE_OBJECT _FileObject;
UNICODE_STRING UniDeviceNameString;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
WCHAR *FileNameBuffer=NULL;
WORD FileObjectSize;
PIRP Irp;
KEVENT kEvent;
PIO_STACK_LOCATION IrpSp;
ACCESS_STATE AccessState;
AUX_ACCESS_DATA AuxData;
IO_SECURITY_CONTEXT SecurityContext;
PLIST_ENTRY IrpList;
InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_CASE_INSENSITIVE, 0, NULL);
//in win7 x86
FileObjectSize=0x80;
//创建文件对象
ntStatus = ObCreateObject(KernelMode,
*IoFileObjectType,
&ObjectAttributes,
KernelMode,
NULL,
FileObjectSize,
0,
0,
&_FileObject);
if(!NT_SUCCESS(ntStatus))
{
return ntStatus;
}
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); //在Irp堆栈上申请内存空间 大小为之前查询的DeviceObject->Size
if(Irp == NULL)
{
ObDereferenceObject(_FileObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
RtlZeroMemory(_FileObject, FileObjectSize);
_FileObject->Type = IO_TYPE_FILE; //文件对象类型
_FileObject->Size = FileObjectSize; //文件对象大小
_FileObject->DeviceObject = RealDevice; //查询到的卷设备
_FileObject->Flags = FO_SYNCHRONOUS_IO;
FileNameBuffer=ExAllocatePool(NonPagedPool,FilePath->MaximumLength);
if (FileNameBuffer==NULL)
{
ObDereferenceObject(_FileObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyMemory(FileNameBuffer,FilePath->Buffer,FilePath->Length);//文件对象中的文件路径
_FileObject->FileName.Buffer=FileNameBuffer; //
_FileObject->FileName.Length=FilePath->Length;
_FileObject->FileName.MaximumLength=FilePath->MaximumLength;
IrpList=(PLIST_ENTRY)((DWORD)FileObject+0x74); //IrpList 循环指向自身
IrpList->Flink=IrpList;
IrpList->Blink=IrpList;
KeInitializeEvent(&_FileObject->Lock, SynchronizationEvent, FALSE);
KeInitializeEvent(&_FileObject->Event, NotificationEvent, FALSE);
RtlZeroMemory(&AuxData, sizeof(AUX_ACCESS_DATA));
ntStatus = SeCreateAccessState( &AccessState, //访问权限
&AuxData,
DesiredAccess,
IoGetFileObjectGenericMapping());
if (!NT_SUCCESS(ntStatus))
{
IoFreeIrp(Irp);
ObDereferenceObject(_FileObject);
ExFreePool(FileNameBuffer);
return ntStatus;
}
SecurityContext.SecurityQos = NULL;
SecurityContext.AccessState = &AccessState;
SecurityContext.DesiredAccess = DesiredAccess;
SecurityContext.FullCreateOptions = 0;
Irp->MdlAddress = NULL;
Irp->AssociatedIrp.SystemBuffer = NULL;
Irp->Flags = IRP_CREATE_OPERATION|IRP_SYNCHRONOUS_API;
Irp->RequestorMode = KernelMode;
Irp->UserIosb = &IoStatusBlock;
Irp->UserEvent = &kEvent;
Irp->PendingReturned = FALSE;
Irp->Cancel = FALSE;
Irp->CancelRoutine = NULL;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
Irp->Tail.Overlay.OriginalFileObject = _FileObject;
IrpSp = IoGetNextIrpStackLocation(Irp);
IrpSp->MajorFunction = IRP_MJ_CREATE;
IrpSp->DeviceObject = DeviceObject;
IrpSp->FileObject = _FileObject;
IrpSp->Parameters.Create.SecurityContext = &SecurityContext;
IrpSp->Parameters.Create.Options = (CreateDisposition << 24) | CreateOptions;
IrpSp->Parameters.Create.FileAttributes = (USHORT)FileAttributes;
IrpSp->Parameters.Create.ShareAccess = (USHORT)ShareAccess;
IrpSp->Parameters.Create.EaLength = 0;
IoSetCompletionRoutine(Irp, IoCompletionRoutine, 0, TRUE, TRUE, TRUE);
ntStatus = IoCallDriver(DeviceObject, Irp);
if(ntStatus == STATUS_PENDING)
KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, 0);
ntStatus = IoStatusBlock.Status;
if(!NT_SUCCESS(ntStatus))
{
_FileObject->DeviceObject = NULL;
ObDereferenceObject(_FileObject);
}
else
{//增加引用计数
InterlockedIncrement(&_FileObject->DeviceObject->ReferenceCount);
if (_FileObject->Vpb)
InterlockedIncrement(&_FileObject->Vpb->ReferenceCount);
*FileObject = _FileObject;
}
return ntStatus;
}
NTSTATUS
IoCompletionRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context)
{
*Irp->UserIosb = Irp->IoStatus;
if (Irp->UserEvent)
KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, 0);
if (Irp->MdlAddress)
{
IoFreeMdl(Irp->MdlAddress);
Irp->MdlAddress = NULL;
}
IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}
//查询irp堆栈信息,传入FileObject
NTSTATUS
IrpQueryInformationFile(
IN PFILE_OBJECT FileObject,
IN PDEVICE_OBJECT DeviceObject,
OUT PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass)
{
NTSTATUS ntStatus;
PIRP Irp;
KEVENT kEvent;
PIO_STACK_LOCATION IrpSp;
IO_STATUS_BLOCK IoStatusBlock;
// if (FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL)
// return STATUS_UNSUCCESSFUL;
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if(Irp == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
RtlZeroMemory(FileInformation, Length);
Irp->AssociatedIrp.SystemBuffer = FileInformation;
Irp->UserEvent = &kEvent;
Irp->UserIosb = &IoStatusBlock;
Irp->RequestorMode = KernelMode;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject;
IrpSp = IoGetNextIrpStackLocation(Irp);
IrpSp->MajorFunction = IRP_MJ_QUERY_INFORMATION;
IrpSp->DeviceObject = DeviceObject;
IrpSp->FileObject = FileObject;
IrpSp->Parameters.QueryFile.Length = Length;
IrpSp->Parameters.QueryFile.FileInformationClass = FileInformationClass;
IoSetCompletionRoutine(Irp, IoCompletionRoutine, 0, TRUE, TRUE, TRUE);
ntStatus = IoCallDriver(DeviceObject, Irp);
if (ntStatus == STATUS_PENDING)
KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, 0);
return IoStatusBlock.Status;
}
//Irp请求,将文件读入缓冲区中
NTSTATUS
IrpReadFile(
IN PFILE_OBJECT FileObject,
IN PDEVICE_OBJECT DeviceObject,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL)
{
NTSTATUS ntStatus;
PIRP Irp;
KEVENT kEvent;
PIO_STACK_LOCATION IrpSp;
//
if(ByteOffset == NULL)
{
if(!(FileObject->Flags & FO_SYNCHRONOUS_IO))
return STATUS_INVALID_PARAMETER;
ByteOffset = &FileObject->CurrentByteOffset;
}
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if(Irp == NULL) return STATUS_INSUFFICIENT_RESOURCES;
RtlZeroMemory(Buffer, Length);
if(FileObject->DeviceObject->Flags & DO_BUFFERED_IO) //缓冲方式
{
Irp->AssociatedIrp.SystemBuffer = Buffer;
}
else if(FileObject->DeviceObject->Flags & DO_DIRECT_IO) //直接方式
{
Irp->MdlAddress = IoAllocateMdl(Buffer, Length, 0, 0, 0);
if (Irp->MdlAddress == NULL)
{
IoFreeIrp(Irp);
return STATUS_INSUFFICIENT_RESOURCES;
}
MmBuildMdlForNonPagedPool(Irp->MdlAddress);
}
else //其他方式
{
Irp->UserBuffer = Buffer;
}
KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
Irp->UserEvent = &kEvent;
Irp->UserIosb = IoStatusBlock;
Irp->RequestorMode = KernelMode;
Irp->Flags = IRP_READ_OPERATION;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject;
IrpSp = IoGetNextIrpStackLocation(Irp);
IrpSp->MajorFunction = IRP_MJ_READ;
IrpSp->MinorFunction = IRP_MN_NORMAL;
IrpSp->DeviceObject = DeviceObject;
IrpSp->FileObject = FileObject;
IrpSp->Parameters.Read.Length = Length;
IrpSp->Parameters.Read.ByteOffset = *ByteOffset;
IoSetCompletionRoutine(Irp, IoCompletionRoutine, 0, TRUE, TRUE, TRUE);
ntStatus = IoCallDriver(DeviceObject, Irp);
if (ntStatus == STATUS_PENDING)
KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, 0);
return IoStatusBlock->Status;
}
@@ -0,0 +1,42 @@
#include "Reload.h"
NTSTATUS
IrpCreateFile(
IN PUNICODE_STRING FilePath,
IN ACCESS_MASK DesiredAccess,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PDEVICE_OBJECT DeviceObject,
IN PDEVICE_OBJECT RealDevice,
OUT PFILE_OBJECT *FileObject
);
NTSTATUS
IoCompletionRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context);
NTSTATUS
IrpQueryInformationFile(
IN PFILE_OBJECT FileObject,
IN PDEVICE_OBJECT DeviceObject,
OUT PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass);
//Irp请求,将文件读入缓冲区中
NTSTATUS
IrpReadFile(
IN PFILE_OBJECT FileObject,
IN PDEVICE_OBJECT DeviceObject,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL);
@@ -0,0 +1,461 @@
#include "FixRelocation.h"
/*
重定位表 修复
*/
BOOLEAN
FixBaseRelocTable (
PVOID NewImageBase,
DWORD ExistImageBase
)
{
LONGLONG Diff;
ULONG TotalCountBytes = 0;
ULONG_PTR VA;
ULONGLONG OriginalImageBase;
ULONG SizeOfBlock;
PUCHAR FixupVA;
USHORT Offset;
PUSHORT NextOffset = NULL;
PIMAGE_NT_HEADERS NtHeaders;
PIMAGE_BASE_RELOCATION NextBlock;
NtHeaders = RtlImageNtHeader( NewImageBase );
if (NtHeaders == NULL)
{
return FALSE;
}
switch (NtHeaders->OptionalHeader.Magic) {
case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
OriginalImageBase =
((PIMAGE_NT_HEADERS32)NtHeaders)->OptionalHeader.ImageBase;
break;
case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
OriginalImageBase =
((PIMAGE_NT_HEADERS64)NtHeaders)->OptionalHeader.ImageBase;
break;
default:
return FALSE;
}
//
// Locate the relocation section.
//
NextBlock = (PIMAGE_BASE_RELOCATION)RtlImageDirectoryEntryToData(
NewImageBase, TRUE, IMAGE_DIRECTORY_ENTRY_BASERELOC, &TotalCountBytes);
//
// It is possible for a file to have no relocations, but the relocations
// must not have been stripped.
//
if (!NextBlock || !TotalCountBytes)
{
if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
{
DbgPrint("Image can't be relocated, no fixup information.\n");
return FALSE;
}
else
{
return TRUE;
}
}
//
// If the image has a relocation table, then apply the specified fixup
// information to the image.
//
Diff = (ULONG_PTR)ExistImageBase - OriginalImageBase;
while (TotalCountBytes)
{
SizeOfBlock = NextBlock->SizeOfBlock;
TotalCountBytes -= SizeOfBlock;
SizeOfBlock -= sizeof(IMAGE_BASE_RELOCATION);
SizeOfBlock /= sizeof(USHORT);
NextOffset = (PUSHORT)((PCHAR)NextBlock + sizeof(IMAGE_BASE_RELOCATION));
VA = (ULONG_PTR)NewImageBase + NextBlock->VirtualAddress;
if ( !(NextBlock = LdrProcessRelocationBlockLongLong( VA,
SizeOfBlock,
NextOffset,
Diff)) )
{
DbgPrint("%s: Unknown base relocation type\n");
return FALSE;
}
}
return TRUE;
}
/*修复重定位表*/
PIMAGE_BASE_RELOCATION
LdrProcessRelocationBlockLongLong(
IN ULONG_PTR VA,
IN ULONG SizeOfBlock,
IN PUSHORT NextOffset,
IN LONGLONG Diff
)
{
PUCHAR FixupVA;
USHORT Offset;
LONG Temp;
ULONG Temp32;
ULONGLONG Value64;
LONGLONG Temp64;
while (SizeOfBlock--) {
Offset = *NextOffset & (USHORT)0xfff;
FixupVA = (PUCHAR)(VA + Offset);
//
// Apply the fixups.
//
switch ((*NextOffset) >> 12) {
case IMAGE_REL_BASED_HIGHLOW :
//
// HighLow - (32-bits) relocate the high and low half
// of an address.
//
*(LONG UNALIGNED *)FixupVA += (ULONG) Diff;
break;
case IMAGE_REL_BASED_HIGH :
//
// High - (16-bits) relocate the high half of an address.
//
Temp = *(PUSHORT)FixupVA << 16;
Temp += (ULONG) Diff;
*(PUSHORT)FixupVA = (USHORT)(Temp >> 16);
break;
case IMAGE_REL_BASED_HIGHADJ :
//
// Adjust high - (16-bits) relocate the high half of an
// address and adjust for sign extension of low half.
//
//
// If the address has already been relocated then don't
// process it again now or information will be lost.
//
if (Offset & LDRP_RELOCATION_FINAL) {
++NextOffset;
--SizeOfBlock;
break;
}
Temp = *(PUSHORT)FixupVA << 16;
++NextOffset;
--SizeOfBlock;
Temp += (LONG)(*(PSHORT)NextOffset);
Temp += (ULONG) Diff;
Temp += 0x8000;
*(PUSHORT)FixupVA = (USHORT)(Temp >> 16);
break;
case IMAGE_REL_BASED_LOW :
//
// Low - (16-bit) relocate the low half of an address.
//
Temp = *(PSHORT)FixupVA;
Temp += (ULONG) Diff;
*(PUSHORT)FixupVA = (USHORT)Temp;
break;
case IMAGE_REL_BASED_IA64_IMM64:
//
// Align it to bundle address before fixing up the
// 64-bit immediate value of the movl instruction.
//
FixupVA = (PUCHAR)((ULONG_PTR)FixupVA & ~(15));
Value64 = (ULONGLONG)0;
//
// Extract the lower 32 bits of IMM64 from bundle
//
EXT_IMM64(Value64,
(PULONG)FixupVA + EMARCH_ENC_I17_IMM7B_INST_WORD_X,
EMARCH_ENC_I17_IMM7B_SIZE_X,
EMARCH_ENC_I17_IMM7B_INST_WORD_POS_X,
EMARCH_ENC_I17_IMM7B_VAL_POS_X);
EXT_IMM64(Value64,
(PULONG)FixupVA + EMARCH_ENC_I17_IMM9D_INST_WORD_X,
EMARCH_ENC_I17_IMM9D_SIZE_X,
EMARCH_ENC_I17_IMM9D_INST_WORD_POS_X,
EMARCH_ENC_I17_IMM9D_VAL_POS_X);
EXT_IMM64(Value64,
(PULONG)FixupVA + EMARCH_ENC_I17_IMM5C_INST_WORD_X,
EMARCH_ENC_I17_IMM5C_SIZE_X,
EMARCH_ENC_I17_IMM5C_INST_WORD_POS_X,
EMARCH_ENC_I17_IMM5C_VAL_POS_X);
EXT_IMM64(Value64,
(PULONG)FixupVA + EMARCH_ENC_I17_IC_INST_WORD_X,
EMARCH_ENC_I17_IC_SIZE_X,
EMARCH_ENC_I17_IC_INST_WORD_POS_X,
EMARCH_ENC_I17_IC_VAL_POS_X);
EXT_IMM64(Value64,
(PULONG)FixupVA + EMARCH_ENC_I17_IMM41a_INST_WORD_X,
EMARCH_ENC_I17_IMM41a_SIZE_X,
EMARCH_ENC_I17_IMM41a_INST_WORD_POS_X,
EMARCH_ENC_I17_IMM41a_VAL_POS_X);
EXT_IMM64(Value64,
((PULONG)FixupVA + EMARCH_ENC_I17_IMM41b_INST_WORD_X),
EMARCH_ENC_I17_IMM41b_SIZE_X,
EMARCH_ENC_I17_IMM41b_INST_WORD_POS_X,
EMARCH_ENC_I17_IMM41b_VAL_POS_X);
EXT_IMM64(Value64,
((PULONG)FixupVA + EMARCH_ENC_I17_IMM41c_INST_WORD_X),
EMARCH_ENC_I17_IMM41c_SIZE_X,
EMARCH_ENC_I17_IMM41c_INST_WORD_POS_X,
EMARCH_ENC_I17_IMM41c_VAL_POS_X);
EXT_IMM64(Value64,
((PULONG)FixupVA + EMARCH_ENC_I17_SIGN_INST_WORD_X),
EMARCH_ENC_I17_SIGN_SIZE_X,
EMARCH_ENC_I17_SIGN_INST_WORD_POS_X,
EMARCH_ENC_I17_SIGN_VAL_POS_X);
//
// Update 64-bit address
//
Value64+=Diff;
//
// Insert IMM64 into bundle
//
INS_IMM64(Value64,
((PULONG)FixupVA + EMARCH_ENC_I17_IMM7B_INST_WORD_X),
EMARCH_ENC_I17_IMM7B_SIZE_X,
EMARCH_ENC_I17_IMM7B_INST_WORD_POS_X,
EMARCH_ENC_I17_IMM7B_VAL_POS_X);
INS_IMM64(Value64,
((PULONG)FixupVA + EMARCH_ENC_I17_IMM9D_INST_WORD_X),
EMARCH_ENC_I17_IMM9D_SIZE_X,
EMARCH_ENC_I17_IMM9D_INST_WORD_POS_X,
EMARCH_ENC_I17_IMM9D_VAL_POS_X);
INS_IMM64(Value64,
((PULONG)FixupVA + EMARCH_ENC_I17_IMM5C_INST_WORD_X),
EMARCH_ENC_I17_IMM5C_SIZE_X,
EMARCH_ENC_I17_IMM5C_INST_WORD_POS_X,
EMARCH_ENC_I17_IMM5C_VAL_POS_X);
INS_IMM64(Value64,
((PULONG)FixupVA + EMARCH_ENC_I17_IC_INST_WORD_X),
EMARCH_ENC_I17_IC_SIZE_X,
EMARCH_ENC_I17_IC_INST_WORD_POS_X,
EMARCH_ENC_I17_IC_VAL_POS_X);
INS_IMM64(Value64,
((PULONG)FixupVA + EMARCH_ENC_I17_IMM41a_INST_WORD_X),
EMARCH_ENC_I17_IMM41a_SIZE_X,
EMARCH_ENC_I17_IMM41a_INST_WORD_POS_X,
EMARCH_ENC_I17_IMM41a_VAL_POS_X);
INS_IMM64(Value64,
((PULONG)FixupVA + EMARCH_ENC_I17_IMM41b_INST_WORD_X),
EMARCH_ENC_I17_IMM41b_SIZE_X,
EMARCH_ENC_I17_IMM41b_INST_WORD_POS_X,
EMARCH_ENC_I17_IMM41b_VAL_POS_X);
INS_IMM64(Value64,
((PULONG)FixupVA + EMARCH_ENC_I17_IMM41c_INST_WORD_X),
EMARCH_ENC_I17_IMM41c_SIZE_X,
EMARCH_ENC_I17_IMM41c_INST_WORD_POS_X,
EMARCH_ENC_I17_IMM41c_VAL_POS_X);
INS_IMM64(Value64,
((PULONG)FixupVA + EMARCH_ENC_I17_SIGN_INST_WORD_X),
EMARCH_ENC_I17_SIGN_SIZE_X,
EMARCH_ENC_I17_SIGN_INST_WORD_POS_X,
EMARCH_ENC_I17_SIGN_VAL_POS_X);
break;
case IMAGE_REL_BASED_DIR64:
*(ULONGLONG UNALIGNED *)FixupVA += Diff;
break;
case IMAGE_REL_BASED_MIPS_JMPADDR :
//
// JumpAddress - (32-bits) relocate a MIPS jump address.
//
Temp = (*(PULONG)FixupVA & 0x3ffffff) << 2;
Temp += (ULONG) Diff;
*(PULONG)FixupVA = (*(PULONG)FixupVA & ~0x3ffffff) |
((Temp >> 2) & 0x3ffffff);
break;
case IMAGE_REL_BASED_ABSOLUTE :
//
// Absolute - no fixup required.
//
break;
case IMAGE_REL_BASED_SECTION :
//
// Section Relative reloc. Ignore for now.
//
break;
case IMAGE_REL_BASED_REL32 :
//
// Relative intrasection. Ignore for now.
//
break;
default :
//
// Illegal - illegal relocation type.
//
return (PIMAGE_BASE_RELOCATION)NULL;
}
++NextOffset;
}
return (PIMAGE_BASE_RELOCATION)NextOffset;
}
/*
获得NtHeader
*/
NTSTATUS
NTAPI
RtlImageNtHeaderEx(
ULONG Flags,
PVOID Base,
ULONG64 Size,
OUT PIMAGE_NT_HEADERS * OutHeaders
)
{
PIMAGE_NT_HEADERS NtHeaders = 0;
ULONG e_lfanew = 0;
BOOLEAN RangeCheck = 0;
NTSTATUS Status = 0;
const ULONG ValidFlags =
RTL_IMAGE_NT_HEADER_EX_FLAG_NO_RANGE_CHECK;
if (OutHeaders != NULL) {
*OutHeaders = NULL;
}
if (OutHeaders == NULL) {
Status = STATUS_INVALID_PARAMETER;
goto Exit;
}
if ((Flags & ~ValidFlags) != 0) {
Status = STATUS_INVALID_PARAMETER;
goto Exit;
}
if (Base == NULL || Base == (PVOID)(LONG_PTR)-1) {
Status = STATUS_INVALID_PARAMETER;
goto Exit;
}
RangeCheck = ((Flags & RTL_IMAGE_NT_HEADER_EX_FLAG_NO_RANGE_CHECK) == 0);
if (RangeCheck) {
if (Size < sizeof(IMAGE_DOS_HEADER)) {
Status = STATUS_INVALID_IMAGE_FORMAT;
goto Exit;
}
}
//
// Exception handling is not available in the boot loader, and exceptions
// were not historically caught here in kernel mode. Drivers are considered
// trusted, so we can't get an exception here due to a bad file, but we
// could take an inpage error.
//
#define EXIT goto Exit
if (((PIMAGE_DOS_HEADER)Base)->e_magic != IMAGE_DOS_SIGNATURE) {
Status = STATUS_INVALID_IMAGE_FORMAT;
EXIT;
}
e_lfanew = ((PIMAGE_DOS_HEADER)Base)->e_lfanew;
if (RangeCheck) {
if (e_lfanew >= Size
#define SIZEOF_PE_SIGNATURE 4
|| e_lfanew >= (MAXULONG - SIZEOF_PE_SIGNATURE - sizeof(IMAGE_FILE_HEADER))
|| (e_lfanew + SIZEOF_PE_SIGNATURE + sizeof(IMAGE_FILE_HEADER)) >= Size
) {
Status = STATUS_INVALID_IMAGE_FORMAT;
EXIT;
}
}
NtHeaders = (PIMAGE_NT_HEADERS)((PCHAR)Base + e_lfanew);
//
// In kernelmode, do not cross from usermode address to kernelmode address.
//
if (Base < MM_HIGHEST_USER_ADDRESS) {
if ((PVOID)NtHeaders >= MM_HIGHEST_USER_ADDRESS) {
Status = STATUS_INVALID_IMAGE_FORMAT;
EXIT;
}
//
// Note that this check is slightly overeager since IMAGE_NT_HEADERS has
// a builtin array of data_directories that may be larger than the image
// actually has. A better check would be to add FileHeader.SizeOfOptionalHeader,
// after ensuring that the FileHeader does not cross the u/k boundary.
//
if ((PVOID)((PCHAR)NtHeaders + sizeof (IMAGE_NT_HEADERS)) >= MM_HIGHEST_USER_ADDRESS) {
Status = STATUS_INVALID_IMAGE_FORMAT;
EXIT;
}
}
if (NtHeaders->Signature != IMAGE_NT_SIGNATURE) {
Status = STATUS_INVALID_IMAGE_FORMAT;
EXIT;
}
Status = STATUS_SUCCESS;
Exit:
if (NT_SUCCESS(Status)) {
*OutHeaders = NtHeaders;
}
return Status;
}
//
// PIMAGE_NT_HEADERS
// NTAPI
// RtlImageNtHeader(
// PVOID Base
// )
// {
// PIMAGE_NT_HEADERS NtHeaders = NULL;
// (VOID)RtlImageNtHeaderEx(RTL_IMAGE_NT_HEADER_EX_FLAG_NO_RANGE_CHECK, Base, 0, &NtHeaders);
// return NtHeaders;
// }
//
//
@@ -0,0 +1,33 @@
#include "Reload.h"
BOOLEAN
FixBaseRelocTable (
PVOID NewImageBase,
DWORD ExistImageBase
);
PIMAGE_BASE_RELOCATION
LdrProcessRelocationBlockLongLong(
IN ULONG_PTR VA,
IN ULONG SizeOfBlock,
IN PUSHORT NextOffset,
IN LONGLONG Diff
);
NTSTATUS
NTAPI
RtlImageNtHeaderEx(
ULONG Flags,
PVOID Base,
ULONG64 Size,
OUT PIMAGE_NT_HEADERS * OutHeaders
);
PIMAGE_NT_HEADERS
NTAPI
RtlImageNtHeader(
PVOID Base
);
@@ -0,0 +1,694 @@
#include "KernelHookCheck.h"
#include "libdasm.h"
#include "Common.h"
#include "Reload.h"
ULONG IntHookCount; //记录Hook数量
extern DWORD OriginalKiServiceTable;
extern PSERVICE_DESCRIPTOR_TABLE OriginalServiceDescriptorTable;
extern ULONG_PTR SystemKernelModuleBase;
extern ULONG_PTR SystemKernelModuleSize;
extern ULONG_PTR ImageModuleBase;
BOOLEAN KernelHookCheck(PINLINEHOOKINFO InlineHookInfo)
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PIMAGE_NT_HEADERS NtHeader;
PIMAGE_EXPORT_DIRECTORY ExportTable;
ULONG* FunctionAddresses;
ULONG* FunctionNames;
USHORT* FunctionIndexs;
ULONG ulIndex;
ULONG i;
CHAR* szFunctionName;
SIZE_T ViewSize=0;
ULONG_PTR ulFunctionAddress;
BOOL bIsZwFunction = FALSE;
ULONG ulOldAddress;
ULONG ulReloadAddress;
PUCHAR ulTemp;
__try{
NtHeader = RtlImageNtHeader((PVOID)ImageModuleBase);
if (NtHeader && NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress){
ExportTable =(IMAGE_EXPORT_DIRECTORY*)((ULONG_PTR)ImageModuleBase + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
FunctionAddresses = (ULONG*)((ULONG_PTR)ImageModuleBase + ExportTable->AddressOfFunctions);
FunctionNames = (ULONG*)((ULONG_PTR)ImageModuleBase + ExportTable->AddressOfNames);
FunctionIndexs = (USHORT*)((ULONG_PTR)ImageModuleBase + ExportTable->AddressOfNameOrdinals);
for(i = 0; i < ExportTable->NumberOfNames; i++)
{
szFunctionName = (LPSTR)((ULONG_PTR)ImageModuleBase + FunctionNames[i]);
ulIndex = FunctionIndexs[i];
ulFunctionAddress = (ULONG_PTR)((ULONG_PTR)ImageModuleBase + FunctionAddresses[ulIndex]);
// ulIndex=*(ULONG*)(ulFunctionAddress+1); //32 bit 1 64 bit 4 //服务号
//对于非Zw系列函数 偏移到系统的该函数地址处
ulReloadAddress = ulFunctionAddress;
ulOldAddress = ulReloadAddress - (ULONG)ImageModuleBase + SystemKernelModuleBase;
if (!ulOldAddress ||
!MmIsAddressValid((PVOID)ulOldAddress) ||
!ulReloadAddress ||
!MmIsAddressValid((PVOID)ulReloadAddress))
{
continue;
}
bIsZwFunction = FALSE;
//检查下一层第一个call的函数的hook
if (*szFunctionName == 'Z' &&
*(szFunctionName+1) == 'w')
{
bIsZwFunction = TRUE;
ulIndex = *((WORD*)(ulFunctionAddress + 1)); //得到服务号
if (ulIndex > 0 &&
ulIndex <= OriginalServiceDescriptorTable->TableSize)
{
//对于Zw系列函数 获得系统Ntos中 对应的Nt函数的地址
ulReloadAddress = OriginalServiceDescriptorTable->ServiceTable[ulIndex];
ulOldAddress = ulReloadAddress - (ULONG)ImageModuleBase + SystemKernelModuleBase;
}
}
if (bIsZwFunction)
{
//如果 bIsZwFunction == TRUE 重新效验一下地址的有效性
if (!ulOldAddress ||
!MmIsAddressValid((PVOID)ulOldAddress) ||
!ulReloadAddress ||
!MmIsAddressValid((PVOID)ulReloadAddress))
{
continue;
}
}
else //下一层函数只扫描非Zw开头的,并且只扫描未导出函数
{
GetNextFunctionAddress(ImageModuleBase,ulOldAddress,szFunctionName,InlineHookInfo);
}
ulTemp = NULL;
//对于Zw中的Nt函数 、 导出函数
//判断是否Ntos 导出表Hook
//ulOldAddress 是根据重载地址 - Base + KernelBase 真正函数的地址
ulTemp = (PUCHAR)GetEatHook(ulOldAddress,i,SystemKernelModuleBase,SystemKernelModuleSize); //比较EAT Hook
if(ulTemp)
{//导出表Hook了
FillInlineHookInfo(ulTemp,InlineHookInfo,szFunctionName,ulOldAddress,1); //EAT Hook 1
}
//是否是InlineHook
CheckFuncByOpcode((PVOID)ulReloadAddress,InlineHookInfo,szFunctionName,(PVOID)ulOldAddress);
}
}
}__except(EXCEPTION_EXECUTE_HANDLER)
{
}
return STATUS_SUCCESS;
}
VOID FillInlineHookInfo(PUCHAR ulTemp,PINLINEHOOKINFO InlineHookInfo,CHAR* szFunctionName,ULONG ulOldAddress,ULONG HookType)
{
ULONG ulHookModuleBase;
ULONG ulHookModuleSize;
char lpszHookModuleImage[256];
ULONG IntHookCount = InlineHookInfo->ulCount;
memset(lpszHookModuleImage,0,sizeof(lpszHookModuleImage));
if (!IsAddressInSystem(
(ULONG)ulTemp,
&ulHookModuleBase,
&ulHookModuleSize,
lpszHookModuleImage))
{
memset(lpszHookModuleImage,0,sizeof(lpszHookModuleImage));
strcat(lpszHookModuleImage,"Unknown4");
ulHookModuleBase = 0;
ulHookModuleSize = 0;
}
InlineHookInfo->InlineHook[IntHookCount].ulMemoryHookBase = (ULONG)ulTemp;
memset(InlineHookInfo->InlineHook[IntHookCount].lpszFunction,0,sizeof(InlineHookInfo->InlineHook[IntHookCount].lpszFunction));
memset(InlineHookInfo->InlineHook[IntHookCount].lpszHookModuleImage,0,sizeof(InlineHookInfo->InlineHook[IntHookCount].lpszHookModuleImage));
memcpy(InlineHookInfo->InlineHook[IntHookCount].lpszFunction,szFunctionName,strlen(szFunctionName));
memcpy(InlineHookInfo->InlineHook[IntHookCount].lpszHookModuleImage,lpszHookModuleImage,strlen(lpszHookModuleImage));
InlineHookInfo->InlineHook[IntHookCount].ulMemoryFunctionBase = (ULONG)ulOldAddress;
InlineHookInfo->InlineHook[IntHookCount].ulHookModuleBase = ulHookModuleBase;
InlineHookInfo->InlineHook[IntHookCount].ulHookModuleSize = ulHookModuleSize;
InlineHookInfo->InlineHook[IntHookCount].ulHookType = HookType; //eat hook 1 Inline Hook 0
IntHookCount++;
InlineHookInfo->ulCount++;
}
VOID CheckFuncByOpcode(PVOID ulReloadAddress,PINLINEHOOKINFO InlineHookInfo,CHAR* szFunctionName,PVOID ulOldAddress)
{
INSTRUCTION Inst;
INSTRUCTION Instb;
ULONG ulHookFunctionAddress;
size_t ulCodeSize;
PUCHAR p;
PUCHAR ulTemp;
int Flagss;
if (GetFunctionCodeSize(ulOldAddress) == GetFunctionCodeSize(ulReloadAddress) &&
memcmp(ulReloadAddress,ulOldAddress,GetFunctionCodeSize(ulOldAddress)) != 0)
{//被Hook了
//开始扫描hooksss
ulCodeSize = GetFunctionCodeSize(ulOldAddress);
for (p = (PUCHAR)ulOldAddress ;(ULONG)p < (ULONG)ulOldAddress+ulCodeSize; p++)
{
//折半扫描,如果前面一半一样,则开始扫描下一半
if (memcmp(ulReloadAddress,ulOldAddress,ulCodeSize/2) == 0)
{
ulCodeSize = ulCodeSize + ulCodeSize/2;
continue;
}
if (*p == 0xcc ||
*p == 0xc2)
{
break;
}
ulHookFunctionAddress = (*(PULONG)(p + 1) + (ULONG)p + 5); //得到hook的地址
if (!MmIsAddressValid((PVOID)ulHookFunctionAddress))
{
continue;
}
ulTemp = NULL;
get_instruction(&Inst,p,MODE_32);
switch (Inst.type)
{
case INSTRUCTION_TYPE_JMP:
if(Inst.opcode==0xFF&&Inst.modrm==0x25)
{
//DIRECT_JMP
ulTemp = (PUCHAR)Inst.op1.displacement;
}
else if (Inst.opcode==0xEB)
{
ulTemp = (PUCHAR)(p+Inst.op1.immediate);
}
else if(Inst.opcode==0xE9)
{
//RELATIVE_JMP;
ulTemp = (PUCHAR)(p+Inst.op1.immediate);
}
break;
case INSTRUCTION_TYPE_CALL:
if(Inst.opcode==0xFF&&Inst.modrm==0x15)
{
//DIRECT_CALL
ulTemp = (PUCHAR)Inst.op1.displacement;
}
else if (Inst.opcode==0x9A)
{
ulTemp = (PUCHAR)(p+Inst.op1.immediate);
}
else if(Inst.opcode==0xE8)
{
//RELATIVE_CALL;
ulTemp = (PUCHAR)(p+Inst.op1.immediate);
}
break;
case INSTRUCTION_TYPE_PUSH:
if(!RMmIsAddressValid((PVOID)(p)))
{
break;
}
get_instruction(&Instb,(BYTE*)(p),MODE_32);
if(Instb.type == INSTRUCTION_TYPE_RET)
{
//StartAddress+len-inst.length-instb.length;
ulTemp = (PUCHAR)Instb.op1.displacement;
}
break;
}
if (ulTemp &&
RMmIsAddressValid(ulTemp) &&
RMmIsAddressValid(p)) //hook的地址也要有效才可以哦
{
if ((ULONG)ulTemp > SystemKernelModuleBase &&
(ULONG)ulTemp < SystemKernelModuleBase+SystemKernelModuleSize) //太近的跳也不是
{
goto Next;
}
//ulTemp也不能小于 SystemKernelModuleBase
if ((ULONG)ulTemp < SystemKernelModuleBase)
{
goto Next;
}
//KdPrint(("%08x-%08x-%08x",p,ulTemp,(SystemKernelModuleBase + SystemKernelModuleSize + 0xfffffff)));
if (*(ULONG *)ulTemp == 0x00000000 ||
*(ULONG *)ulTemp == 0x00000005 ||
*(ULONG *)ulTemp == 0xc0000012)
{
goto Next;
}
Flagss = 0;
__asm{
mov esi,ulTemp
mov ax,word ptr [esi]
cmp ax,0x0000
jz Cont//是add byte ptr [eax],al
//结束
mov Flagss,1
Cont:
}
if (Flagss != 1)
goto Next;
ulTemp = ulTemp+0x5;
//简单处理一下二级跳
if (*ulTemp == 0xe9 ||
*ulTemp == 0xe8)
{
ulTemp = (PUCHAR)(*(PULONG)(ulTemp+1)+(ULONG)(ulTemp+5));
}
FillInlineHookInfo(ulTemp,InlineHookInfo,szFunctionName,(ULONG)p,0); //Inline Hook
Next:
_asm{nop}
}
}
}
}
//获取导出函数下一级0xe8 call函数的inlinehookcheck
ULONG GetNextFunctionAddress(ULONG ulNtDllModuleBase,ULONG ulOldAddress,char *functionName,PINLINEHOOKINFO InlineHookInfo)
{
ULONG ulCodeSize;
ULONG ulNextFunCodeSize;
ULONG ulNextFunReloadCodeSize;
PUCHAR i;
PUCHAR ulNextFunctionAddress = NULL;
PUCHAR ulReloadNextFunctionAddress = NULL;
BOOL bRetOK = FALSE;
PUCHAR ulTemp;
ULONG ulHookFunctionAddress;
PUCHAR p;
INSTRUCTION Inst;
INSTRUCTION Instb;
char lpszHookModuleImage[256];
ULONG ulHookModuleBase;
ULONG ulHookModuleSize;
int Flagss;
if (!MmIsAddressValid((PVOID)ulOldAddress))
{
return bRetOK;
}
__try
{
ulCodeSize = GetFunctionCodeSize((PVOID)ulOldAddress);
for (i=(PUCHAR)ulOldAddress;i < i+ulCodeSize;i++)
{
//扫描二次跳转
if (*i == 0xe8)
{
ulNextFunctionAddress = (PUCHAR)(*(PULONG)(i+1)+(ULONG)(i+5));
if (MmIsAddressValid((PVOID)ulNextFunctionAddress))
{
//判断一下是否是导出函数
if (IsFunctionInExportTable(ulNtDllModuleBase,(ULONG)ulNextFunctionAddress))
{
return 0;
}
//做hook 扫描
ulReloadNextFunctionAddress = ulNextFunctionAddress - SystemKernelModuleBase + ImageModuleBase;
if (MmIsAddressValid(ulReloadNextFunctionAddress) &&
MmIsAddressValid(ulNextFunctionAddress))
{
ulNextFunCodeSize = GetFunctionCodeSize(ulNextFunctionAddress);
ulNextFunReloadCodeSize = GetFunctionCodeSize(ulReloadNextFunctionAddress);
if (ulNextFunCodeSize == ulNextFunReloadCodeSize &&
memcmp(ulReloadNextFunctionAddress,ulNextFunctionAddress,ulNextFunCodeSize) != 0)
{
//被hook了
for (p = (PUCHAR)ulNextFunctionAddress ;(ULONG)p < (ULONG)ulNextFunctionAddress+ulNextFunCodeSize; p++)
{
//折半扫描,如果前面一半一样,则开始扫描下一半
if (memcmp(ulReloadNextFunctionAddress, ulNextFunctionAddress,ulNextFunCodeSize/2) == 0)
{
ulNextFunCodeSize = ulNextFunCodeSize + ulNextFunCodeSize/2;
continue;
}
//是否结束?
if (*p == 0xcc ||
*p == 0xc2)
{
break;
}
ulHookFunctionAddress = (*(PULONG)(p + 1) + (ULONG)p + 5); //得到地址
if (!RMmIsAddressValid((PVOID)ulHookFunctionAddress))
{
continue;
}
ulTemp = NULL;
get_instruction(&Inst,p,MODE_32);
switch (Inst.type)
{
case INSTRUCTION_TYPE_JMP:
if(Inst.opcode==0xFF&&Inst.modrm==0x25)
{
//DIRECT_JMP
ulTemp = (PUCHAR)Inst.op1.displacement;
}
else if (Inst.opcode==0xEB)
{
ulTemp = (PUCHAR)(p+Inst.op1.immediate);
}
else if(Inst.opcode==0xE9)
{
//RELATIVE_JMP;
ulTemp = (PUCHAR)(p+Inst.op1.immediate);
}
break;
case INSTRUCTION_TYPE_CALL:
if(Inst.opcode==0xFF&&Inst.modrm==0x15)
{
//DIRECT_CALL
ulTemp = (PUCHAR)Inst.op1.displacement;
}
else if (Inst.opcode==0x9A)
{
ulTemp = (PUCHAR)(p+Inst.op1.immediate);
}
else if(Inst.opcode==0xE8)
{
//RELATIVE_CALL;
ulTemp = (PUCHAR)(p+Inst.op1.immediate);
}
break;
case INSTRUCTION_TYPE_PUSH:
if(!RMmIsAddressValid((PVOID)(p)))
{
break;
}
get_instruction(&Instb,(BYTE*)(p),MODE_32);
if(Instb.type == INSTRUCTION_TYPE_RET)
{
//StartAddress+len-inst.length-instb.length;
ulTemp = (PUCHAR)Instb.op1.displacement;
}
break;
}
if (ulTemp &&
MmIsAddressValid(ulTemp) &&
MmIsAddressValid(p)) //hook的地址也要有效才可以哦
{
if ((ULONG)ulTemp > SystemKernelModuleBase &&
(ULONG)ulTemp < SystemKernelModuleBase+SystemKernelModuleSize) //太近的跳也不是
{
goto Next;
}
//ulTemp也不能小于 SystemKernelModuleBase
if ((ULONG)ulTemp < SystemKernelModuleBase)
{
goto Next;
}
if (*(ULONG *)ulTemp == 0x00000000 ||
*(ULONG *)ulTemp == 0x00000005)
{
goto Next;
}
Flagss = 0;
__asm{
mov esi,ulTemp
mov ax,word ptr [esi]
cmp ax,0x0000
jz Cont//是add byte ptr [eax],al
mov Flagss,1
Cont:
}
if (Flagss != 1)
goto Next;
ulTemp = ulTemp+0x5;
//简单处理一下二级跳
if (*ulTemp == 0xe9 ||
*ulTemp == 0xe8)
{
ulTemp = (PUCHAR)(*(PULONG)(ulTemp+1)+(ULONG)(ulTemp+5));
}
FillInlineHookInfo(ulTemp+0x5,InlineHookInfo,functionName,(ULONG)p,2);
Next:
_asm{nop}
}
}
}
}
}
}
//结束鸟
if (*i == 0xcc ||
*i == 0xc2)
{
return 0;
}
}
}__except(EXCEPTION_EXECUTE_HANDLER){
}
return 0;
}
BOOLEAN IsFunctionInExportTable(ULONG ulModuleBase,ULONG ulFunctionAddress)
{
PIMAGE_DOS_HEADER pDosHeader;
PIMAGE_NT_HEADERS NtDllHeader;
IMAGE_OPTIONAL_HEADER opthdr;
DWORD* arrayOfFunctionAddresses;
DWORD* arrayOfFunctionNames;
WORD* arrayOfFunctionOrdinals;
DWORD functionOrdinal;
DWORD Base, x, functionAddress,ulOldAddress;
IMAGE_EXPORT_DIRECTORY *pExportTable;
char *functionName;
__try
{
pDosHeader=(PIMAGE_DOS_HEADER)ulModuleBase;
if (pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
{
KdPrint(("failed to find NtHeader\r\n"));
return FALSE;
}
NtDllHeader=(PIMAGE_NT_HEADERS)(ULONG)((ULONG)pDosHeader+pDosHeader->e_lfanew);
if (NtDllHeader->Signature!=IMAGE_NT_SIGNATURE)
{
KdPrint(("failed to find NtHeader\r\n"));
return FALSE;
}
opthdr = NtDllHeader->OptionalHeader;
pExportTable =(IMAGE_EXPORT_DIRECTORY*)((BYTE*)ulModuleBase + opthdr.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT]. VirtualAddress); //得到导出表
arrayOfFunctionAddresses = (DWORD*)( (BYTE*)ulModuleBase + pExportTable->AddressOfFunctions); //地址表
arrayOfFunctionNames = (DWORD*)((BYTE*)ulModuleBase + pExportTable->AddressOfNames); //函数名表
arrayOfFunctionOrdinals = (WORD*)( (BYTE*)ulModuleBase + pExportTable->AddressOfNameOrdinals);
Base = pExportTable->Base;
for(x = 0; x < pExportTable->NumberOfFunctions; x++) //在整个导出表里扫描
{
//functionName = (char*)((BYTE*)ulModuleBase + arrayOfFunctionNames[x]);
functionOrdinal = arrayOfFunctionOrdinals[x] + Base - 1;
functionAddress = (DWORD)((BYTE*)ulModuleBase + arrayOfFunctionAddresses[functionOrdinal]);
//KdPrint(("%08x:%s\r\n",functionAddress,functionName));
//ulOldAddress = GetSystemRoutineAddress(0,functionName);
ulOldAddress = functionAddress - ulModuleBase + SystemKernelModuleBase;
if (ulFunctionAddress == ulOldAddress)
{
//是导出函数,退出
return TRUE;
}
}
}__except(EXCEPTION_EXECUTE_HANDLER){
}
return FALSE;
}
BOOLEAN ReSetEatHook(CHAR *lpszFunction,ULONG ulReloadKernelModule,ULONG ulKernelModule)
{
ULONG ulModuleBase;
PIMAGE_DOS_HEADER pDosHeader;
PIMAGE_NT_HEADERS NtDllHeader;
IMAGE_OPTIONAL_HEADER opthdr;
DWORD* arrayOfFunctionAddresses;
DWORD* arrayOfFunctionNames;
WORD* arrayOfFunctionOrdinals;
DWORD functionOrdinal;
DWORD Base,x,functionAddress;
IMAGE_EXPORT_DIRECTORY *pExportTable;
char *functionName = NULL;
BOOL bIsEatHooked = FALSE;
int position;
ULONG ulFunctionOrdinal;
//恢复的时候 用reload的ImageModuleBase
ulModuleBase = ulReloadKernelModule;
pDosHeader = (PIMAGE_DOS_HEADER)ulModuleBase;
if (pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
{
KdPrint(("failed to find NtHeader\r\n"));
return 0;
}
NtDllHeader=(PIMAGE_NT_HEADERS)(ULONG)((ULONG)pDosHeader+pDosHeader->e_lfanew);
if (NtDllHeader->Signature!=IMAGE_NT_SIGNATURE)
{
KdPrint(("failed to find NtHeader\r\n"));
return 0;
}
opthdr = NtDllHeader->OptionalHeader;
pExportTable =(IMAGE_EXPORT_DIRECTORY*)((BYTE*)ulModuleBase + opthdr.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT]. VirtualAddress); //得到导出表
arrayOfFunctionAddresses = (DWORD*)( (BYTE*)ulModuleBase + pExportTable->AddressOfFunctions); //地址表
arrayOfFunctionNames = (DWORD*)((BYTE*)ulModuleBase + pExportTable->AddressOfNames); //函数名表
arrayOfFunctionOrdinals = (WORD*)( (BYTE*)ulModuleBase + pExportTable->AddressOfNameOrdinals);
Base = pExportTable->Base;
for(x = 0; x < pExportTable->NumberOfFunctions; x++) //在整个导出表里扫描
{
functionName = (char*)((BYTE*)ulModuleBase + arrayOfFunctionNames[x]);
ulFunctionOrdinal = arrayOfFunctionOrdinals[x] + Base - 1;
ulFunctionOrdinal = arrayOfFunctionAddresses[ulFunctionOrdinal];
functionAddress = (DWORD)((BYTE*)ulModuleBase + ulFunctionOrdinal);
if (_stricmp(lpszFunction,functionName) == 0)
{
KdPrint(("reload ulFunctionOrdinal:%08x:%s",ulFunctionOrdinal,functionName));
//开始恢复
ulModuleBase = ulKernelModule;
pDosHeader = (PIMAGE_DOS_HEADER)ulModuleBase;
if (pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
{
KdPrint(("failed to find NtHeader\r\n"));
return 0;
}
NtDllHeader=(PIMAGE_NT_HEADERS)(ULONG)((ULONG)pDosHeader+pDosHeader->e_lfanew);
if (NtDllHeader->Signature!=IMAGE_NT_SIGNATURE)
{
KdPrint(("failed to find NtHeader\r\n"));
return 0;
}
opthdr = NtDllHeader->OptionalHeader;
pExportTable =(IMAGE_EXPORT_DIRECTORY*)((BYTE*)ulModuleBase + opthdr.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT]. VirtualAddress); //得到导出表
arrayOfFunctionAddresses = (DWORD*)( (BYTE*)ulModuleBase + pExportTable->AddressOfFunctions); //地址表
arrayOfFunctionNames = (DWORD*)((BYTE*)ulModuleBase + pExportTable->AddressOfNames); //函数名表
arrayOfFunctionOrdinals = (WORD*)( (BYTE*)ulModuleBase + pExportTable->AddressOfNameOrdinals);
Base = pExportTable->Base;
_asm
{
CLI
MOV EAX, CR0
AND EAX, NOT 10000H
MOV CR0, EAX
}
arrayOfFunctionAddresses[arrayOfFunctionOrdinals[x] + Base - 1] = ulFunctionOrdinal;
_asm
{
MOV EAX, CR0
OR EAX, 10000H
MOV CR0, EAX
STI
}
break;
}
}
return TRUE;
}
ULONG GetEatHook(ULONG ulOldAddress,int x,ULONG ulSystemKernelModuleBase,ULONG ulSystemKernelModuleSize)
{
ULONG ulModuleBase;
PIMAGE_DOS_HEADER pDosHeader;
PIMAGE_NT_HEADERS NtDllHeader;
IMAGE_OPTIONAL_HEADER opthdr;
DWORD* arrayOfFunctionAddresses;
DWORD* arrayOfFunctionNames;
WORD* arrayOfFunctionOrdinals;
DWORD functionOrdinal;
DWORD Base,functionAddress;
IMAGE_EXPORT_DIRECTORY *pExportTable;
char *functionName = NULL;
BOOL bIsEatHooked = FALSE;
ULONG position = 0;
ULONG ulFunctionOrdinal;
ulModuleBase = ulSystemKernelModuleBase;
pDosHeader = (PIMAGE_DOS_HEADER)ulModuleBase;
if (pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
{
KdPrint(("failed to find NtHeader\r\n"));
return 0;
}
NtDllHeader=(PIMAGE_NT_HEADERS)(ULONG)((ULONG)pDosHeader+pDosHeader->e_lfanew);
if (NtDllHeader->Signature!=IMAGE_NT_SIGNATURE)
{
KdPrint(("failed to find NtHeader\r\n"));
return 0;
}
opthdr = NtDllHeader->OptionalHeader;
pExportTable =(IMAGE_EXPORT_DIRECTORY*)((BYTE*)ulModuleBase + opthdr.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT]. VirtualAddress); //得到导出表
arrayOfFunctionAddresses = (DWORD*)( (BYTE*)ulModuleBase + pExportTable->AddressOfFunctions); //地址表
arrayOfFunctionNames = (DWORD*)((BYTE*)ulModuleBase + pExportTable->AddressOfNames); //函数名表
arrayOfFunctionOrdinals = (WORD*)( (BYTE*)ulModuleBase + pExportTable->AddressOfNameOrdinals);
Base = pExportTable->Base;
functionName = (char*)((BYTE*)ulModuleBase + arrayOfFunctionNames[x]);
ulFunctionOrdinal = arrayOfFunctionOrdinals[x] + Base - 1;
functionAddress = (DWORD)((BYTE*)ulModuleBase + arrayOfFunctionAddresses[ulFunctionOrdinal]);
if (*functionName == 'Z' &&
*(functionName+1) == 'w')
{
position = *((WORD*)(functionAddress + 1)); //得到服务号
if (position > 0 &&
position <= OriginalServiceDescriptorTable->TableSize)
{
//得到原始地址
functionAddress = OriginalServiceDescriptorTable->ServiceTable[position] - (ULONG)ImageModuleBase + SystemKernelModuleBase;
}
}
if (ulOldAddress != functionAddress)
{
KdPrint(("EAT HOOK %08x:%s\r\n",functionAddress,functionName));
return functionAddress;
}
return 0;
}
@@ -0,0 +1,11 @@
#include "DriverEntry.h"
BOOLEAN KernelHookCheck(PINLINEHOOKINFO InlineHookInfo);
VOID FillInlineHookInfo(PUCHAR ulTemp,PINLINEHOOKINFO InlineHookInfo,CHAR* szFunctionName,ULONG ulOldAddress,ULONG HookType);
VOID CheckFuncByOpcode(PVOID ulReloadAddress,PINLINEHOOKINFO InlineHookInfo,CHAR* szFunctionName,PVOID ulOldAddress);
ULONG GetNextFunctionAddress(ULONG ulNtDllModuleBase,ULONG ulOldAddress,char *functionName,PINLINEHOOKINFO InlineHookInfo);
BOOLEAN ReSetEatHook(CHAR *lpszFunction,ULONG ulReloadKernelModule,ULONG ulKernelModule);
ULONG GetEatHook(ULONG ulOldAddress,int x,ULONG ulSystemKernelModuleBase,ULONG ulSystemKernelModuleSize);
BOOLEAN IsFunctionInExportTable(ULONG ulModuleBase,ULONG ulFunctionAddress);
@@ -0,0 +1,820 @@
#include "KernelReload.h"
#include "FileSystem.h"
#include "FixRelocation.h"
/*ZwQuerySystemInformation大法 枚举模块信息 获得第一模块 Ntos..*/
BOOLEAN GetSystemKernelModuleInfo(WCHAR **SystemKernelModulePath,PDWORD SystemKernelModuleBase,PDWORD SystemKernelModuleSize)
{
NTSTATUS status;
ULONG ulSize,i;
PMODULES pModuleList;
char *lpszKernelName=NULL;
ANSI_STRING AnsiKernelModule;
UNICODE_STRING UnicodeKernelModule;
BOOLEAN bRet=TRUE;
__try
{
status=ZwQuerySystemInformation(
SystemModuleInformation,
NULL,
0,
&ulSize
);
if (status != STATUS_INFO_LENGTH_MISMATCH)
{
return FALSE;
}
pModuleList=(PMODULES)ExAllocatePool(NonPagedPool,ulSize);
if (pModuleList)
{
status=ZwQuerySystemInformation(
SystemModuleInformation,
pModuleList,
ulSize,
&ulSize
);
if (!NT_SUCCESS(status))
{
bRet = FALSE;
}
}
if (!bRet)
{
if (pModuleList)
ExFreePool(pModuleList);
return FALSE;
}
*SystemKernelModulePath=ExAllocatePool(NonPagedPool,260*2);
if (*SystemKernelModulePath==NULL)
{
*SystemKernelModuleBase=0;
*SystemKernelModuleSize=0;
return FALSE;
}
lpszKernelName = pModuleList->smi[0].ModuleNameOffset+pModuleList->smi[0].ImageName; //第一模块名称
RtlInitAnsiString(&AnsiKernelModule,lpszKernelName);
RtlAnsiStringToUnicodeString(&UnicodeKernelModule,&AnsiKernelModule,TRUE);
RtlZeroMemory(*SystemKernelModulePath,260*2);
wcscat(*SystemKernelModulePath,L"\\SystemRoot\\system32\\");
memcpy(
*SystemKernelModulePath+wcslen(L"\\SystemRoot\\system32\\"), //第一模块路径
UnicodeKernelModule.Buffer,
UnicodeKernelModule.Length
);
*SystemKernelModuleBase=(DWORD)pModuleList->smi[0].Base; //获得第一模块地址
*SystemKernelModuleSize=(DWORD)pModuleList->smi[0].Size; //获得第一模块大小
ExFreePool(pModuleList);
RtlFreeUnicodeString(&UnicodeKernelModule);
}__except(EXCEPTION_EXECUTE_HANDLER){
}
return TRUE;
}
/*获得文件对象中DeviceObject和RealDevice*/
BOOLEAN IoGetFileSystemVpbInfo(IN PFILE_OBJECT FileObject,PDEVICE_OBJECT *DeviceObject,PDEVICE_OBJECT *RealDevice)
{
//PDEVICE_OBJECT deviceObject;
// If the file object has a mounted Vpb, use its DeviceObject.
if(FileObject->Vpb != NULL && FileObject->Vpb->DeviceObject != NULL)
{
*DeviceObject = FileObject->Vpb->DeviceObject;
*RealDevice= FileObject->Vpb->RealDevice;
// Otherwise, if the real device has a VPB that indicates that it is mounted,
// then use the file system device object associated with the VPB.
}
else if
(
!(FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
&&
FileObject->DeviceObject->Vpb != NULL
&&
FileObject->DeviceObject->Vpb->DeviceObject != NULL
)
{
*DeviceObject = FileObject->DeviceObject->Vpb->DeviceObject;
*RealDevice = FileObject->DeviceObject->Vpb->RealDevice;
// Otherwise, just return the real device object.
}
else
{
*DeviceObject = FileObject->DeviceObject;
*RealDevice=NULL;
}
if (*RealDevice==NULL||*DeviceObject==NULL)
{
return FALSE;
}
// Simply return the resultant file object.
return TRUE;
}
//获得FileObject中的RealDevice和DeviceObject
BOOLEAN GetDeviceObjectFromFileFullName(WCHAR *FileFullName,PDEVICE_OBJECT *RealDevice, PDEVICE_OBJECT *DeviceObject)
{
WCHAR wRootName[32]={0};
UNICODE_STRING RootName;
OBJECT_ATTRIBUTES ObjectAttributes={0};
NTSTATUS status;
HANDLE hFile;
IO_STATUS_BLOCK IoStatus;
PFILE_OBJECT FileObject;
if (FileFullName[0]==0x005C)
{//in \Windows\system32\ntkrnlpa.exe
wcscpy(wRootName,L"\\SystemRoot");
}
else
{
wcscpy(wRootName,L"\\DosDevices\\*:\\");
wRootName[12]=FileFullName[0];
}
RtlInitUnicodeString(&RootName,wRootName);
InitializeObjectAttributes(&ObjectAttributes, &RootName,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
//RootName.Buffer = "\SystemRoot"
status = IoCreateFile(
&hFile,
SYNCHRONIZE,
&ObjectAttributes,
&IoStatus,
0,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
FILE_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0,
0,
NULL,
IO_NO_PARAMETER_CHECKING);
if (!NT_SUCCESS(status))
{
return FALSE;
}
status=ObReferenceObjectByHandle(hFile,1,*IoFileObjectType,KernelMode,&FileObject,NULL);
if (!NT_SUCCESS(status))
{
ZwClose(hFile);
return FALSE;
}
if(!IoGetFileSystemVpbInfo(FileObject,DeviceObject,RealDevice)) //获得FileObject中的deviceObject和RealDevice
{
ObfDereferenceObject(FileObject);
ZwClose(hFile);
return FALSE;
}
ObfDereferenceObject(FileObject);
ZwClose(hFile);
return TRUE;
}
/*获得系统目录*/
BOOLEAN GetWindowsRootName(WCHAR *WindowsRootName)
{
UNICODE_STRING RootName,ObjectName;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE hLink;
NTSTATUS status;
WCHAR *SystemRootName=(WCHAR*)0x7FFE0030;
WCHAR *ObjectNameBuffer=(WCHAR*)ExAllocatePool(NonPagedPool,260*2);
if (ObjectNameBuffer==NULL)
{
return FALSE;
}
RtlZeroMemory(ObjectNameBuffer,260*2);
RtlInitUnicodeString(&RootName,L"\\SystemRoot");
InitializeObjectAttributes(&ObjectAttributes,&RootName,OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
status=ZwOpenSymbolicLinkObject(&hLink,1,&ObjectAttributes);
if (NT_SUCCESS(status))
{
ObjectName.Buffer=ObjectNameBuffer;
ObjectName.Length=0;
ObjectName.MaximumLength=260*2;
status=ZwQuerySymbolicLinkObject(hLink,&ObjectName,NULL);
//ObjectNameBuffer \Device\Harddisk0\Partition1\Windows
if (NT_SUCCESS(status))
{
int ObjectNameLength=ObjectName.Length/2;
int Index;
for (Index=ObjectNameLength-1;Index>0;Index--)
{
if (ObjectNameBuffer[Index]==0x005C)
{
if (!MmIsAddressValid(&WindowsRootName[ObjectNameLength-Index]))
{
break;
}
//\Windows WindowsRootName
RtlCopyMemory(WindowsRootName,&ObjectNameBuffer[Index],(ObjectNameLength-Index)*2);
ExFreePool(ObjectNameBuffer);
return TRUE;
}
}
}
}
ExFreePool(ObjectNameBuffer);
if (!MmIsAddressValid(SystemRootName))
{
return FALSE;
}
if (SystemRootName[1]!=0x003A||SystemRootName[2]!=0x005C)
{
return FALSE;
}
wcscpy(WindowsRootName,&SystemRootName[2]);
return TRUE;
}
/*
自己创建文件对象,挂入FileObject->IrpList 并返回文件句柄
*/
//\SystemRoot\system32\ntkrnlpa.exe
NTSTATUS KernelOpenFile(wchar_t *FileFullName,
PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
ULONG FileAttributes,
ULONG ShareAccess,
ULONG CreateDisposition,
ULONG CreateOptions)
{
WCHAR SystemRootName[32]=L"\\SystemRoot";
WCHAR *FileNodeName=NULL;
UNICODE_STRING FilePath;
PDEVICE_OBJECT RealDevice,DeviceObject;
NTSTATUS status=STATUS_UNSUCCESSFUL;
PFILE_OBJECT FileObject;
FileNodeName=ExAllocatePool(NonPagedPool,260*2);
if (FileNodeName==NULL)
{
return status;
}
RtlZeroMemory(FileNodeName,260*2);
if (_wcsnicmp(FileFullName,SystemRootName,wcslen(SystemRootName))==0) //忘记相等返回什么了 不过应该是不完整路径 这里面是修复
{
//in
int Len;
if(!GetWindowsRootName(FileNodeName)) // \Windows
{
ExFreePool(FileNodeName);
return status;
}
Len=wcslen(SystemRootName);
wcscat(FileNodeName,&FileFullName[Len]);
//FileNodeName == \Windows\system32\ntkrnlpa.exe
//FileFullName == \SystemRoot\system32\ntkrnlpa.exe
}
else
{
if (FileFullName[1]!=0x003A||FileFullName[2]!=0x005C)
{
return status;
}
wcscpy(FileNodeName,&FileFullName[2]);
}
if(!GetDeviceObjectFromFileFullName(FileFullName,&RealDevice,&DeviceObject)) //获得FileObject中的DeviceObject和RealDevice
{
ExFreePool(FileNodeName);
return status;
}
//FileNodeName == \Windows\system32\ntkrnlpa.exe
RtlInitUnicodeString(&FilePath,FileNodeName);
status=IrpCreateFile(&FilePath,DesiredAccess,FileAttributes,ShareAccess,CreateDisposition,CreateOptions,DeviceObject,RealDevice,&FileObject);
//创建文件对象 挂入FileObject->IrpList中
if (!NT_SUCCESS(status))
{
ExFreePool(FileNodeName);
return status;
}
//根据文件对象,获得文件句柄
status=ObOpenObjectByPointer(
FileObject,
OBJ_KERNEL_HANDLE, //verifier下测试要指定OBJ_KERNEL_HANDLE
0,
DesiredAccess|0x100000,
*IoFileObjectType,
0,
FileHandle);
ObfDereferenceObject(FileObject);
return status;
}
//查询irp信息,返回filesize
NTSTATUS KernelGetFileSize(HANDLE hFile, PLARGE_INTEGER FileSize)
{
NTSTATUS status;
PFILE_OBJECT FileObject;
PDEVICE_OBJECT DeviceObject,RealDevice;
FILE_STANDARD_INFORMATION FileInformation;
status=ObReferenceObjectByHandle(hFile, 0, *IoFileObjectType, KernelMode, &FileObject, 0);
if (!NT_SUCCESS(status))
{
return status;
}
if(!IoGetFileSystemVpbInfo(FileObject,&DeviceObject,&RealDevice))
{
ObDereferenceObject(FileObject);
return STATUS_UNSUCCESSFUL;
}
//查询irp堆栈信息,传入FileObject
status=IrpQueryInformationFile(FileObject,DeviceObject,&FileInformation,sizeof(FILE_STANDARD_INFORMATION),FileStandardInformation);
if (!NT_SUCCESS(status))
{
ObDereferenceObject(FileObject);
return status;
}
FileSize->HighPart=FileInformation.EndOfFile.HighPart;
FileSize->LowPart=FileInformation.EndOfFile.LowPart;
ObDereferenceObject(FileObject);
return status;
}
/*
传入文件句柄、文件大小读取文件到内存中
*/
NTSTATUS KernelReadFile(HANDLE hFile, PLARGE_INTEGER ByteOffset, ULONG Length, PVOID FileBuffer, PIO_STATUS_BLOCK IoStatusBlock)
{
NTSTATUS status;
PFILE_OBJECT FileObject;
PDEVICE_OBJECT DeviceObject,RealDevice;
FILE_STANDARD_INFORMATION FileInformation;
status=ObReferenceObjectByHandle(hFile, 0, *IoFileObjectType, KernelMode, &FileObject, 0);
if (!NT_SUCCESS(status))
{
return status;
}
if(!IoGetFileSystemVpbInfo(FileObject,&DeviceObject,&RealDevice))
{
ObDereferenceObject(FileObject);
return STATUS_UNSUCCESSFUL;
}
status=IrpReadFile(FileObject,DeviceObject,IoStatusBlock,FileBuffer,Length,ByteOffset); //Irp请求,将文件读入缓冲区中
ObDereferenceObject(FileObject);
return status;
}
/*
修复FileBuffer中的偏移 按照VirtualAglin 对齐
filebuffer 为读取的内存 ImageModuleBase为系统中的模块地址
*/
BOOLEAN ImageFile(BYTE *FileBuffer,BYTE **ImageModuleBase)
{
PIMAGE_DOS_HEADER ImageDosHeader;
PIMAGE_NT_HEADERS ImageNtHeaders;
PIMAGE_SECTION_HEADER ImageSectionHeader;
DWORD FileAlignment,SectionAlignment,NumberOfSections,SizeOfImage,SizeOfHeaders;
DWORD Index;
BYTE *ImageBase;
DWORD SizeOfNtHeaders;
ImageDosHeader=(PIMAGE_DOS_HEADER)FileBuffer;
if (ImageDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
{
return FALSE;
}
ImageNtHeaders=(PIMAGE_NT_HEADERS)(FileBuffer+ImageDosHeader->e_lfanew);
if (ImageNtHeaders->Signature!=IMAGE_NT_SIGNATURE)
{
return FALSE;
}
FileAlignment=ImageNtHeaders->OptionalHeader.FileAlignment;//0x200
SectionAlignment=ImageNtHeaders->OptionalHeader.SectionAlignment;//0x1000
NumberOfSections=ImageNtHeaders->FileHeader.NumberOfSections;//0x16
SizeOfImage=ImageNtHeaders->OptionalHeader.SizeOfImage;//0x412000
SizeOfHeaders=ImageNtHeaders->OptionalHeader.SizeOfHeaders;//0x800
SizeOfImage=AlignSize(SizeOfImage,SectionAlignment);//0x412000
ImageBase=ExAllocatePool(NonPagedPool,SizeOfImage);
if (ImageBase==NULL)
{
return FALSE;
}
RtlZeroMemory(ImageBase,SizeOfImage);
//0xf8
SizeOfNtHeaders=sizeof(ImageNtHeaders->FileHeader) + sizeof(ImageNtHeaders->Signature)+ImageNtHeaders->FileHeader.SizeOfOptionalHeader;
ImageSectionHeader=(PIMAGE_SECTION_HEADER)((DWORD)ImageNtHeaders+SizeOfNtHeaders);
for (Index=0;Index<NumberOfSections;Index++)
{
ImageSectionHeader[Index].SizeOfRawData=AlignSize(ImageSectionHeader[Index].SizeOfRawData,FileAlignment);
ImageSectionHeader[Index].Misc.VirtualSize=AlignSize(ImageSectionHeader[Index].Misc.VirtualSize,SectionAlignment);
}
if (ImageSectionHeader[NumberOfSections-1].VirtualAddress+ImageSectionHeader[NumberOfSections-1].SizeOfRawData>SizeOfImage)
{//no in
ImageSectionHeader[NumberOfSections-1].SizeOfRawData = SizeOfImage-ImageSectionHeader[NumberOfSections-1].VirtualAddress;
}
RtlCopyMemory(ImageBase,FileBuffer,SizeOfHeaders);
for (Index=0;Index<NumberOfSections;Index++)
{
DWORD FileOffset=ImageSectionHeader[Index].PointerToRawData;
DWORD Length=ImageSectionHeader[Index].SizeOfRawData;
DWORD ImageOffset=ImageSectionHeader[Index].VirtualAddress;
RtlCopyMemory(&ImageBase[ImageOffset],&FileBuffer[FileOffset],Length);
}
*ImageModuleBase=ImageBase;
return TRUE;
}
ULONG AlignSize(ULONG nSize, ULONG nAlign)
{
return ((nSize + nAlign - 1) / nAlign * nAlign);
}
/*
通过DriverObject->DriverSection 遍历 内核模块
*/
PVOID GetKernelModuleBase(PDRIVER_OBJECT DriverObject,char *KernelModuleName)
{
PLDR_DATA_TABLE_ENTRY DriverSection,LdrEntry;
ANSI_STRING AnsiKernelModuleName;
UNICODE_STRING UniKernelModuleName;
UNICODE_STRING ModuleName;
WCHAR *Buffer;
int Lentgh,Index;
RtlInitAnsiString(&AnsiKernelModuleName,KernelModuleName);
RtlAnsiStringToUnicodeString(&UniKernelModuleName,&AnsiKernelModuleName,TRUE);
Buffer=ExAllocatePool(NonPagedPool,260*2);
if (Buffer==NULL)
{
return NULL;
}
RtlZeroMemory(Buffer,206*2);
DriverSection=DriverObject->DriverSection;
LdrEntry=(PLDR_DATA_TABLE_ENTRY)DriverSection->InLoadOrderLinks.Flink;
while (LdrEntry&&DriverSection!=LdrEntry)
{
//(DWORD)LdrEntry->DllBase>=*(DWORD*)MmSystemRangeStart&&
if (LdrEntry->FullDllName.Length>0&&
LdrEntry->FullDllName.Buffer!=NULL)
{
if (MmIsAddressValid(&LdrEntry->FullDllName.Buffer[LdrEntry->FullDllName.Length/2-1]))
{
Lentgh=LdrEntry->FullDllName.Length/2;
for (Index=Lentgh-1;Index>0;Index--)
{
if (LdrEntry->FullDllName.Buffer[Index]==0x005C)
{
break;
}
}
if (LdrEntry->FullDllName.Buffer[Index]==0x005C)
{
RtlCopyMemory(Buffer,&(LdrEntry->FullDllName.Buffer[Index+1]),(Lentgh-Index-1)*2);
ModuleName.Buffer=Buffer;
ModuleName.Length=(Lentgh-Index-1)*2;
ModuleName.MaximumLength=260*2;
}
else
{
RtlCopyMemory(Buffer,LdrEntry->FullDllName.Buffer,Lentgh*2);
ModuleName.Buffer=Buffer;
ModuleName.Length=Lentgh*2;
ModuleName.MaximumLength=260*2;
}
if (RtlEqualUnicodeString(&ModuleName,&UniKernelModuleName,TRUE))
{
ExFreePool(Buffer);
return LdrEntry->DllBase;
}
}
}
LdrEntry=(PLDR_DATA_TABLE_ENTRY)LdrEntry->InLoadOrderLinks.Flink;
}
ExFreePool(Buffer);
return NULL;
}
/*
通过导出表获得函数地址
*/
PVOID
MiFindExportedRoutine (
IN PVOID DllBase,
BOOLEAN ByName,
IN char *RoutineName,
DWORD Ordinal
)
{
USHORT OrdinalNumber;
PULONG NameTableBase;
PUSHORT NameOrdinalTableBase;
PULONG AddressTableBase;
PULONG Addr;
LONG High;
LONG Low;
LONG Middle;
LONG Result;
ULONG ExportSize;
PVOID FunctionAddress;
PIMAGE_EXPORT_DIRECTORY ExportDirectory;
PAGED_CODE();
//获得导出表
ExportDirectory = (PIMAGE_EXPORT_DIRECTORY) RtlImageDirectoryEntryToData (
DllBase,
TRUE,
IMAGE_DIRECTORY_ENTRY_EXPORT,
&ExportSize);
if (ExportDirectory == NULL) {
return NULL;
}
NameTableBase = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNames);
NameOrdinalTableBase = (PUSHORT)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNameOrdinals);
AddressTableBase=(PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfFunctions);
if (!ByName)
{
return (PVOID)AddressTableBase[Ordinal];
}
Low = 0;
Middle = 0;
High = ExportDirectory->NumberOfNames - 1;
while (High >= Low) {
Middle = (Low + High) >> 1;
Result = strcmp (RoutineName,
(PCHAR)DllBase + NameTableBase[Middle]);
if (Result < 0) {
High = Middle - 1;
}
else if (Result > 0) {
Low = Middle + 1;
}
else {
break;
}
}
if (High < Low) {
return NULL;
}
OrdinalNumber = NameOrdinalTableBase[Middle];
if ((ULONG)OrdinalNumber >= ExportDirectory->NumberOfFunctions) {
return NULL;
}
Addr = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfFunctions);
FunctionAddress = (PVOID)((PCHAR)DllBase + Addr[OrdinalNumber]);
//
// Forwarders are not used by the kernel and HAL to each other.
//
ASSERT ((FunctionAddress <= (PVOID)ExportDirectory) ||
(FunctionAddress >= (PVOID)((PCHAR)ExportDirectory + ExportSize)));
return FunctionAddress;
}
BOOLEAN InsertOriginalFirstThunk(DWORD ImageBase,DWORD ExistImageBase,PIMAGE_THUNK_DATA FirstThunk)
{
DWORD Offset;
PIMAGE_THUNK_DATA OriginalFirstThunk;
Offset=(DWORD)FirstThunk-ImageBase;
OriginalFirstThunk=(PIMAGE_THUNK_DATA)(ExistImageBase+Offset);
while (OriginalFirstThunk->u1.Function)
{
FirstThunk->u1.Function=OriginalFirstThunk->u1.Function;
OriginalFirstThunk++;
FirstThunk++;
}
return TRUE;
}
//修复导入表
BOOLEAN FixImportTable(BYTE *ImageBase,DWORD ExistImageBase,PDRIVER_OBJECT DriverObject)
{
PIMAGE_IMPORT_DESCRIPTOR ImageImportDescriptor=NULL;
PIMAGE_THUNK_DATA ImageThunkData,FirstThunk;
PIMAGE_IMPORT_BY_NAME ImortByName;
DWORD ImportSize;
PVOID ModuleBase;
char ModuleName[260];
DWORD FunctionAddress;
//得到导入表地址
ImageImportDescriptor=(PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(ImageBase,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT,&ImportSize);
if (ImageImportDescriptor==NULL)
{
return FALSE;
}
while (ImageImportDescriptor->OriginalFirstThunk&&ImageImportDescriptor->Name)
{
strcpy(ModuleName,(char*)(ImageBase+ImageImportDescriptor->Name)); //导入信息名称
//ntoskrnl.exe(NTKRNLPA.exe、ntkrnlmp.exe、ntkrpamp.exe)
if (_stricmp(ModuleName,"ntkrnlpa.exe")==0||
_stricmp(ModuleName,"ntoskrnl.exe")==0||
_stricmp(ModuleName,"ntkrnlmp.exe")==0||
_stricmp(ModuleName,"ntkrpamp.exe")==0)
{//no in
ModuleBase=GetKernelModuleBase(DriverObject,"ntkrnlpa.exe"); //通过DriverObject->DriverSection 遍历内核模块
if (ModuleBase==NULL)
{
ModuleBase=GetKernelModuleBase(DriverObject,"ntoskrnl.exe");
if (ModuleBase==NULL)
{
ModuleBase=GetKernelModuleBase(DriverObject,"ntkrnlmp.exe");
if (ModuleBase==NULL)
{
ModuleBase=GetKernelModuleBase(DriverObject,"ntkrpamp.exe");
}
}
}
}
else
{
ModuleBase=GetKernelModuleBase(DriverObject,ModuleName);
}
if (ModuleBase==NULL)
{
FirstThunk=(PIMAGE_THUNK_DATA)(ImageBase+ImageImportDescriptor->FirstThunk);
InsertOriginalFirstThunk((DWORD)ImageBase,ExistImageBase,FirstThunk);
ImageImportDescriptor++;
continue;
}
//PSHED.dll
ImageThunkData=(PIMAGE_THUNK_DATA)(ImageBase+ImageImportDescriptor->OriginalFirstThunk);
FirstThunk=(PIMAGE_THUNK_DATA)(ImageBase+ImageImportDescriptor->FirstThunk);
while(ImageThunkData->u1.Ordinal)
{
//序号导入
if(IMAGE_SNAP_BY_ORDINAL32(ImageThunkData->u1.Ordinal))
{
//通过系统内核的导出表 名称- 获得 函数地址
FunctionAddress=(DWORD)MiFindExportedRoutine(ModuleBase,FALSE,NULL,ImageThunkData->u1.Ordinal & ~IMAGE_ORDINAL_FLAG32);
if (FunctionAddress==0)
{
return FALSE;
}
FirstThunk->u1.Function=FunctionAddress;
}
//函数名导入
else
{
//
ImortByName=(PIMAGE_IMPORT_BY_NAME)(ImageBase+ImageThunkData->u1.AddressOfData);
FunctionAddress=(DWORD)MiFindExportedRoutine(ModuleBase,TRUE,ImortByName->Name,0);
if (FunctionAddress==0)
{
return FALSE;
}
FirstThunk->u1.Function=FunctionAddress;
}
FirstThunk++;
ImageThunkData++;
}
ImageImportDescriptor++;
}
return TRUE;
}
/*
system32//NtosKrnl.exe ..
*/
BOOLEAN PeLoad(
WCHAR *FileFullPath,
BYTE **ImageModeleBase,
PDRIVER_OBJECT DeviceObject,
DWORD ExistImageBase
)
{
NTSTATUS Status;
HANDLE hFile;
LARGE_INTEGER FileSize;
DWORD Length;
BYTE *FileBuffer;
BYTE *ImageBase;
IO_STATUS_BLOCK IoStatus;
//\SystemRoot\system32\ntkrnlpa.exe
Status=KernelOpenFile(FileFullPath,&hFile,0x100020,0x80,1,1,0x20); //自己创建文件对象,挂入FileObject->IrpList 并返回文件句柄
if (!NT_SUCCESS(Status))
{
return FALSE;
}
Status=KernelGetFileSize(hFile,&FileSize); //读取irp信息,返回filesize
if (!NT_SUCCESS(Status))
{
ZwClose(hFile);
return FALSE;
}
Length=FileSize.LowPart;
FileBuffer=ExAllocatePool(PagedPool,Length);
if (FileBuffer==NULL)
{
ZwClose(hFile);
return FALSE;
}
Status=KernelReadFile(hFile,NULL,Length,FileBuffer,&IoStatus); //传入文件句柄、文件大小 通过irp请求,读取文件到内存中
if (!NT_SUCCESS(Status))
{
ZwClose(hFile);
ExFreePool(FileBuffer);
return FALSE;
}
ZwClose(hFile);
if(!ImageFile(FileBuffer,&ImageBase)) //修复FileBuffer中的偏移 按照VirtualAglin 对齐 得到全局ImageModuleBase
{
ExFreePool(FileBuffer);
return FALSE;
}
ExFreePool(FileBuffer);
//2k3下MiFindExportedRoutine调用失败
if(!FixImportTable(ImageBase,ExistImageBase,DeviceObject)) //修复导入表
{
ExFreePool(ImageBase);
return FALSE;
}
if(!FixBaseRelocTable(ImageBase,ExistImageBase)) //修复重定位表
{
ExFreePool(ImageBase);
return FALSE;
}
*ImageModeleBase=ImageBase; //得到最后的基地址 就是 和 原来内存中格式一样的 一块ntos
return TRUE;
}
@@ -0,0 +1,64 @@
#include "Reload.h"
BOOLEAN GetSystemKernelModuleInfo(WCHAR **SystemKernelModulePath,PDWORD SystemKernelModuleBase,PDWORD SystemKernelModuleSize);
BOOLEAN IoGetFileSystemVpbInfo(IN PFILE_OBJECT FileObject,PDEVICE_OBJECT *DeviceObject,PDEVICE_OBJECT *RealDevice);
BOOLEAN GetDeviceObjectFromFileFullName(WCHAR *FileFullName,PDEVICE_OBJECT *RealDevice, PDEVICE_OBJECT *DeviceObject);
BOOLEAN GetWindowsRootName(WCHAR *WindowsRootName);
NTSTATUS KernelOpenFile(wchar_t *FileFullName,
PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
ULONG FileAttributes,
ULONG ShareAccess,
ULONG CreateDisposition,
ULONG CreateOptions);
NTSTATUS KernelGetFileSize(HANDLE hFile, PLARGE_INTEGER FileSize);
NTSTATUS KernelReadFile(HANDLE hFile, PLARGE_INTEGER ByteOffset, ULONG Length, PVOID FileBuffer, PIO_STATUS_BLOCK IoStatusBlock);
BOOLEAN ImageFile(BYTE *FileBuffer,BYTE **ImageModuleBase);
ULONG AlignSize(ULONG nSize, ULONG nAlign);
PVOID GetKernelModuleBase(PDRIVER_OBJECT DriverObject,char *KernelModuleName);
BOOLEAN InsertOriginalFirstThunk(DWORD ImageBase,DWORD ExistImageBase,PIMAGE_THUNK_DATA FirstThunk);
PVOID
MiFindExportedRoutine (
IN PVOID DllBase,
BOOLEAN ByName,
IN char *RoutineName,
DWORD Ordinal
);
BOOLEAN FixImportTable(BYTE *ImageBase,DWORD ExistImageBase,PDRIVER_OBJECT DriverObject);
BOOLEAN PeLoad(
WCHAR *FileFullPath,
BYTE **ImageModeleBase,
PDRIVER_OBJECT DeviceObject,
DWORD ExistImageBase
);
@@ -0,0 +1 @@
Check Kernel EAT Hook
@@ -0,0 +1,355 @@
#include "Reload.h"
#include "KernelReload.h"
WCHAR* SystemKernelFilePath = NULL;
ULONG_PTR SystemKernelModuleBase = 0;
ULONG_PTR SystemKernelModuleSize = 0;
ULONG_PTR ImageModuleBase;
PVOID OriginalKiServiceTable;
extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;
PSERVICE_DESCRIPTOR_TABLE OriginalServiceDescriptorTable;
PSERVICE_DESCRIPTOR_TABLE Safe_ServiceDescriptorTable;
/*
输入FuncName 、 原来Ntos地址 、自己重载 Ntos地址
//第一次都是通过 系统的原来偏移 + NewBase 获得函数地址
//然后通过自己的RMmGetSystemRoutineAddress获得 偏移+NewBase 获得函数地址
还不能找到则遍历导出表
*/
ULONG ReLoadNtosCALL(WCHAR *lpwzFuncTion,ULONG ulOldNtosBase,ULONG ulReloadNtosBase)
{
UNICODE_STRING UnicodeFunctionName;
ULONG ulOldFunctionAddress;
PUCHAR ulReloadFunctionAddress = NULL;
int index=0;
PIMAGE_DOS_HEADER pDosHeader;
PIMAGE_NT_HEADERS NtDllHeader;
IMAGE_OPTIONAL_HEADER opthdr;
DWORD* arrayOfFunctionAddresses;
DWORD* arrayOfFunctionNames;
WORD* arrayOfFunctionOrdinals;
DWORD functionOrdinal;
DWORD Base, x, functionAddress,position;
char* functionName;
IMAGE_EXPORT_DIRECTORY *pExportTable;
ULONG ulNtDllModuleBase;
UNICODE_STRING UnicodeFunction;
UNICODE_STRING UnicodeExportTableFunction;
ANSI_STRING ExportTableFunction;
//第一次都是通过 系统的原来偏移 + NewBase 获得函数地址
//然后通过自己的RMmGetSystemRoutineAddress获得 偏移+NewBase 获得函数地址
__try
{
if (RRtlInitUnicodeString &&
RRtlCompareUnicodeString &&
RMmGetSystemRoutineAddress &&
RMmIsAddressValid)
{
RRtlInitUnicodeString(&UnicodeFunctionName,lpwzFuncTion);
ulOldFunctionAddress = (DWORD)RMmGetSystemRoutineAddress(&UnicodeFunctionName);
ulReloadFunctionAddress = (PUCHAR)(ulOldFunctionAddress - ulOldNtosBase + ulReloadNtosBase); //获得重载的FuncAddr
if (RMmIsAddressValid(ulReloadFunctionAddress)) //如果无效就从 导出表 获取? 应该不会无效
{
return (ULONG)ulReloadFunctionAddress;
}
//从导出表里获取
ulNtDllModuleBase = ulReloadNtosBase;
pDosHeader = (PIMAGE_DOS_HEADER)ulReloadNtosBase;
if (pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
{
KdPrint(("failed to find NtHeader\r\n"));
return 0;
}
NtDllHeader=(PIMAGE_NT_HEADERS)(ULONG)((ULONG)pDosHeader+pDosHeader->e_lfanew);
if (NtDllHeader->Signature!=IMAGE_NT_SIGNATURE)
{
KdPrint(("failed to find NtHeader\r\n"));
return 0;
}
opthdr = NtDllHeader->OptionalHeader;
pExportTable =(IMAGE_EXPORT_DIRECTORY*)((BYTE*)ulNtDllModuleBase + opthdr.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT]. VirtualAddress); //得到导出表
arrayOfFunctionAddresses = (DWORD*)( (BYTE*)ulNtDllModuleBase + pExportTable->AddressOfFunctions); //地址表
arrayOfFunctionNames = (DWORD*)((BYTE*)ulNtDllModuleBase + pExportTable->AddressOfNames); //函数名表
arrayOfFunctionOrdinals = (WORD*)((BYTE*)ulNtDllModuleBase + pExportTable->AddressOfNameOrdinals);
Base = pExportTable->Base;
for(x = 0; x < pExportTable->NumberOfFunctions; x++) //在整个导出表里扫描
{
functionName = (char*)( (BYTE*)ulNtDllModuleBase + arrayOfFunctionNames[x]);
functionOrdinal = arrayOfFunctionOrdinals[x] + Base - 1;
functionAddress = (DWORD)((BYTE*)ulNtDllModuleBase + arrayOfFunctionAddresses[functionOrdinal]);
RtlInitAnsiString(&ExportTableFunction,functionName);
RtlAnsiStringToUnicodeString(&UnicodeExportTableFunction,&ExportTableFunction,TRUE);
RRtlInitUnicodeString(&UnicodeFunction,lpwzFuncTion);
if (RRtlCompareUnicodeString(&UnicodeExportTableFunction,&UnicodeFunction,TRUE) == 0)
{
RtlFreeUnicodeString(&UnicodeExportTableFunction);
return functionAddress;
}
RtlFreeUnicodeString(&UnicodeExportTableFunction);
}
return 0;
}
RtlInitUnicodeString(&UnicodeFunctionName,lpwzFuncTion);
ulOldFunctionAddress = (DWORD)MmGetSystemRoutineAddress(&UnicodeFunctionName);
ulReloadFunctionAddress = (PUCHAR)(ulOldFunctionAddress - ulOldNtosBase + ulReloadNtosBase);
//KdPrint(("%ws:%08x:%08x",lpwzFuncTion,ulOldFunctionAddress,ulReloadFunctionAddress));
if (MmIsAddressValid(ulReloadFunctionAddress))
{
return (ULONG)ulReloadFunctionAddress;
}
//
}__except(EXCEPTION_EXECUTE_HANDLER){
KdPrint(("EXCEPTION_EXECUTE_HANDLER"));
}
return 0;
}
/*重载Ntos*/
NTSTATUS ReLoadNtos(PDRIVER_OBJECT DriverObject,DWORD RetAddress)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
ULONG ulKeAddSystemServiceTable;
PULONG p;
if (!GetSystemKernelModuleInfo(
&SystemKernelFilePath,
&SystemKernelModuleBase,
&SystemKernelModuleSize
))
{
KdPrint(("Get System Kernel Module failed"));
return status;
}
if (InitSafeOperationModule(
DriverObject,
SystemKernelFilePath,
SystemKernelModuleBase
))
{
KdPrint(("Init Ntos module success\r\n"));
RRtlInitUnicodeString = NULL;
RMmGetSystemRoutineAddress = NULL;
RMmIsAddressValid = NULL;
RRtlCompareUnicodeString = NULL;
RPsGetCurrentProcess = NULL;
status = STATUS_UNSUCCESSFUL;
//第一次都是通过 系统的原来偏移 + NewBase 获得函数地址
//然后通过自己的RMmGetSystemRoutineAddress获得 偏移+NewBase 获得函数地址
RRtlInitUnicodeString = (ReloadRtlInitUnicodeString)ReLoadNtosCALL(L"RtlInitUnicodeString",SystemKernelModuleBase,ImageModuleBase);
RRtlCompareUnicodeString = (ReloadRtlCompareUnicodeString)ReLoadNtosCALL(L"RtlCompareUnicodeString",SystemKernelModuleBase,ImageModuleBase);
RMmGetSystemRoutineAddress = (ReloadMmGetSystemRoutineAddress)ReLoadNtosCALL(L"MmGetSystemRoutineAddress",SystemKernelModuleBase,ImageModuleBase);
RMmIsAddressValid = (ReloadMmIsAddressValid)ReLoadNtosCALL(L"MmIsAddressValid",SystemKernelModuleBase,ImageModuleBase);
RPsGetCurrentProcess = (ReloadPsGetCurrentProcess)ReLoadNtosCALL(L"PsGetCurrentProcess",SystemKernelModuleBase,ImageModuleBase);
if (!RRtlInitUnicodeString ||
!RRtlCompareUnicodeString ||
!RMmGetSystemRoutineAddress ||
!RMmIsAddressValid ||
!RPsGetCurrentProcess)
{
KdPrint(("Init NtosCALL failed"));
return status;
}
}
return status;
}
BOOLEAN InitSafeOperationModule(PDRIVER_OBJECT pDriverObject,WCHAR *SystemModulePath,ULONG KernelModuleBase)
{
UNICODE_STRING FileName;
HANDLE hSection;
PDWORD FixdOriginalKiServiceTable;
PDWORD CsRootkitOriginalKiServiceTable;
ULONG i = 0;
//自己peload 一个ntos*,这样就解决了跟其他安全软件的冲突啦~
if (!PeLoad(SystemModulePath,(BYTE**)&ImageModuleBase,pDriverObject,KernelModuleBase))
{
return FALSE;
}
OriginalKiServiceTable = ExAllocatePool(NonPagedPool,KeServiceDescriptorTable->TableSize*sizeof(DWORD));
if (!OriginalKiServiceTable)
{
return FALSE;
}
//获得SSDT基址,通过重定位表比较得到
if(!GetOriginalKiServiceTable((BYTE*)ImageModuleBase,KernelModuleBase,(DWORD*)&OriginalKiServiceTable))
{
ExFreePool(OriginalKiServiceTable);
return FALSE;
}
//修复SSDT函数地址 都是自己Reload的函数地址 干净的
FixOriginalKiServiceTable((PDWORD)OriginalKiServiceTable,(DWORD)ImageModuleBase,KernelModuleBase);
OriginalServiceDescriptorTable = (PSERVICE_DESCRIPTOR_TABLE)ExAllocatePool(NonPagedPool,sizeof(SERVICE_DESCRIPTOR_TABLE)*4);
if (OriginalServiceDescriptorTable == NULL)
{
ExFreePool(OriginalKiServiceTable);
return FALSE;
}
RtlZeroMemory(OriginalServiceDescriptorTable,sizeof(SERVICE_DESCRIPTOR_TABLE)*4);
//修复SERVICE_DESCRIPTOR_TABLE 结构
OriginalServiceDescriptorTable->ServiceTable = (PDWORD)OriginalKiServiceTable;
OriginalServiceDescriptorTable->CounterTable = KeServiceDescriptorTable->CounterTable;
OriginalServiceDescriptorTable->TableSize = KeServiceDescriptorTable->TableSize;
OriginalServiceDescriptorTable->ArgumentTable = KeServiceDescriptorTable->ArgumentTable;
CsRootkitOriginalKiServiceTable = (PDWORD)ExAllocatePool(NonPagedPool,KeServiceDescriptorTable->TableSize*sizeof(DWORD));
if (CsRootkitOriginalKiServiceTable==NULL)
{
ExFreePool(OriginalServiceDescriptorTable);
ExFreePool(OriginalKiServiceTable);
return FALSE;
}
RtlZeroMemory(CsRootkitOriginalKiServiceTable,KeServiceDescriptorTable->TableSize*sizeof(DWORD));
Safe_ServiceDescriptorTable = (PSERVICE_DESCRIPTOR_TABLE)ExAllocatePool(NonPagedPool,sizeof(SERVICE_DESCRIPTOR_TABLE)*4);
if (Safe_ServiceDescriptorTable == NULL)
{
ExFreePool(OriginalServiceDescriptorTable);
ExFreePool(CsRootkitOriginalKiServiceTable);
ExFreePool(OriginalKiServiceTable);
return FALSE;
}
//这是一个干净的原始表,每个表里所对应的SSDT函数的地址都是原始函数
RtlZeroMemory(Safe_ServiceDescriptorTable,sizeof(SERVICE_DESCRIPTOR_TABLE)*4);
//填充原始函数地址
for (i = 0; i < KeServiceDescriptorTable->TableSize; i++)
{
CsRootkitOriginalKiServiceTable[i] = OriginalServiceDescriptorTable->ServiceTable[i];
}
Safe_ServiceDescriptorTable->ServiceTable = (PDWORD)CsRootkitOriginalKiServiceTable;
Safe_ServiceDescriptorTable->CounterTable = KeServiceDescriptorTable->CounterTable;
Safe_ServiceDescriptorTable->TableSize = KeServiceDescriptorTable->TableSize;
Safe_ServiceDescriptorTable->ArgumentTable = KeServiceDescriptorTable->ArgumentTable;
//释放就会bsod
//ExFreePool(OriginalKiServiceTable);
return TRUE;
}
VOID FixOriginalKiServiceTable(PDWORD OriginalKiServiceTable,DWORD ModuleBase,DWORD ExistImageBase)
{
DWORD FuctionCount;
DWORD Index;
FuctionCount=KeServiceDescriptorTable->TableSize; //函数个数
KdPrint(("ssdt funcion count:%X---KiServiceTable:%X\n",FuctionCount,KeServiceDescriptorTable->ServiceTable));
for (Index=0;Index<FuctionCount;Index++)
{
OriginalKiServiceTable[Index]=OriginalKiServiceTable[Index]-ExistImageBase+ModuleBase; //修复SSDT函数地址
}
}
//通过KeServiceDescriptorTable的RVA与重定位表项解析的地址RVA比较,一致则取出其中的SSDT表地址
BOOLEAN GetOriginalKiServiceTable(BYTE *NewImageBase,DWORD ExistImageBase,DWORD *NewKiServiceTable)
{
PIMAGE_DOS_HEADER ImageDosHeader;
PIMAGE_NT_HEADERS ImageNtHeaders;
DWORD KeServiceDescriptorTableRva;
PIMAGE_BASE_RELOCATION ImageBaseReloc=NULL;
DWORD RelocSize;
int ItemCount,Index;
int Type;
PDWORD RelocAddress;
DWORD RvaData;
DWORD count=0;
WORD *TypeOffset;
ImageDosHeader=(PIMAGE_DOS_HEADER)NewImageBase;
if (ImageDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
{
return FALSE;
}
ImageNtHeaders=(PIMAGE_NT_HEADERS)(NewImageBase+ImageDosHeader->e_lfanew);
if (ImageNtHeaders->Signature!=IMAGE_NT_SIGNATURE)
{
return FALSE;
}
KeServiceDescriptorTableRva=(DWORD)MiFindExportedRoutine(NewImageBase,TRUE,"KeServiceDescriptorTable",0);
if (KeServiceDescriptorTableRva==0)
{
return FALSE;
}
KeServiceDescriptorTableRva=KeServiceDescriptorTableRva-(DWORD)NewImageBase;
ImageBaseReloc=RtlImageDirectoryEntryToData(NewImageBase,TRUE,IMAGE_DIRECTORY_ENTRY_BASERELOC,&RelocSize);
if (ImageBaseReloc==NULL)
{
return FALSE;
}
while (ImageBaseReloc->SizeOfBlock)
{
count++;
ItemCount=(ImageBaseReloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION))/2;
TypeOffset=(WORD*)((DWORD)ImageBaseReloc+sizeof(IMAGE_BASE_RELOCATION));
for (Index=0;Index<ItemCount;Index++)
{
Type=TypeOffset[Index]>>12; //高4位是类型 低12位位页内偏移 4k
if (Type==3)
{
//Base + Virtual 定位到页 + 低12位 = RelocAddress 需要修复的地址
RelocAddress=(PDWORD)((DWORD)(TypeOffset[Index]&0x0fff)+ImageBaseReloc->VirtualAddress+(DWORD)NewImageBase);
RvaData=*RelocAddress-ExistImageBase;
if (RvaData==KeServiceDescriptorTableRva) //重定位表中的rva 是 KeServiceDescriptorTable 表项的
{
if(*(USHORT*)((DWORD)RelocAddress-2)==0x05c7)
{
/*
1: kd> dd 0x89651c12 RelocAddress - 2
89651c12 79c005c7 bd9c83f8
1: kd> dd KeServiceDescriptorTable
83f879c0 83e9bd9c 00000000 00000191 83e9c3e4
83f879d0 00000000 00000000 00000000 00000000
1: kd> dd 0x89651c14 RelocAddress
89651c14 83f879c0 83e9bd9c 79c41589 c8a383f8
89651c24 c783f879 f879cc05 e9c3e483 d8158983
*/
//RelocAddress 里面存放着 KeServiceDesriptorTable地址
//RelocAddress + 4 存放着 KeServiceDesriptorTable第一成员也就是SSDT基址
*NewKiServiceTable=*(DWORD*)((DWORD)RelocAddress+4)-ExistImageBase+(DWORD)NewImageBase;
return TRUE;
}
}
}
}
ImageBaseReloc=(PIMAGE_BASE_RELOCATION)((DWORD)ImageBaseReloc+ImageBaseReloc->SizeOfBlock);
}
return FALSE;
}
@@ -0,0 +1,242 @@
#include "DriverEntry.h"
#include <ntimage.h>
#pragma once
typedef unsigned long DWORD;
typedef DWORD * PDWORD;
typedef unsigned char BYTE, *PBYTE;
typedef unsigned short WORD, *PWORD;
typedef struct _SYSTEM_MODULE_INFORMATION // 系统模块信息
{
ULONG Reserved[2];
ULONG Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT Unknown;
USHORT LoadCount;
USHORT ModuleNameOffset;
CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
typedef struct _tagSysModuleList { //模块链结构
ULONG ulCount;
SYSTEM_MODULE_INFORMATION smi[1];
} MODULES, *PMODULES;
typedef enum _SYSTEM_INFORMATION_CLASS
{
SystemBasicInformation, // 0 Y N
SystemProcessorInformation, // 1 Y N
SystemPerformanceInformation, // 2 Y N
SystemTimeOfDayInformation, // 3 Y N
SystemNotImplemented1, // 4 Y N
SystemProcessesAndThreadsInformation, // 5 Y N
SystemCallCounts, // 6 Y N
SystemConfigurationInformation, // 7 Y N
SystemProcessorTimes, // 8 Y N
SystemGlobalFlag, // 9 Y Y
SystemNotImplemented2, // 10 Y N
SystemModuleInformation, // 11 Y N
SystemLockInformation, // 12 Y N
SystemNotImplemented3, // 13 Y N
SystemNotImplemented4, // 14 Y N
SystemNotImplemented5, // 15 Y N
SystemHandleInformation, // 16 Y N
SystemObjectInformation, // 17 Y N
SystemPagefileInformation, // 18 Y N
SystemInstructionEmulationCounts, // 19 Y N
SystemInvalidInfoClass1, // 20
SystemCacheInformation, // 21 Y Y
SystemPoolTagInformation, // 22 Y N
SystemProcessorStatistics, // 23 Y N
SystemDpcInformation, // 24 Y Y
SystemNotImplemented6, // 25 Y N
SystemLoadImage, // 26 N Y
SystemUnloadImage, // 27 N Y
SystemTimeAdjustment, // 28 Y Y
SystemNotImplemented7, // 29 Y N
SystemNotImplemented8, // 30 Y N
SystemNotImplemented9, // 31 Y N
SystemCrashDumpInformation, // 32 Y N
SystemExceptionInformation, // 33 Y N
SystemCrashDumpStateInformation, // 34 Y Y/N
SystemKernelDebuggerInformation, // 35 Y N
SystemContextSwitchInformation, // 36 Y N
SystemRegistryQuotaInformation, // 37 Y Y
SystemLoadAndCallImage, // 38 N Y
SystemPrioritySeparation, // 39 N Y
SystemNotImplemented10, // 40 Y N
SystemNotImplemented11, // 41 Y N
SystemInvalidInfoClass2, // 42
SystemInvalidInfoClass3, // 43
SystemTimeZoneInformation, // 44 Y N
SystemLookasideInformation, // 45 Y N
SystemSetTimeSlipEvent, // 46 N Y
SystemCreateSession, // 47 N Y
SystemDeleteSession, // 48 N Y
SystemInvalidInfoClass4, // 49
SystemRangeStartInformation, // 50 Y N
SystemVerifierInformation, // 51 Y Y
SystemAddVerifier, // 52 N Y
SystemSessionProcessesInformation // 53 Y N
} SYSTEM_INFORMATION_CLASS;
#define LDRP_RELOCATION_FINAL 0x2
#define RTL_IMAGE_NT_HEADER_EX_FLAG_NO_RANGE_CHECK (0x00000001)
typedef struct _AUX_ACCESS_DATA {
PPRIVILEGE_SET PrivilegesUsed;
GENERIC_MAPPING GenericMapping;
ACCESS_MASK AccessesToAudit;
ACCESS_MASK MaximumAuditMask;
ULONG Unknown[41];
} AUX_ACCESS_DATA, *PAUX_ACCESS_DATA;
typedef struct _LDR_DATA_TABLE_ENTRY
{
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT TlsIndex;
union
{
LIST_ENTRY HashLinks;
struct
{
PVOID SectionPointer;
ULONG CheckSum;
};
};
union
{
ULONG TimeDateStamp;
PVOID LoadedImports;
};
PVOID EntryPointActivationContext;
PVOID PatchInformation;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
// typedef struct _IMAGE_BASE_RELOCATION {
// DWORD VirtualAddress;
// DWORD SizeOfBlock;
// // WORD TypeOffset[1];
// } IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION;
// typedef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION;
typedef struct _SERVICE_DESCRIPTOR_TABLE {
/*
* Table containing cServices elements of pointers to service handler
* functions, indexed by service ID.
*/
PDWORD ServiceTable;
/*
* Table that counts how many times each service is used. This table
* is only updated in checked builds.
*/
PULONG CounterTable;
/*
* Number of services contained in this table.
*/
ULONG TableSize;
/*
* Table containing the number of bytes of parameters the handler
* function takes.
*/
PUCHAR ArgumentTable;
} SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TABLE;
NTSTATUS ReLoadNtos(PDRIVER_OBJECT DriverObject,DWORD RetAddress);
NTSTATUS
NTAPI
ZwQuerySystemInformation(
IN SYSTEM_INFORMATION_CLASS SystemInfoClass,
OUT PVOID SystemInfoBuffer,
IN ULONG SystemInfoBufferSize,
OUT PULONG BytesReturned OPTIONAL
);
NTSTATUS
NTAPI
ObCreateObject (
IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
IN POBJECT_TYPE ObjectType,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN KPROCESSOR_MODE AccessMode,
IN OUT PVOID ParseContext OPTIONAL,
IN ULONG ObjectSize,
IN ULONG PagedPoolCharge OPTIONAL,
IN ULONG NonPagedPoolCharge OPTIONAL,
OUT PVOID *Object
);
NTSTATUS
NTAPI
SeCreateAccessState(
PACCESS_STATE AccessState,
PAUX_ACCESS_DATA AuxData,
ACCESS_MASK Access,
PGENERIC_MAPPING GenericMapping
);
NTSYSAPI
PVOID
NTAPI
RtlImageDirectoryEntryToData (
IN PVOID Base,
IN BOOLEAN MappedAsImage,
IN USHORT DirectoryEntry,
OUT PULONG Size
);
BOOLEAN InitSafeOperationModule(PDRIVER_OBJECT pDriverObject,WCHAR *SystemModulePath,ULONG KernelModuleBase);
typedef VOID (__stdcall *ReloadRtlInitUnicodeString)(
__inout PUNICODE_STRING DestinationString,
__in_opt PCWSTR SourceString
);
ReloadRtlInitUnicodeString RRtlInitUnicodeString;
typedef LONG (__stdcall * ReloadRtlCompareUnicodeString)(
__in PCUNICODE_STRING String1,
__in PCUNICODE_STRING String2,
__in BOOLEAN CaseInSensitive
);
ReloadRtlCompareUnicodeString RRtlCompareUnicodeString;
typedef PVOID (__stdcall *ReloadMmGetSystemRoutineAddress)(
__in PUNICODE_STRING SystemRoutineName
);
ReloadMmGetSystemRoutineAddress RMmGetSystemRoutineAddress;
typedef BOOLEAN (__stdcall * ReloadMmIsAddressValid)(
__in PVOID VirtualAddress
);
ReloadMmIsAddressValid RMmIsAddressValid;
typedef PEPROCESS (__stdcall *ReloadPsGetCurrentProcess)(void);
ReloadPsGetCurrentProcess RPsGetCurrentProcess;
BOOLEAN GetOriginalKiServiceTable(BYTE *NewImageBase,DWORD ExistImageBase,DWORD *NewKiServiceTable);
VOID FixOriginalKiServiceTable(PDWORD OriginalKiServiceTable,DWORD ModuleBase,DWORD ExistImageBase);
@@ -0,0 +1,515 @@
/*
* libdasm -- simple x86 disassembly library
* (c) 2004 - 2005 jt / nologin.org
*
*/
#ifndef _LIBDASM_H
#define _LIBDASM_H
#ifdef __cplusplus
extern "C" {
#endif
#define __LIBDASM_VERSION__ 0x01020000
#define GET_VERSION_MAJOR \
(__LIBDASM_VERSION__ & 0xff000000) >> 24
#define GET_VERSION_MINOR1 \
(__LIBDASM_VERSION__ & 0x00ff0000) >> 16
#define GET_VERSION_MINOR2 \
(__LIBDASM_VERSION__ & 0x0000ff00) >> 8
#define GET_VERSION_MINOR3 \
(__LIBDASM_VERSION__ & 0x000000ff)
// Data types
#if _WIN32
//#include <windows.h>
#define __inline__ __inline
#define snprintf _snprintf
typedef unsigned __int64 QWORD; // for MSVC
typedef signed __int8 SBYTE;
typedef signed __int16 SWORD;
typedef signed __int32 SDWORD;
typedef signed __int64 SQWORD;
#else
#if defined __sun
#define BYTE_ORDER 1234
#define BIG_ENDIAN 1234
#define LITTLE_ENDIAN 4321
#define u_int8_t uint8_t
#define u_int16_t uint16_t
#define u_int32_t uint32_t
#define u_int64_t uint64_t
#endif // other *nix
#include <sys/types.h>
typedef u_int8_t BYTE;
typedef u_int16_t WORD;
typedef u_int32_t DWORD;
typedef u_int64_t QWORD;
typedef int8_t SBYTE;
typedef int16_t SWORD;
typedef int32_t SDWORD;
typedef int64_t SQWORD;
#endif
// Define endianess
#ifndef __X86__
// These should catch x86 with most compilers
#if defined _X86_ || defined _i386_ || defined __i386__
#define __X86__
#endif
#endif
#ifndef __LITTLE_ENDIAN__
// These should catch little-endian with most compilers
#if (BYTE_ORDER == LITTLE_ENDIAN) || defined __X86__ || defined _ALPHA_
#define __LITTLE_ENDIAN__
#endif
#endif
typedef unsigned long DWORD;
typedef unsigned long *PDWORD;
typedef unsigned short WORD;
typedef unsigned char BYTE;
typedef unsigned char *PBYTE;
//typedef unsigned short HMODULE;
// Registers
#define REGISTER_EAX 0
#define REGISTER_ECX 1
#define REGISTER_EDX 2
#define REGISTER_EBX 3
#define REGISTER_ESP 4
#define REGISTER_EBP 5
#define REGISTER_ESI 6
#define REGISTER_EDI 7
#define REGISTER_NOP 10 // no register defined
// Registers
#define MASK_REG(x) ((x) & 0x000000FF)
#define REG_EAX REGISTER_EAX
#define REG_AX REG_EAX
#define REG_AL REG_EAX
#define REG_ES REG_EAX // Just for reg_table consistence
#define REG_ST0 REG_EAX // Just for reg_table consistence
#define REG_ECX REGISTER_ECX
#define REG_CX REG_ECX
#define REG_CL REG_ECX
#define REG_CS REG_ECX
#define REG_ST1 REG_ECX
#define REG_EDX REGISTER_EDX
#define REG_DX REG_EDX
#define REG_DL REG_EDX
#define REG_SS REG_EDX
#define REG_ST2 REG_EDX
#define REG_EBX REGISTER_EBX
#define REG_BX REG_EBX
#define REG_BL REG_EBX
#define REG_DS REG_EBX
#define REG_ST3 REG_EBX
#define REG_ESP REGISTER_ESP
#define REG_SP REG_ESP
#define REG_AH REG_ESP // Just for reg_table consistence
#define REG_FS REG_ESP
#define REG_ST4 REG_ESP
#define REG_EBP REGISTER_EBP
#define REG_BP REG_EBP
#define REG_CH REG_EBP
#define REG_GS REG_EBP
#define REG_ST5 REG_EBP
#define REG_ESI REGISTER_ESI
#define REG_SI REG_ESI
#define REG_DH REG_ESI
#define REG_ST6 REG_ESI
#define REG_EDI REGISTER_EDI
#define REG_DI REG_EDI
#define REG_BH REG_EDI
#define REG_ST7 REG_EDI
#define REG_NOP REGISTER_NOP
// Register types
#define REGISTER_TYPE_GEN 1
#define REGISTER_TYPE_SEGMENT 2
#define REGISTER_TYPE_DEBUG 3
#define REGISTER_TYPE_CONTROL 4
#define REGISTER_TYPE_TEST 5
#define REGISTER_TYPE_XMM 6
#define REGISTER_TYPE_MMX 7
#define REGISTER_TYPE_FPU 8
// Disassembling mode
enum Mode {
MODE_32, // 32-bit
MODE_16 // 16-bit
};
// Disassembling format
enum Format {
FORMAT_ATT,
FORMAT_INTEL,
};
// Instruction types (just the most common ones atm)
enum Instruction {
// Integer instructions
INSTRUCTION_TYPE_ASC, // aaa, aam, etc.
INSTRUCTION_TYPE_DCL, // daa, das
INSTRUCTION_TYPE_MOV,
INSTRUCTION_TYPE_MOVSR, // segment register
INSTRUCTION_TYPE_ADD,
INSTRUCTION_TYPE_XADD,
INSTRUCTION_TYPE_ADC,
INSTRUCTION_TYPE_SUB,
INSTRUCTION_TYPE_SBB,
INSTRUCTION_TYPE_INC,
INSTRUCTION_TYPE_DEC,
INSTRUCTION_TYPE_DIV,
INSTRUCTION_TYPE_IDIV,
INSTRUCTION_TYPE_NOT,
INSTRUCTION_TYPE_NEG,
INSTRUCTION_TYPE_STOS,
INSTRUCTION_TYPE_LODS,
INSTRUCTION_TYPE_SCAS,
INSTRUCTION_TYPE_MOVS,
INSTRUCTION_TYPE_MOVSX,
INSTRUCTION_TYPE_MOVZX,
INSTRUCTION_TYPE_CMPS,
INSTRUCTION_TYPE_SHX, // signed/unsigned shift left/right
INSTRUCTION_TYPE_ROX, // signed/unsigned rot left/right
INSTRUCTION_TYPE_MUL,
INSTRUCTION_TYPE_IMUL,
INSTRUCTION_TYPE_EIMUL, // "extended" imul with 2-3 operands
INSTRUCTION_TYPE_XOR,
INSTRUCTION_TYPE_LEA,
INSTRUCTION_TYPE_XCHG,
INSTRUCTION_TYPE_CMP,
INSTRUCTION_TYPE_TEST,
INSTRUCTION_TYPE_PUSH,
INSTRUCTION_TYPE_AND,
INSTRUCTION_TYPE_OR,
INSTRUCTION_TYPE_POP,
INSTRUCTION_TYPE_JMP,
INSTRUCTION_TYPE_JMPC, // conditional jump
INSTRUCTION_TYPE_SETC, // conditional byte set
INSTRUCTION_TYPE_MOVC, // conditional mov
INSTRUCTION_TYPE_LOOP,
INSTRUCTION_TYPE_CALL,
INSTRUCTION_TYPE_RET,
INSTRUCTION_TYPE_INT, // interrupt
INSTRUCTION_TYPE_BT, // bit tests
INSTRUCTION_TYPE_BTS,
INSTRUCTION_TYPE_BTR,
INSTRUCTION_TYPE_BTC,
INSTRUCTION_TYPE_BSF,
INSTRUCTION_TYPE_BSR,
INSTRUCTION_TYPE_BSWAP,
INSTRUCTION_TYPE_SGDT,
INSTRUCTION_TYPE_SIDT,
INSTRUCTION_TYPE_SLDT,
INSTRUCTION_TYPE_LFP,
// FPU instructions
INSTRUCTION_TYPE_FCMOVC, // float conditional mov
INSTRUCTION_TYPE_FADD,
INSTRUCTION_TYPE_FADDP,
INSTRUCTION_TYPE_FIADD,
INSTRUCTION_TYPE_FSUB,
INSTRUCTION_TYPE_FSUBP,
INSTRUCTION_TYPE_FISUB,
INSTRUCTION_TYPE_FSUBR,
INSTRUCTION_TYPE_FSUBRP,
INSTRUCTION_TYPE_FISUBR,
INSTRUCTION_TYPE_FMUL,
INSTRUCTION_TYPE_FMULP,
INSTRUCTION_TYPE_FIMUL,
INSTRUCTION_TYPE_FDIV,
INSTRUCTION_TYPE_FDIVP,
INSTRUCTION_TYPE_FDIVR,
INSTRUCTION_TYPE_FDIVRP,
INSTRUCTION_TYPE_FIDIV,
INSTRUCTION_TYPE_FIDIVR,
INSTRUCTION_TYPE_FCOM,
INSTRUCTION_TYPE_FCOMP,
INSTRUCTION_TYPE_FCOMPP,
INSTRUCTION_TYPE_FCOMI,
INSTRUCTION_TYPE_FCOMIP,
INSTRUCTION_TYPE_FUCOM,
INSTRUCTION_TYPE_FUCOMP,
INSTRUCTION_TYPE_FUCOMPP,
INSTRUCTION_TYPE_FUCOMI,
INSTRUCTION_TYPE_FUCOMIP,
INSTRUCTION_TYPE_FST,
INSTRUCTION_TYPE_FSTP,
INSTRUCTION_TYPE_FIST,
INSTRUCTION_TYPE_FISTP,
INSTRUCTION_TYPE_FISTTP,
INSTRUCTION_TYPE_FLD,
INSTRUCTION_TYPE_FILD,
INSTRUCTION_TYPE_FICOM,
INSTRUCTION_TYPE_FICOMP,
INSTRUCTION_TYPE_FFREE,
INSTRUCTION_TYPE_FFREEP,
INSTRUCTION_TYPE_FXCH,
INSTRUCTION_TYPE_FPU, // Other FPU instructions
INSTRUCTION_TYPE_MMX, // Other MMX instructions
INSTRUCTION_TYPE_SSE, // Other SSE instructions
INSTRUCTION_TYPE_OTHER, // Other instructions :-)
INSTRUCTION_TYPE_PRIV // Privileged instruction
};
// Operand types
enum Operand {
OPERAND_TYPE_NONE, // operand not present
OPERAND_TYPE_MEMORY, // memory operand ([eax], [0], etc.)
OPERAND_TYPE_REGISTER, // register operand (eax, mm0, etc.)
OPERAND_TYPE_IMMEDIATE, // immediate operand (0x1234)
};
// Structure definitions
// struct INST is used internally by the library
typedef struct _INST {
enum Instruction type; // Instruction type
const char *mnemonic; // Instruction mnemonic
int flags1; // First operand flags (if any)
int flags2; // Second operand flags (if any)
int flags3; // Additional operand flags (if any)
int modrm; // Is MODRM byte present?
} INST, *PINST;
// Operands for the instruction
typedef struct _OPERAND {
enum Operand type; // Operand type (register, memory, etc)
int reg; // Register (if any)
int basereg; // Base register (if any)
int indexreg; // Index register (if any)
int scale; // Scale (if any)
int dispbytes; // Displacement bytes (0 = no displacement)
int dispoffset; // Displacement value offset
int immbytes; // Immediate bytes (0 = no immediate)
int immoffset; // Immediate value offset
int sectionbytes; // Section prefix bytes (0 = no section prefix)
WORD section; // Section prefix value
DWORD displacement; // Displacement value
DWORD immediate; // Immediate value
int flags; // Operand flags
} OPERAND, *POPERAND;
// struct INSTRUCTION is used to interface the library
typedef struct _INSTRUCTION {
int length; // Instruction length
enum Instruction type; // Instruction type
enum Mode mode; // Addressing mode
BYTE opcode; // Actual opcode
BYTE modrm; // MODRM byte
BYTE sib; // SIB byte
int extindex; // Extension table index
int fpuindex; // FPU table index
int dispbytes; // Displacement bytes (0 = no displacement)
int immbytes; // Immediate bytes (0 = no immediate)
int sectionbytes; // Section prefix bytes (0 = no section prefix)
OPERAND op1; // First operand (if any)
OPERAND op2; // Second operand (if any)
OPERAND op3; // Additional operand (if any)
PINST ptr; // Pointer to instruction table
int flags; // Instruction flags
} INSTRUCTION, *PINSTRUCTION;
// Function definitions
int get_instruction(
INSTRUCTION *inst, // pointer to INSTRUCTION structure
BYTE *addr, // code buffer
enum Mode mode // mode: MODE_32 or MODE_16
);
// Get complete instruction string
int get_instruction_string(
INSTRUCTION *inst, // pointer to INSTRUCTION structure
enum Format format, // instruction format: FORMAT_ATT or FORMAT_INTEL
DWORD offset, // instruction absolute address
char *string, // string buffer
int length // string length
);
// Get mnemonic string
int get_mnemonic_string(
INSTRUCTION *inst, // pointer to INSTRUCTION structure
enum Format format, // instruction format: FORMAT_ATT or FORMAT_INTEL
char *string, // string buffer
int length // string length
);
// Get individual operand string
int get_operand_string(
INSTRUCTION *inst, // pointer to INSTRUCTION structure
POPERAND op, // pointer to OPERAND structure
enum Format format, // instruction format: FORMAT_ATT or FORMAT_INTEL
DWORD offset, // instruction absolute address
char *string, // string buffer
int length // string length
);
// Helper functions
int get_register_type(
POPERAND op
);
int get_operand_type(
POPERAND op
);
int get_operand_register(
POPERAND op
);
int get_operand_basereg(
POPERAND op
);
int get_operand_indexreg(
POPERAND op
);
int get_operand_scale(
POPERAND op
);
int get_operand_immediate(
POPERAND op,
DWORD *imm // returned immediate value
);
int get_operand_displacement(
POPERAND op,
DWORD *disp // returned displacement value
);
POPERAND get_source_operand(
PINSTRUCTION inst
);
POPERAND get_destination_operand(
PINSTRUCTION inst
);
// Instruction prefix groups
// Group 1
#define MASK_PREFIX_G1(x) ((x) & 0xFF000000) >> 24
#define PREFIX_LOCK 0x01000000 // 0xf0
#define PREFIX_REPNE 0x02000000 // 0xf2
#define PREFIX_REP 0x03000000 // 0xf3
#define PREFIX_REPE 0x03000000 // 0xf3
// Group 2
#define MASK_PREFIX_G2(x) ((x) & 0x00FF0000) >> 16
#define PREFIX_ES_OVERRIDE 0x00010000 // 0x26
#define PREFIX_CS_OVERRIDE 0x00020000 // 0x2e
#define PREFIX_SS_OVERRIDE 0x00030000 // 0x36
#define PREFIX_DS_OVERRIDE 0x00040000 // 0x3e
#define PREFIX_FS_OVERRIDE 0x00050000 // 0x64
#define PREFIX_GS_OVERRIDE 0x00060000 // 0x65
// Group 3 & 4
#define MASK_PREFIX_G3(x) ((x) & 0x0000FF00) >> 8
#define MASK_PREFIX_OPERAND(x) ((x) & 0x00000F00) >> 8
#define MASK_PREFIX_ADDR(x) ((x) & 0x0000F000) >> 12
#define PREFIX_OPERAND_SIZE_OVERRIDE 0x00000100 // 0x66
#define PREFIX_ADDR_SIZE_OVERRIDE 0x00001000 // 0x67
// Extensions
#define MASK_EXT(x) ((x) & 0x000000FF)
#define EXT_G1 0x00000001
#define EXT_G2 0x00000002
#define EXT_G3 0x00000003
#define EXT_G4 0x00000004
#define EXT_G5 0x00000005
#define EXT_G6 0x00000006
#define EXT_G7 0x00000007
#define EXT_G8 0x00000008
#define EXT_G9 0x00000009
#define EXT_GA 0x0000000a
#define EXT_GB 0x0000000b
#define EXT_GC 0x0000000c
#define EXT_GD 0x0000000d
#define EXT_GE 0x0000000e
#define EXT_GF 0x0000000f
#define EXT_G0 0x00000010
// Extra groups for 2 and 3-byte opcodes, and FPU stuff
#define EXT_T2 0x00000020 // opcode table 2
#define EXT_CP 0x00000030 // co-processor
// Operand flags
#define FLAGS_NONE 0
// Operand Addressing Methods, from the Intel manual
#define MASK_AM(x) ((x) & 0x00FF0000)
#define AM_A 0x00010000 // Direct address with segment prefix
#define AM_C 0x00020000 // MODRM reg field defines control register
#define AM_D 0x00030000 // MODRM reg field defines debug register
#define AM_E 0x00040000 // MODRM byte defines reg/memory address
#define AM_G 0x00050000 // MODRM byte defines general-purpose reg
#define AM_I 0x00060000 // Immediate data follows
#define AM_J 0x00070000 // Immediate value is relative to EIP
#define AM_M 0x00080000 // MODRM mod field can refer only to memory
#define AM_O 0x00090000 // Displacement follows (without modrm/sib)
#define AM_P 0x000a0000 // MODRM reg field defines MMX register
#define AM_Q 0x000b0000 // MODRM defines MMX register or memory
#define AM_R 0x000c0000 // MODRM mod field can only refer to register
#define AM_S 0x000d0000 // MODRM reg field defines segment register
#define AM_T 0x000e0000 // MODRM reg field defines test register
#define AM_V 0x000f0000 // MODRM reg field defines XMM register
#define AM_W 0x00100000 // MODRM defines XMM register or memory
// Extra addressing modes used in this implementation
#define AM_I1 0x00200000 // Immediate byte 1 encoded in instruction
#define AM_REG 0x00210000 // Register encoded in instruction
// Operand Types, from the intel manual
#define MASK_OT(x) ((x) & 0xFF000000)
#define OT_a 0x01000000
#define OT_b 0x02000000 // always 1 byte
#define OT_c 0x03000000 // byte or word, depending on operand
#define OT_d 0x04000000 // double-word
#define OT_q 0x05000000 // quad-word
#define OT_dq 0x06000000 // double quad-word
#define OT_v 0x07000000 // word or double-word, depending on operand
#define OT_w 0x08000000 // always word
#define OT_p 0x09000000 // 32-bit or 48-bit pointer
#define OT_pi 0x0a000000 // quadword MMX register
#define OT_pd 0x0b000000 // 128-bit double-precision float
#define OT_ps 0x0c000000 // 128-bit single-precision float
#define OT_s 0x0d000000 // 6-byte pseudo descriptor
#define OT_sd 0x0e000000 // Scalar of 128-bit double-precision float
#define OT_ss 0x0f000000 // Scalar of 128-bit single-precision float
#define OT_si 0x10000000 // Doubleword integer register
#define OT_t 0x11000000 // 80-bit packed FP data
// Additional operand flags
#define MASK_FLAGS(x) ((x) & 0x0000FF00)
#define F_s 0x00000100 // sign-extend 1-byte immediate
#define F_r 0x00000200 // use segment register
#define F_f 0x00000300 // use FPU register
// MODRM byte
#define MASK_MODRM_MOD(x) (((x) & 0xc0) >> 6)
#define MASK_MODRM_REG(x) (((x) & 0x38) >> 3)
#define MASK_MODRM_RM(x) ((x) & 0x7)
// SIB byte
#define MASK_SIB_SCALE(x) MASK_MODRM_MOD(x)
#define MASK_SIB_INDEX(x) MASK_MODRM_REG(x)
#define MASK_SIB_BASE(x) MASK_MODRM_RM(x)
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,18 @@
TARGETNAME=CheckKernelHook
#TARGETPATH=$(BASEDIR)\lib
TARGETPATH=obj
TARGETTYPE=DRIVER
INCLUDES=.\
SOURCES= \
DriverEntry.c \
Common.c \
KernelHookCheck.c \
Reload.c \
FileSystem.c \
FixRelocation.c \
KernelReload.c \
libdasm.c
@@ -0,0 +1,3 @@
1.Reload the first kernel module
2.check EAT function (Zwxx)
3.check InlineHook (not Zwxx)